diff --git a/build/bundle-schemas.cjs b/build/bundle-schemas.cjs new file mode 100644 index 0000000..205ef09 --- /dev/null +++ b/build/bundle-schemas.cjs @@ -0,0 +1,70 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +const fs = require('fs').promises; +const Bundler = require("@hyperjump/json-schema-bundle"); + +(async function () { + bundle(`https://json-schema.org/draft/2019-09/schema`, 'draft09'); + bundle(`https://json-schema.org/draft/2020-12/schema`, 'draft12'); +}()); + +async function bundle(uri, filename) { + const metaSchema = await Bundler.get(uri); + const bundle = await Bundler.bundle(metaSchema); + const jsonified = JSON.stringify(bundle, null, 2).replace(/"undefined": ""/g, '"$dynamicAnchor": "meta"'); + const jsified = 'export default ' + printObject(JSON.parse(jsonified)); + fs.writeFile(`./${filename}.json`, jsonified, 'utf8'); + fs.writeFile(`./${filename}.js`, jsified, 'utf8'); +} + +function printLiteral(value) { + if (typeof value === 'string') { + return `'${value}'`; + } + return value; +} + +function printKey(value) { + if (value.match(/^[a-zA-Z_$][a-zA-Z0-9_$]*$/)) { + return `${value}`; + } + return `'${value}'`; +} + +function indent(level) { + return '\t'.repeat(level); +} + +function printObject(obj, indentLevel = 0) { + const result = []; + if (Array.isArray(obj)) { + result.push(`[`); + for (const item of obj) { + if (typeof item === 'object' && item !== null) { + result.push(`${indent(indentLevel + 1)}${printObject(item, indentLevel + 1)},`); + } else { + result.push(`${indent(indentLevel + 1)}${printLiteral(item)},`); + } + } + result.push(`${indent(indentLevel)}]`); + return result.join('\n'); + } + if (obj === null) { + result.push(`null`); + return result.join('\n'); + } + + result.push(`{`); + for (const [key, value] of Object.entries(obj)) { + if (typeof value === 'object' && value !== null) { + result.push(`${indent(indentLevel + 1)}${printKey(key)}: ${printObject(value, indentLevel + 1)},`); + } else { + result.push(`${indent(indentLevel + 1)}${printKey(key)}: ${printLiteral(value)},`); + } + } + result.push(`${indent(indentLevel)}}`); + return result.join('\n'); +} diff --git a/src/services/configuration.ts b/src/services/configuration.ts index 7ff29da..86220e0 100644 --- a/src/services/configuration.ts +++ b/src/services/configuration.ts @@ -457,7 +457,804 @@ export const schemaContributions: ISchemaContributions = { 'not': { '$ref': '#' } }, 'default': true + }, + 'https://json-schema.org/draft/2020-12/schema': { + $id: 'https://json-schema.org/draft/2020-12/schema', + $schema: 'https://json-schema.org/draft/2020-12/schema', + title: 'Core and Validation specifications meta-schema', + $dynamicAnchor: 'meta', + allOf: [ + { + $ref: 'meta/core', + }, + { + $ref: 'meta/applicator', + }, + { + $ref: 'meta/unevaluated', + }, + { + $ref: 'meta/validation', + }, + { + $ref: 'meta/meta-data', + }, + { + $ref: 'meta/format-annotation', + }, + { + $ref: 'meta/content', + }, + ], + type: [ + 'object', + 'boolean', + ], + properties: { + definitions: { + $comment: 'While no longer an official keyword as it is replaced by $defs, this keyword is retained in the meta-schema to prevent incompatible extensions as it remains in common use.', + type: 'object', + additionalProperties: { + $dynamicRef: '#meta', + }, + default: { + }, + }, + dependencies: { + $comment: '"dependencies" is no longer a keyword, but schema authors should avoid redefining it to facilitate a smooth transition to "dependentSchemas" and "dependentRequired"', + type: 'object', + additionalProperties: { + anyOf: [ + { + $dynamicRef: '#meta', + }, + { + $ref: 'meta/validation#/$defs/stringArray', + }, + ], + }, + }, + }, + $defs: { + 'https://json-schema.org/draft/2020-12/meta/core': { + $id: 'https://json-schema.org/draft/2020-12/meta/core', + title: 'Core vocabulary meta-schema', + $dynamicAnchor: 'meta', + type: [ + 'object', + 'boolean', + ], + properties: { + $id: { + type: 'string', + format: 'uri-reference', + $comment: 'Non-empty fragments not allowed.', + pattern: '^[^#]*#?$', + }, + $schema: { + type: 'string', + format: 'uri', + }, + $anchor: { + type: 'string', + pattern: '^[A-Za-z_][-A-Za-z0-9._]*$', + }, + $ref: { + type: 'string', + format: 'uri-reference', + }, + $dynamicRef: { + type: 'string', + format: 'uri-reference', + }, + $dynamicAnchor: { + type: 'string', + pattern: '^[A-Za-z_][-A-Za-z0-9._]*$', + }, + $vocabulary: { + type: 'object', + propertyNames: { + type: 'string', + format: 'uri', + }, + additionalProperties: { + type: 'boolean', + }, + }, + $comment: { + type: 'string', + }, + $defs: { + type: 'object', + additionalProperties: { + $dynamicRef: '#meta', + }, + default: { + }, + }, + }, + }, + 'https://json-schema.org/draft/2020-12/meta/applicator': { + $id: 'https://json-schema.org/draft/2020-12/meta/applicator', + title: 'Applicator vocabulary meta-schema', + $dynamicAnchor: 'meta', + type: [ + 'object', + 'boolean', + ], + properties: { + prefixItems: { + $ref: '#/$defs/schemaArray', + }, + items: { + $dynamicRef: '#meta', + }, + contains: { + $dynamicRef: '#meta', + }, + additionalProperties: { + $dynamicRef: '#meta', + }, + properties: { + type: 'object', + additionalProperties: { + $dynamicRef: '#meta', + }, + default: { + }, + }, + patternProperties: { + type: 'object', + additionalProperties: { + $dynamicRef: '#meta', + }, + propertyNames: { + format: 'regex', + }, + default: { + }, + }, + dependentSchemas: { + type: 'object', + additionalProperties: { + $dynamicRef: '#meta', + }, + }, + propertyNames: { + $dynamicRef: '#meta', + }, + if: { + $dynamicRef: '#meta', + }, + then: { + $dynamicRef: '#meta', + }, + else: { + $dynamicRef: '#meta', + }, + allOf: { + $ref: '#/$defs/schemaArray', + }, + anyOf: { + $ref: '#/$defs/schemaArray', + }, + oneOf: { + $ref: '#/$defs/schemaArray', + }, + not: { + $dynamicRef: '#meta', + }, + }, + $defs: { + schemaArray: { + type: 'array', + minItems: 1, + items: { + $dynamicRef: '#meta', + }, + }, + }, + }, + 'https://json-schema.org/draft/2020-12/meta/unevaluated': { + $id: 'https://json-schema.org/draft/2020-12/meta/unevaluated', + title: 'Unevaluated applicator vocabulary meta-schema', + $dynamicAnchor: 'meta', + type: [ + 'object', + 'boolean', + ], + properties: { + unevaluatedItems: { + $dynamicRef: '#meta', + }, + unevaluatedProperties: { + $dynamicRef: '#meta', + }, + }, + }, + 'https://json-schema.org/draft/2020-12/meta/validation': { + $id: 'https://json-schema.org/draft/2020-12/meta/validation', + title: 'Validation vocabulary meta-schema', + $dynamicAnchor: 'meta', + type: [ + 'object', + 'boolean', + ], + properties: { + multipleOf: { + type: 'number', + exclusiveMinimum: 0, + }, + maximum: { + type: 'number', + }, + exclusiveMaximum: { + type: 'number', + }, + minimum: { + type: 'number', + }, + exclusiveMinimum: { + type: 'number', + }, + maxLength: { + $ref: '#/$defs/nonNegativeInteger', + }, + minLength: { + $ref: '#/$defs/nonNegativeIntegerDefault0', + }, + pattern: { + type: 'string', + format: 'regex', + }, + maxItems: { + $ref: '#/$defs/nonNegativeInteger', + }, + minItems: { + $ref: '#/$defs/nonNegativeIntegerDefault0', + }, + uniqueItems: { + type: 'boolean', + default: false, + }, + maxContains: { + $ref: '#/$defs/nonNegativeInteger', + }, + minContains: { + $ref: '#/$defs/nonNegativeInteger', + default: 1, + }, + maxProperties: { + $ref: '#/$defs/nonNegativeInteger', + }, + minProperties: { + $ref: '#/$defs/nonNegativeIntegerDefault0', + }, + required: { + $ref: '#/$defs/stringArray', + }, + dependentRequired: { + type: 'object', + additionalProperties: { + $ref: '#/$defs/stringArray', + }, + }, + const: true, + enum: { + type: 'array', + items: true, + }, + type: { + anyOf: [ + { + $ref: '#/$defs/simpleTypes', + }, + { + type: 'array', + items: { + $ref: '#/$defs/simpleTypes', + }, + minItems: 1, + uniqueItems: true, + }, + ], + }, + }, + $defs: { + nonNegativeInteger: { + type: 'integer', + minimum: 0, + }, + nonNegativeIntegerDefault0: { + $ref: '#/$defs/nonNegativeInteger', + default: 0, + }, + simpleTypes: { + enum: [ + 'array', + 'boolean', + 'integer', + 'null', + 'number', + 'object', + 'string', + ], + }, + stringArray: { + type: 'array', + items: { + type: 'string', + }, + uniqueItems: true, + default: [ + ], + }, + }, + }, + 'https://json-schema.org/draft/2020-12/meta/meta-data': { + $id: 'https://json-schema.org/draft/2020-12/meta/meta-data', + title: 'Meta-data vocabulary meta-schema', + $dynamicAnchor: 'meta', + type: [ + 'object', + 'boolean', + ], + properties: { + title: { + type: 'string', + }, + description: { + type: 'string', + }, + default: true, + deprecated: { + type: 'boolean', + default: false, + }, + readOnly: { + type: 'boolean', + default: false, + }, + writeOnly: { + type: 'boolean', + default: false, + }, + examples: { + type: 'array', + items: true, + }, + }, + }, + 'https://json-schema.org/draft/2020-12/meta/format-annotation': { + $id: 'https://json-schema.org/draft/2020-12/meta/format-annotation', + title: 'Format vocabulary meta-schema for annotation results', + $dynamicAnchor: 'meta', + type: [ + 'object', + 'boolean', + ], + properties: { + format: { + type: 'string', + }, + }, + }, + 'https://json-schema.org/draft/2020-12/meta/content': { + $id: 'https://json-schema.org/draft/2020-12/meta/content', + title: 'Content vocabulary meta-schema', + $dynamicAnchor: 'meta', + type: [ + 'object', + 'boolean', + ], + properties: { + contentMediaType: { + type: 'string', + }, + contentEncoding: { + type: 'string', + }, + contentSchema: { + $dynamicRef: '#meta', + }, + }, + }, + }, + }, + 'https://json-schema.org/draft/2019-09/schema': { + $id: 'https://json-schema.org/draft/2019-09/schema', + $schema: 'https://json-schema.org/draft/2019-09/schema', + $dynamicAnchor: 'meta', + title: 'Core and Validation specifications meta-schema', + allOf: [ + { + $ref: 'meta/core', + }, + { + $ref: 'meta/applicator', + }, + { + $ref: 'meta/validation', + }, + { + $ref: 'meta/meta-data', + }, + { + $ref: 'meta/format', + }, + { + $ref: 'meta/content', + }, + ], + type: [ + 'object', + 'boolean', + ], + properties: { + definitions: { + $comment: 'While no longer an official keyword as it is replaced by $defs, this keyword is retained in the meta-schema to prevent incompatible extensions as it remains in common use.', + type: 'object', + additionalProperties: { + $recursiveRef: '#', + }, + default: { + }, + }, + dependencies: { + $comment: '"dependencies" is no longer a keyword, but schema authors should avoid redefining it to facilitate a smooth transition to "dependentSchemas" and "dependentRequired"', + type: 'object', + additionalProperties: { + anyOf: [ + { + $recursiveRef: '#', + }, + { + $ref: 'meta/validation#/$defs/stringArray', + }, + ], + }, + }, + }, + $defs: { + 'https://json-schema.org/draft/2019-09/meta/core': { + $id: 'https://json-schema.org/draft/2019-09/meta/core', + $dynamicAnchor: 'meta', + title: 'Core vocabulary meta-schema', + type: [ + 'object', + 'boolean', + ], + properties: { + $id: { + type: 'string', + format: 'uri-reference', + $comment: 'Non-empty fragments not allowed.', + pattern: '^[^#]*#?$', + }, + $schema: { + type: 'string', + format: 'uri', + }, + $anchor: { + type: 'string', + pattern: '^[A-Za-z][-A-Za-z0-9.:_]*$', + }, + $ref: { + type: 'string', + format: 'uri-reference', + }, + $recursiveRef: { + type: 'string', + format: 'uri-reference', + }, + $recursiveAnchor: { + type: 'boolean', + default: false, + }, + $vocabulary: { + type: 'object', + propertyNames: { + type: 'string', + format: 'uri', + }, + additionalProperties: { + type: 'boolean', + }, + }, + $comment: { + type: 'string', + }, + $defs: { + type: 'object', + additionalProperties: { + $recursiveRef: '#', + }, + default: { + }, + }, + }, + }, + 'https://json-schema.org/draft/2019-09/meta/applicator': { + $id: 'https://json-schema.org/draft/2019-09/meta/applicator', + $dynamicAnchor: 'meta', + title: 'Applicator vocabulary meta-schema', + properties: { + additionalItems: { + $recursiveRef: '#', + }, + unevaluatedItems: { + $recursiveRef: '#', + }, + items: { + anyOf: [ + { + $recursiveRef: '#', + }, + { + $ref: '#/$defs/schemaArray', + }, + ], + }, + contains: { + $recursiveRef: '#', + }, + additionalProperties: { + $recursiveRef: '#', + }, + unevaluatedProperties: { + $recursiveRef: '#', + }, + properties: { + type: 'object', + additionalProperties: { + $recursiveRef: '#', + }, + default: { + }, + }, + patternProperties: { + type: 'object', + additionalProperties: { + $recursiveRef: '#', + }, + propertyNames: { + format: 'regex', + }, + default: { + }, + }, + dependentSchemas: { + type: 'object', + additionalProperties: { + $recursiveRef: '#', + }, + }, + propertyNames: { + $recursiveRef: '#', + }, + if: { + $recursiveRef: '#', + }, + then: { + $recursiveRef: '#', + }, + else: { + $recursiveRef: '#', + }, + allOf: { + $ref: '#/$defs/schemaArray', + }, + anyOf: { + $ref: '#/$defs/schemaArray', + }, + oneOf: { + $ref: '#/$defs/schemaArray', + }, + not: { + $recursiveRef: '#', + }, + }, + $defs: { + schemaArray: { + type: 'array', + minItems: 1, + items: { + $recursiveRef: '#', + }, + }, + }, + }, + 'https://json-schema.org/draft/2019-09/meta/validation': { + $id: 'https://json-schema.org/draft/2019-09/meta/validation', + $dynamicAnchor: 'meta', + title: 'Validation vocabulary meta-schema', + type: [ + 'object', + 'boolean', + ], + properties: { + multipleOf: { + type: 'number', + exclusiveMinimum: 0, + }, + maximum: { + type: 'number', + }, + exclusiveMaximum: { + type: 'number', + }, + minimum: { + type: 'number', + }, + exclusiveMinimum: { + type: 'number', + }, + maxLength: { + $ref: '#/$defs/nonNegativeInteger', + }, + minLength: { + $ref: '#/$defs/nonNegativeIntegerDefault0', + }, + pattern: { + type: 'string', + format: 'regex', + }, + maxItems: { + $ref: '#/$defs/nonNegativeInteger', + }, + minItems: { + $ref: '#/$defs/nonNegativeIntegerDefault0', + }, + uniqueItems: { + type: 'boolean', + default: false, + }, + maxContains: { + $ref: '#/$defs/nonNegativeInteger', + }, + minContains: { + $ref: '#/$defs/nonNegativeInteger', + default: 1, + }, + maxProperties: { + $ref: '#/$defs/nonNegativeInteger', + }, + minProperties: { + $ref: '#/$defs/nonNegativeIntegerDefault0', + }, + required: { + $ref: '#/$defs/stringArray', + }, + dependentRequired: { + type: 'object', + additionalProperties: { + $ref: '#/$defs/stringArray', + }, + }, + const: true, + enum: { + type: 'array', + items: true, + }, + type: { + anyOf: [ + { + $ref: '#/$defs/simpleTypes', + }, + { + type: 'array', + items: { + $ref: '#/$defs/simpleTypes', + }, + minItems: 1, + uniqueItems: true, + }, + ], + }, + }, + $defs: { + nonNegativeInteger: { + type: 'integer', + minimum: 0, + }, + nonNegativeIntegerDefault0: { + $ref: '#/$defs/nonNegativeInteger', + default: 0, + }, + simpleTypes: { + enum: [ + 'array', + 'boolean', + 'integer', + 'null', + 'number', + 'object', + 'string', + ], + }, + stringArray: { + type: 'array', + items: { + type: 'string', + }, + uniqueItems: true, + default: [ + ], + }, + }, + }, + 'https://json-schema.org/draft/2019-09/meta/meta-data': { + $id: 'https://json-schema.org/draft/2019-09/meta/meta-data', + $dynamicAnchor: 'meta', + title: 'Meta-data vocabulary meta-schema', + type: [ + 'object', + 'boolean', + ], + properties: { + title: { + type: 'string', + }, + description: { + type: 'string', + }, + default: true, + deprecated: { + type: 'boolean', + default: false, + }, + readOnly: { + type: 'boolean', + default: false, + }, + writeOnly: { + type: 'boolean', + default: false, + }, + examples: { + type: 'array', + items: true, + }, + }, + }, + 'https://json-schema.org/draft/2019-09/meta/format': { + $id: 'https://json-schema.org/draft/2019-09/meta/format', + $dynamicAnchor: 'meta', + title: 'Format vocabulary meta-schema', + type: [ + 'object', + 'boolean', + ], + properties: { + format: { + type: 'string', + }, + }, + }, + 'https://json-schema.org/draft/2019-09/meta/content': { + $id: 'https://json-schema.org/draft/2019-09/meta/content', + $dynamicAnchor: 'meta', + title: 'Content vocabulary meta-schema', + type: [ + 'object', + 'boolean', + ], + properties: { + contentMediaType: { + type: 'string', + }, + contentEncoding: { + type: 'string', + }, + contentSchema: { + $recursiveRef: '#', + }, + }, + }, + }, } + + } }; const descriptions: { [prop: string]: string } = {