diff --git a/implementations/js-jetio/Dockerfile b/implementations/js-jetio/Dockerfile new file mode 100644 index 000000000..3cfa08893 --- /dev/null +++ b/implementations/js-jetio/Dockerfile @@ -0,0 +1,7 @@ +FROM node:22-alpine +WORKDIR /usr/src/myapp +COPY package.json ./ +RUN npm install --omit=dev +COPY meta-schemas/ ./meta-schemas/ +COPY bowtie_jetio.mjs ./ +CMD ["node", "bowtie_jetio.mjs"] diff --git a/implementations/js-jetio/bowtie_jetio.mjs b/implementations/js-jetio/bowtie_jetio.mjs new file mode 100644 index 000000000..d14af3bce --- /dev/null +++ b/implementations/js-jetio/bowtie_jetio.mjs @@ -0,0 +1,108 @@ +import { createInterface } from "node:readline"; +import { readFileSync } from "node:fs"; +import { JetValidator } from "@jetio/validator"; +import { loadAllMetaSchemas } from "./meta-schemas/loader.mjs"; + +const pkg = JSON.parse( + readFileSync( + new URL("./node_modules/@jetio/validator/package.json", import.meta.url), + ), +); + +let started = false; +let implicitDialect = null; + +function draftOptionFor(dialect) { + if (!dialect) return {}; + if (dialect.includes("draft-06")) return { draft: "draft6" }; + if (dialect.includes("draft-07")) return { draft: "draft7" }; + if (dialect.includes("2019-09")) return { draft: "draft2019-09" }; + return { draft: "draft2020-12" }; +} + +const handlers = { + start(req) { + if (req.version !== 1) + throw new Error(`unsupported IHOP version ${req.version}`); + started = true; + return { + version: 1, + implementation: { + language: "javascript", + name: "jetio-validator", + version: pkg.version, + homepage: "https://github.com/official-jetio/validator", + issues: "https://github.com/official-jetio/validator/issues", + source: "https://github.com/official-jetio/validator", + dialects: [ + "https://json-schema.org/draft/2020-12/schema", + "https://json-schema.org/draft/2019-09/schema", + "http://json-schema.org/draft-07/schema#", + "http://json-schema.org/draft-06/schema#", + ], + }, + }; + }, + + dialect(req) { + if (!started) throw new Error("not started"); + implicitDialect = req.dialect; + return { ok: true }; + }, + + run(req) { + if (!started) throw new Error("not started"); + const { seq, case: kase } = req; + try { + const schema = kase.schema; + const isBool = typeof schema === "boolean"; + const hasSchema = + !isBool && schema && typeof schema === "object" && "$schema" in schema; + + const base = { strict: false, validateFormats: false }; + const jet = new JetValidator( + hasSchema ? base : { ...base, ...draftOptionFor(implicitDialect) }, + ); + loadAllMetaSchemas(jet); + + for (const [uri, s] of Object.entries(kase.registry ?? {})) + if (typeof s !== "boolean") jet.addSchema(s, uri); + + if (!isBool) { + const rootId = schema.$id || schema.id; + if (rootId) jet.addSchema(schema, rootId); + } + + const validate = jet.compile(schema); + const results = kase.tests.map((t) => ({ + valid: Boolean(validate(t.instance)), + })); + return { seq, results }; + } catch (err) { + console.error( + `[jet] ${kase.schema?.$id ?? kase.schema?.$schema ?? "?"} :: ${err?.stack ?? err}`, + ); + return { + seq, + errored: true, + context: { + message: String(err?.message ?? err), + traceback: err?.stack, + }, + }; + } + }, + + stop() { + if (!started) throw new Error("not started"); + process.exit(0); + }, +}; + +const rl = createInterface({ input: process.stdin }); +rl.on("line", (line) => { + if (!line.trim()) return; + const req = JSON.parse(line); + const res = handlers[req.cmd](req); + if (res) process.stdout.write(JSON.stringify(res) + "\n"); +}); diff --git a/implementations/js-jetio/meta-schemas/draft-06/schema.json b/implementations/js-jetio/meta-schemas/draft-06/schema.json new file mode 100644 index 000000000..1ab567098 --- /dev/null +++ b/implementations/js-jetio/meta-schemas/draft-06/schema.json @@ -0,0 +1,218 @@ +{ + "$schema": "http://json-schema.org/draft-06/schema#", + "$id": "http://json-schema.org/draft-06/schema#", + "title": "Core schema meta-schema", + "definitions": { + "schemaArray": { + "type": "array", + "minItems": 1, + "items": { + "$ref": "#" + } + }, + "nonNegativeInteger": { + "type": "integer", + "minimum": 0 + }, + "nonNegativeIntegerDefault0": { + "allOf": [ + { + "$ref": "#/definitions/nonNegativeInteger" + }, + { + "default": 0 + } + ] + }, + "simpleTypes": { + "enum": [ + "array", + "boolean", + "integer", + "null", + "number", + "object", + "string" + ] + }, + "stringArray": { + "type": "array", + "items": { + "type": "string" + }, + "uniqueItems": true, + "default": [] + } + }, + "type": [ + "object", + "boolean" + ], + "properties": { + "$id": { + "type": "string", + "format": "uri-reference" + }, + "$schema": { + "type": "string", + "format": "uri" + }, + "$ref": { + "type": "string", + "format": "uri-reference" + }, + "title": { + "type": "string" + }, + "description": { + "type": "string" + }, + "default": {}, + "examples": { + "type": "array", + "items": {} + }, + "multipleOf": { + "type": "number", + "exclusiveMinimum": 0 + }, + "maximum": { + "type": "number" + }, + "exclusiveMaximum": { + "type": "number" + }, + "minimum": { + "type": "number" + }, + "exclusiveMinimum": { + "type": "number" + }, + "maxLength": { + "$ref": "#/definitions/nonNegativeInteger" + }, + "minLength": { + "$ref": "#/definitions/nonNegativeIntegerDefault0" + }, + "pattern": { + "type": "string", + "format": "regex" + }, + "additionalItems": { + "$ref": "#" + }, + "items": { + "anyOf": [ + { + "$ref": "#" + }, + { + "$ref": "#/definitions/schemaArray" + } + ], + "default": {} + }, + "maxItems": { + "$ref": "#/definitions/nonNegativeInteger" + }, + "minItems": { + "$ref": "#/definitions/nonNegativeIntegerDefault0" + }, + "uniqueItems": { + "type": "boolean", + "default": false + }, + "contains": { + "$ref": "#" + }, + "maxProperties": { + "$ref": "#/definitions/nonNegativeInteger" + }, + "minProperties": { + "$ref": "#/definitions/nonNegativeIntegerDefault0" + }, + "required": { + "$ref": "#/definitions/stringArray" + }, + "additionalProperties": { + "$ref": "#" + }, + "definitions": { + "type": "object", + "additionalProperties": { + "$ref": "#" + }, + "default": {} + }, + "properties": { + "type": "object", + "additionalProperties": { + "$ref": "#" + }, + "default": {} + }, + "patternProperties": { + "type": "object", + "additionalProperties": { + "$ref": "#" + }, + "propertyNames": { + "format": "regex" + }, + "default": {} + }, + "dependencies": { + "type": "object", + "additionalProperties": { + "anyOf": [ + { + "$ref": "#" + }, + { + "$ref": "#/definitions/stringArray" + } + ] + } + }, + "propertyNames": { + "$ref": "#" + }, + "const": {}, + "enum": { + "type": "array", + "minItems": 1, + "uniqueItems": true + }, + "type": { + "anyOf": [ + { + "$ref": "#/definitions/simpleTypes" + }, + { + "type": "array", + "items": { + "$ref": "#/definitions/simpleTypes" + }, + "minItems": 1, + "uniqueItems": true + } + ] + }, + "format": { + "type": "string" + }, + "allOf": { + "$ref": "#/definitions/schemaArray" + }, + "anyOf": { + "$ref": "#/definitions/schemaArray" + }, + "oneOf": { + "$ref": "#/definitions/schemaArray" + }, + "not": { + "$ref": "#" + } + }, + "default": {} +} diff --git a/implementations/js-jetio/meta-schemas/draft-07/schema.json b/implementations/js-jetio/meta-schemas/draft-07/schema.json new file mode 100644 index 000000000..99389d7ab --- /dev/null +++ b/implementations/js-jetio/meta-schemas/draft-07/schema.json @@ -0,0 +1,245 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "http://json-schema.org/draft-07/schema#", + "title": "Core schema meta-schema", + "definitions": { + "schemaArray": { + "type": "array", + "minItems": 1, + "items": { + "$ref": "#" + } + }, + "nonNegativeInteger": { + "type": "integer", + "minimum": 0 + }, + "nonNegativeIntegerDefault0": { + "allOf": [ + { + "$ref": "#/definitions/nonNegativeInteger" + }, + { + "default": 0 + } + ] + }, + "simpleTypes": { + "enum": [ + "array", + "boolean", + "integer", + "null", + "number", + "object", + "string" + ] + }, + "stringArray": { + "type": "array", + "items": { + "type": "string" + }, + "uniqueItems": true, + "default": [] + } + }, + "type": [ + "object", + "boolean" + ], + "properties": { + "$id": { + "type": "string", + "format": "uri-reference" + }, + "$schema": { + "type": "string", + "format": "uri" + }, + "$ref": { + "type": "string", + "format": "uri-reference" + }, + "$comment": { + "type": "string" + }, + "title": { + "type": "string" + }, + "description": { + "type": "string" + }, + "default": true, + "readOnly": { + "type": "boolean", + "default": false + }, + "writeOnly": { + "type": "boolean", + "default": false + }, + "examples": { + "type": "array", + "items": true + }, + "multipleOf": { + "type": "number", + "exclusiveMinimum": 0 + }, + "maximum": { + "type": "number" + }, + "exclusiveMaximum": { + "type": "number" + }, + "minimum": { + "type": "number" + }, + "exclusiveMinimum": { + "type": "number" + }, + "maxLength": { + "$ref": "#/definitions/nonNegativeInteger" + }, + "minLength": { + "$ref": "#/definitions/nonNegativeIntegerDefault0" + }, + "pattern": { + "type": "string", + "format": "regex" + }, + "additionalItems": { + "$ref": "#" + }, + "items": { + "anyOf": [ + { + "$ref": "#" + }, + { + "$ref": "#/definitions/schemaArray" + } + ], + "default": true + }, + "maxItems": { + "$ref": "#/definitions/nonNegativeInteger" + }, + "minItems": { + "$ref": "#/definitions/nonNegativeIntegerDefault0" + }, + "uniqueItems": { + "type": "boolean", + "default": false + }, + "contains": { + "$ref": "#" + }, + "maxProperties": { + "$ref": "#/definitions/nonNegativeInteger" + }, + "minProperties": { + "$ref": "#/definitions/nonNegativeIntegerDefault0" + }, + "required": { + "$ref": "#/definitions/stringArray" + }, + "additionalProperties": { + "$ref": "#" + }, + "definitions": { + "type": "object", + "additionalProperties": { + "$ref": "#" + }, + "default": {} + }, + "properties": { + "type": "object", + "additionalProperties": { + "$ref": "#" + }, + "default": {} + }, + "patternProperties": { + "type": "object", + "additionalProperties": { + "$ref": "#" + }, + "propertyNames": { + "format": "regex" + }, + "default": {} + }, + "dependencies": { + "type": "object", + "additionalProperties": { + "anyOf": [ + { + "$ref": "#" + }, + { + "$ref": "#/definitions/stringArray" + } + ] + } + }, + "propertyNames": { + "$ref": "#" + }, + "const": true, + "enum": { + "type": "array", + "items": true, + "minItems": 1, + "uniqueItems": true + }, + "type": { + "anyOf": [ + { + "$ref": "#/definitions/simpleTypes" + }, + { + "type": "array", + "items": { + "$ref": "#/definitions/simpleTypes" + }, + "minItems": 1, + "uniqueItems": true + } + ] + }, + "format": { + "type": "string" + }, + "contentMediaType": { + "type": "string" + }, + "contentEncoding": { + "type": "string" + }, + "if": { + "$ref": "#" + }, + "then": { + "$ref": "#" + }, + "else": { + "$ref": "#" + }, + "allOf": { + "$ref": "#/definitions/schemaArray" + }, + "anyOf": { + "$ref": "#/definitions/schemaArray" + }, + "oneOf": { + "$ref": "#/definitions/schemaArray" + }, + "not": { + "$ref": "#" + } + }, + "default": true +} diff --git a/implementations/js-jetio/meta-schemas/draft/2019-09/meta/applicator.json b/implementations/js-jetio/meta-schemas/draft/2019-09/meta/applicator.json new file mode 100644 index 000000000..e49563dc9 --- /dev/null +++ b/implementations/js-jetio/meta-schemas/draft/2019-09/meta/applicator.json @@ -0,0 +1,93 @@ +{ + "$schema": "https://json-schema.org/draft/2019-09/schema", + "$id": "https://json-schema.org/draft/2019-09/meta/applicator", + "$recursiveAnchor": true, + "title": "Applicator vocabulary meta-schema", + "type": [ + "object", + "boolean" + ], + "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": "#" + } + } + } +} diff --git a/implementations/js-jetio/meta-schemas/draft/2019-09/meta/content.json b/implementations/js-jetio/meta-schemas/draft/2019-09/meta/content.json new file mode 100644 index 000000000..f4914ada7 --- /dev/null +++ b/implementations/js-jetio/meta-schemas/draft/2019-09/meta/content.json @@ -0,0 +1,21 @@ +{ + "$schema": "https://json-schema.org/draft/2019-09/schema", + "$id": "https://json-schema.org/draft/2019-09/meta/content", + "$recursiveAnchor": true, + "title": "Content vocabulary meta-schema", + "type": [ + "object", + "boolean" + ], + "properties": { + "contentMediaType": { + "type": "string" + }, + "contentEncoding": { + "type": "string" + }, + "contentSchema": { + "$recursiveRef": "#" + } + } +} diff --git a/implementations/js-jetio/meta-schemas/draft/2019-09/meta/core.json b/implementations/js-jetio/meta-schemas/draft/2019-09/meta/core.json new file mode 100644 index 000000000..444fc5d25 --- /dev/null +++ b/implementations/js-jetio/meta-schemas/draft/2019-09/meta/core.json @@ -0,0 +1,58 @@ +{ + "$schema": "https://json-schema.org/draft/2019-09/schema", + "$id": "https://json-schema.org/draft/2019-09/meta/core", + "$recursiveAnchor": true, + "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": {} + } + } +} diff --git a/implementations/js-jetio/meta-schemas/draft/2019-09/meta/format.json b/implementations/js-jetio/meta-schemas/draft/2019-09/meta/format.json new file mode 100644 index 000000000..5ef7384a7 --- /dev/null +++ b/implementations/js-jetio/meta-schemas/draft/2019-09/meta/format.json @@ -0,0 +1,15 @@ +{ + "$schema": "https://json-schema.org/draft/2019-09/schema", + "$id": "https://json-schema.org/draft/2019-09/meta/format", + "$recursiveAnchor": true, + "title": "Format vocabulary meta-schema", + "type": [ + "object", + "boolean" + ], + "properties": { + "format": { + "type": "string" + } + } +} diff --git a/implementations/js-jetio/meta-schemas/draft/2019-09/meta/meta-data.json b/implementations/js-jetio/meta-schemas/draft/2019-09/meta/meta-data.json new file mode 100644 index 000000000..bf37b11ab --- /dev/null +++ b/implementations/js-jetio/meta-schemas/draft/2019-09/meta/meta-data.json @@ -0,0 +1,35 @@ +{ + "$schema": "https://json-schema.org/draft/2019-09/schema", + "$id": "https://json-schema.org/draft/2019-09/meta/meta-data", + "$recursiveAnchor": true, + "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 + } + } +} diff --git a/implementations/js-jetio/meta-schemas/draft/2019-09/meta/validation.json b/implementations/js-jetio/meta-schemas/draft/2019-09/meta/validation.json new file mode 100644 index 000000000..12c295b02 --- /dev/null +++ b/implementations/js-jetio/meta-schemas/draft/2019-09/meta/validation.json @@ -0,0 +1,119 @@ +{ + "$schema": "https://json-schema.org/draft/2019-09/schema", + "$id": "https://json-schema.org/draft/2019-09/meta/validation", + "$recursiveAnchor": true, + "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": [] + } + } +} diff --git a/implementations/js-jetio/meta-schemas/draft/2019-09/schema.json b/implementations/js-jetio/meta-schemas/draft/2019-09/schema.json new file mode 100644 index 000000000..514fd4fe4 --- /dev/null +++ b/implementations/js-jetio/meta-schemas/draft/2019-09/schema.json @@ -0,0 +1,62 @@ +{ + "$schema": "https://json-schema.org/draft/2019-09/schema", + "$id": "https://json-schema.org/draft/2019-09/schema", + "$vocabulary": { + "https://json-schema.org/draft/2019-09/vocab/core": true, + "https://json-schema.org/draft/2019-09/vocab/applicator": true, + "https://json-schema.org/draft/2019-09/vocab/validation": true, + "https://json-schema.org/draft/2019-09/vocab/meta-data": true, + "https://json-schema.org/draft/2019-09/vocab/format": false, + "https://json-schema.org/draft/2019-09/vocab/content": true + }, + "$recursiveAnchor": true, + "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" + } + ] + } + } + } +} diff --git a/implementations/js-jetio/meta-schemas/draft/2020-12/meta/applicator.json b/implementations/js-jetio/meta-schemas/draft/2020-12/meta/applicator.json new file mode 100644 index 000000000..7ec5c5cd6 --- /dev/null +++ b/implementations/js-jetio/meta-schemas/draft/2020-12/meta/applicator.json @@ -0,0 +1,81 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://json-schema.org/draft/2020-12/meta/applicator", + "$dynamicAnchor": "meta", + "title": "Applicator vocabulary meta-schema", + "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" + }, + "default": {} + }, + "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" + } + } + } +} diff --git a/implementations/js-jetio/meta-schemas/draft/2020-12/meta/content.json b/implementations/js-jetio/meta-schemas/draft/2020-12/meta/content.json new file mode 100644 index 000000000..fb86c2603 --- /dev/null +++ b/implementations/js-jetio/meta-schemas/draft/2020-12/meta/content.json @@ -0,0 +1,21 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://json-schema.org/draft/2020-12/meta/content", + "$dynamicAnchor": "meta", + "title": "Content vocabulary meta-schema", + "type": [ + "object", + "boolean" + ], + "properties": { + "contentEncoding": { + "type": "string" + }, + "contentMediaType": { + "type": "string" + }, + "contentSchema": { + "$dynamicRef": "#meta" + } + } +} diff --git a/implementations/js-jetio/meta-schemas/draft/2020-12/meta/core.json b/implementations/js-jetio/meta-schemas/draft/2020-12/meta/core.json new file mode 100644 index 000000000..4b1c5057d --- /dev/null +++ b/implementations/js-jetio/meta-schemas/draft/2020-12/meta/core.json @@ -0,0 +1,64 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://json-schema.org/draft/2020-12/meta/core", + "$dynamicAnchor": "meta", + "title": "Core vocabulary meta-schema", + "type": [ + "object", + "boolean" + ], + "properties": { + "$id": { + "$ref": "#/$defs/uriReferenceString", + "$comment": "Non-empty fragments not allowed.", + "pattern": "^[^#]*#?$" + }, + "$schema": { + "$ref": "#/$defs/uriString" + }, + "$ref": { + "$ref": "#/$defs/uriReferenceString" + }, + "$anchor": { + "$ref": "#/$defs/anchorString" + }, + "$dynamicRef": { + "$ref": "#/$defs/uriReferenceString" + }, + "$dynamicAnchor": { + "$ref": "#/$defs/anchorString" + }, + "$vocabulary": { + "type": "object", + "propertyNames": { + "$ref": "#/$defs/uriString" + }, + "additionalProperties": { + "type": "boolean" + } + }, + "$comment": { + "type": "string" + }, + "$defs": { + "type": "object", + "additionalProperties": { + "$dynamicRef": "#meta" + } + } + }, + "$defs": { + "anchorString": { + "type": "string", + "pattern": "^[A-Za-z_][-A-Za-z0-9._]*$" + }, + "uriString": { + "type": "string", + "format": "uri" + }, + "uriReferenceString": { + "type": "string", + "format": "uri-reference" + } + } +} diff --git a/implementations/js-jetio/meta-schemas/draft/2020-12/meta/format-annotation.json b/implementations/js-jetio/meta-schemas/draft/2020-12/meta/format-annotation.json new file mode 100644 index 000000000..da47ad518 --- /dev/null +++ b/implementations/js-jetio/meta-schemas/draft/2020-12/meta/format-annotation.json @@ -0,0 +1,15 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://json-schema.org/draft/2020-12/meta/format-annotation", + "$dynamicAnchor": "meta", + "title": "Format vocabulary meta-schema for annotation results", + "type": [ + "object", + "boolean" + ], + "properties": { + "format": { + "type": "string" + } + } +} diff --git a/implementations/js-jetio/meta-schemas/draft/2020-12/meta/meta-data.json b/implementations/js-jetio/meta-schemas/draft/2020-12/meta/meta-data.json new file mode 100644 index 000000000..dc04269cb --- /dev/null +++ b/implementations/js-jetio/meta-schemas/draft/2020-12/meta/meta-data.json @@ -0,0 +1,35 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://json-schema.org/draft/2020-12/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 + } + } +} diff --git a/implementations/js-jetio/meta-schemas/draft/2020-12/meta/unevaluated.json b/implementations/js-jetio/meta-schemas/draft/2020-12/meta/unevaluated.json new file mode 100644 index 000000000..a46c4683c --- /dev/null +++ b/implementations/js-jetio/meta-schemas/draft/2020-12/meta/unevaluated.json @@ -0,0 +1,18 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://json-schema.org/draft/2020-12/meta/unevaluated", + "$dynamicAnchor": "meta", + "title": "Unevaluated applicator vocabulary meta-schema", + "type": [ + "object", + "boolean" + ], + "properties": { + "unevaluatedItems": { + "$dynamicRef": "#meta" + }, + "unevaluatedProperties": { + "$dynamicRef": "#meta" + } + } +} diff --git a/implementations/js-jetio/meta-schemas/draft/2020-12/meta/validation.json b/implementations/js-jetio/meta-schemas/draft/2020-12/meta/validation.json new file mode 100644 index 000000000..003d4a0a2 --- /dev/null +++ b/implementations/js-jetio/meta-schemas/draft/2020-12/meta/validation.json @@ -0,0 +1,119 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://json-schema.org/draft/2020-12/meta/validation", + "$dynamicAnchor": "meta", + "title": "Validation vocabulary meta-schema", + "type": [ + "object", + "boolean" + ], + "properties": { + "type": { + "anyOf": [ + { + "$ref": "#/$defs/simpleTypes" + }, + { + "type": "array", + "items": { + "$ref": "#/$defs/simpleTypes" + }, + "minItems": 1, + "uniqueItems": true + } + ] + }, + "const": true, + "enum": { + "type": "array", + "items": true + }, + "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" + } + } + }, + "$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": [] + } + } +} diff --git a/implementations/js-jetio/meta-schemas/draft/2020-12/schema.json b/implementations/js-jetio/meta-schemas/draft/2020-12/schema.json new file mode 100644 index 000000000..605a83375 --- /dev/null +++ b/implementations/js-jetio/meta-schemas/draft/2020-12/schema.json @@ -0,0 +1,80 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://json-schema.org/draft/2020-12/schema", + "$vocabulary": { + "https://json-schema.org/draft/2020-12/vocab/core": true, + "https://json-schema.org/draft/2020-12/vocab/applicator": true, + "https://json-schema.org/draft/2020-12/vocab/unevaluated": true, + "https://json-schema.org/draft/2020-12/vocab/validation": true, + "https://json-schema.org/draft/2020-12/vocab/meta-data": true, + "https://json-schema.org/draft/2020-12/vocab/format-annotation": true, + "https://json-schema.org/draft/2020-12/vocab/content": true + }, + "$dynamicAnchor": "meta", + "title": "Core and Validation specifications meta-schema", + "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" + ], + "$comment": "This meta-schema also defines keywords that have appeared in previous drafts in order to prevent incompatible extensions as they remain in common use.", + "properties": { + "definitions": { + "$comment": "\"definitions\" has been replaced by \"$defs\".", + "type": "object", + "additionalProperties": { + "$dynamicRef": "#meta" + }, + "deprecated": true, + "default": {} + }, + "dependencies": { + "$comment": "\"dependencies\" has been split and replaced by \"dependentSchemas\" and \"dependentRequired\" in order to serve their differing semantics.", + "type": "object", + "additionalProperties": { + "anyOf": [ + { + "$dynamicRef": "#meta" + }, + { + "$ref": "meta/validation#/$defs/stringArray" + } + ] + }, + "deprecated": true, + "default": {} + }, + "$recursiveAnchor": { + "$comment": "\"$recursiveAnchor\" has been replaced by \"$dynamicAnchor\".", + "$ref": "meta/core#/$defs/anchorString", + "deprecated": true + }, + "$recursiveRef": { + "$comment": "\"$recursiveRef\" has been replaced by \"$dynamicRef\".", + "$ref": "meta/core#/$defs/uriReferenceString", + "deprecated": true + } + } +} diff --git a/implementations/js-jetio/meta-schemas/loader.d.mts b/implementations/js-jetio/meta-schemas/loader.d.mts new file mode 100644 index 000000000..1e5f34fa1 --- /dev/null +++ b/implementations/js-jetio/meta-schemas/loader.d.mts @@ -0,0 +1,10 @@ +/** + * Auto-generated meta-schema loader + * Generated by: jetvalidator-meta load + */ + +export function loadDraft06(jetValidator: any): void; +export function loadDraft07(jetValidator: any): void; +export function loadDraft201909(jetValidator: any): void; +export function loadDraft202012(jetValidator: any): void; +export function loadAllMetaSchemas(jetValidator: any): void; diff --git a/implementations/js-jetio/meta-schemas/loader.mjs b/implementations/js-jetio/meta-schemas/loader.mjs new file mode 100644 index 000000000..ad0605e15 --- /dev/null +++ b/implementations/js-jetio/meta-schemas/loader.mjs @@ -0,0 +1,91 @@ +/** + * Auto-generated meta-schema loader + * Generated by: jetvalidator-meta load + * + * Usage: + * import { loadDraft07, loadAllMetaSchemas } from './loader.mjs'; + * + * const jetValidator = new JetValidator(); + * loadDraft07(jetValidator); // Load specific version + * // OR + * loadAllMetaSchemas(jetValidator); // Load all versions + */ + +import schema_draft_06 from './draft-06/schema.json' with { type: "json" }; + +import schema_draft_07 from './draft-07/schema.json' with { type: "json" }; + +import schema_draft_2019_09 from './draft/2019-09/schema.json' with { type: "json" }; +import schema_draft_2019_09_core from './draft/2019-09/meta/core.json' with { type: "json" }; +import schema_draft_2019_09_applicator from './draft/2019-09/meta/applicator.json' with { type: "json" }; +import schema_draft_2019_09_validation from './draft/2019-09/meta/validation.json' with { type: "json" }; +import schema_draft_2019_09_meta_data from './draft/2019-09/meta/meta-data.json' with { type: "json" }; +import schema_draft_2019_09_format from './draft/2019-09/meta/format.json' with { type: "json" }; +import schema_draft_2019_09_content from './draft/2019-09/meta/content.json' with { type: "json" }; + +import schema_draft_2020_12 from './draft/2020-12/schema.json' with { type: "json" }; +import schema_draft_2020_12_core from './draft/2020-12/meta/core.json' with { type: "json" }; +import schema_draft_2020_12_applicator from './draft/2020-12/meta/applicator.json' with { type: "json" }; +import schema_draft_2020_12_unevaluated from './draft/2020-12/meta/unevaluated.json' with { type: "json" }; +import schema_draft_2020_12_validation from './draft/2020-12/meta/validation.json' with { type: "json" }; +import schema_draft_2020_12_meta_data from './draft/2020-12/meta/meta-data.json' with { type: "json" }; +import schema_draft_2020_12_format_annotation from './draft/2020-12/meta/format-annotation.json' with { type: "json" }; +import schema_draft_2020_12_content from './draft/2020-12/meta/content.json' with { type: "json" }; + + +export function loadDraft06(jetValidator) { + jetValidator.addMetaSchema(schema_draft_06, 'https://json-schema.org/draft-06/schema'); + jetValidator.addMetaSchema(schema_draft_06, 'draft-06'); + +} + +export function loadDraft07(jetValidator) { + jetValidator.addMetaSchema(schema_draft_07, 'https://json-schema.org/draft-07/schema'); + jetValidator.addMetaSchema(schema_draft_07, 'draft-07'); + +} + +export function loadDraft201909(jetValidator) { + jetValidator.addMetaSchema(schema_draft_2019_09, 'https://json-schema.org/draft/2019-09/schema'); + jetValidator.addMetaSchema(schema_draft_2019_09, 'draft/2019-09'); + + jetValidator.addMetaSchema(schema_draft_2019_09_core, 'https://json-schema.org/draft/2019-09/meta/core'); + jetValidator.addMetaSchema(schema_draft_2019_09_core, 'draft/2019-09/meta/core'); + jetValidator.addMetaSchema(schema_draft_2019_09_applicator, 'https://json-schema.org/draft/2019-09/meta/applicator'); + jetValidator.addMetaSchema(schema_draft_2019_09_applicator, 'draft/2019-09/meta/applicator'); + jetValidator.addMetaSchema(schema_draft_2019_09_validation, 'https://json-schema.org/draft/2019-09/meta/validation'); + jetValidator.addMetaSchema(schema_draft_2019_09_validation, 'draft/2019-09/meta/validation'); + jetValidator.addMetaSchema(schema_draft_2019_09_meta_data, 'https://json-schema.org/draft/2019-09/meta/meta-data'); + jetValidator.addMetaSchema(schema_draft_2019_09_meta_data, 'draft/2019-09/meta/meta-data'); + jetValidator.addMetaSchema(schema_draft_2019_09_format, 'https://json-schema.org/draft/2019-09/meta/format'); + jetValidator.addMetaSchema(schema_draft_2019_09_format, 'draft/2019-09/meta/format'); + jetValidator.addMetaSchema(schema_draft_2019_09_content, 'https://json-schema.org/draft/2019-09/meta/content'); + jetValidator.addMetaSchema(schema_draft_2019_09_content, 'draft/2019-09/meta/content'); +} + +export function loadDraft202012(jetValidator) { + jetValidator.addMetaSchema(schema_draft_2020_12, 'https://json-schema.org/draft/2020-12/schema'); + jetValidator.addMetaSchema(schema_draft_2020_12, 'draft/2020-12'); + + jetValidator.addMetaSchema(schema_draft_2020_12_core, 'https://json-schema.org/draft/2020-12/meta/core'); + jetValidator.addMetaSchema(schema_draft_2020_12_core, 'draft/2020-12/meta/core'); + jetValidator.addMetaSchema(schema_draft_2020_12_applicator, 'https://json-schema.org/draft/2020-12/meta/applicator'); + jetValidator.addMetaSchema(schema_draft_2020_12_applicator, 'draft/2020-12/meta/applicator'); + jetValidator.addMetaSchema(schema_draft_2020_12_unevaluated, 'https://json-schema.org/draft/2020-12/meta/unevaluated'); + jetValidator.addMetaSchema(schema_draft_2020_12_unevaluated, 'draft/2020-12/meta/unevaluated'); + jetValidator.addMetaSchema(schema_draft_2020_12_validation, 'https://json-schema.org/draft/2020-12/meta/validation'); + jetValidator.addMetaSchema(schema_draft_2020_12_validation, 'draft/2020-12/meta/validation'); + jetValidator.addMetaSchema(schema_draft_2020_12_meta_data, 'https://json-schema.org/draft/2020-12/meta/meta-data'); + jetValidator.addMetaSchema(schema_draft_2020_12_meta_data, 'draft/2020-12/meta/meta-data'); + jetValidator.addMetaSchema(schema_draft_2020_12_format_annotation, 'https://json-schema.org/draft/2020-12/meta/format-annotation'); + jetValidator.addMetaSchema(schema_draft_2020_12_format_annotation, 'draft/2020-12/meta/format-annotation'); + jetValidator.addMetaSchema(schema_draft_2020_12_content, 'https://json-schema.org/draft/2020-12/meta/content'); + jetValidator.addMetaSchema(schema_draft_2020_12_content, 'draft/2020-12/meta/content'); +} + +export function loadAllMetaSchemas(jetValidator) { + loadDraft06(jetValidator); + loadDraft07(jetValidator); + loadDraft201909(jetValidator); + loadDraft202012(jetValidator); +} diff --git a/implementations/js-jetio/package.json b/implementations/js-jetio/package.json new file mode 100644 index 000000000..709ff286a --- /dev/null +++ b/implementations/js-jetio/package.json @@ -0,0 +1,6 @@ +{ + "type": "module", + "dependencies": { + "@jetio/validator": "^3.0.1" + } +}