@earendil-works/pi-schema 1.5.0 → 1.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -8,11 +8,12 @@ export interface Resolved {
8
8
  export declare const DEFAULT_BASE = "https://json-schema.invalid/root.json";
9
9
  /**
10
10
  * Resolves references in the root schema and the registered documents. The schema is indexed on the first
11
- * reference, so a schema without references is never walked for identifiers.
11
+ * reference or the first `$id` a walker meets, so a schema with neither is never walked for identifiers.
12
12
  */
13
13
  export declare class Resolver {
14
14
  readonly draft: "2020-12" | "7";
15
- readonly rootBase: string;
15
+ /** The base URI the root schema is walked from; walkers apply the root's own `$id` through `baseFor`. */
16
+ readonly rootBase = "https://json-schema.invalid/root.json";
16
17
  /** Schema object to the base URI it was indexed under. */
17
18
  readonly baseOf: Map<object, string>;
18
19
  /** URI (with a `#name` fragment) of every `$dynamicAnchor`, to its schema. */
@@ -1 +1 @@
1
- {"version":3,"file":"resolver.d.ts","sourceRoot":"","sources":["../src/resolver.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE3E,gEAAgE;AAChE,MAAM,WAAW,QAAQ;IACxB,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACtB;AAED,2FAA2F;AAC3F,eAAO,MAAM,YAAY,0CAA0C,CAAC;AAEpE;;;GAGG;AACH,qBAAa,QAAQ;IACpB,QAAQ,CAAC,KAAK,EAAE,SAAS,GAAG,GAAG,CAAC;IAChC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,0DAA0D;IAC1D,QAAQ,CAAC,MAAM,sBAA6B;IAC5C,8EAA8E;IAC9E,QAAQ,CAAC,cAAc,4BAAmC;IAC1D,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAa;IAClC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAiB;IACzC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAiC;IAC1D,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAU;IAC3C,mGAAmG;IACnG,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAqB;IAChD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA8B;IACxD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAmC;IAC3D,OAAO,CAAC,OAAO,CAAS;IAExB,YAAY,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,cAAc,EAMpD;IAED;;;OAGG;IACH,OAAO,CAAC,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAOhD;IAED,yEAAyE;IACzE,aAAa,IAAI,IAAI,CAQpB;IAED;;;OAGG;IACH,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,QAAQ,CAS3C;IAED,yEAAyE;IACzE,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAE/C;IAED,OAAO,CAAC,IAAI;IAaZ,mEAAmE;IACnE,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAG9C;IAGD,OAAO,CAAC,KAAK;IAkCb,OAAO,CAAC,IAAI;IAQZ,OAAO,CAAC,OAAO;CAcf;AAqBD,wFAAwF;AACxF,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,YAAY,CAEpE;AAED,8GAA8G;AAC9G,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAM5D;AAED,kCAAkC;AAClC,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAG9C"}
1
+ {"version":3,"file":"resolver.d.ts","sourceRoot":"","sources":["../src/resolver.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE3E,gEAAgE;AAChE,MAAM,WAAW,QAAQ;IACxB,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACtB;AAED,2FAA2F;AAC3F,eAAO,MAAM,YAAY,0CAA0C,CAAC;AAEpE;;;GAGG;AACH,qBAAa,QAAQ;IACpB,QAAQ,CAAC,KAAK,EAAE,SAAS,GAAG,GAAG,CAAC;IAChC,yGAAyG;IACzG,QAAQ,CAAC,QAAQ,2CAAgB;IACjC,0DAA0D;IAC1D,QAAQ,CAAC,MAAM,sBAA6B;IAC5C,8EAA8E;IAC9E,QAAQ,CAAC,cAAc,4BAAmC;IAC1D,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAa;IAClC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAiB;IACzC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAiC;IAC1D,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAU;IAC3C,mGAAmG;IACnG,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAqB;IAChD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA8B;IACxD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAmC;IAC3D,OAAO,CAAC,OAAO,CAAS;IAExB,YAAY,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,cAAc,EAKpD;IAED;;;OAGG;IACH,OAAO,CAAC,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAahD;IAED,yEAAyE;IACzE,aAAa,IAAI,IAAI,CAQpB;IAED;;;OAGG;IACH,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,QAAQ,CAS3C;IAED,yEAAyE;IACzE,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAE/C;IAED,OAAO,CAAC,IAAI;IAaZ,mEAAmE;IACnE,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAG9C;IAGD,OAAO,CAAC,KAAK;IAkCb,OAAO,CAAC,IAAI;IAQZ,OAAO,CAAC,OAAO;CAcf;AAqBD,wFAAwF;AACxF,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,YAAY,CAEpE;AAED,8GAA8G;AAC9G,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAM5D;AAED,kCAAkC;AAClC,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAG9C"}
package/dist/resolver.js CHANGED
@@ -4,11 +4,12 @@
4
4
  export const DEFAULT_BASE = "https://json-schema.invalid/root.json";
5
5
  /**
6
6
  * Resolves references in the root schema and the registered documents. The schema is indexed on the first
7
- * reference, so a schema without references is never walked for identifiers.
7
+ * reference or the first `$id` a walker meets, so a schema with neither is never walked for identifiers.
8
8
  */
9
9
  export class Resolver {
10
10
  draft;
11
- rootBase;
11
+ /** The base URI the root schema is walked from; walkers apply the root's own `$id` through `baseFor`. */
12
+ rootBase = DEFAULT_BASE;
12
13
  /** Schema object to the base URI it was indexed under. */
13
14
  baseOf = new Map();
14
15
  /** URI (with a `#name` fragment) of every `$dynamicAnchor`, to its schema. */
@@ -27,19 +28,25 @@ export class Resolver {
27
28
  this.root = root;
28
29
  this.options = options;
29
30
  this.rejectUnresolved = options.unresolvedRefs === "reject";
30
- this.rootBase = isSchemaObject(root) ? this.baseFor(root, DEFAULT_BASE) : DEFAULT_BASE;
31
31
  }
32
32
  /**
33
33
  * The base URI of `node`, whose parent has `base`: its `$id` changes it, unless draft 7 makes the `$id` inert. Once
34
34
  * the schema is indexed, the indexed base (a resolved reference target already has its own).
35
35
  */
36
36
  baseFor(node, base) {
37
- const indexed = this.baseOf.get(node);
37
+ let indexed = this.baseOf.get(node);
38
38
  if (indexed !== undefined)
39
39
  return indexed;
40
40
  const id = node.$id;
41
41
  if (typeof id !== "string")
42
42
  return base;
43
+ // Index before applying an `$id`: a caller's `base` may already include it, and the index applies it once.
44
+ if (!this.indexed) {
45
+ this.ensureIndexed();
46
+ indexed = this.baseOf.get(node);
47
+ if (indexed !== undefined)
48
+ return indexed;
49
+ }
43
50
  if (this.draft === "7" && (typeof node.$ref === "string" || id.startsWith("#")))
44
51
  return base;
45
52
  return documentOf(resolveUri(id, base));
@@ -1 +1 @@
1
- {"version":3,"file":"resolver.js","sourceRoot":"","sources":["../src/resolver.ts"],"names":[],"mappings":"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","sourcesContent":["// Reference resolution of one compile: schema resources, anchors and JSON Pointers over the root schema and the\n// registered documents. A Resolver lives only while a schema compiles (or while its errors are explained).\n\nimport type { CompileOptions, JsonSchema, SchemaObject } from \"./types.ts\";\n\n/** A schema and the base URI its references resolve against. */\nexport interface Resolved {\n\treadonly node: unknown;\n\treadonly base: string;\n}\n\n/** The base URI of a root schema without `$id`; relative references resolve against it. */\nexport const DEFAULT_BASE = \"https://json-schema.invalid/root.json\";\n\n/**\n * Resolves references in the root schema and the registered documents. The schema is indexed on the first\n * reference, so a schema without references is never walked for identifiers.\n */\nexport class Resolver {\n\treadonly draft: \"2020-12\" | \"7\";\n\treadonly rootBase: string;\n\t/** Schema object to the base URI it was indexed under. */\n\treadonly baseOf = new Map<object, string>();\n\t/** URI (with a `#name` fragment) of every `$dynamicAnchor`, to its schema. */\n\treadonly dynamicAnchors = new Map<string, SchemaObject>();\n\tprivate readonly root: JsonSchema;\n\tprivate readonly options: CompileOptions;\n\tprivate readonly registry = new Map<string, JsonSchema>();\n\tprivate readonly rejectUnresolved: boolean;\n\t/** The references that named nothing and resolved to `false` (with `unresolvedRefs: \"reject\"`). */\n\tprivate readonly unresolved = new Set<string>();\n\tprivate readonly resources = new Map<string, unknown>();\n\tprivate readonly anchors = new Map<string, SchemaObject>();\n\tprivate indexed = false;\n\n\tconstructor(root: JsonSchema, options: CompileOptions) {\n\t\tthis.draft = options.draft === \"7\" ? \"7\" : \"2020-12\";\n\t\tthis.root = root;\n\t\tthis.options = options;\n\t\tthis.rejectUnresolved = options.unresolvedRefs === \"reject\";\n\t\tthis.rootBase = isSchemaObject(root) ? this.baseFor(root, DEFAULT_BASE) : DEFAULT_BASE;\n\t}\n\n\t/**\n\t * The base URI of `node`, whose parent has `base`: its `$id` changes it, unless draft 7 makes the `$id` inert. Once\n\t * the schema is indexed, the indexed base (a resolved reference target already has its own).\n\t */\n\tbaseFor(node: SchemaObject, base: string): string {\n\t\tconst indexed = this.baseOf.get(node);\n\t\tif (indexed !== undefined) return indexed;\n\t\tconst id = node.$id;\n\t\tif (typeof id !== \"string\") return base;\n\t\tif (this.draft === \"7\" && (typeof node.$ref === \"string\" || id.startsWith(\"#\"))) return base;\n\t\treturn documentOf(resolveUri(id, base));\n\t}\n\n\t/** Indexes the root schema and the registered documents' URIs (once). */\n\tensureIndexed(): void {\n\t\tif (this.indexed) return;\n\t\tthis.indexed = true;\n\t\tfor (const [uri, schema] of Object.entries(this.options.schemas ?? {})) {\n\t\t\tthis.registry.set(documentOf(resolveUri(uri, DEFAULT_BASE)), schema);\n\t\t}\n\t\tthis.resources.set(DEFAULT_BASE, this.root);\n\t\tthis.index(this.root, DEFAULT_BASE);\n\t}\n\n\t/**\n\t * The schema a reference names, with the base URI it compiles under. Throws if it names nothing, or, with\n\t * `unresolvedRefs: \"reject\"`, resolves to `false`, the schema no value passes.\n\t */\n\tresolve(ref: string, base: string): Resolved {\n\t\tthis.ensureIndexed();\n\t\tif (!this.rejectUnresolved) return this.find(ref, base);\n\t\ttry {\n\t\t\treturn this.find(ref, base);\n\t\t} catch {\n\t\t\tthis.unresolved.add(resolveUri(ref, base));\n\t\t\treturn { node: false, base };\n\t\t}\n\t}\n\n\t/** Whether `ref`, from `base`, named nothing and resolved to `false`. */\n\tisUnresolved(ref: string, base: string): boolean {\n\t\treturn this.unresolved.has(resolveUri(ref, base));\n\t}\n\n\tprivate find(ref: string, base: string): Resolved {\n\t\tconst uri = resolveUri(ref, base);\n\t\tconst doc = documentOf(uri);\n\t\tconst fragment = uri.length > doc.length ? decodeURIComponent(uri.slice(doc.length + 1)) : \"\";\n\t\tconst root = this.resources.has(doc) ? this.resources.get(doc) : this.load(doc);\n\t\tif (root === undefined) throw new Error(`Unresolved $ref ${ref} (no schema registered for ${doc})`);\n\t\tif (fragment === \"\") return { node: root, base: doc };\n\t\tif (fragment.startsWith(\"/\")) return this.pointer(root, doc, fragment);\n\t\tconst target = this.anchors.get(`${doc}#${fragment}`);\n\t\tif (target === undefined) throw new Error(`Unresolved $ref ${ref} (no anchor ${fragment} in ${doc})`);\n\t\treturn { node: target, base: this.baseOf.get(target) ?? doc };\n\t}\n\n\t/** Whether `node` is the root of the schema resource at `base`. */\n\tisResource(node: object, base: string): boolean {\n\t\tthis.ensureIndexed();\n\t\treturn this.resources.get(base) === node;\n\t}\n\n\t// Walks only keywords that hold subschemas: an `$id` inside `enum`, `const` or an unknown keyword names nothing.\n\tprivate index(node: unknown, base: string): void {\n\t\tif (!isSchemaObject(node) || this.baseOf.has(node)) return;\n\t\tlet b = base;\n\t\t// In draft 7 a `$ref` makes every sibling keyword, `$id` included, inert.\n\t\tconst refOnly = this.draft === \"7\" && typeof node.$ref === \"string\";\n\t\tif (!refOnly && typeof node.$id === \"string\") {\n\t\t\tif (this.draft === \"7\" && node.$id.startsWith(\"#\")) this.anchors.set(documentOf(b) + node.$id, node);\n\t\t\telse {\n\t\t\t\tconst uri = resolveUri(node.$id, b);\n\t\t\t\tb = documentOf(uri);\n\t\t\t\tthis.resources.set(b, node);\n\t\t\t\tif (uri.length > b.length + 1) this.anchors.set(uri, node);\n\t\t\t}\n\t\t}\n\t\tthis.baseOf.set(node, b);\n\t\tif (refOnly) return;\n\t\tif (this.draft !== \"7\") {\n\t\t\tif (typeof node.$anchor === \"string\") this.anchors.set(`${b}#${node.$anchor}`, node);\n\t\t\tif (typeof node.$dynamicAnchor === \"string\") {\n\t\t\t\tthis.anchors.set(`${b}#${node.$dynamicAnchor}`, node);\n\t\t\t\tthis.dynamicAnchors.set(`${b}#${node.$dynamicAnchor}`, node);\n\t\t\t}\n\t\t}\n\t\tfor (const key of SCHEMA_KEYWORDS) this.index(node[key], b);\n\t\tfor (const key of MAP_KEYWORDS) {\n\t\t\tconst map = node[key];\n\t\t\tif (isSchemaObject(map)) for (const k of Object.keys(map)) this.index(map[k], b);\n\t\t}\n\t\tfor (const key of ARRAY_KEYWORDS) {\n\t\t\tconst list = node[key];\n\t\t\tif (Array.isArray(list)) for (const s of list) this.index(s, b);\n\t\t}\n\t}\n\n\tprivate load(doc: string): JsonSchema | undefined {\n\t\tconst schema = this.registry.get(doc);\n\t\tif (schema === undefined) return undefined;\n\t\tthis.resources.set(doc, schema);\n\t\tthis.index(schema, doc);\n\t\treturn schema;\n\t}\n\n\tprivate pointer(root: unknown, base: string, fragment: string): Resolved {\n\t\tlet node = root;\n\t\tlet b = base;\n\t\tfor (const raw of fragment.split(\"/\").slice(1)) {\n\t\t\tconst key = raw.replace(/~1/g, \"/\").replace(/~0/g, \"~\");\n\t\t\tnode =\n\t\t\t\ttypeof node === \"object\" && node !== null && Object.hasOwn(node, key)\n\t\t\t\t\t? (node as SchemaObject)[key]\n\t\t\t\t\t: undefined;\n\t\t\tif (node === undefined) throw new Error(`Unresolved $ref #${fragment} in ${base}`);\n\t\t\tif (typeof node === \"object\" && node !== null) b = this.baseOf.get(node) ?? b;\n\t\t}\n\t\treturn { node, base: b };\n\t}\n}\n\nconst SCHEMA_KEYWORDS = [\n\t\"additionalProperties\",\n\t\"propertyNames\",\n\t\"contains\",\n\t\"not\",\n\t\"if\",\n\t\"then\",\n\t\"else\",\n\t\"unevaluatedProperties\",\n\t\"unevaluatedItems\",\n\t\"additionalItems\",\n\t\"contentSchema\",\n\t\"items\",\n];\n\nconst MAP_KEYWORDS = [\"properties\", \"patternProperties\", \"$defs\", \"definitions\", \"dependentSchemas\", \"dependencies\"];\n\nconst ARRAY_KEYWORDS = [\"allOf\", \"anyOf\", \"oneOf\", \"prefixItems\", \"items\"];\n\n/** Whether `value` is a schema object (not `true`/`false`, an array or a primitive). */\nexport function isSchemaObject(value: unknown): value is SchemaObject {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\n/** `ref` resolved against `base`. URNs and other bases a URL parser rejects take fragment-only references. */\nexport function resolveUri(ref: string, base: string): string {\n\ttry {\n\t\treturn new URL(ref, base).href;\n\t} catch {\n\t\treturn ref.startsWith(\"#\") ? documentOf(base) + ref : ref;\n\t}\n}\n\n/** `uri` without its fragment. */\nexport function documentOf(uri: string): string {\n\tconst hash = uri.indexOf(\"#\");\n\treturn hash < 0 ? uri : uri.slice(0, hash);\n}\n"]}
1
+ {"version":3,"file":"resolver.js","sourceRoot":"","sources":["../src/resolver.ts"],"names":[],"mappings":"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","sourcesContent":["// Reference resolution of one compile: schema resources, anchors and JSON Pointers over the root schema and the\n// registered documents. A Resolver lives only while a schema compiles (or while its errors are explained).\n\nimport type { CompileOptions, JsonSchema, SchemaObject } from \"./types.ts\";\n\n/** A schema and the base URI its references resolve against. */\nexport interface Resolved {\n\treadonly node: unknown;\n\treadonly base: string;\n}\n\n/** The base URI of a root schema without `$id`; relative references resolve against it. */\nexport const DEFAULT_BASE = \"https://json-schema.invalid/root.json\";\n\n/**\n * Resolves references in the root schema and the registered documents. The schema is indexed on the first\n * reference or the first `$id` a walker meets, so a schema with neither is never walked for identifiers.\n */\nexport class Resolver {\n\treadonly draft: \"2020-12\" | \"7\";\n\t/** The base URI the root schema is walked from; walkers apply the root's own `$id` through `baseFor`. */\n\treadonly rootBase = DEFAULT_BASE;\n\t/** Schema object to the base URI it was indexed under. */\n\treadonly baseOf = new Map<object, string>();\n\t/** URI (with a `#name` fragment) of every `$dynamicAnchor`, to its schema. */\n\treadonly dynamicAnchors = new Map<string, SchemaObject>();\n\tprivate readonly root: JsonSchema;\n\tprivate readonly options: CompileOptions;\n\tprivate readonly registry = new Map<string, JsonSchema>();\n\tprivate readonly rejectUnresolved: boolean;\n\t/** The references that named nothing and resolved to `false` (with `unresolvedRefs: \"reject\"`). */\n\tprivate readonly unresolved = new Set<string>();\n\tprivate readonly resources = new Map<string, unknown>();\n\tprivate readonly anchors = new Map<string, SchemaObject>();\n\tprivate indexed = false;\n\n\tconstructor(root: JsonSchema, options: CompileOptions) {\n\t\tthis.draft = options.draft === \"7\" ? \"7\" : \"2020-12\";\n\t\tthis.root = root;\n\t\tthis.options = options;\n\t\tthis.rejectUnresolved = options.unresolvedRefs === \"reject\";\n\t}\n\n\t/**\n\t * The base URI of `node`, whose parent has `base`: its `$id` changes it, unless draft 7 makes the `$id` inert. Once\n\t * the schema is indexed, the indexed base (a resolved reference target already has its own).\n\t */\n\tbaseFor(node: SchemaObject, base: string): string {\n\t\tlet indexed = this.baseOf.get(node);\n\t\tif (indexed !== undefined) return indexed;\n\t\tconst id = node.$id;\n\t\tif (typeof id !== \"string\") return base;\n\t\t// Index before applying an `$id`: a caller's `base` may already include it, and the index applies it once.\n\t\tif (!this.indexed) {\n\t\t\tthis.ensureIndexed();\n\t\t\tindexed = this.baseOf.get(node);\n\t\t\tif (indexed !== undefined) return indexed;\n\t\t}\n\t\tif (this.draft === \"7\" && (typeof node.$ref === \"string\" || id.startsWith(\"#\"))) return base;\n\t\treturn documentOf(resolveUri(id, base));\n\t}\n\n\t/** Indexes the root schema and the registered documents' URIs (once). */\n\tensureIndexed(): void {\n\t\tif (this.indexed) return;\n\t\tthis.indexed = true;\n\t\tfor (const [uri, schema] of Object.entries(this.options.schemas ?? {})) {\n\t\t\tthis.registry.set(documentOf(resolveUri(uri, DEFAULT_BASE)), schema);\n\t\t}\n\t\tthis.resources.set(DEFAULT_BASE, this.root);\n\t\tthis.index(this.root, DEFAULT_BASE);\n\t}\n\n\t/**\n\t * The schema a reference names, with the base URI it compiles under. Throws if it names nothing, or, with\n\t * `unresolvedRefs: \"reject\"`, resolves to `false`, the schema no value passes.\n\t */\n\tresolve(ref: string, base: string): Resolved {\n\t\tthis.ensureIndexed();\n\t\tif (!this.rejectUnresolved) return this.find(ref, base);\n\t\ttry {\n\t\t\treturn this.find(ref, base);\n\t\t} catch {\n\t\t\tthis.unresolved.add(resolveUri(ref, base));\n\t\t\treturn { node: false, base };\n\t\t}\n\t}\n\n\t/** Whether `ref`, from `base`, named nothing and resolved to `false`. */\n\tisUnresolved(ref: string, base: string): boolean {\n\t\treturn this.unresolved.has(resolveUri(ref, base));\n\t}\n\n\tprivate find(ref: string, base: string): Resolved {\n\t\tconst uri = resolveUri(ref, base);\n\t\tconst doc = documentOf(uri);\n\t\tconst fragment = uri.length > doc.length ? decodeURIComponent(uri.slice(doc.length + 1)) : \"\";\n\t\tconst root = this.resources.has(doc) ? this.resources.get(doc) : this.load(doc);\n\t\tif (root === undefined) throw new Error(`Unresolved $ref ${ref} (no schema registered for ${doc})`);\n\t\tif (fragment === \"\") return { node: root, base: doc };\n\t\tif (fragment.startsWith(\"/\")) return this.pointer(root, doc, fragment);\n\t\tconst target = this.anchors.get(`${doc}#${fragment}`);\n\t\tif (target === undefined) throw new Error(`Unresolved $ref ${ref} (no anchor ${fragment} in ${doc})`);\n\t\treturn { node: target, base: this.baseOf.get(target) ?? doc };\n\t}\n\n\t/** Whether `node` is the root of the schema resource at `base`. */\n\tisResource(node: object, base: string): boolean {\n\t\tthis.ensureIndexed();\n\t\treturn this.resources.get(base) === node;\n\t}\n\n\t// Walks only keywords that hold subschemas: an `$id` inside `enum`, `const` or an unknown keyword names nothing.\n\tprivate index(node: unknown, base: string): void {\n\t\tif (!isSchemaObject(node) || this.baseOf.has(node)) return;\n\t\tlet b = base;\n\t\t// In draft 7 a `$ref` makes every sibling keyword, `$id` included, inert.\n\t\tconst refOnly = this.draft === \"7\" && typeof node.$ref === \"string\";\n\t\tif (!refOnly && typeof node.$id === \"string\") {\n\t\t\tif (this.draft === \"7\" && node.$id.startsWith(\"#\")) this.anchors.set(documentOf(b) + node.$id, node);\n\t\t\telse {\n\t\t\t\tconst uri = resolveUri(node.$id, b);\n\t\t\t\tb = documentOf(uri);\n\t\t\t\tthis.resources.set(b, node);\n\t\t\t\tif (uri.length > b.length + 1) this.anchors.set(uri, node);\n\t\t\t}\n\t\t}\n\t\tthis.baseOf.set(node, b);\n\t\tif (refOnly) return;\n\t\tif (this.draft !== \"7\") {\n\t\t\tif (typeof node.$anchor === \"string\") this.anchors.set(`${b}#${node.$anchor}`, node);\n\t\t\tif (typeof node.$dynamicAnchor === \"string\") {\n\t\t\t\tthis.anchors.set(`${b}#${node.$dynamicAnchor}`, node);\n\t\t\t\tthis.dynamicAnchors.set(`${b}#${node.$dynamicAnchor}`, node);\n\t\t\t}\n\t\t}\n\t\tfor (const key of SCHEMA_KEYWORDS) this.index(node[key], b);\n\t\tfor (const key of MAP_KEYWORDS) {\n\t\t\tconst map = node[key];\n\t\t\tif (isSchemaObject(map)) for (const k of Object.keys(map)) this.index(map[k], b);\n\t\t}\n\t\tfor (const key of ARRAY_KEYWORDS) {\n\t\t\tconst list = node[key];\n\t\t\tif (Array.isArray(list)) for (const s of list) this.index(s, b);\n\t\t}\n\t}\n\n\tprivate load(doc: string): JsonSchema | undefined {\n\t\tconst schema = this.registry.get(doc);\n\t\tif (schema === undefined) return undefined;\n\t\tthis.resources.set(doc, schema);\n\t\tthis.index(schema, doc);\n\t\treturn schema;\n\t}\n\n\tprivate pointer(root: unknown, base: string, fragment: string): Resolved {\n\t\tlet node = root;\n\t\tlet b = base;\n\t\tfor (const raw of fragment.split(\"/\").slice(1)) {\n\t\t\tconst key = raw.replace(/~1/g, \"/\").replace(/~0/g, \"~\");\n\t\t\tnode =\n\t\t\t\ttypeof node === \"object\" && node !== null && Object.hasOwn(node, key)\n\t\t\t\t\t? (node as SchemaObject)[key]\n\t\t\t\t\t: undefined;\n\t\t\tif (node === undefined) throw new Error(`Unresolved $ref #${fragment} in ${base}`);\n\t\t\tif (typeof node === \"object\" && node !== null) b = this.baseOf.get(node) ?? b;\n\t\t}\n\t\treturn { node, base: b };\n\t}\n}\n\nconst SCHEMA_KEYWORDS = [\n\t\"additionalProperties\",\n\t\"propertyNames\",\n\t\"contains\",\n\t\"not\",\n\t\"if\",\n\t\"then\",\n\t\"else\",\n\t\"unevaluatedProperties\",\n\t\"unevaluatedItems\",\n\t\"additionalItems\",\n\t\"contentSchema\",\n\t\"items\",\n];\n\nconst MAP_KEYWORDS = [\"properties\", \"patternProperties\", \"$defs\", \"definitions\", \"dependentSchemas\", \"dependencies\"];\n\nconst ARRAY_KEYWORDS = [\"allOf\", \"anyOf\", \"oneOf\", \"prefixItems\", \"items\"];\n\n/** Whether `value` is a schema object (not `true`/`false`, an array or a primitive). */\nexport function isSchemaObject(value: unknown): value is SchemaObject {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\n/** `ref` resolved against `base`. URNs and other bases a URL parser rejects take fragment-only references. */\nexport function resolveUri(ref: string, base: string): string {\n\ttry {\n\t\treturn new URL(ref, base).href;\n\t} catch {\n\t\treturn ref.startsWith(\"#\") ? documentOf(base) + ref : ref;\n\t}\n}\n\n/** `uri` without its fragment. */\nexport function documentOf(uri: string): string {\n\tconst hash = uri.indexOf(\"#\");\n\treturn hash < 0 ? uri : uri.slice(0, hash);\n}\n"]}
@@ -11,6 +11,8 @@ interface Primitives {
11
11
  Integer: number;
12
12
  Boolean: boolean;
13
13
  Null: null;
14
+ BigInt: bigint;
15
+ Undefined: undefined;
14
16
  Unknown: unknown;
15
17
  Any: any;
16
18
  }
@@ -24,7 +26,13 @@ type KindStatic<S, K> = K extends keyof Primitives ? Primitives[K] : K extends "
24
26
  readonly anyOf: readonly (infer B)[];
25
27
  } ? Static<B> : unknown : K extends "Record" ? S extends {
26
28
  readonly patternProperties: infer P;
27
- } ? Record<RecordKey<keyof P>, Static<P[keyof P]>> : unknown : unknown;
29
+ } ? Record<RecordKey<keyof P>, Static<P[keyof P]>> : unknown : K extends "Enum" ? S extends {
30
+ readonly enum: readonly (infer V)[];
31
+ } ? V : unknown : K extends "Tuple" ? S extends {
32
+ readonly items: infer I extends readonly unknown[];
33
+ } ? {
34
+ -readonly [N in keyof I]: Static<I[N]>;
35
+ } : unknown : unknown;
28
36
  type Optional = {
29
37
  readonly "~optional": true;
30
38
  };
@@ -1 +1 @@
1
- {"version":3,"file":"typebox-static.d.ts","sourceRoot":"","sources":["../src/typebox-static.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"typebox-static.d.ts","sourceRoot":"","sources":["../src/typebox-static.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,7 @@
1
1
  // The static types of TypeBox-built schemas, read from the type shapes TypeBox 1.x declares (`'~kind'`, `'~optional'`,
2
2
  // `'~readonly'`, `'~unsafe'`) without importing TypeBox, so `Static` also types tool arguments of TypeBox schemas.
3
- // Only the common kinds are mapped; every other kind (Enum, Tuple, Intersect, Cyclic, Ref, ...) is `unknown`.
3
+ // Only the common kinds are mapped; every other kind (Intersect, Cyclic, Ref, ...) is `unknown`. Tuples are plain
4
+ // tuples: an element marked `Type.Optional`, `Type.Rest` or `Type.Readonly` is typed by its schema alone (`[string]`
5
+ // where TypeBox gives `[string?]`), unlike TypeBox; tuples of tool and API schemas are fixed pairs, typed exactly.
4
6
  export {};
5
7
  //# sourceMappingURL=typebox-static.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"typebox-static.js","sourceRoot":"","sources":["../src/typebox-static.ts"],"names":[],"mappings":"AAAA,uHAAuH;AACvH,mHAAmH;AACnH,8GAA8G","sourcesContent":["// The static types of TypeBox-built schemas, read from the type shapes TypeBox 1.x declares (`'~kind'`, `'~optional'`,\n// `'~readonly'`, `'~unsafe'`) without importing TypeBox, so `Static` also types tool arguments of TypeBox schemas.\n// Only the common kinds are mapped; every other kind (Enum, Tuple, Intersect, Cyclic, Ref, ...) is `unknown`.\n\nimport type { Static } from \"./builders.ts\";\n\n/** The value type of a TypeBox schema type by its `'~kind'`, or its `Type.Unsafe` type; `unknown` for other kinds. */\nexport type TypeBoxStatic<S> = S extends { readonly \"~kind\": infer K }\n\t? KindStatic<S, K>\n\t: S extends { readonly \"~unsafe\": infer T }\n\t\t? T\n\t\t: unknown;\n\ninterface Primitives {\n\tString: string;\n\tNumber: number;\n\tInteger: number;\n\tBoolean: boolean;\n\tNull: null;\n\tUnknown: unknown;\n\tAny: any;\n}\n\ntype KindStatic<S, K> = K extends keyof Primitives\n\t? Primitives[K]\n\t: K extends \"Literal\"\n\t\t? S extends { readonly const: infer V }\n\t\t\t? V\n\t\t\t: unknown\n\t\t: K extends \"Array\"\n\t\t\t? S extends { readonly items: infer I }\n\t\t\t\t? Static<I>[]\n\t\t\t\t: unknown\n\t\t\t: K extends \"Object\"\n\t\t\t\t? S extends { readonly properties: infer P }\n\t\t\t\t\t? ObjectStatic<P>\n\t\t\t\t\t: unknown\n\t\t\t\t: K extends \"Union\"\n\t\t\t\t\t? S extends { readonly anyOf: readonly (infer B)[] }\n\t\t\t\t\t\t? Static<B>\n\t\t\t\t\t\t: unknown\n\t\t\t\t\t: K extends \"Record\"\n\t\t\t\t\t\t? S extends { readonly patternProperties: infer P }\n\t\t\t\t\t\t\t? Record<RecordKey<keyof P>, Static<P[keyof P]>>\n\t\t\t\t\t\t\t: unknown\n\t\t\t\t\t\t: unknown;\n\ntype Optional = { readonly \"~optional\": true };\n\ntype Readonly = { readonly \"~readonly\": true };\n\n// As TypeBox: no properties is `object`; `'~optional'` properties may be omitted, `'~readonly'` ones are readonly.\ntype ObjectStatic<P> = keyof P extends never\n\t? object\n\t: Simplify<\n\t\t\t{ -readonly [K in keyof P as P[K] extends Optional | Readonly ? never : K]: Static<P[K]> } & {\n\t\t\t\t-readonly [K in keyof P as P[K] extends Optional ? (P[K] extends Readonly ? never : K) : never]?: Static<\n\t\t\t\t\tP[K]\n\t\t\t\t>;\n\t\t\t} & {\n\t\t\t\treadonly [K in keyof P as P[K] extends Readonly ? (P[K] extends Optional ? never : K) : never]: Static<\n\t\t\t\t\tP[K]\n\t\t\t\t>;\n\t\t\t} & {\n\t\t\t\treadonly [K in keyof P as P[K] extends Optional ? (P[K] extends Readonly ? K : never) : never]?: Static<\n\t\t\t\t\tP[K]\n\t\t\t\t>;\n\t\t\t}\n\t\t>;\n\ntype Simplify<T> = { [K in keyof T]: T[K] } & {};\n\n// TypeBox's key patterns for integer and number keys; every other pattern types its keys as strings.\ntype RecordKey<Pattern> = Pattern extends \"^-?(?:0|[1-9][0-9]*)$\" | \"^-?(?:0|[1-9][0-9]*)(?:\\\\.[0-9]+)?$\"\n\t? number\n\t: string;\n"]}
1
+ {"version":3,"file":"typebox-static.js","sourceRoot":"","sources":["../src/typebox-static.ts"],"names":[],"mappings":"AAAA,uHAAuH;AACvH,mHAAmH;AACnH,kHAAkH;AAClH,qHAAqH;AACrH,mHAAmH","sourcesContent":["// The static types of TypeBox-built schemas, read from the type shapes TypeBox 1.x declares (`'~kind'`, `'~optional'`,\n// `'~readonly'`, `'~unsafe'`) without importing TypeBox, so `Static` also types tool arguments of TypeBox schemas.\n// Only the common kinds are mapped; every other kind (Intersect, Cyclic, Ref, ...) is `unknown`. Tuples are plain\n// tuples: an element marked `Type.Optional`, `Type.Rest` or `Type.Readonly` is typed by its schema alone (`[string]`\n// where TypeBox gives `[string?]`), unlike TypeBox; tuples of tool and API schemas are fixed pairs, typed exactly.\n\nimport type { Static } from \"./builders.ts\";\n\n/** The value type of a TypeBox schema type by its `'~kind'`, or its `Type.Unsafe` type; `unknown` for other kinds. */\nexport type TypeBoxStatic<S> = S extends { readonly \"~kind\": infer K }\n\t? KindStatic<S, K>\n\t: S extends { readonly \"~unsafe\": infer T }\n\t\t? T\n\t\t: unknown;\n\ninterface Primitives {\n\tString: string;\n\tNumber: number;\n\tInteger: number;\n\tBoolean: boolean;\n\tNull: null;\n\tBigInt: bigint;\n\tUndefined: undefined;\n\tUnknown: unknown;\n\tAny: any;\n}\n\ntype KindStatic<S, K> = K extends keyof Primitives\n\t? Primitives[K]\n\t: K extends \"Literal\"\n\t\t? S extends { readonly const: infer V }\n\t\t\t? V\n\t\t\t: unknown\n\t\t: K extends \"Array\"\n\t\t\t? S extends { readonly items: infer I }\n\t\t\t\t? Static<I>[]\n\t\t\t\t: unknown\n\t\t\t: K extends \"Object\"\n\t\t\t\t? S extends { readonly properties: infer P }\n\t\t\t\t\t? ObjectStatic<P>\n\t\t\t\t\t: unknown\n\t\t\t\t: K extends \"Union\"\n\t\t\t\t\t? S extends { readonly anyOf: readonly (infer B)[] }\n\t\t\t\t\t\t? Static<B>\n\t\t\t\t\t\t: unknown\n\t\t\t\t\t: K extends \"Record\"\n\t\t\t\t\t\t? S extends { readonly patternProperties: infer P }\n\t\t\t\t\t\t\t? Record<RecordKey<keyof P>, Static<P[keyof P]>>\n\t\t\t\t\t\t\t: unknown\n\t\t\t\t\t\t: K extends \"Enum\"\n\t\t\t\t\t\t\t? S extends { readonly enum: readonly (infer V)[] }\n\t\t\t\t\t\t\t\t? V\n\t\t\t\t\t\t\t\t: unknown\n\t\t\t\t\t\t\t: K extends \"Tuple\"\n\t\t\t\t\t\t\t\t? S extends { readonly items: infer I extends readonly unknown[] }\n\t\t\t\t\t\t\t\t\t? { -readonly [N in keyof I]: Static<I[N]> }\n\t\t\t\t\t\t\t\t\t: unknown\n\t\t\t\t\t\t\t\t: unknown;\n\ntype Optional = { readonly \"~optional\": true };\n\ntype Readonly = { readonly \"~readonly\": true };\n\n// As TypeBox: no properties is `object`; `'~optional'` properties may be omitted, `'~readonly'` ones are readonly.\ntype ObjectStatic<P> = keyof P extends never\n\t? object\n\t: Simplify<\n\t\t\t{ -readonly [K in keyof P as P[K] extends Optional | Readonly ? never : K]: Static<P[K]> } & {\n\t\t\t\t-readonly [K in keyof P as P[K] extends Optional ? (P[K] extends Readonly ? never : K) : never]?: Static<\n\t\t\t\t\tP[K]\n\t\t\t\t>;\n\t\t\t} & {\n\t\t\t\treadonly [K in keyof P as P[K] extends Readonly ? (P[K] extends Optional ? never : K) : never]: Static<\n\t\t\t\t\tP[K]\n\t\t\t\t>;\n\t\t\t} & {\n\t\t\t\treadonly [K in keyof P as P[K] extends Optional ? (P[K] extends Readonly ? K : never) : never]?: Static<\n\t\t\t\t\tP[K]\n\t\t\t\t>;\n\t\t\t}\n\t\t>;\n\ntype Simplify<T> = { [K in keyof T]: T[K] } & {};\n\n// TypeBox's key patterns for integer and number keys; every other pattern types its keys as strings.\ntype RecordKey<Pattern> = Pattern extends \"^-?(?:0|[1-9][0-9]*)$\" | \"^-?(?:0|[1-9][0-9]*)(?:\\\\.[0-9]+)?$\"\n\t? number\n\t: string;\n"]}
@@ -22,6 +22,15 @@ export declare class Validator<T = unknown> {
22
22
  * kept, so a validator whose values always pass never pays for it.
23
23
  */
24
24
  errors(value: unknown): ValidationError[];
25
+ /**
26
+ * `value` itself when it is valid, else its errors: check() and errors() in one result, without coercion.
27
+ *
28
+ * Not TypeBox's `Value.Parse`, which also clones, fills defaults, converts and strips undeclared properties before
29
+ * it checks. This only checks: the strict replacement where `Value.Parse` is used to validate (its other steps
30
+ * change nothing for a valid value of a schema without defaults or extra properties). Use `parse()` with
31
+ * `coerce: true` for conversion.
32
+ */
33
+ validate(value: unknown): ParseResult<T>;
25
34
  }
26
35
  /** A validator compiled with `coerce: true`: it also coerces loosely typed input towards the schema. */
27
36
  export declare class CoercingValidator<T = unknown> extends Validator<T> {
@@ -1 +1 @@
1
- {"version":3,"file":"validator.d.ts","sourceRoot":"","sources":["../src/validator.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAI5C,OAAO,KAAK,EAAE,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElG;;;;GAIG;AACH,wBAAgB,OAAO,CAAC,CAAC,SAAS,UAAU,EAC3C,MAAM,EAAE,CAAC,EACT,OAAO,EAAE,cAAc,GAAG;IAAE,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAA;CAAE,GACjD,iBAAiB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;AAChC,wBAAgB,OAAO,CAAC,CAAC,SAAS,UAAU,EAAE,MAAM,EAAE,CAAC,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;AAazG,oHAAoH;AACpH,qBAAa,SAAS,CAAC,CAAC,GAAG,OAAO;IACjC,iGAAiG;IACjG,QAAQ,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,KAAK,IAAI,CAAC,CAAC;IAC/C,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;IACtC,SAAS,CAAC,QAAQ,CAAC,OAAO,EAAE,cAAc,CAAC;IAC3C,OAAO,CAAC,SAAS,CAAoC;IAErD,YAAY,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,KAAK,EAKpE;IAED;;;OAGG;IACH,MAAM,CAAC,KAAK,EAAE,OAAO,GAAG,eAAe,EAAE,CAIxC;CACD;AAED,wGAAwG;AACxG,qBAAa,iBAAiB,CAAC,CAAC,GAAG,OAAO,CAAE,SAAQ,SAAS,CAAC,CAAC,CAAC;IAC/D,OAAO,CAAC,OAAO,CAAkC;IAEjD;;;;;OAKG;IACH,MAAM,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAG9B;IAED,4FAA4F;IAC5F,KAAK,CAAC,KAAK,EAAE,OAAO,GAAG,WAAW,CAAC,CAAC,CAAC,CAGpC;CACD"}
1
+ {"version":3,"file":"validator.d.ts","sourceRoot":"","sources":["../src/validator.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAI5C,OAAO,KAAK,EAAE,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElG;;;;GAIG;AACH,wBAAgB,OAAO,CAAC,CAAC,SAAS,UAAU,EAC3C,MAAM,EAAE,CAAC,EACT,OAAO,EAAE,cAAc,GAAG;IAAE,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAA;CAAE,GACjD,iBAAiB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;AAChC,wBAAgB,OAAO,CAAC,CAAC,SAAS,UAAU,EAAE,MAAM,EAAE,CAAC,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;AAazG,oHAAoH;AACpH,qBAAa,SAAS,CAAC,CAAC,GAAG,OAAO;IACjC,iGAAiG;IACjG,QAAQ,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,KAAK,IAAI,CAAC,CAAC;IAC/C,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;IACtC,SAAS,CAAC,QAAQ,CAAC,OAAO,EAAE,cAAc,CAAC;IAC3C,OAAO,CAAC,SAAS,CAAoC;IAErD,YAAY,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,KAAK,EAKpE;IAED;;;OAGG;IACH,MAAM,CAAC,KAAK,EAAE,OAAO,GAAG,eAAe,EAAE,CAIxC;IAED;;;;;;;OAOG;IACH,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,WAAW,CAAC,CAAC,CAAC,CAEvC;CACD;AAED,wGAAwG;AACxG,qBAAa,iBAAiB,CAAC,CAAC,GAAG,OAAO,CAAE,SAAQ,SAAS,CAAC,CAAC,CAAC;IAC/D,OAAO,CAAC,OAAO,CAAkC;IAEjD;;;;;OAKG;IACH,MAAM,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAG9B;IAED,4FAA4F;IAC5F,KAAK,CAAC,KAAK,EAAE,OAAO,GAAG,WAAW,CAAC,CAAC,CAAC,CAEpC;CACD"}
package/dist/validator.js CHANGED
@@ -32,6 +32,17 @@ export class Validator {
32
32
  this.explainer ??= new Explainer(compiler(this.schema, this.options), this.schema);
33
33
  return this.explainer.errors(value);
34
34
  }
35
+ /**
36
+ * `value` itself when it is valid, else its errors: check() and errors() in one result, without coercion.
37
+ *
38
+ * Not TypeBox's `Value.Parse`, which also clones, fills defaults, converts and strips undeclared properties before
39
+ * it checks. This only checks: the strict replacement where `Value.Parse` is used to validate (its other steps
40
+ * change nothing for a valid value of a schema without defaults or extra properties). Use `parse()` with
41
+ * `coerce: true` for conversion.
42
+ */
43
+ validate(value) {
44
+ return this.check(value) ? { ok: true, value } : { ok: false, errors: this.errors(value) };
45
+ }
35
46
  }
36
47
  /** A validator compiled with `coerce: true`: it also coerces loosely typed input towards the schema. */
37
48
  export class CoercingValidator extends Validator {
@@ -48,8 +59,7 @@ export class CoercingValidator extends Validator {
48
59
  }
49
60
  /** Coerces `value`, then checks it: the coerced value when it is valid, else its errors. */
50
61
  parse(value) {
51
- const coerced = this.coerce(value);
52
- return this.check(coerced) ? { ok: true, value: coerced } : { ok: false, errors: this.errors(coerced) };
62
+ return this.validate(this.coerce(value));
53
63
  }
54
64
  }
55
65
  function compileCheck(schema, options) {
@@ -1 +1 @@
1
- {"version":3,"file":"validator.js","sourceRoot":"","sources":["../src/validator.ts"],"names":[],"mappings":"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","sourcesContent":["// compile(): a schema to a Validator, whose `check` is the fast boolean path and whose `errors` explains failures.\n\nimport type { Static } from \"./builders.ts\";\nimport { Coercer } from \"./coerce.ts\";\nimport { Compiler, RESTART } from \"./compiler.ts\";\nimport { Explainer } from \"./explain.ts\";\nimport type { Check, CompileOptions, JsonSchema, ParseResult, ValidationError } from \"./types.ts\";\n\n/**\n * Compiles `schema` into a Validator. Throws if the schema is malformed or a `$ref` names nothing (register other\n * documents with `options.schemas`). The schema is read, never modified. With `coerce: true` the validator also\n * coerces and parses loosely typed input.\n */\nexport function compile<S extends JsonSchema>(\n\tschema: S,\n\toptions: CompileOptions & { readonly coerce: true },\n): CoercingValidator<Static<S>>;\nexport function compile<S extends JsonSchema>(schema: S, options?: CompileOptions): Validator<Static<S>>;\nexport function compile<S extends JsonSchema>(\n\tschema: S,\n\toptions: CompileOptions = NO_OPTIONS,\n): Validator<Static<S>> | CoercingValidator<Static<S>> {\n\tconst check = compileCheck(schema, options);\n\treturn options.coerce === true\n\t\t? new CoercingValidator(schema, options, check)\n\t\t: new Validator(schema, options, check);\n}\n\nconst NO_OPTIONS: CompileOptions = Object.freeze({});\n\n/** A compiled schema whose valid values have type `T` (`unknown` unless the schema was built with the builders). */\nexport class Validator<T = unknown> {\n\t/** Whether `value` is valid. A plain function: it may be passed around without its validator. */\n\treadonly check: (value: unknown) => value is T;\n\tprotected readonly schema: JsonSchema;\n\tprotected readonly options: CompileOptions;\n\tprivate explainer: Explainer | undefined = undefined;\n\n\tconstructor(schema: JsonSchema, options: CompileOptions, check: Check) {\n\t\t// A compiled check is exactly the test that a value has the schema's static type.\n\t\tthis.check = check as (value: unknown) => value is T;\n\t\tthis.schema = schema;\n\t\tthis.options = options;\n\t}\n\n\t/**\n\t * Why `value` is invalid: one error per failing keyword, `[]` when it is valid. Built on the first failure and\n\t * kept, so a validator whose values always pass never pays for it.\n\t */\n\terrors(value: unknown): ValidationError[] {\n\t\tif (this.check(value)) return [];\n\t\tthis.explainer ??= new Explainer(compiler(this.schema, this.options), this.schema);\n\t\treturn this.explainer.errors(value);\n\t}\n}\n\n/** A validator compiled with `coerce: true`: it also coerces loosely typed input towards the schema. */\nexport class CoercingValidator<T = unknown> extends Validator<T> {\n\tprivate coercer: Coercer | undefined = undefined;\n\n\t/**\n\t * `value` coerced towards the schema: numeric strings to numbers, `\"true\"` to `true`, a single value to a one-item\n\t * array, an optional `null` dropped, the first union branch the value converts to (the README lists every rule).\n\t * Only the changed paths are copied; `value` comes back itself when nothing changes, and is never modified. Values\n\t * that cannot be coerced stay as they are. The rules are built on the first call.\n\t */\n\tcoerce(value: unknown): unknown {\n\t\tthis.coercer ??= new Coercer(compiler(this.schema, this.options), this.schema);\n\t\treturn this.coercer.coerce(value);\n\t}\n\n\t/** Coerces `value`, then checks it: the coerced value when it is valid, else its errors. */\n\tparse(value: unknown): ParseResult<T> {\n\t\tconst coerced = this.coerce(value);\n\t\treturn this.check(coerced) ? { ok: true, value: coerced } : { ok: false, errors: this.errors(coerced) };\n\t}\n}\n\nfunction compileCheck(schema: JsonSchema, options: CompileOptions): Check {\n\treturn compiler(schema, options).root();\n}\n\n// Most schemas compile without tracking the dynamic scope; one with a bookended $dynamicRef compiles again with it.\nfunction compiler(schema: JsonSchema, options: CompileOptions): Compiler {\n\tconst plain = new Compiler(schema, options, false);\n\ttry {\n\t\tplain.root();\n\t\treturn plain;\n\t} catch (error) {\n\t\tif (error !== RESTART) throw error;\n\t\treturn new Compiler(schema, options, true);\n\t}\n}\n"]}
1
+ {"version":3,"file":"validator.js","sourceRoot":"","sources":["../src/validator.ts"],"names":[],"mappings":"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","sourcesContent":["// compile(): a schema to a Validator, whose `check` is the fast boolean path and whose `errors` explains failures.\n\nimport type { Static } from \"./builders.ts\";\nimport { Coercer } from \"./coerce.ts\";\nimport { Compiler, RESTART } from \"./compiler.ts\";\nimport { Explainer } from \"./explain.ts\";\nimport type { Check, CompileOptions, JsonSchema, ParseResult, ValidationError } from \"./types.ts\";\n\n/**\n * Compiles `schema` into a Validator. Throws if the schema is malformed or a `$ref` names nothing (register other\n * documents with `options.schemas`). The schema is read, never modified. With `coerce: true` the validator also\n * coerces and parses loosely typed input.\n */\nexport function compile<S extends JsonSchema>(\n\tschema: S,\n\toptions: CompileOptions & { readonly coerce: true },\n): CoercingValidator<Static<S>>;\nexport function compile<S extends JsonSchema>(schema: S, options?: CompileOptions): Validator<Static<S>>;\nexport function compile<S extends JsonSchema>(\n\tschema: S,\n\toptions: CompileOptions = NO_OPTIONS,\n): Validator<Static<S>> | CoercingValidator<Static<S>> {\n\tconst check = compileCheck(schema, options);\n\treturn options.coerce === true\n\t\t? new CoercingValidator(schema, options, check)\n\t\t: new Validator(schema, options, check);\n}\n\nconst NO_OPTIONS: CompileOptions = Object.freeze({});\n\n/** A compiled schema whose valid values have type `T` (`unknown` unless the schema was built with the builders). */\nexport class Validator<T = unknown> {\n\t/** Whether `value` is valid. A plain function: it may be passed around without its validator. */\n\treadonly check: (value: unknown) => value is T;\n\tprotected readonly schema: JsonSchema;\n\tprotected readonly options: CompileOptions;\n\tprivate explainer: Explainer | undefined = undefined;\n\n\tconstructor(schema: JsonSchema, options: CompileOptions, check: Check) {\n\t\t// A compiled check is exactly the test that a value has the schema's static type.\n\t\tthis.check = check as (value: unknown) => value is T;\n\t\tthis.schema = schema;\n\t\tthis.options = options;\n\t}\n\n\t/**\n\t * Why `value` is invalid: one error per failing keyword, `[]` when it is valid. Built on the first failure and\n\t * kept, so a validator whose values always pass never pays for it.\n\t */\n\terrors(value: unknown): ValidationError[] {\n\t\tif (this.check(value)) return [];\n\t\tthis.explainer ??= new Explainer(compiler(this.schema, this.options), this.schema);\n\t\treturn this.explainer.errors(value);\n\t}\n\n\t/**\n\t * `value` itself when it is valid, else its errors: check() and errors() in one result, without coercion.\n\t *\n\t * Not TypeBox's `Value.Parse`, which also clones, fills defaults, converts and strips undeclared properties before\n\t * it checks. This only checks: the strict replacement where `Value.Parse` is used to validate (its other steps\n\t * change nothing for a valid value of a schema without defaults or extra properties). Use `parse()` with\n\t * `coerce: true` for conversion.\n\t */\n\tvalidate(value: unknown): ParseResult<T> {\n\t\treturn this.check(value) ? { ok: true, value } : { ok: false, errors: this.errors(value) };\n\t}\n}\n\n/** A validator compiled with `coerce: true`: it also coerces loosely typed input towards the schema. */\nexport class CoercingValidator<T = unknown> extends Validator<T> {\n\tprivate coercer: Coercer | undefined = undefined;\n\n\t/**\n\t * `value` coerced towards the schema: numeric strings to numbers, `\"true\"` to `true`, a single value to a one-item\n\t * array, an optional `null` dropped, the first union branch the value converts to (the README lists every rule).\n\t * Only the changed paths are copied; `value` comes back itself when nothing changes, and is never modified. Values\n\t * that cannot be coerced stay as they are. The rules are built on the first call.\n\t */\n\tcoerce(value: unknown): unknown {\n\t\tthis.coercer ??= new Coercer(compiler(this.schema, this.options), this.schema);\n\t\treturn this.coercer.coerce(value);\n\t}\n\n\t/** Coerces `value`, then checks it: the coerced value when it is valid, else its errors. */\n\tparse(value: unknown): ParseResult<T> {\n\t\treturn this.validate(this.coerce(value));\n\t}\n}\n\nfunction compileCheck(schema: JsonSchema, options: CompileOptions): Check {\n\treturn compiler(schema, options).root();\n}\n\n// Most schemas compile without tracking the dynamic scope; one with a bookended $dynamicRef compiles again with it.\nfunction compiler(schema: JsonSchema, options: CompileOptions): Compiler {\n\tconst plain = new Compiler(schema, options, false);\n\ttry {\n\t\tplain.root();\n\t\treturn plain;\n\t} catch (error) {\n\t\tif (error !== RESTART) throw error;\n\t\treturn new Compiler(schema, options, true);\n\t}\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@earendil-works/pi-schema",
3
- "version": "1.5.0",
3
+ "version": "1.5.1",
4
4
  "description": "JSON Schema validation without eval: drafts 2020-12 and 7, compiled into plain closures",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -22,7 +22,7 @@
22
22
  "dist",
23
23
  "README.md",
24
24
  "CHANGELOG.md",
25
- "LICENSES"
25
+ "THIRD_PARTY_NOTICES"
26
26
  ],
27
27
  "scripts": {
28
28
  "clean": "node ../../scripts/package-files.mjs clean dist",