diff --git a/contracts/mdbase.view/1.0.0.md b/contracts/mdbase.view/1.0.0.md new file mode 100644 index 0000000..6c014f3 --- /dev/null +++ b/contracts/mdbase.view/1.0.0.md @@ -0,0 +1,26 @@ +--- +kind: mdbase.contract +contract_type: record +id: mdbase.view +version: 1.0.0 +name: Saved view +description: Shared query scope and stable named views executable through the Query profile. +record_schema: + dialect: json-schema-2020-12 + ref: ../../schemas/mdbase.view/1.0.0.schema.json +--- + +# Saved view + +A record exposed through `mdbase.view` stores shared query scope and one or more +stable named views. Each named view resolves to the query model in Chapter 11. +Optional `presentation` metadata is advisory and does not alter headless query +results. + +Implementing this contract is how a collection declares which of its records +are saved views. A tool that advertises `view_records` discovers and executes +views through this contract's type implementations, not through a reserved type +name, path, or frontmatter value. + +This artifact is passive. Implementing it grants no authority to read, execute, +or modify any record. diff --git a/dist/artifacts/contracts/mdbase.view/1.0.0.md b/dist/artifacts/contracts/mdbase.view/1.0.0.md new file mode 100644 index 0000000..6c014f3 --- /dev/null +++ b/dist/artifacts/contracts/mdbase.view/1.0.0.md @@ -0,0 +1,26 @@ +--- +kind: mdbase.contract +contract_type: record +id: mdbase.view +version: 1.0.0 +name: Saved view +description: Shared query scope and stable named views executable through the Query profile. +record_schema: + dialect: json-schema-2020-12 + ref: ../../schemas/mdbase.view/1.0.0.schema.json +--- + +# Saved view + +A record exposed through `mdbase.view` stores shared query scope and one or more +stable named views. Each named view resolves to the query model in Chapter 11. +Optional `presentation` metadata is advisory and does not alter headless query +results. + +Implementing this contract is how a collection declares which of its records +are saved views. A tool that advertises `view_records` discovers and executes +views through this contract's type implementations, not through a reserved type +name, path, or frontmatter value. + +This artifact is passive. Implementing it grants no authority to read, execute, +or modify any record. diff --git a/dist/artifacts/schemas/mdbase.view/1.0.0.schema.json b/dist/artifacts/schemas/mdbase.view/1.0.0.schema.json new file mode 100644 index 0000000..d98e82f --- /dev/null +++ b/dist/artifacts/schemas/mdbase.view/1.0.0.schema.json @@ -0,0 +1,261 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://mdbase.dev/schemas/v0.3/view.schema.json", + "title": "mdbase.view 1.0.0 record contract view", + "description": "The contract view of a saved-view record. A type implements mdbase.view by mapping these fields; the optional type property only lets the canonical view type validate its own membership value.", + "type": "object", + "required": ["id", "version", "name", "views"], + "properties": { + "type": { "type": "string", "minLength": 1 }, + "id": { "$ref": "#/$defs/identifier" }, + "version": { "type": "integer", "minimum": 1 }, + "name": { "type": "string", "minLength": 1 }, + "description": { "type": "string" }, + "query": { "$ref": "#/$defs/sharedQuery" }, + "properties": { "$ref": "#/$defs/propertyMetadataSet" }, + "summary_functions": { "$ref": "#/$defs/summaryFunctionSet" }, + "views": { + "type": "array", + "minItems": 1, + "items": { "$ref": "#/$defs/view" } + } + }, + "patternProperties": { + "^x-[A-Za-z][A-Za-z0-9._:-]{0,127}$": { "$ref": "#/$defs/extension" } + }, + "additionalProperties": false, + "$defs": { + "identifier": { + "type": "string", + "pattern": "^[A-Za-z][A-Za-z0-9._:-]*$" + }, + "typeName": { + "type": "string", + "pattern": "^[A-Za-z][A-Za-z0-9_-]{0,127}$" + }, + "fieldName": { + "type": "string", + "pattern": "^[A-Za-z_][A-Za-z0-9_:-]*$" + }, + "expression": { + "type": "string", + "minLength": 1 + }, + "extension": { + "type": "object", + "additionalProperties": true + }, + "typeList": { + "type": "array", + "minItems": 1, + "uniqueItems": true, + "items": { "$ref": "#/$defs/typeName" } + }, + "sharedQuery": { + "type": "object", + "properties": { + "types": { "$ref": "#/$defs/typeList" }, + "where": { "$ref": "#/$defs/expression" }, + "context": { "$ref": "#/$defs/viewContext" }, + "projections": { "$ref": "#/$defs/projectionSet" } + }, + "patternProperties": { + "^x-[A-Za-z][A-Za-z0-9._:-]{0,127}$": { "$ref": "#/$defs/extension" } + }, + "additionalProperties": false + }, + "viewContext": { + "type": "object", + "required": ["this"], + "properties": { + "this": { "$ref": "#/$defs/thisContext" } + }, + "patternProperties": { + "^x-[A-Za-z][A-Za-z0-9._:-]{0,127}$": { "$ref": "#/$defs/extension" } + }, + "additionalProperties": false + }, + "thisContext": { + "type": "object", + "properties": { + "on_missing": { + "enum": ["view", "null", "error"], + "default": "view" + }, + "types": { "$ref": "#/$defs/typeList" } + }, + "patternProperties": { + "^x-[A-Za-z][A-Za-z0-9._:-]{0,127}$": { "$ref": "#/$defs/extension" } + }, + "additionalProperties": false + }, + "projectionSet": { + "type": "object", + "propertyNames": { "$ref": "#/$defs/fieldName" }, + "additionalProperties": { "$ref": "#/$defs/projection" } + }, + "projection": { + "type": "object", + "required": ["expr"], + "properties": { + "expr": { "$ref": "#/$defs/expression" }, + "description": { "type": "string" } + }, + "patternProperties": { + "^x-[A-Za-z][A-Za-z0-9._:-]{0,127}$": { "$ref": "#/$defs/extension" } + }, + "additionalProperties": false + }, + "propertyMetadataSet": { + "type": "object", + "propertyNames": { "type": "string", "minLength": 1 }, + "additionalProperties": { "$ref": "#/$defs/propertyMetadata" } + }, + "propertyMetadata": { + "type": "object", + "properties": { + "label": { "type": "string" }, + "description": { "type": "string" }, + "format": { "type": "string" }, + "hidden": { "type": "boolean" } + }, + "patternProperties": { + "^x-[A-Za-z][A-Za-z0-9._:-]{0,127}$": { "$ref": "#/$defs/extension" } + }, + "additionalProperties": false + }, + "summaryFunctionSet": { + "type": "object", + "propertyNames": { "$ref": "#/$defs/fieldName" }, + "additionalProperties": { "$ref": "#/$defs/summaryFunction" } + }, + "summaryFunction": { + "type": "object", + "required": ["expr"], + "properties": { + "expr": { "$ref": "#/$defs/expression" }, + "description": { "type": "string" } + }, + "patternProperties": { + "^x-[A-Za-z][A-Za-z0-9._:-]{0,127}$": { "$ref": "#/$defs/extension" } + }, + "additionalProperties": false + }, + "view": { + "type": "object", + "required": ["id", "name"], + "properties": { + "id": { "$ref": "#/$defs/identifier" }, + "name": { "type": "string", "minLength": 1 }, + "description": { "type": "string" }, + "types": { "$ref": "#/$defs/typeList" }, + "where": { "$ref": "#/$defs/expression" }, + "context": { "$ref": "#/$defs/viewContext" }, + "projections": { "$ref": "#/$defs/projectionSet" }, + "select": { "$ref": "#/$defs/select" }, + "order_by": { "$ref": "#/$defs/orderBy" }, + "group_by": { "$ref": "#/$defs/groupBy" }, + "summaries": { "$ref": "#/$defs/summaries" }, + "limit": { "type": "integer", "minimum": 0 }, + "offset": { "type": "integer", "minimum": 0 }, + "include_body": { "type": "boolean", "default": false }, + "frontmatter_mode": { + "enum": ["effective", "persisted", "both"], + "default": "effective" + }, + "presentation": { "$ref": "#/$defs/presentation" } + }, + "patternProperties": { + "^x-[A-Za-z][A-Za-z0-9._:-]{0,127}$": { "$ref": "#/$defs/extension" } + }, + "additionalProperties": false + }, + "select": { + "type": "array", + "minItems": 1, + "items": { + "oneOf": [ + { "type": "string", "minLength": 1 }, + { "$ref": "#/$defs/selectExpression" } + ] + } + }, + "selectExpression": { + "type": "object", + "required": ["name", "expr"], + "properties": { + "name": { "$ref": "#/$defs/fieldName" }, + "expr": { "$ref": "#/$defs/expression" }, + "label": { "type": "string" }, + "description": { "type": "string" } + }, + "patternProperties": { + "^x-[A-Za-z][A-Za-z0-9._:-]{0,127}$": { "$ref": "#/$defs/extension" } + }, + "additionalProperties": false + }, + "orderBy": { + "type": "array", + "minItems": 1, + "items": { + "type": "object", + "required": ["field"], + "properties": { + "field": { "type": "string", "minLength": 1 }, + "direction": { "enum": ["asc", "desc"], "default": "asc" } + }, + "additionalProperties": false + } + }, + "groupBy": { + "type": "array", + "minItems": 1, + "items": { + "type": "object", + "required": ["field"], + "properties": { + "field": { "type": "string", "minLength": 1 }, + "direction": { "enum": ["asc", "desc"], "default": "asc" } + }, + "additionalProperties": false + } + }, + "summaries": { + "type": "array", + "minItems": 1, + "items": { "$ref": "#/$defs/summary" } + }, + "summary": { + "type": "object", + "required": ["field", "function"], + "properties": { + "field": { "type": "string", "minLength": 1 }, + "function": { "$ref": "#/$defs/identifier" }, + "name": { "$ref": "#/$defs/fieldName" }, + "label": { "type": "string" } + }, + "additionalProperties": false + }, + "presentation": { + "type": "object", + "required": ["type"], + "properties": { + "type": { "$ref": "#/$defs/identifier" }, + "fallback": { "$ref": "#/$defs/identifier" }, + "mappings": { + "type": "object", + "propertyNames": { "$ref": "#/$defs/fieldName" }, + "additionalProperties": { "type": "string", "minLength": 1 } + }, + "options": { + "type": "object", + "additionalProperties": true + } + }, + "patternProperties": { + "^x-[A-Za-z][A-Za-z0-9._:-]{0,127}$": { "$ref": "#/$defs/extension" } + }, + "additionalProperties": false + } + } +} diff --git a/dist/artifacts/types/view/1.md b/dist/artifacts/types/view/1.md new file mode 100644 index 0000000..9f38f2a --- /dev/null +++ b/dist/artifacts/types/view/1.md @@ -0,0 +1,352 @@ +--- +kind: mdbase.type +name: view +version: 1 +description: 'Saved views: shared query scope and stable named views' +match: + where: + type: view +schema: + dialect: json-schema-2020-12 + value: + $schema: https://json-schema.org/draft/2020-12/schema + title: View + description: 'Saved views: shared query scope and stable named views.' + type: object + required: + - type + - id + - version + - name + - views + properties: + type: + const: view + id: + $ref: '#/$defs/identifier' + version: + type: integer + minimum: 1 + name: + type: string + minLength: 1 + description: + type: string + query: + $ref: '#/$defs/sharedQuery' + properties: + $ref: '#/$defs/propertyMetadataSet' + summary_functions: + $ref: '#/$defs/summaryFunctionSet' + views: + type: array + minItems: 1 + items: + $ref: '#/$defs/view' + patternProperties: + ^x-[A-Za-z][A-Za-z0-9._:-]{0,127}$: + $ref: '#/$defs/extension' + additionalProperties: false + $defs: + identifier: + type: string + pattern: ^[A-Za-z][A-Za-z0-9._:-]*$ + typeName: + type: string + pattern: ^[A-Za-z][A-Za-z0-9_-]{0,127}$ + fieldName: + type: string + pattern: ^[A-Za-z_][A-Za-z0-9_:-]*$ + expression: + type: string + minLength: 1 + extension: + type: object + additionalProperties: true + typeList: + type: array + minItems: 1 + uniqueItems: true + items: + $ref: '#/$defs/typeName' + sharedQuery: + type: object + properties: + types: + $ref: '#/$defs/typeList' + where: + $ref: '#/$defs/expression' + context: + $ref: '#/$defs/viewContext' + projections: + $ref: '#/$defs/projectionSet' + patternProperties: + ^x-[A-Za-z][A-Za-z0-9._:-]{0,127}$: + $ref: '#/$defs/extension' + additionalProperties: false + viewContext: + type: object + required: + - this + properties: + this: + $ref: '#/$defs/thisContext' + patternProperties: + ^x-[A-Za-z][A-Za-z0-9._:-]{0,127}$: + $ref: '#/$defs/extension' + additionalProperties: false + thisContext: + type: object + properties: + on_missing: + enum: + - view + - 'null' + - error + default: view + types: + $ref: '#/$defs/typeList' + patternProperties: + ^x-[A-Za-z][A-Za-z0-9._:-]{0,127}$: + $ref: '#/$defs/extension' + additionalProperties: false + projectionSet: + type: object + propertyNames: + $ref: '#/$defs/fieldName' + additionalProperties: + $ref: '#/$defs/projection' + projection: + type: object + required: + - expr + properties: + expr: + $ref: '#/$defs/expression' + description: + type: string + patternProperties: + ^x-[A-Za-z][A-Za-z0-9._:-]{0,127}$: + $ref: '#/$defs/extension' + additionalProperties: false + propertyMetadataSet: + type: object + propertyNames: + type: string + minLength: 1 + additionalProperties: + $ref: '#/$defs/propertyMetadata' + propertyMetadata: + type: object + properties: + label: + type: string + description: + type: string + format: + type: string + hidden: + type: boolean + patternProperties: + ^x-[A-Za-z][A-Za-z0-9._:-]{0,127}$: + $ref: '#/$defs/extension' + additionalProperties: false + summaryFunctionSet: + type: object + propertyNames: + $ref: '#/$defs/fieldName' + additionalProperties: + $ref: '#/$defs/summaryFunction' + summaryFunction: + type: object + required: + - expr + properties: + expr: + $ref: '#/$defs/expression' + description: + type: string + patternProperties: + ^x-[A-Za-z][A-Za-z0-9._:-]{0,127}$: + $ref: '#/$defs/extension' + additionalProperties: false + view: + type: object + required: + - id + - name + properties: + id: + $ref: '#/$defs/identifier' + name: + type: string + minLength: 1 + description: + type: string + types: + $ref: '#/$defs/typeList' + where: + $ref: '#/$defs/expression' + context: + $ref: '#/$defs/viewContext' + projections: + $ref: '#/$defs/projectionSet' + select: + $ref: '#/$defs/select' + order_by: + $ref: '#/$defs/orderBy' + group_by: + $ref: '#/$defs/groupBy' + summaries: + $ref: '#/$defs/summaries' + limit: + type: integer + minimum: 0 + offset: + type: integer + minimum: 0 + include_body: + type: boolean + default: false + frontmatter_mode: + enum: + - effective + - persisted + - both + default: effective + presentation: + $ref: '#/$defs/presentation' + patternProperties: + ^x-[A-Za-z][A-Za-z0-9._:-]{0,127}$: + $ref: '#/$defs/extension' + additionalProperties: false + select: + type: array + minItems: 1 + items: + oneOf: + - type: string + minLength: 1 + - $ref: '#/$defs/selectExpression' + selectExpression: + type: object + required: + - name + - expr + properties: + name: + $ref: '#/$defs/fieldName' + expr: + $ref: '#/$defs/expression' + label: + type: string + description: + type: string + patternProperties: + ^x-[A-Za-z][A-Za-z0-9._:-]{0,127}$: + $ref: '#/$defs/extension' + additionalProperties: false + orderBy: + type: array + minItems: 1 + items: + type: object + required: + - field + properties: + field: + type: string + minLength: 1 + direction: + enum: + - asc + - desc + default: asc + additionalProperties: false + groupBy: + type: array + minItems: 1 + items: + type: object + required: + - field + properties: + field: + type: string + minLength: 1 + direction: + enum: + - asc + - desc + default: asc + additionalProperties: false + summaries: + type: array + minItems: 1 + items: + $ref: '#/$defs/summary' + summary: + type: object + required: + - field + - function + properties: + field: + type: string + minLength: 1 + function: + $ref: '#/$defs/identifier' + name: + $ref: '#/$defs/fieldName' + label: + type: string + additionalProperties: false + presentation: + type: object + required: + - type + properties: + type: + $ref: '#/$defs/identifier' + fallback: + $ref: '#/$defs/identifier' + mappings: + type: object + propertyNames: + $ref: '#/$defs/fieldName' + additionalProperties: + type: string + minLength: 1 + options: + type: object + additionalProperties: true + patternProperties: + ^x-[A-Za-z][A-Za-z0-9._:-]{0,127}$: + $ref: '#/$defs/extension' + additionalProperties: false +implements: +- contract: mdbase.view + version: 1.0.0 + fields: + id: id + version: version + name: name + description: description + query: query + properties: properties + summary_functions: summary_functions + views: views +collection: + display: + name_field: name +--- + +# View + +A view record stores shared query scope and one or more stable named views. +Tools that support saved views discover these records through the `mdbase.view` +contract and run each named view as an ordinary query. + +This type belongs to your collection once installed. You can rename fields or +change how records are matched, as long as the `implements` mapping still +points each contract field at the right frontmatter field. diff --git a/dist/catalog.json b/dist/catalog.json index 443a622..3506bc7 100644 --- a/dist/catalog.json +++ b/dist/catalog.json @@ -199,6 +199,16 @@ "artifact": "./artifacts/contracts/mdbase.runtime.workflow/1.0.0.md", "standards": [] }, + { + "id": "mdbase.view", + "version": "1.0.0", + "name": "Saved view", + "description": "Shared query scope and stable named views executable through the Query profile.", + "contract_type": "record", + "digest": "sha256:91eae42371c2d411b20d3c976aece3071bbd753963b77b6bcdc26137a8fdcded", + "artifact": "./artifacts/contracts/mdbase.view/1.0.0.md", + "standards": [] + }, { "id": "tasknotes.task", "version": "0.3.0-rc.3", @@ -465,6 +475,43 @@ ] } }, + { + "id": "mdbase.view", + "version": "1.0.0", + "name": "Saved views", + "description": "The mdbase.view contract and an editable View type for saved, reusable queries.", + "digest": "sha256:d2a3ff8629699b183bb8117d7499697fecc7685ed8558cae6d9a87311d7cfd05", + "provision": "./packs/mdbase.view/1.0.0.json", + "provides": [ + { + "id": "mdbase.view", + "version": "1.0.0", + "digest": "sha256:0918acefce08cddd778fab768fe4f2e4615d263a0eec3e5330b6897c686d744e" + } + ], + "resource_count": 3, + "display": { + "name": "Saved views", + "summary": "Save reusable queries that any view-aware app can list and run.", + "category": "work", + "audience": "general", + "icon": "table", + "badges": [ + "Portable views" + ] + }, + "installation": { + "visibility": "default", + "recommendation": "optional", + "primary_type": "view", + "types": [ + { + "name": "view", + "label": "View" + } + ] + } + }, { "id": "tasknotes.task", "version": "0.3.0-rc.12", diff --git a/dist/packs/mdbase.view/1.0.0.json b/dist/packs/mdbase.view/1.0.0.json new file mode 100644 index 0000000..210fa58 --- /dev/null +++ b/dist/packs/mdbase.view/1.0.0.json @@ -0,0 +1,53 @@ +{ + "manifest": { + "kind": "mdbase.type-pack", + "id": "mdbase.view", + "version": "1.0.0", + "name": "Saved views", + "description": "The mdbase.view contract and an editable View type for saved, reusable queries.", + "resources": [ + { + "kind": "schema", + "mode": "managed", + "source": "schemas/mdbase.view/1.0.0.schema.json", + "target": "schemas/mdbase.view/1.0.0.schema.json", + "digest": "sha256:d58b8b691c14d59f0575fc1cc93ab5b46363c485e4469bc58039ec0cece7ca36" + }, + { + "kind": "contract", + "mode": "managed", + "source": "contracts/mdbase.view/1.0.0.md", + "target": "_contracts/mdbase.view/1.0.0.md", + "digest": "sha256:91eae42371c2d411b20d3c976aece3071bbd753963b77b6bcdc26137a8fdcded" + }, + { + "kind": "type", + "mode": "seed", + "source": "types/view/1.md", + "target": "_types/view.md", + "digest": "sha256:480919f6f88f91592abb9fe7971f09e874d536c6883981616b181cf14cbe7ff4" + } + ] + }, + "resources": [ + { + "source": "schemas/mdbase.view/1.0.0.schema.json", + "document": "{\n \"$schema\": \"https://json-schema.org/draft/2020-12/schema\",\n \"$id\": \"https://mdbase.dev/schemas/v0.3/view.schema.json\",\n \"title\": \"mdbase.view 1.0.0 record contract view\",\n \"description\": \"The contract view of a saved-view record. A type implements mdbase.view by mapping these fields; the optional type property only lets the canonical view type validate its own membership value.\",\n \"type\": \"object\",\n \"required\": [\"id\", \"version\", \"name\", \"views\"],\n \"properties\": {\n \"type\": { \"type\": \"string\", \"minLength\": 1 },\n \"id\": { \"$ref\": \"#/$defs/identifier\" },\n \"version\": { \"type\": \"integer\", \"minimum\": 1 },\n \"name\": { \"type\": \"string\", \"minLength\": 1 },\n \"description\": { \"type\": \"string\" },\n \"query\": { \"$ref\": \"#/$defs/sharedQuery\" },\n \"properties\": { \"$ref\": \"#/$defs/propertyMetadataSet\" },\n \"summary_functions\": { \"$ref\": \"#/$defs/summaryFunctionSet\" },\n \"views\": {\n \"type\": \"array\",\n \"minItems\": 1,\n \"items\": { \"$ref\": \"#/$defs/view\" }\n }\n },\n \"patternProperties\": {\n \"^x-[A-Za-z][A-Za-z0-9._:-]{0,127}$\": { \"$ref\": \"#/$defs/extension\" }\n },\n \"additionalProperties\": false,\n \"$defs\": {\n \"identifier\": {\n \"type\": \"string\",\n \"pattern\": \"^[A-Za-z][A-Za-z0-9._:-]*$\"\n },\n \"typeName\": {\n \"type\": \"string\",\n \"pattern\": \"^[A-Za-z][A-Za-z0-9_-]{0,127}$\"\n },\n \"fieldName\": {\n \"type\": \"string\",\n \"pattern\": \"^[A-Za-z_][A-Za-z0-9_:-]*$\"\n },\n \"expression\": {\n \"type\": \"string\",\n \"minLength\": 1\n },\n \"extension\": {\n \"type\": \"object\",\n \"additionalProperties\": true\n },\n \"typeList\": {\n \"type\": \"array\",\n \"minItems\": 1,\n \"uniqueItems\": true,\n \"items\": { \"$ref\": \"#/$defs/typeName\" }\n },\n \"sharedQuery\": {\n \"type\": \"object\",\n \"properties\": {\n \"types\": { \"$ref\": \"#/$defs/typeList\" },\n \"where\": { \"$ref\": \"#/$defs/expression\" },\n \"context\": { \"$ref\": \"#/$defs/viewContext\" },\n \"projections\": { \"$ref\": \"#/$defs/projectionSet\" }\n },\n \"patternProperties\": {\n \"^x-[A-Za-z][A-Za-z0-9._:-]{0,127}$\": { \"$ref\": \"#/$defs/extension\" }\n },\n \"additionalProperties\": false\n },\n \"viewContext\": {\n \"type\": \"object\",\n \"required\": [\"this\"],\n \"properties\": {\n \"this\": { \"$ref\": \"#/$defs/thisContext\" }\n },\n \"patternProperties\": {\n \"^x-[A-Za-z][A-Za-z0-9._:-]{0,127}$\": { \"$ref\": \"#/$defs/extension\" }\n },\n \"additionalProperties\": false\n },\n \"thisContext\": {\n \"type\": \"object\",\n \"properties\": {\n \"on_missing\": {\n \"enum\": [\"view\", \"null\", \"error\"],\n \"default\": \"view\"\n },\n \"types\": { \"$ref\": \"#/$defs/typeList\" }\n },\n \"patternProperties\": {\n \"^x-[A-Za-z][A-Za-z0-9._:-]{0,127}$\": { \"$ref\": \"#/$defs/extension\" }\n },\n \"additionalProperties\": false\n },\n \"projectionSet\": {\n \"type\": \"object\",\n \"propertyNames\": { \"$ref\": \"#/$defs/fieldName\" },\n \"additionalProperties\": { \"$ref\": \"#/$defs/projection\" }\n },\n \"projection\": {\n \"type\": \"object\",\n \"required\": [\"expr\"],\n \"properties\": {\n \"expr\": { \"$ref\": \"#/$defs/expression\" },\n \"description\": { \"type\": \"string\" }\n },\n \"patternProperties\": {\n \"^x-[A-Za-z][A-Za-z0-9._:-]{0,127}$\": { \"$ref\": \"#/$defs/extension\" }\n },\n \"additionalProperties\": false\n },\n \"propertyMetadataSet\": {\n \"type\": \"object\",\n \"propertyNames\": { \"type\": \"string\", \"minLength\": 1 },\n \"additionalProperties\": { \"$ref\": \"#/$defs/propertyMetadata\" }\n },\n \"propertyMetadata\": {\n \"type\": \"object\",\n \"properties\": {\n \"label\": { \"type\": \"string\" },\n \"description\": { \"type\": \"string\" },\n \"format\": { \"type\": \"string\" },\n \"hidden\": { \"type\": \"boolean\" }\n },\n \"patternProperties\": {\n \"^x-[A-Za-z][A-Za-z0-9._:-]{0,127}$\": { \"$ref\": \"#/$defs/extension\" }\n },\n \"additionalProperties\": false\n },\n \"summaryFunctionSet\": {\n \"type\": \"object\",\n \"propertyNames\": { \"$ref\": \"#/$defs/fieldName\" },\n \"additionalProperties\": { \"$ref\": \"#/$defs/summaryFunction\" }\n },\n \"summaryFunction\": {\n \"type\": \"object\",\n \"required\": [\"expr\"],\n \"properties\": {\n \"expr\": { \"$ref\": \"#/$defs/expression\" },\n \"description\": { \"type\": \"string\" }\n },\n \"patternProperties\": {\n \"^x-[A-Za-z][A-Za-z0-9._:-]{0,127}$\": { \"$ref\": \"#/$defs/extension\" }\n },\n \"additionalProperties\": false\n },\n \"view\": {\n \"type\": \"object\",\n \"required\": [\"id\", \"name\"],\n \"properties\": {\n \"id\": { \"$ref\": \"#/$defs/identifier\" },\n \"name\": { \"type\": \"string\", \"minLength\": 1 },\n \"description\": { \"type\": \"string\" },\n \"types\": { \"$ref\": \"#/$defs/typeList\" },\n \"where\": { \"$ref\": \"#/$defs/expression\" },\n \"context\": { \"$ref\": \"#/$defs/viewContext\" },\n \"projections\": { \"$ref\": \"#/$defs/projectionSet\" },\n \"select\": { \"$ref\": \"#/$defs/select\" },\n \"order_by\": { \"$ref\": \"#/$defs/orderBy\" },\n \"group_by\": { \"$ref\": \"#/$defs/groupBy\" },\n \"summaries\": { \"$ref\": \"#/$defs/summaries\" },\n \"limit\": { \"type\": \"integer\", \"minimum\": 0 },\n \"offset\": { \"type\": \"integer\", \"minimum\": 0 },\n \"include_body\": { \"type\": \"boolean\", \"default\": false },\n \"frontmatter_mode\": {\n \"enum\": [\"effective\", \"persisted\", \"both\"],\n \"default\": \"effective\"\n },\n \"presentation\": { \"$ref\": \"#/$defs/presentation\" }\n },\n \"patternProperties\": {\n \"^x-[A-Za-z][A-Za-z0-9._:-]{0,127}$\": { \"$ref\": \"#/$defs/extension\" }\n },\n \"additionalProperties\": false\n },\n \"select\": {\n \"type\": \"array\",\n \"minItems\": 1,\n \"items\": {\n \"oneOf\": [\n { \"type\": \"string\", \"minLength\": 1 },\n { \"$ref\": \"#/$defs/selectExpression\" }\n ]\n }\n },\n \"selectExpression\": {\n \"type\": \"object\",\n \"required\": [\"name\", \"expr\"],\n \"properties\": {\n \"name\": { \"$ref\": \"#/$defs/fieldName\" },\n \"expr\": { \"$ref\": \"#/$defs/expression\" },\n \"label\": { \"type\": \"string\" },\n \"description\": { \"type\": \"string\" }\n },\n \"patternProperties\": {\n \"^x-[A-Za-z][A-Za-z0-9._:-]{0,127}$\": { \"$ref\": \"#/$defs/extension\" }\n },\n \"additionalProperties\": false\n },\n \"orderBy\": {\n \"type\": \"array\",\n \"minItems\": 1,\n \"items\": {\n \"type\": \"object\",\n \"required\": [\"field\"],\n \"properties\": {\n \"field\": { \"type\": \"string\", \"minLength\": 1 },\n \"direction\": { \"enum\": [\"asc\", \"desc\"], \"default\": \"asc\" }\n },\n \"additionalProperties\": false\n }\n },\n \"groupBy\": {\n \"type\": \"array\",\n \"minItems\": 1,\n \"items\": {\n \"type\": \"object\",\n \"required\": [\"field\"],\n \"properties\": {\n \"field\": { \"type\": \"string\", \"minLength\": 1 },\n \"direction\": { \"enum\": [\"asc\", \"desc\"], \"default\": \"asc\" }\n },\n \"additionalProperties\": false\n }\n },\n \"summaries\": {\n \"type\": \"array\",\n \"minItems\": 1,\n \"items\": { \"$ref\": \"#/$defs/summary\" }\n },\n \"summary\": {\n \"type\": \"object\",\n \"required\": [\"field\", \"function\"],\n \"properties\": {\n \"field\": { \"type\": \"string\", \"minLength\": 1 },\n \"function\": { \"$ref\": \"#/$defs/identifier\" },\n \"name\": { \"$ref\": \"#/$defs/fieldName\" },\n \"label\": { \"type\": \"string\" }\n },\n \"additionalProperties\": false\n },\n \"presentation\": {\n \"type\": \"object\",\n \"required\": [\"type\"],\n \"properties\": {\n \"type\": { \"$ref\": \"#/$defs/identifier\" },\n \"fallback\": { \"$ref\": \"#/$defs/identifier\" },\n \"mappings\": {\n \"type\": \"object\",\n \"propertyNames\": { \"$ref\": \"#/$defs/fieldName\" },\n \"additionalProperties\": { \"type\": \"string\", \"minLength\": 1 }\n },\n \"options\": {\n \"type\": \"object\",\n \"additionalProperties\": true\n }\n },\n \"patternProperties\": {\n \"^x-[A-Za-z][A-Za-z0-9._:-]{0,127}$\": { \"$ref\": \"#/$defs/extension\" }\n },\n \"additionalProperties\": false\n }\n }\n}\n" + }, + { + "source": "contracts/mdbase.view/1.0.0.md", + "document": "---\nkind: mdbase.contract\ncontract_type: record\nid: mdbase.view\nversion: 1.0.0\nname: Saved view\ndescription: Shared query scope and stable named views executable through the Query profile.\nrecord_schema:\n dialect: json-schema-2020-12\n ref: ../../schemas/mdbase.view/1.0.0.schema.json\n---\n\n# Saved view\n\nA record exposed through `mdbase.view` stores shared query scope and one or more\nstable named views. Each named view resolves to the query model in Chapter 11.\nOptional `presentation` metadata is advisory and does not alter headless query\nresults.\n\nImplementing this contract is how a collection declares which of its records\nare saved views. A tool that advertises `view_records` discovers and executes\nviews through this contract's type implementations, not through a reserved type\nname, path, or frontmatter value.\n\nThis artifact is passive. Implementing it grants no authority to read, execute,\nor modify any record.\n" + }, + { + "source": "types/view/1.md", + "document": "---\nkind: mdbase.type\nname: view\nversion: 1\ndescription: 'Saved views: shared query scope and stable named views'\nmatch:\n where:\n type: view\nschema:\n dialect: json-schema-2020-12\n value:\n $schema: https://json-schema.org/draft/2020-12/schema\n title: View\n description: 'Saved views: shared query scope and stable named views.'\n type: object\n required:\n - type\n - id\n - version\n - name\n - views\n properties:\n type:\n const: view\n id:\n $ref: '#/$defs/identifier'\n version:\n type: integer\n minimum: 1\n name:\n type: string\n minLength: 1\n description:\n type: string\n query:\n $ref: '#/$defs/sharedQuery'\n properties:\n $ref: '#/$defs/propertyMetadataSet'\n summary_functions:\n $ref: '#/$defs/summaryFunctionSet'\n views:\n type: array\n minItems: 1\n items:\n $ref: '#/$defs/view'\n patternProperties:\n ^x-[A-Za-z][A-Za-z0-9._:-]{0,127}$:\n $ref: '#/$defs/extension'\n additionalProperties: false\n $defs:\n identifier:\n type: string\n pattern: ^[A-Za-z][A-Za-z0-9._:-]*$\n typeName:\n type: string\n pattern: ^[A-Za-z][A-Za-z0-9_-]{0,127}$\n fieldName:\n type: string\n pattern: ^[A-Za-z_][A-Za-z0-9_:-]*$\n expression:\n type: string\n minLength: 1\n extension:\n type: object\n additionalProperties: true\n typeList:\n type: array\n minItems: 1\n uniqueItems: true\n items:\n $ref: '#/$defs/typeName'\n sharedQuery:\n type: object\n properties:\n types:\n $ref: '#/$defs/typeList'\n where:\n $ref: '#/$defs/expression'\n context:\n $ref: '#/$defs/viewContext'\n projections:\n $ref: '#/$defs/projectionSet'\n patternProperties:\n ^x-[A-Za-z][A-Za-z0-9._:-]{0,127}$:\n $ref: '#/$defs/extension'\n additionalProperties: false\n viewContext:\n type: object\n required:\n - this\n properties:\n this:\n $ref: '#/$defs/thisContext'\n patternProperties:\n ^x-[A-Za-z][A-Za-z0-9._:-]{0,127}$:\n $ref: '#/$defs/extension'\n additionalProperties: false\n thisContext:\n type: object\n properties:\n on_missing:\n enum:\n - view\n - 'null'\n - error\n default: view\n types:\n $ref: '#/$defs/typeList'\n patternProperties:\n ^x-[A-Za-z][A-Za-z0-9._:-]{0,127}$:\n $ref: '#/$defs/extension'\n additionalProperties: false\n projectionSet:\n type: object\n propertyNames:\n $ref: '#/$defs/fieldName'\n additionalProperties:\n $ref: '#/$defs/projection'\n projection:\n type: object\n required:\n - expr\n properties:\n expr:\n $ref: '#/$defs/expression'\n description:\n type: string\n patternProperties:\n ^x-[A-Za-z][A-Za-z0-9._:-]{0,127}$:\n $ref: '#/$defs/extension'\n additionalProperties: false\n propertyMetadataSet:\n type: object\n propertyNames:\n type: string\n minLength: 1\n additionalProperties:\n $ref: '#/$defs/propertyMetadata'\n propertyMetadata:\n type: object\n properties:\n label:\n type: string\n description:\n type: string\n format:\n type: string\n hidden:\n type: boolean\n patternProperties:\n ^x-[A-Za-z][A-Za-z0-9._:-]{0,127}$:\n $ref: '#/$defs/extension'\n additionalProperties: false\n summaryFunctionSet:\n type: object\n propertyNames:\n $ref: '#/$defs/fieldName'\n additionalProperties:\n $ref: '#/$defs/summaryFunction'\n summaryFunction:\n type: object\n required:\n - expr\n properties:\n expr:\n $ref: '#/$defs/expression'\n description:\n type: string\n patternProperties:\n ^x-[A-Za-z][A-Za-z0-9._:-]{0,127}$:\n $ref: '#/$defs/extension'\n additionalProperties: false\n view:\n type: object\n required:\n - id\n - name\n properties:\n id:\n $ref: '#/$defs/identifier'\n name:\n type: string\n minLength: 1\n description:\n type: string\n types:\n $ref: '#/$defs/typeList'\n where:\n $ref: '#/$defs/expression'\n context:\n $ref: '#/$defs/viewContext'\n projections:\n $ref: '#/$defs/projectionSet'\n select:\n $ref: '#/$defs/select'\n order_by:\n $ref: '#/$defs/orderBy'\n group_by:\n $ref: '#/$defs/groupBy'\n summaries:\n $ref: '#/$defs/summaries'\n limit:\n type: integer\n minimum: 0\n offset:\n type: integer\n minimum: 0\n include_body:\n type: boolean\n default: false\n frontmatter_mode:\n enum:\n - effective\n - persisted\n - both\n default: effective\n presentation:\n $ref: '#/$defs/presentation'\n patternProperties:\n ^x-[A-Za-z][A-Za-z0-9._:-]{0,127}$:\n $ref: '#/$defs/extension'\n additionalProperties: false\n select:\n type: array\n minItems: 1\n items:\n oneOf:\n - type: string\n minLength: 1\n - $ref: '#/$defs/selectExpression'\n selectExpression:\n type: object\n required:\n - name\n - expr\n properties:\n name:\n $ref: '#/$defs/fieldName'\n expr:\n $ref: '#/$defs/expression'\n label:\n type: string\n description:\n type: string\n patternProperties:\n ^x-[A-Za-z][A-Za-z0-9._:-]{0,127}$:\n $ref: '#/$defs/extension'\n additionalProperties: false\n orderBy:\n type: array\n minItems: 1\n items:\n type: object\n required:\n - field\n properties:\n field:\n type: string\n minLength: 1\n direction:\n enum:\n - asc\n - desc\n default: asc\n additionalProperties: false\n groupBy:\n type: array\n minItems: 1\n items:\n type: object\n required:\n - field\n properties:\n field:\n type: string\n minLength: 1\n direction:\n enum:\n - asc\n - desc\n default: asc\n additionalProperties: false\n summaries:\n type: array\n minItems: 1\n items:\n $ref: '#/$defs/summary'\n summary:\n type: object\n required:\n - field\n - function\n properties:\n field:\n type: string\n minLength: 1\n function:\n $ref: '#/$defs/identifier'\n name:\n $ref: '#/$defs/fieldName'\n label:\n type: string\n additionalProperties: false\n presentation:\n type: object\n required:\n - type\n properties:\n type:\n $ref: '#/$defs/identifier'\n fallback:\n $ref: '#/$defs/identifier'\n mappings:\n type: object\n propertyNames:\n $ref: '#/$defs/fieldName'\n additionalProperties:\n type: string\n minLength: 1\n options:\n type: object\n additionalProperties: true\n patternProperties:\n ^x-[A-Za-z][A-Za-z0-9._:-]{0,127}$:\n $ref: '#/$defs/extension'\n additionalProperties: false\nimplements:\n- contract: mdbase.view\n version: 1.0.0\n fields:\n id: id\n version: version\n name: name\n description: description\n query: query\n properties: properties\n summary_functions: summary_functions\n views: views\ncollection:\n display:\n name_field: name\n---\n\n# View\n\nA view record stores shared query scope and one or more stable named views.\nTools that support saved views discover these records through the `mdbase.view`\ncontract and run each named view as an ordinary query.\n\nThis type belongs to your collection once installed. You can rename fields or\nchange how records are matched, as long as the `implements` mapping still\npoints each contract field at the right frontmatter field.\n" + } + ], + "provides": [ + { + "id": "mdbase.view", + "version": "1.0.0", + "digest": "sha256:0918acefce08cddd778fab768fe4f2e4615d263a0eec3e5330b6897c686d744e" + } + ] +} diff --git a/dist/schemas/mdbase.view/1.0.0.schema.json b/dist/schemas/mdbase.view/1.0.0.schema.json new file mode 100644 index 0000000..d98e82f --- /dev/null +++ b/dist/schemas/mdbase.view/1.0.0.schema.json @@ -0,0 +1,261 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://mdbase.dev/schemas/v0.3/view.schema.json", + "title": "mdbase.view 1.0.0 record contract view", + "description": "The contract view of a saved-view record. A type implements mdbase.view by mapping these fields; the optional type property only lets the canonical view type validate its own membership value.", + "type": "object", + "required": ["id", "version", "name", "views"], + "properties": { + "type": { "type": "string", "minLength": 1 }, + "id": { "$ref": "#/$defs/identifier" }, + "version": { "type": "integer", "minimum": 1 }, + "name": { "type": "string", "minLength": 1 }, + "description": { "type": "string" }, + "query": { "$ref": "#/$defs/sharedQuery" }, + "properties": { "$ref": "#/$defs/propertyMetadataSet" }, + "summary_functions": { "$ref": "#/$defs/summaryFunctionSet" }, + "views": { + "type": "array", + "minItems": 1, + "items": { "$ref": "#/$defs/view" } + } + }, + "patternProperties": { + "^x-[A-Za-z][A-Za-z0-9._:-]{0,127}$": { "$ref": "#/$defs/extension" } + }, + "additionalProperties": false, + "$defs": { + "identifier": { + "type": "string", + "pattern": "^[A-Za-z][A-Za-z0-9._:-]*$" + }, + "typeName": { + "type": "string", + "pattern": "^[A-Za-z][A-Za-z0-9_-]{0,127}$" + }, + "fieldName": { + "type": "string", + "pattern": "^[A-Za-z_][A-Za-z0-9_:-]*$" + }, + "expression": { + "type": "string", + "minLength": 1 + }, + "extension": { + "type": "object", + "additionalProperties": true + }, + "typeList": { + "type": "array", + "minItems": 1, + "uniqueItems": true, + "items": { "$ref": "#/$defs/typeName" } + }, + "sharedQuery": { + "type": "object", + "properties": { + "types": { "$ref": "#/$defs/typeList" }, + "where": { "$ref": "#/$defs/expression" }, + "context": { "$ref": "#/$defs/viewContext" }, + "projections": { "$ref": "#/$defs/projectionSet" } + }, + "patternProperties": { + "^x-[A-Za-z][A-Za-z0-9._:-]{0,127}$": { "$ref": "#/$defs/extension" } + }, + "additionalProperties": false + }, + "viewContext": { + "type": "object", + "required": ["this"], + "properties": { + "this": { "$ref": "#/$defs/thisContext" } + }, + "patternProperties": { + "^x-[A-Za-z][A-Za-z0-9._:-]{0,127}$": { "$ref": "#/$defs/extension" } + }, + "additionalProperties": false + }, + "thisContext": { + "type": "object", + "properties": { + "on_missing": { + "enum": ["view", "null", "error"], + "default": "view" + }, + "types": { "$ref": "#/$defs/typeList" } + }, + "patternProperties": { + "^x-[A-Za-z][A-Za-z0-9._:-]{0,127}$": { "$ref": "#/$defs/extension" } + }, + "additionalProperties": false + }, + "projectionSet": { + "type": "object", + "propertyNames": { "$ref": "#/$defs/fieldName" }, + "additionalProperties": { "$ref": "#/$defs/projection" } + }, + "projection": { + "type": "object", + "required": ["expr"], + "properties": { + "expr": { "$ref": "#/$defs/expression" }, + "description": { "type": "string" } + }, + "patternProperties": { + "^x-[A-Za-z][A-Za-z0-9._:-]{0,127}$": { "$ref": "#/$defs/extension" } + }, + "additionalProperties": false + }, + "propertyMetadataSet": { + "type": "object", + "propertyNames": { "type": "string", "minLength": 1 }, + "additionalProperties": { "$ref": "#/$defs/propertyMetadata" } + }, + "propertyMetadata": { + "type": "object", + "properties": { + "label": { "type": "string" }, + "description": { "type": "string" }, + "format": { "type": "string" }, + "hidden": { "type": "boolean" } + }, + "patternProperties": { + "^x-[A-Za-z][A-Za-z0-9._:-]{0,127}$": { "$ref": "#/$defs/extension" } + }, + "additionalProperties": false + }, + "summaryFunctionSet": { + "type": "object", + "propertyNames": { "$ref": "#/$defs/fieldName" }, + "additionalProperties": { "$ref": "#/$defs/summaryFunction" } + }, + "summaryFunction": { + "type": "object", + "required": ["expr"], + "properties": { + "expr": { "$ref": "#/$defs/expression" }, + "description": { "type": "string" } + }, + "patternProperties": { + "^x-[A-Za-z][A-Za-z0-9._:-]{0,127}$": { "$ref": "#/$defs/extension" } + }, + "additionalProperties": false + }, + "view": { + "type": "object", + "required": ["id", "name"], + "properties": { + "id": { "$ref": "#/$defs/identifier" }, + "name": { "type": "string", "minLength": 1 }, + "description": { "type": "string" }, + "types": { "$ref": "#/$defs/typeList" }, + "where": { "$ref": "#/$defs/expression" }, + "context": { "$ref": "#/$defs/viewContext" }, + "projections": { "$ref": "#/$defs/projectionSet" }, + "select": { "$ref": "#/$defs/select" }, + "order_by": { "$ref": "#/$defs/orderBy" }, + "group_by": { "$ref": "#/$defs/groupBy" }, + "summaries": { "$ref": "#/$defs/summaries" }, + "limit": { "type": "integer", "minimum": 0 }, + "offset": { "type": "integer", "minimum": 0 }, + "include_body": { "type": "boolean", "default": false }, + "frontmatter_mode": { + "enum": ["effective", "persisted", "both"], + "default": "effective" + }, + "presentation": { "$ref": "#/$defs/presentation" } + }, + "patternProperties": { + "^x-[A-Za-z][A-Za-z0-9._:-]{0,127}$": { "$ref": "#/$defs/extension" } + }, + "additionalProperties": false + }, + "select": { + "type": "array", + "minItems": 1, + "items": { + "oneOf": [ + { "type": "string", "minLength": 1 }, + { "$ref": "#/$defs/selectExpression" } + ] + } + }, + "selectExpression": { + "type": "object", + "required": ["name", "expr"], + "properties": { + "name": { "$ref": "#/$defs/fieldName" }, + "expr": { "$ref": "#/$defs/expression" }, + "label": { "type": "string" }, + "description": { "type": "string" } + }, + "patternProperties": { + "^x-[A-Za-z][A-Za-z0-9._:-]{0,127}$": { "$ref": "#/$defs/extension" } + }, + "additionalProperties": false + }, + "orderBy": { + "type": "array", + "minItems": 1, + "items": { + "type": "object", + "required": ["field"], + "properties": { + "field": { "type": "string", "minLength": 1 }, + "direction": { "enum": ["asc", "desc"], "default": "asc" } + }, + "additionalProperties": false + } + }, + "groupBy": { + "type": "array", + "minItems": 1, + "items": { + "type": "object", + "required": ["field"], + "properties": { + "field": { "type": "string", "minLength": 1 }, + "direction": { "enum": ["asc", "desc"], "default": "asc" } + }, + "additionalProperties": false + } + }, + "summaries": { + "type": "array", + "minItems": 1, + "items": { "$ref": "#/$defs/summary" } + }, + "summary": { + "type": "object", + "required": ["field", "function"], + "properties": { + "field": { "type": "string", "minLength": 1 }, + "function": { "$ref": "#/$defs/identifier" }, + "name": { "$ref": "#/$defs/fieldName" }, + "label": { "type": "string" } + }, + "additionalProperties": false + }, + "presentation": { + "type": "object", + "required": ["type"], + "properties": { + "type": { "$ref": "#/$defs/identifier" }, + "fallback": { "$ref": "#/$defs/identifier" }, + "mappings": { + "type": "object", + "propertyNames": { "$ref": "#/$defs/fieldName" }, + "additionalProperties": { "type": "string", "minLength": 1 } + }, + "options": { + "type": "object", + "additionalProperties": true + } + }, + "patternProperties": { + "^x-[A-Za-z][A-Za-z0-9._:-]{0,127}$": { "$ref": "#/$defs/extension" } + }, + "additionalProperties": false + } + } +} diff --git a/packs/mdbase.view/1.0.0.pack.yaml b/packs/mdbase.view/1.0.0.pack.yaml new file mode 100644 index 0000000..d424f02 --- /dev/null +++ b/packs/mdbase.view/1.0.0.pack.yaml @@ -0,0 +1,33 @@ +kind: mdbase.catalog-pack +id: mdbase.view +version: 1.0.0 +name: Saved views +description: The mdbase.view contract and an editable View type for saved, reusable queries. +display: + name: Saved views + summary: Save reusable queries that any view-aware app can list and run. + category: work + audience: general + icon: table + badges: + - Portable views +installation: + visibility: default + recommendation: optional + primary_type: view +provides: + - id: mdbase.view + version: 1.0.0 +resources: + - kind: schema + mode: managed + source: schemas/mdbase.view/1.0.0.schema.json + target: schemas/mdbase.view/1.0.0.schema.json + - kind: contract + mode: managed + source: contracts/mdbase.view/1.0.0.md + target: _contracts/mdbase.view/1.0.0.md + - kind: type + mode: seed + source: types/view/1.md + target: _types/view.md diff --git a/schemas/mdbase.view/1.0.0.schema.json b/schemas/mdbase.view/1.0.0.schema.json new file mode 100644 index 0000000..d98e82f --- /dev/null +++ b/schemas/mdbase.view/1.0.0.schema.json @@ -0,0 +1,261 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://mdbase.dev/schemas/v0.3/view.schema.json", + "title": "mdbase.view 1.0.0 record contract view", + "description": "The contract view of a saved-view record. A type implements mdbase.view by mapping these fields; the optional type property only lets the canonical view type validate its own membership value.", + "type": "object", + "required": ["id", "version", "name", "views"], + "properties": { + "type": { "type": "string", "minLength": 1 }, + "id": { "$ref": "#/$defs/identifier" }, + "version": { "type": "integer", "minimum": 1 }, + "name": { "type": "string", "minLength": 1 }, + "description": { "type": "string" }, + "query": { "$ref": "#/$defs/sharedQuery" }, + "properties": { "$ref": "#/$defs/propertyMetadataSet" }, + "summary_functions": { "$ref": "#/$defs/summaryFunctionSet" }, + "views": { + "type": "array", + "minItems": 1, + "items": { "$ref": "#/$defs/view" } + } + }, + "patternProperties": { + "^x-[A-Za-z][A-Za-z0-9._:-]{0,127}$": { "$ref": "#/$defs/extension" } + }, + "additionalProperties": false, + "$defs": { + "identifier": { + "type": "string", + "pattern": "^[A-Za-z][A-Za-z0-9._:-]*$" + }, + "typeName": { + "type": "string", + "pattern": "^[A-Za-z][A-Za-z0-9_-]{0,127}$" + }, + "fieldName": { + "type": "string", + "pattern": "^[A-Za-z_][A-Za-z0-9_:-]*$" + }, + "expression": { + "type": "string", + "minLength": 1 + }, + "extension": { + "type": "object", + "additionalProperties": true + }, + "typeList": { + "type": "array", + "minItems": 1, + "uniqueItems": true, + "items": { "$ref": "#/$defs/typeName" } + }, + "sharedQuery": { + "type": "object", + "properties": { + "types": { "$ref": "#/$defs/typeList" }, + "where": { "$ref": "#/$defs/expression" }, + "context": { "$ref": "#/$defs/viewContext" }, + "projections": { "$ref": "#/$defs/projectionSet" } + }, + "patternProperties": { + "^x-[A-Za-z][A-Za-z0-9._:-]{0,127}$": { "$ref": "#/$defs/extension" } + }, + "additionalProperties": false + }, + "viewContext": { + "type": "object", + "required": ["this"], + "properties": { + "this": { "$ref": "#/$defs/thisContext" } + }, + "patternProperties": { + "^x-[A-Za-z][A-Za-z0-9._:-]{0,127}$": { "$ref": "#/$defs/extension" } + }, + "additionalProperties": false + }, + "thisContext": { + "type": "object", + "properties": { + "on_missing": { + "enum": ["view", "null", "error"], + "default": "view" + }, + "types": { "$ref": "#/$defs/typeList" } + }, + "patternProperties": { + "^x-[A-Za-z][A-Za-z0-9._:-]{0,127}$": { "$ref": "#/$defs/extension" } + }, + "additionalProperties": false + }, + "projectionSet": { + "type": "object", + "propertyNames": { "$ref": "#/$defs/fieldName" }, + "additionalProperties": { "$ref": "#/$defs/projection" } + }, + "projection": { + "type": "object", + "required": ["expr"], + "properties": { + "expr": { "$ref": "#/$defs/expression" }, + "description": { "type": "string" } + }, + "patternProperties": { + "^x-[A-Za-z][A-Za-z0-9._:-]{0,127}$": { "$ref": "#/$defs/extension" } + }, + "additionalProperties": false + }, + "propertyMetadataSet": { + "type": "object", + "propertyNames": { "type": "string", "minLength": 1 }, + "additionalProperties": { "$ref": "#/$defs/propertyMetadata" } + }, + "propertyMetadata": { + "type": "object", + "properties": { + "label": { "type": "string" }, + "description": { "type": "string" }, + "format": { "type": "string" }, + "hidden": { "type": "boolean" } + }, + "patternProperties": { + "^x-[A-Za-z][A-Za-z0-9._:-]{0,127}$": { "$ref": "#/$defs/extension" } + }, + "additionalProperties": false + }, + "summaryFunctionSet": { + "type": "object", + "propertyNames": { "$ref": "#/$defs/fieldName" }, + "additionalProperties": { "$ref": "#/$defs/summaryFunction" } + }, + "summaryFunction": { + "type": "object", + "required": ["expr"], + "properties": { + "expr": { "$ref": "#/$defs/expression" }, + "description": { "type": "string" } + }, + "patternProperties": { + "^x-[A-Za-z][A-Za-z0-9._:-]{0,127}$": { "$ref": "#/$defs/extension" } + }, + "additionalProperties": false + }, + "view": { + "type": "object", + "required": ["id", "name"], + "properties": { + "id": { "$ref": "#/$defs/identifier" }, + "name": { "type": "string", "minLength": 1 }, + "description": { "type": "string" }, + "types": { "$ref": "#/$defs/typeList" }, + "where": { "$ref": "#/$defs/expression" }, + "context": { "$ref": "#/$defs/viewContext" }, + "projections": { "$ref": "#/$defs/projectionSet" }, + "select": { "$ref": "#/$defs/select" }, + "order_by": { "$ref": "#/$defs/orderBy" }, + "group_by": { "$ref": "#/$defs/groupBy" }, + "summaries": { "$ref": "#/$defs/summaries" }, + "limit": { "type": "integer", "minimum": 0 }, + "offset": { "type": "integer", "minimum": 0 }, + "include_body": { "type": "boolean", "default": false }, + "frontmatter_mode": { + "enum": ["effective", "persisted", "both"], + "default": "effective" + }, + "presentation": { "$ref": "#/$defs/presentation" } + }, + "patternProperties": { + "^x-[A-Za-z][A-Za-z0-9._:-]{0,127}$": { "$ref": "#/$defs/extension" } + }, + "additionalProperties": false + }, + "select": { + "type": "array", + "minItems": 1, + "items": { + "oneOf": [ + { "type": "string", "minLength": 1 }, + { "$ref": "#/$defs/selectExpression" } + ] + } + }, + "selectExpression": { + "type": "object", + "required": ["name", "expr"], + "properties": { + "name": { "$ref": "#/$defs/fieldName" }, + "expr": { "$ref": "#/$defs/expression" }, + "label": { "type": "string" }, + "description": { "type": "string" } + }, + "patternProperties": { + "^x-[A-Za-z][A-Za-z0-9._:-]{0,127}$": { "$ref": "#/$defs/extension" } + }, + "additionalProperties": false + }, + "orderBy": { + "type": "array", + "minItems": 1, + "items": { + "type": "object", + "required": ["field"], + "properties": { + "field": { "type": "string", "minLength": 1 }, + "direction": { "enum": ["asc", "desc"], "default": "asc" } + }, + "additionalProperties": false + } + }, + "groupBy": { + "type": "array", + "minItems": 1, + "items": { + "type": "object", + "required": ["field"], + "properties": { + "field": { "type": "string", "minLength": 1 }, + "direction": { "enum": ["asc", "desc"], "default": "asc" } + }, + "additionalProperties": false + } + }, + "summaries": { + "type": "array", + "minItems": 1, + "items": { "$ref": "#/$defs/summary" } + }, + "summary": { + "type": "object", + "required": ["field", "function"], + "properties": { + "field": { "type": "string", "minLength": 1 }, + "function": { "$ref": "#/$defs/identifier" }, + "name": { "$ref": "#/$defs/fieldName" }, + "label": { "type": "string" } + }, + "additionalProperties": false + }, + "presentation": { + "type": "object", + "required": ["type"], + "properties": { + "type": { "$ref": "#/$defs/identifier" }, + "fallback": { "$ref": "#/$defs/identifier" }, + "mappings": { + "type": "object", + "propertyNames": { "$ref": "#/$defs/fieldName" }, + "additionalProperties": { "type": "string", "minLength": 1 } + }, + "options": { + "type": "object", + "additionalProperties": true + } + }, + "patternProperties": { + "^x-[A-Za-z][A-Za-z0-9._:-]{0,127}$": { "$ref": "#/$defs/extension" } + }, + "additionalProperties": false + } + } +} diff --git a/types/view/1.md b/types/view/1.md new file mode 100644 index 0000000..9f38f2a --- /dev/null +++ b/types/view/1.md @@ -0,0 +1,352 @@ +--- +kind: mdbase.type +name: view +version: 1 +description: 'Saved views: shared query scope and stable named views' +match: + where: + type: view +schema: + dialect: json-schema-2020-12 + value: + $schema: https://json-schema.org/draft/2020-12/schema + title: View + description: 'Saved views: shared query scope and stable named views.' + type: object + required: + - type + - id + - version + - name + - views + properties: + type: + const: view + id: + $ref: '#/$defs/identifier' + version: + type: integer + minimum: 1 + name: + type: string + minLength: 1 + description: + type: string + query: + $ref: '#/$defs/sharedQuery' + properties: + $ref: '#/$defs/propertyMetadataSet' + summary_functions: + $ref: '#/$defs/summaryFunctionSet' + views: + type: array + minItems: 1 + items: + $ref: '#/$defs/view' + patternProperties: + ^x-[A-Za-z][A-Za-z0-9._:-]{0,127}$: + $ref: '#/$defs/extension' + additionalProperties: false + $defs: + identifier: + type: string + pattern: ^[A-Za-z][A-Za-z0-9._:-]*$ + typeName: + type: string + pattern: ^[A-Za-z][A-Za-z0-9_-]{0,127}$ + fieldName: + type: string + pattern: ^[A-Za-z_][A-Za-z0-9_:-]*$ + expression: + type: string + minLength: 1 + extension: + type: object + additionalProperties: true + typeList: + type: array + minItems: 1 + uniqueItems: true + items: + $ref: '#/$defs/typeName' + sharedQuery: + type: object + properties: + types: + $ref: '#/$defs/typeList' + where: + $ref: '#/$defs/expression' + context: + $ref: '#/$defs/viewContext' + projections: + $ref: '#/$defs/projectionSet' + patternProperties: + ^x-[A-Za-z][A-Za-z0-9._:-]{0,127}$: + $ref: '#/$defs/extension' + additionalProperties: false + viewContext: + type: object + required: + - this + properties: + this: + $ref: '#/$defs/thisContext' + patternProperties: + ^x-[A-Za-z][A-Za-z0-9._:-]{0,127}$: + $ref: '#/$defs/extension' + additionalProperties: false + thisContext: + type: object + properties: + on_missing: + enum: + - view + - 'null' + - error + default: view + types: + $ref: '#/$defs/typeList' + patternProperties: + ^x-[A-Za-z][A-Za-z0-9._:-]{0,127}$: + $ref: '#/$defs/extension' + additionalProperties: false + projectionSet: + type: object + propertyNames: + $ref: '#/$defs/fieldName' + additionalProperties: + $ref: '#/$defs/projection' + projection: + type: object + required: + - expr + properties: + expr: + $ref: '#/$defs/expression' + description: + type: string + patternProperties: + ^x-[A-Za-z][A-Za-z0-9._:-]{0,127}$: + $ref: '#/$defs/extension' + additionalProperties: false + propertyMetadataSet: + type: object + propertyNames: + type: string + minLength: 1 + additionalProperties: + $ref: '#/$defs/propertyMetadata' + propertyMetadata: + type: object + properties: + label: + type: string + description: + type: string + format: + type: string + hidden: + type: boolean + patternProperties: + ^x-[A-Za-z][A-Za-z0-9._:-]{0,127}$: + $ref: '#/$defs/extension' + additionalProperties: false + summaryFunctionSet: + type: object + propertyNames: + $ref: '#/$defs/fieldName' + additionalProperties: + $ref: '#/$defs/summaryFunction' + summaryFunction: + type: object + required: + - expr + properties: + expr: + $ref: '#/$defs/expression' + description: + type: string + patternProperties: + ^x-[A-Za-z][A-Za-z0-9._:-]{0,127}$: + $ref: '#/$defs/extension' + additionalProperties: false + view: + type: object + required: + - id + - name + properties: + id: + $ref: '#/$defs/identifier' + name: + type: string + minLength: 1 + description: + type: string + types: + $ref: '#/$defs/typeList' + where: + $ref: '#/$defs/expression' + context: + $ref: '#/$defs/viewContext' + projections: + $ref: '#/$defs/projectionSet' + select: + $ref: '#/$defs/select' + order_by: + $ref: '#/$defs/orderBy' + group_by: + $ref: '#/$defs/groupBy' + summaries: + $ref: '#/$defs/summaries' + limit: + type: integer + minimum: 0 + offset: + type: integer + minimum: 0 + include_body: + type: boolean + default: false + frontmatter_mode: + enum: + - effective + - persisted + - both + default: effective + presentation: + $ref: '#/$defs/presentation' + patternProperties: + ^x-[A-Za-z][A-Za-z0-9._:-]{0,127}$: + $ref: '#/$defs/extension' + additionalProperties: false + select: + type: array + minItems: 1 + items: + oneOf: + - type: string + minLength: 1 + - $ref: '#/$defs/selectExpression' + selectExpression: + type: object + required: + - name + - expr + properties: + name: + $ref: '#/$defs/fieldName' + expr: + $ref: '#/$defs/expression' + label: + type: string + description: + type: string + patternProperties: + ^x-[A-Za-z][A-Za-z0-9._:-]{0,127}$: + $ref: '#/$defs/extension' + additionalProperties: false + orderBy: + type: array + minItems: 1 + items: + type: object + required: + - field + properties: + field: + type: string + minLength: 1 + direction: + enum: + - asc + - desc + default: asc + additionalProperties: false + groupBy: + type: array + minItems: 1 + items: + type: object + required: + - field + properties: + field: + type: string + minLength: 1 + direction: + enum: + - asc + - desc + default: asc + additionalProperties: false + summaries: + type: array + minItems: 1 + items: + $ref: '#/$defs/summary' + summary: + type: object + required: + - field + - function + properties: + field: + type: string + minLength: 1 + function: + $ref: '#/$defs/identifier' + name: + $ref: '#/$defs/fieldName' + label: + type: string + additionalProperties: false + presentation: + type: object + required: + - type + properties: + type: + $ref: '#/$defs/identifier' + fallback: + $ref: '#/$defs/identifier' + mappings: + type: object + propertyNames: + $ref: '#/$defs/fieldName' + additionalProperties: + type: string + minLength: 1 + options: + type: object + additionalProperties: true + patternProperties: + ^x-[A-Za-z][A-Za-z0-9._:-]{0,127}$: + $ref: '#/$defs/extension' + additionalProperties: false +implements: +- contract: mdbase.view + version: 1.0.0 + fields: + id: id + version: version + name: name + description: description + query: query + properties: properties + summary_functions: summary_functions + views: views +collection: + display: + name_field: name +--- + +# View + +A view record stores shared query scope and one or more stable named views. +Tools that support saved views discover these records through the `mdbase.view` +contract and run each named view as an ordinary query. + +This type belongs to your collection once installed. You can rename fields or +change how records are matched, as long as the `implements` mapping still +points each contract field at the right frontmatter field.