@effected/schemastore 0.5.0 → 0.6.0

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.
@@ -57,8 +57,9 @@
57
57
  *
58
58
  * Both consumers of the registry route through {@link KeywordFamilies.isDeclared}:
59
59
  * `DocumentLint`'s `UnknownKeyword` check (a declared key is not flagged) and
60
- * `AnnotationCarriers` (only declared keys are re-grafted after the Draft-07
61
- * lowering). One predicate, so the lint and the carriers cannot drift.
60
+ * `StoreDocument.fromSchema`'s gate (a key outside the families fails the
61
+ * build rather than being emitted). One predicate, so the lint and the gate
62
+ * cannot drift.
62
63
  */
63
64
  const VSCODE_KEYWORDS = /* @__PURE__ */ new Set([
64
65
  "allowTrailingCommas",
package/README.md CHANGED
@@ -5,7 +5,7 @@
5
5
  [![Node.js %3E%3D24.11.0](https://img.shields.io/badge/Node.js-%3E%3D24.11.0-5fa04e.svg)](https://nodejs.org/)
6
6
  [![TypeScript 7.0](https://img.shields.io/badge/TypeScript-7.0-3178c6.svg)](https://www.typescriptlang.org/)
7
7
 
8
- Build, version, validate and lint SchemaStore-shaped Draft-07 JSON Schema documents from Effect Schema sources. Core effect already owns the generation pipeline: `Schema.toJsonSchemaDocument` produces Draft 2020-12 and `JsonSchema.toDocumentDraft07` lowers it. This package owns what [SchemaStore](https://www.schemastore.org) expects around that output — the publication shape (`$schema` + `$id` + root + `$defs`, with the `#/definitions` → `#/$defs` ref rewrite the lowering makes necessary), annotation carriers that keep the language-server keyword families alive through the lowering, catalog entries in both versioning modes, structural and hygiene lints, ajv strict-mode validation, canonical JSON text and content-comparing write-if-changed file IO. `SchemaPipeline` runs that whole emit loop over a list of targets, so a build script calls one function.
8
+ Build, version, validate and lint SchemaStore-shaped Draft-07 JSON Schema documents from Effect Schema sources. Core effect already owns the generation pipeline: `Schema.toJsonSchemaDocument` produces Draft 2020-12 and `JsonSchema.toDocumentDraft07` lowers it. This package owns what [SchemaStore](https://www.schemastore.org) expects around that output — the publication shape (`$schema` + `$id` + root + `$defs`, with the `#/definitions` → `#/$defs` ref rewrite the lowering makes necessary), the gate that holds a document's non-standard surface to the language-server keyword families it declares, catalog entries in both versioning modes, structural and hygiene lints, ajv strict-mode validation, canonical JSON text and content-comparing write-if-changed file IO. `SchemaPipeline` runs that whole emit loop over a list of targets, so a build script calls one function.
9
9
 
10
10
  > **Pre-release.** This package is part of the `@effected/*` kit, in pre-`1.0.0`
11
11
  > development against a single pinned Effect v4 prerelease. Packages graduate to
@@ -21,7 +21,7 @@ Build, version, validate and lint SchemaStore-shaped Draft-07 JSON Schema docume
21
21
 
22
22
  ## Why @effected/schemastore
23
23
 
24
- Generating a JSON Schema from an Effect Schema is a solved problem — core does it. Publishing that schema where editors find it is not. SchemaStore recommends Draft-07 because that is what the language servers actually support, and core's Draft-07 lowering has two consequences a publisher must deal with: it rewrites `$ref` pointers to the canonical `#/definitions/...` form while the published document keeps its pool under `$defs`, and it drops every keyword outside its fixed copy-list which is exactly where `markdownDescription`, `x-taplo` and the other editor keywords live. Around the document itself sits SchemaStore's own contract: ajv strict mode as the validation gate, catalog entries whose `fileMatch` patterns must not be generic and versioned schemas as suffixed files plus a `versions` map whose `url` points at the latest. This package is that last mile, so a build script does not have to reinvent it.
24
+ Generating a JSON Schema from an Effect Schema is a solved problem — core does it. Publishing that schema where editors find it is not. SchemaStore recommends Draft-07 because that is what the language servers actually support, and core's Draft-07 lowering has two consequences a publisher must deal with: it rewrites `$ref` pointers to the canonical `#/definitions/...` form while the published document keeps its pool under `$defs`, and it carries unknown and custom keywords through as opaque values so `markdownDescription`, `x-taplo` and the other editor keywords survive, and the publisher's problem is not getting them through but keeping anything *else* out of a document SchemaStore's own gate would reject. Around the document itself sits SchemaStore's own contract: ajv strict mode as the validation gate, catalog entries whose `fileMatch` patterns must not be generic and versioned schemas as suffixed files plus a `versions` map whose `url` points at the latest. This package is that last mile, so a build script does not have to reinvent it.
25
25
 
26
26
  The scope is deliberately narrow. There is no schema construction here, no ref resolution beyond the document's own `$defs` pool and no dialect conversion — core's `JsonSchema` owns the generation pipeline, ajv provides the validation gate and this package owns the SchemaStore shape in between.
27
27
 
@@ -75,7 +75,7 @@ console.log(Effect.runSync(program));
75
75
  // }
76
76
  ```
77
77
 
78
- `fromSchema` runs the whole pipeline — 2020-12 generation, Draft-07 lowering, the `$ref` rewrite and the annotation re-graft — so every `$ref` in a built document already resolves against its `$defs` pool. `toJson()` is the flat publication shape (`$defs` omitted when empty) and `serializeResult` routes through the owned canonical serializer, tab-indented with a single trailing newline. If core cannot convert a schema, the failure is typed as `SchemaConversionError` and carries the `$id` and the structured cause.
78
+ `fromSchema` runs the whole pipeline — 2020-12 generation, Draft-07 lowering, the `$ref` rewrite and the declared-family gate — so every `$ref` in a built document already resolves against its `$defs` pool. `toJson()` is the flat publication shape (`$defs` omitted when empty) and `serializeResult` routes through the owned canonical serializer, tab-indented with a single trailing newline. If core cannot convert a schema, the failure is typed as `SchemaConversionError` and carries the `$id` and the structured cause.
79
79
 
80
80
  ## Annotate at the definition site
81
81
 
@@ -83,7 +83,7 @@ One constraint bites consumers who do not know it, so it comes before the featur
83
83
 
84
84
  ## Carrying language-server annotations
85
85
 
86
- SchemaStore documents lean on non-standard keywords the editors read: the vscode-json-languageservice set (`markdownDescription`, `defaultSnippets`, `enumDescriptions`, `markdownEnumDescriptions`, `allowTrailingCommas`), taplo's `x-taplo` keys, tombi's `x-tombi-*` and IntelliJ's `x-intellij-*`. Effect Schema annotations accept arbitrary string keys, so `Schema.String.annotate({ "x-taplo": { ... } })` type-checks with no module augmentation but core's Draft-07 lowering copies a fixed keyword subset and would drop them. `StoreDocument.fromSchema` re-grafts the declared families onto the lowered document with a parallel walk (`AnnotationCarriers`), so the annotation you wrote is the keyword that ships:
86
+ SchemaStore documents lean on non-standard keywords the editors read: the vscode-json-languageservice set (`markdownDescription`, `defaultSnippets`, `enumDescriptions`, `markdownEnumDescriptions`, `allowTrailingCommas`), taplo's `x-taplo` keys, tombi's `x-tombi-*` and IntelliJ's `x-intellij-*`. Effect Schema annotations accept arbitrary string keys, so `Schema.String.annotate({ "x-taplo": { ... } })` type-checks with no module augmentation, and core's Draft-07 lowering carries the key through as an opaque value — in place, on the node you attached it to. `StoreDocument.fromSchema` admits the declared families unconditionally, so the annotation you wrote is the keyword that ships:
87
87
 
88
88
  ```ts
89
89
  import { StoreDocument } from "@effected/schemastore";
@@ -104,7 +104,9 @@ console.log(Effect.runSync(program));
104
104
  // => { name: { type: "string", "x-taplo": { docs: { main: "The display name." } } } }
105
105
  ```
106
106
 
107
- The declared families are always admitted — `KeywordFamilies` is the one registry, consumed by both the carriers and the lint, so the two cannot drift on what counts as declared. A caller-supplied `includeAnnotationKey` predicate is consulted in addition, but know the boundary: keys it admits outside the declared families reach the Draft 2020-12 document and are still dropped by the lowering.
107
+ The declared families are always admitted, whatever a caller-supplied `includeAnnotationKey` answers — `KeywordFamilies` is the one registry, consumed by both the gate and the lint, so the two cannot drift on what counts as declared. The predicate's only remaining effect is to fail the build: a key it admits outside the declared families raises `UndeclaredAnnotationKeyError`, naming every offending key. That is deliberate. This package emits SchemaStore-compatible documents only, and the families are the whole non-standard surface it will ship, so a predicate that reaches past them is a mistake worth hearing about rather than a preference worth honouring quietly.
108
+
109
+ One thing the package does *not* do to a declared-family value is walk inside it. The `#/definitions` → `#/$defs` `$ref` rewrite skips those payloads entirely: they are opaque advice addressed to a language server, so a `$ref`-shaped string inside one means whatever that tool says it means and survives verbatim.
108
110
 
109
111
  `KeywordFamilies` splits into two groups. The upstream families above are mirrored from SchemaStore's own CONTRIBUTING guide — vocabularies the language servers already read. The `x-ai-` prefix (with the trailing dash — bare `x-ai` and a look-alike like `x-aida-foo` are not declared) is different: a house machine-annotation namespace this package owns rather than mirrors, meant for a machine reader rather than an editor. It is a namespace, not a fixed vocabulary — any key under the prefix is declared, and the one recommended (non-binding) key is `x-ai-hint`, a string instruction to a machine reader about the annotated value. A key under the prefix must be one ajv can register: after `x-ai-` only `[A-Za-z0-9_$:-]` (ajv holds a keyword name to `/^[a-z_$][a-z0-9_$:-]*$/i`), so a dot, a space, a slash, an `@`, a `+` or a non-ASCII character makes the engine gate reject the whole document as a finding. A declared-family value must itself be JSON, and must not contain an `$id` — or a repeated `$anchor` — at any depth, not merely as its own top-level key: ajv's reference collection walks unknown keywords looking for them, and a colliding one fails the compile. An empty-string `$id` resolves to the root id and collides too. No upstream tool sanctions `x-ai-` today, so it is intended for self-hosted publication rather than submission to schemastore.org without that repo's own validation-config entry. Because `x-ai-*` advises a reader rather than asserting anything, `DocumentDiff` classifies it as an annotation: adopting the family on an already-published versioned document rewrites that file in place, the same as any other prose change.
110
112
 
@@ -272,7 +274,7 @@ Both gates' findings normalize into one `PipelineFinding` shape, so a single pre
272
274
  SchemaPipeline.run(targets, { blocking: (finding) => finding.source === "validator" });
273
275
  ```
274
276
 
275
- Worth knowing which gate actually stops you here. A target carries a `Schema`, so pipeline documents come from `fromSchema`, and the Draft-07 lowering drops undeclared keywords before the lint ever sees them: `UnknownKeyword` is effectively unreachable through this entry point and **the engine gate is what blocks in practice**. The lint's warning checks earn their keep on depth and on documents the pipeline did not build, such as a hand-assembled `StoreDocument.draft07` or one read back off disk.
277
+ Worth knowing which gate actually stops you here. A target carries a `Schema`, so pipeline documents come from `fromSchema`, which never admits an undeclared keyword in the first place: `UnknownKeyword` is effectively unreachable through this entry point and **the engine gate is what blocks in practice**. The lint's warning checks earn their keep on depth and on documents the pipeline did not build, such as a hand-assembled `StoreDocument.draft07` or one read back off disk.
276
278
 
277
279
  Findings come back as values and are never logged, so the wording of your build output stays yours. A blocking finding fails with `SchemaGateError` carrying every finding that blocked. `run` is **two-phase and all-or-nothing across targets**: every target is generated, gated, and — for a target the contract policy guards — classified against its predecessor before any file is touched, and only then are the held documents written, in order. A gate or contract failure on the third target therefore leaves the first two unwritten too, not merely the third; nothing is written unless every target passes both gates.
278
280
 
@@ -316,7 +318,7 @@ The classification is key-order insensitive and keyword-position aware, like the
316
318
  ## Features
317
319
 
318
320
  - `StoreDocument` — the assembly pipeline: `fromSchema` / `fromSchemaResult`, the `draft07` constructor for hand-built documents, the flat `toJson()` publication shape, `serializeResult()`, the `DRAFT_07_META_SCHEMA` constant and `SchemaConversionError`.
319
- - `AnnotationCarriers` / `KeywordFamilies` — the post-lowering re-graft and the one registry of declared keyword families (upstream language-server families plus the house `x-ai-` machine-annotation namespace), consumed by both the carriers and the lint so they cannot disagree.
321
+ - `KeywordFamilies` — the one registry of declared keyword families (upstream language-server families plus the house `x-ai-` machine-annotation namespace), consumed by both the `fromSchema` gate and the lint so they cannot disagree.
320
322
  - `SchemaVersioning` / `SchemaVersion` — full-SemVer version labels with `parseResult` / `parse`, the `Order` instance and `latest`, `isPinned` and `next` for the contract-change version bump, plus `fileName`, `schemaUrl` and `catalogUrls` deriving both catalog modes.
321
323
  - `CatalogEntry` — the `catalog.json` entry as a `Schema.Class`, `assemble` and the `fileMatch` hygiene lint (`CatalogLintFinding`).
322
324
  - `DocumentLint` — the total structural lint returning `DocumentLintFinding` values, never an error.
package/StoreDocument.js CHANGED
@@ -1,6 +1,5 @@
1
- import { KeywordFamilies } from "./KeywordFamilies.js";
2
- import { AnnotationCarriers } from "./AnnotationCarriers.js";
3
1
  import { CanonicalJson } from "./CanonicalJson.js";
2
+ import { KeywordFamilies } from "./KeywordFamilies.js";
4
3
  import { Effect, JsonSchema, Result, Schema } from "effect";
5
4
 
6
5
  //#region src/StoreDocument.ts
@@ -34,21 +33,51 @@ var SchemaConversionError = class extends Schema.TaggedError()("SchemaConversion
34
33
  return `Failed to build SchemaStore document "${this.$id}"`;
35
34
  }
36
35
  };
36
+ /**
37
+ * Indicates that a caller-supplied `includeAnnotationKey` admitted an
38
+ * annotation key outside the declared keyword families
39
+ * ({@link KeywordFamilies}).
40
+ *
41
+ * Raised by {@link StoreDocument.fromSchema}. This package emits
42
+ * SchemaStore-compatible documents only, so the declared families are the
43
+ * whole permitted non-standard surface. A key outside them is refused
44
+ * loudly rather than emitted — which would ship a document SchemaStore's
45
+ * own gate rejects — or silently omitted, which would hide the mistake in
46
+ * the caller's predicate.
47
+ *
48
+ * The predicate itself cannot be introspected, so the offending keys are
49
+ * the ones it actually admitted while the document was being generated: a
50
+ * key the source schema never annotates cannot appear here.
51
+ *
52
+ * @public
53
+ */
54
+ var UndeclaredAnnotationKeyError = class extends Schema.TaggedError()("UndeclaredAnnotationKeyError", {
55
+ /** The `$id` of the document that was being built. */
56
+ $id: Schema.String,
57
+ /** The offending keys, deduplicated and sorted. */
58
+ keys: Schema.Array(Schema.String)
59
+ }) {
60
+ get message() {
61
+ const keys = this.keys.map((key) => `"${key}"`).join(", ");
62
+ return `Document "${this.$id}" admits annotation keys outside the declared families: ${keys}`;
63
+ }
64
+ };
37
65
  const DEFINITIONS_REF_PREFIX = /^#\/definitions(?=\/|$)/;
38
66
  var RewriteDepthExceeded = class {
39
67
  _tag = "RewriteDepthExceeded";
40
68
  };
41
- const carry = (source, target) => {
42
- const result = AnnotationCarriers.carryResult(source, target);
43
- if (Result.isFailure(result)) throw result.failure;
44
- return result.success;
45
- };
46
69
  const restoreDefsRefs = (node, depth) => {
47
70
  if (depth >= 256) throw new RewriteDepthExceeded();
48
71
  if (Array.isArray(node)) return node.map((item) => restoreDefsRefs(item, depth + 1));
49
72
  if (typeof node === "object" && node !== null) {
50
73
  const out = Object.create(null);
51
- for (const [key, value] of Object.entries(node)) out[key] = key === "$ref" && typeof value === "string" ? value.replace(DEFINITIONS_REF_PREFIX, "#/$defs") : restoreDefsRefs(value, depth + 1);
74
+ for (const [key, value] of Object.entries(node)) {
75
+ if (KeywordFamilies.isDeclared(key)) {
76
+ out[key] = value;
77
+ continue;
78
+ }
79
+ out[key] = key === "$ref" && typeof value === "string" ? value.replace(DEFINITIONS_REF_PREFIX, "#/$defs") : restoreDefsRefs(value, depth + 1);
80
+ }
52
81
  return out;
53
82
  }
54
83
  return node;
@@ -63,9 +92,17 @@ const restoreDefsRefs = (node, depth) => {
63
92
  * `JsonSchema.toDocumentDraft07` lowering, the `#/definitions` →
64
93
  * `#/$defs` `$ref` rewrite the lowering makes necessary — so every `$ref`
65
94
  * in a built document already resolves against the `$defs` pool — and the
66
- * {@link AnnotationCarriers} re-graft, so annotated non-standard keyword
67
- * families ({@link KeywordFamilies}) survive into the built document. The
68
- * package owns assembly and publication shape, not a JSON Schema engine.
95
+ * gate that holds the document's non-standard surface to the declared
96
+ * keyword families ({@link KeywordFamilies}). The package owns assembly and
97
+ * publication shape, not a JSON Schema engine.
98
+ *
99
+ * Annotated declared-family keys survive into the built document because
100
+ * core's Draft-07 lowering copies unknown and custom keywords through as
101
+ * opaque values, in place, including across the tuple coordinate move
102
+ * (2020-12 `prefixItems[i]` → Draft-07 `items[i]`, trailing `items` →
103
+ * `additionalItems`). This package therefore does no re-grafting of its
104
+ * own; it only declines to rewrite `$ref`-shaped strings *inside* those
105
+ * opaque payloads.
69
106
  *
70
107
  * @public
71
108
  */
@@ -117,14 +154,23 @@ var StoreDocument = class StoreDocument extends Schema.Class("StoreDocument")({
117
154
  static fromSchemaResult(source, options) {
118
155
  try {
119
156
  const userIncludes = options.jsonSchema?.includeAnnotationKey;
157
+ const undeclared = /* @__PURE__ */ new Set();
120
158
  const document = Schema.toJsonSchemaDocument(source, {
121
159
  ...options.jsonSchema,
122
- includeAnnotationKey: (key) => KeywordFamilies.isDeclared(key) || userIncludes?.(key) === true
160
+ includeAnnotationKey: (key) => {
161
+ if (KeywordFamilies.isDeclared(key)) return true;
162
+ if (userIncludes?.(key) === true) undeclared.add(key);
163
+ return false;
164
+ }
123
165
  });
166
+ if (undeclared.size > 0) return Result.fail(UndeclaredAnnotationKeyError.make({
167
+ $id: options.$id,
168
+ keys: [...undeclared].sort()
169
+ }));
124
170
  const lowered = JsonSchema.toDocumentDraft07(document);
125
- const root = carry(document.schema, restoreDefsRefs(lowered.schema, 0));
171
+ const root = restoreDefsRefs(lowered.schema, 0);
126
172
  const defs = Object.create(null);
127
- for (const [name, definition] of Object.entries(lowered.definitions)) defs[name] = carry(document.definitions[name], restoreDefsRefs(definition, 1));
173
+ for (const [name, definition] of Object.entries(lowered.definitions)) defs[name] = restoreDefsRefs(definition, 1);
128
174
  return Result.succeed(StoreDocument.make({
129
175
  $schema: DRAFT_07_META_SCHEMA,
130
176
  $id: options.$id,
@@ -169,4 +215,4 @@ var StoreDocument = class StoreDocument extends Schema.Class("StoreDocument")({
169
215
  };
170
216
 
171
217
  //#endregion
172
- export { DRAFT_07_META_SCHEMA, SchemaConversionError, StoreDocument };
218
+ export { DRAFT_07_META_SCHEMA, SchemaConversionError, StoreDocument, UndeclaredAnnotationKeyError };
package/index.d.ts CHANGED
@@ -1,73 +1,4 @@
1
1
  import { Context, Effect, FileSystem, Layer, Option, Order, Path, Result, Schema } from "effect";
2
- //#region src/AnnotationCarriers.d.ts
3
- declare const CarrierDepthExceededError_base: Schema.Class<CarrierDepthExceededError, Schema.TaggedStruct<"CarrierDepthExceededError", {
4
- /** JSON pointer (in the lowered document's coordinates) where the cap was hit. */
5
- readonly path: Schema.String;
6
- /** The nesting cap that was exceeded. */
7
- readonly maxDepth: Schema.Number;
8
- }>, import("effect/Cause").YieldableError>;
9
- /**
10
- * Indicates that the carrier re-graft walk nested past the package's
11
- * hardening cap (256 levels), which also intercepts cyclic inputs before
12
- * they can recurse forever.
13
- *
14
- * Raised by {@link AnnotationCarriers.carry}.
15
- *
16
- * @public
17
- */
18
- declare class CarrierDepthExceededError extends CarrierDepthExceededError_base {
19
- get message(): string;
20
- }
21
- /**
22
- * Re-grafts the declared non-standard keyword families
23
- * ({@link KeywordFamilies}) from a Draft 2020-12 schema node onto its
24
- * lowered Draft-07 counterpart.
25
- *
26
- * Why this exists: annotation keys admitted into the Draft 2020-12 document
27
- * (core's `includeAnnotationKey`) are **dropped by core's Draft-07 lowering**,
28
- * whose keyword walk copies a fixed subset — verified against the installed
29
- * beta. Carrying `x-taplo`, `x-tombi-*`, `x-intellij-*` or the vscode set
30
- * into an emitted SchemaStore document therefore requires this post-lowering
31
- * step; it cannot ride `ToJsonSchemaOptions` alone.
32
- *
33
- * The walk mirrors the lowering's own structural rules, so every carrier
34
- * lands on the node the annotation was attached to — including the one
35
- * coordinate move the lowering makes (2020-12 `prefixItems[i]` → Draft-07
36
- * `items[i]`, trailing `items` → `additionalItems`). Only declared-family
37
- * keys are copied; nothing else about the target changes.
38
- *
39
- * `StoreDocument.fromSchema` applies this automatically to the root schema
40
- * and every `$defs` pool entry — annotate a schema node
41
- * (`Schema.String.annotate({ "x-taplo": { hidden: true } })`) and the key
42
- * appears in the built document. Call this directly only when driving core's
43
- * pipeline yourself.
44
- *
45
- * Know the boundary (core behavior, probed at the installed beta): an
46
- * annotation must sit on the schema **definition** node. Annotating a
47
- * hoisted (identifier-carrying) schema at its *usage* site — e.g.
48
- * `Person.annotate({...})` inside a struct field — reaches neither the
49
- * `$ref` node nor the pool entry, even in the 2020-12 document, so there is
50
- * nothing to carry.
51
- *
52
- * @public
53
- */
54
- declare class AnnotationCarriers {
55
- private constructor();
56
- /**
57
- * Grafts declared-family keys from `source` (a Draft 2020-12 schema
58
- * node) onto `target` (its lowered Draft-07 counterpart), returning a
59
- * new node. Pure and synchronous — the primitive form;
60
- * {@link AnnotationCarriers.carry} is the same walk behind a span.
61
- */
62
- static carryResult(source: unknown, target: unknown): Result.Result<unknown, CarrierDepthExceededError>;
63
- /**
64
- * Effect form of {@link AnnotationCarriers.carryResult}, adding only the
65
- * `AnnotationCarriers.carry` span. Defined in terms of the `Result`
66
- * primitive — synchronous callers can use that variant directly.
67
- */
68
- static readonly carry: (source: unknown, target: unknown) => Effect.Effect<unknown, CarrierDepthExceededError, never>;
69
- }
70
- //#endregion
71
2
  //#region src/CanonicalJson.d.ts
72
3
  declare const NonJsonValueError_base: Schema.Class<NonJsonValueError, Schema.TaggedStruct<"NonJsonValueError", {
73
4
  /** JSON pointer to the offending value (`""` is the document root). */
@@ -87,7 +18,7 @@ declare const NonJsonValueError_base: Schema.Class<NonJsonValueError, Schema.Tag
87
18
  *
88
19
  * @public
89
20
  */
90
- declare class NonJsonValueError extends NonJsonValueError_base {
21
+ export declare class NonJsonValueError extends NonJsonValueError_base {
91
22
  get message(): string;
92
23
  }
93
24
  declare const JsonDepthExceededError_base: Schema.Class<JsonDepthExceededError, Schema.TaggedStruct<"JsonDepthExceededError", {
@@ -105,7 +36,7 @@ declare const JsonDepthExceededError_base: Schema.Class<JsonDepthExceededError,
105
36
  *
106
37
  * @public
107
38
  */
108
- declare class JsonDepthExceededError extends JsonDepthExceededError_base {
39
+ export declare class JsonDepthExceededError extends JsonDepthExceededError_base {
109
40
  get message(): string;
110
41
  }
111
42
  /**
@@ -149,7 +80,7 @@ interface CanonicalJsonOptions {
149
80
  *
150
81
  * @public
151
82
  */
152
- declare class CanonicalJson {
83
+ export declare class CanonicalJson {
153
84
  private constructor();
154
85
  /**
155
86
  * Serializes `value` to canonical JSON text. Pure and synchronous — the
@@ -213,7 +144,7 @@ type SchemaChange = "none" | "annotations" | "contract";
213
144
  *
214
145
  * @public
215
146
  */
216
- declare class DocumentDiff {
147
+ export declare class DocumentDiff {
217
148
  private constructor();
218
149
  /**
219
150
  * Classify the difference between two emitted document values (the
@@ -253,7 +184,7 @@ declare class DocumentDiff {
253
184
  *
254
185
  * @public
255
186
  */
256
- declare const DRAFT_07_META_SCHEMA = "http://json-schema.org/draft-07/schema#";
187
+ export declare const DRAFT_07_META_SCHEMA = "http://json-schema.org/draft-07/schema#";
257
188
  declare const SchemaConversionError_base: Schema.Class<SchemaConversionError, Schema.TaggedStruct<"SchemaConversionError", {
258
189
  /** The `$id` of the document that failed to build. */
259
190
  readonly $id: Schema.String;
@@ -270,7 +201,34 @@ declare const SchemaConversionError_base: Schema.Class<SchemaConversionError, Sc
270
201
  *
271
202
  * @public
272
203
  */
273
- declare class SchemaConversionError extends SchemaConversionError_base {
204
+ export declare class SchemaConversionError extends SchemaConversionError_base {
205
+ get message(): string;
206
+ }
207
+ declare const UndeclaredAnnotationKeyError_base: Schema.Class<UndeclaredAnnotationKeyError, Schema.TaggedStruct<"UndeclaredAnnotationKeyError", {
208
+ /** The `$id` of the document that was being built. */
209
+ readonly $id: Schema.String;
210
+ /** The offending keys, deduplicated and sorted. */
211
+ readonly keys: Schema.$Array<Schema.String>;
212
+ }>, import("effect/Cause").YieldableError>;
213
+ /**
214
+ * Indicates that a caller-supplied `includeAnnotationKey` admitted an
215
+ * annotation key outside the declared keyword families
216
+ * ({@link KeywordFamilies}).
217
+ *
218
+ * Raised by {@link StoreDocument.fromSchema}. This package emits
219
+ * SchemaStore-compatible documents only, so the declared families are the
220
+ * whole permitted non-standard surface. A key outside them is refused
221
+ * loudly rather than emitted — which would ship a document SchemaStore's
222
+ * own gate rejects — or silently omitted, which would hide the mistake in
223
+ * the caller's predicate.
224
+ *
225
+ * The predicate itself cannot be introspected, so the offending keys are
226
+ * the ones it actually admitted while the document was being generated: a
227
+ * key the source schema never annotates cannot appear here.
228
+ *
229
+ * @public
230
+ */
231
+ export declare class UndeclaredAnnotationKeyError extends UndeclaredAnnotationKeyError_base {
274
232
  get message(): string;
275
233
  }
276
234
  /**
@@ -287,14 +245,17 @@ interface StoreDocumentOptions {
287
245
  * `includeAnnotationKey`).
288
246
  *
289
247
  * The declared non-standard keyword families ({@link KeywordFamilies})
290
- * are **always admitted** and carried into the built document — annotate
291
- * a schema node (`Schema.String.annotate({ "x-taplo": ... })`) and the
292
- * key survives the Draft-07 lowering via the post-lowering re-graft
293
- * ({@link AnnotationCarriers}). A supplied `includeAnnotationKey` is
294
- * consulted *in addition* for other keys; know the boundary: keys it
295
- * admits outside the declared families reach the Draft 2020-12 document
296
- * but are **dropped by the Draft-07 lowering** (its keyword walk copies
297
- * a fixed subset) verified against the installed beta.
248
+ * are **always admitted**, regardless of what a supplied
249
+ * `includeAnnotationKey` answers annotate a schema node
250
+ * (`Schema.String.annotate({ "x-taplo": ... })`) and the key appears in
251
+ * the built document, in place, on the node it was attached to.
252
+ *
253
+ * A supplied `includeAnnotationKey` is consulted only for other keys,
254
+ * and **admitting one fails the build** with
255
+ * {@link UndeclaredAnnotationKeyError}. The families are the entire
256
+ * non-standard surface this package will emit, so the predicate has no
257
+ * admitting role left; it survives only because the rest of
258
+ * `ToJsonSchemaOptions` passes through, and is best left unset.
298
259
  */
299
260
  readonly jsonSchema?: Schema.ToJsonSchemaOptions;
300
261
  }
@@ -318,13 +279,21 @@ declare const StoreDocument_base: Schema.Class<StoreDocument, Schema.Struct<{
318
279
  * `JsonSchema.toDocumentDraft07` lowering, the `#/definitions` →
319
280
  * `#/$defs` `$ref` rewrite the lowering makes necessary — so every `$ref`
320
281
  * in a built document already resolves against the `$defs` pool — and the
321
- * {@link AnnotationCarriers} re-graft, so annotated non-standard keyword
322
- * families ({@link KeywordFamilies}) survive into the built document. The
323
- * package owns assembly and publication shape, not a JSON Schema engine.
282
+ * gate that holds the document's non-standard surface to the declared
283
+ * keyword families ({@link KeywordFamilies}). The package owns assembly and
284
+ * publication shape, not a JSON Schema engine.
285
+ *
286
+ * Annotated declared-family keys survive into the built document because
287
+ * core's Draft-07 lowering copies unknown and custom keywords through as
288
+ * opaque values, in place, including across the tuple coordinate move
289
+ * (2020-12 `prefixItems[i]` → Draft-07 `items[i]`, trailing `items` →
290
+ * `additionalItems`). This package therefore does no re-grafting of its
291
+ * own; it only declines to rewrite `$ref`-shaped strings *inside* those
292
+ * opaque payloads.
324
293
  *
325
294
  * @public
326
295
  */
327
- declare class StoreDocument extends StoreDocument_base {
296
+ export declare class StoreDocument extends StoreDocument_base {
328
297
  /**
329
298
  * Builds a Draft-07 document from its parts, filling `$schema` with
330
299
  * {@link DRAFT_07_META_SCHEMA}.
@@ -357,13 +326,13 @@ declare class StoreDocument extends StoreDocument_base {
357
326
  * synchronous — the primitive form; {@link StoreDocument.fromSchema} is
358
327
  * the same pipeline behind a span.
359
328
  */
360
- static fromSchemaResult(source: Schema.Constraint, options: StoreDocumentOptions): Result.Result<StoreDocument, SchemaConversionError>;
329
+ static fromSchemaResult(source: Schema.Constraint, options: StoreDocumentOptions): Result.Result<StoreDocument, SchemaConversionError | UndeclaredAnnotationKeyError>;
361
330
  /**
362
331
  * Effect form of {@link StoreDocument.fromSchemaResult}, adding only the
363
332
  * `StoreDocument.fromSchema` span. Defined in terms of the `Result`
364
333
  * primitive — synchronous callers can use that variant directly.
365
334
  */
366
- static readonly fromSchema: (source: Schema.Constraint, options: StoreDocumentOptions) => Effect.Effect<StoreDocument, SchemaConversionError, never>;
335
+ static readonly fromSchema: (source: Schema.Constraint, options: StoreDocumentOptions) => Effect.Effect<StoreDocument, SchemaConversionError | UndeclaredAnnotationKeyError, never>;
367
336
  /**
368
337
  * The flat SchemaStore publication shape: `$schema`, `$id`, the root
369
338
  * schema's keywords spread at the top level, then the `$defs` pool.
@@ -392,7 +361,7 @@ declare const SchemaFileReadError_base: Schema.Class<SchemaFileReadError, Schema
392
361
  *
393
362
  * @public
394
363
  */
395
- declare class SchemaFileReadError extends SchemaFileReadError_base {
364
+ export declare class SchemaFileReadError extends SchemaFileReadError_base {
396
365
  get message(): string;
397
366
  }
398
367
  declare const SchemaFileNotFoundError_base: Schema.Class<SchemaFileNotFoundError, Schema.TaggedStruct<"SchemaFileNotFoundError", {
@@ -405,7 +374,7 @@ declare const SchemaFileNotFoundError_base: Schema.Class<SchemaFileNotFoundError
405
374
  *
406
375
  * @public
407
376
  */
408
- declare class SchemaFileNotFoundError extends SchemaFileNotFoundError_base {
377
+ export declare class SchemaFileNotFoundError extends SchemaFileNotFoundError_base {
409
378
  get message(): string;
410
379
  }
411
380
  declare const SchemaFileWriteError_base: Schema.Class<SchemaFileWriteError, Schema.TaggedStruct<"SchemaFileWriteError", {
@@ -421,7 +390,7 @@ declare const SchemaFileWriteError_base: Schema.Class<SchemaFileWriteError, Sche
421
390
  *
422
391
  * @public
423
392
  */
424
- declare class SchemaFileWriteError extends SchemaFileWriteError_base {
393
+ export declare class SchemaFileWriteError extends SchemaFileWriteError_base {
425
394
  get message(): string;
426
395
  }
427
396
  /**
@@ -582,7 +551,7 @@ declare const SchemaFile_base: Context.ServiceClass<SchemaFile, "@effected/schem
582
551
  *
583
552
  * @public
584
553
  */
585
- declare class SchemaFile extends SchemaFile_base {
554
+ export declare class SchemaFile extends SchemaFile_base {
586
555
  /** Build the service implementation from `FileSystem` / `Path` in context; use {@link SchemaFile.layer} to provide it. */
587
556
  static readonly make: Effect.Effect<SchemaFileShape, never, FileSystem.FileSystem | Path.Path>;
588
557
  /**
@@ -604,7 +573,7 @@ declare const InvalidSchemaVersionError_base: Schema.Class<InvalidSchemaVersionE
604
573
  *
605
574
  * @public
606
575
  */
607
- declare class InvalidSchemaVersionError extends InvalidSchemaVersionError_base {
576
+ export declare class InvalidSchemaVersionError extends InvalidSchemaVersionError_base {
608
577
  get message(): string;
609
578
  }
610
579
  /**
@@ -622,13 +591,13 @@ declare class InvalidSchemaVersionError extends InvalidSchemaVersionError_base {
622
591
  *
623
592
  * @public
624
593
  */
625
- declare const SchemaVersion: Schema.brand<Schema.String, "SchemaVersion">;
594
+ export declare const SchemaVersion: Schema.brand<Schema.String, "SchemaVersion">;
626
595
  /**
627
596
  * The type of a validated SchemaStore version label.
628
597
  *
629
598
  * @public
630
599
  */
631
- type SchemaVersion = typeof SchemaVersion.Type;
600
+ export type SchemaVersion = typeof SchemaVersion.Type;
632
601
  /**
633
602
  * The `url`/`versions` half of a catalog entry, as assembled by
634
603
  * {@link SchemaVersioning.catalogUrls}.
@@ -656,7 +625,7 @@ interface CatalogUrls {
656
625
  *
657
626
  * @public
658
627
  */
659
- declare class SchemaVersioning {
628
+ export declare class SchemaVersioning {
660
629
  private constructor();
661
630
  /**
662
631
  * Parses a version label. Pure and synchronous — the primitive form;
@@ -775,7 +744,7 @@ declare const CatalogLintFinding_base: Schema.Class<CatalogLintFinding, Schema.S
775
744
  *
776
745
  * @public
777
746
  */
778
- declare class CatalogLintFinding extends CatalogLintFinding_base {}
747
+ export declare class CatalogLintFinding extends CatalogLintFinding_base {}
779
748
  declare const CatalogEntry_base: Schema.Class<CatalogEntry, Schema.Struct<{
780
749
  /** The schema's display name in the catalog. */
781
750
  readonly name: Schema.String;
@@ -800,7 +769,7 @@ declare const CatalogEntry_base: Schema.Class<CatalogEntry, Schema.Struct<{
800
769
  *
801
770
  * @public
802
771
  */
803
- declare class CatalogEntry extends CatalogEntry_base {
772
+ export declare class CatalogEntry extends CatalogEntry_base {
804
773
  /**
805
774
  * Assembles an entry from a catalog identity plus
806
775
  * {@link SchemaVersioning.catalogUrls}' inputs: pass `versions` for the
@@ -846,7 +815,7 @@ declare const DocumentLintFinding_base: Schema.Class<DocumentLintFinding, Schema
846
815
  *
847
816
  * @public
848
817
  */
849
- declare class DocumentLintFinding extends DocumentLintFinding_base {}
818
+ export declare class DocumentLintFinding extends DocumentLintFinding_base {}
850
819
  /**
851
820
  * Owned structural checks over an assembled {@link StoreDocument} — the
852
821
  * always-available half of the validation story (a real-engine gate like
@@ -866,7 +835,7 @@ declare class DocumentLintFinding extends DocumentLintFinding_base {}
866
835
  *
867
836
  * @public
868
837
  */
869
- declare class DocumentLint {
838
+ export declare class DocumentLint {
870
839
  private constructor();
871
840
  /**
872
841
  * Runs every check; total — hostile nesting degrades to a
@@ -934,8 +903,9 @@ declare class DocumentLint {
934
903
  *
935
904
  * Both consumers of the registry route through {@link KeywordFamilies.isDeclared}:
936
905
  * `DocumentLint`'s `UnknownKeyword` check (a declared key is not flagged) and
937
- * `AnnotationCarriers` (only declared keys are re-grafted after the Draft-07
938
- * lowering). One predicate, so the lint and the carriers cannot drift.
906
+ * `StoreDocument.fromSchema`'s gate (a key outside the families fails the
907
+ * build rather than being emitted). One predicate, so the lint and the gate
908
+ * cannot drift.
939
909
  */
940
910
  /**
941
911
  * The declared non-standard keyword families as one predicate: the
@@ -944,7 +914,7 @@ declare class DocumentLint {
944
914
  *
945
915
  * @public
946
916
  */
947
- declare class KeywordFamilies {
917
+ export declare class KeywordFamilies {
948
918
  private constructor();
949
919
  /**
950
920
  * Whether `key` belongs to a declared non-standard keyword family.
@@ -967,7 +937,7 @@ declare class KeywordFamilies {
967
937
  *
968
938
  * @public
969
939
  */
970
- interface SchemaTarget {
940
+ export interface SchemaTarget {
971
941
  /** The Effect Schema source the document is generated from. */
972
942
  readonly schema: Schema.Constraint;
973
943
  /** The canonical `$id` URL the generated document declares. */
@@ -1005,7 +975,7 @@ interface SchemaTarget {
1005
975
  *
1006
976
  * @public
1007
977
  */
1008
- declare class SchemaTarget {
978
+ export declare class SchemaTarget {
1009
979
  private constructor();
1010
980
  /**
1011
981
  * Builds an unversioned target. `name` is optional — only catalog
@@ -1048,7 +1018,7 @@ declare const SchemaValidatorError_base: Schema.Class<SchemaValidatorError, Sche
1048
1018
  *
1049
1019
  * @public
1050
1020
  */
1051
- declare class SchemaValidatorError extends SchemaValidatorError_base {
1021
+ export declare class SchemaValidatorError extends SchemaValidatorError_base {
1052
1022
  get message(): string;
1053
1023
  }
1054
1024
  declare const ValidationFinding_base: Schema.Class<ValidationFinding, Schema.Struct<{
@@ -1066,7 +1036,7 @@ declare const ValidationFinding_base: Schema.Class<ValidationFinding, Schema.Str
1066
1036
  *
1067
1037
  * @public
1068
1038
  */
1069
- declare class ValidationFinding extends ValidationFinding_base {}
1039
+ export declare class ValidationFinding extends ValidationFinding_base {}
1070
1040
  /**
1071
1041
  * Options for {@link SchemaValidatorShape.validate}.
1072
1042
  *
@@ -1132,7 +1102,7 @@ declare const SchemaValidator_base: Context.ServiceClass<SchemaValidator, "@effe
1132
1102
  *
1133
1103
  * @public
1134
1104
  */
1135
- declare class SchemaValidator extends SchemaValidator_base {
1105
+ export declare class SchemaValidator extends SchemaValidator_base {
1136
1106
  /**
1137
1107
  * The shipped ajv implementation — the default a consumer provides.
1138
1108
  *
@@ -1191,7 +1161,7 @@ declare const PipelineFinding_base: Schema.Class<PipelineFinding, Schema.Struct<
1191
1161
  *
1192
1162
  * @public
1193
1163
  */
1194
- declare class PipelineFinding extends PipelineFinding_base {
1164
+ export declare class PipelineFinding extends PipelineFinding_base {
1195
1165
  /**
1196
1166
  * What to call this finding when rendering it: the check name when the
1197
1167
  * gate named one, the gate itself otherwise.
@@ -1215,7 +1185,7 @@ declare const SchemaGateError_base: Schema.Class<SchemaGateError, Schema.TaggedS
1215
1185
  *
1216
1186
  * @public
1217
1187
  */
1218
- declare class SchemaGateError extends SchemaGateError_base {
1188
+ export declare class SchemaGateError extends SchemaGateError_base {
1219
1189
  get message(): string;
1220
1190
  }
1221
1191
  /**
@@ -1260,7 +1230,7 @@ declare const ContractChangeTarget_base: Schema.Class<ContractChangeTarget, Sche
1260
1230
  *
1261
1231
  * @public
1262
1232
  */
1263
- declare class ContractChangeTarget extends ContractChangeTarget_base {}
1233
+ export declare class ContractChangeTarget extends ContractChangeTarget_base {}
1264
1234
  declare const SchemaContractChangeError_base: Schema.Class<SchemaContractChangeError, Schema.TaggedStruct<"SchemaContractChangeError", {
1265
1235
  /** Every published target whose contract would change, in target order. */
1266
1236
  readonly targets: Schema.$Array<typeof ContractChangeTarget>;
@@ -1272,7 +1242,7 @@ declare const SchemaContractChangeError_base: Schema.Class<SchemaContractChangeE
1272
1242
  *
1273
1243
  * @public
1274
1244
  */
1275
- declare class SchemaContractChangeError extends SchemaContractChangeError_base {
1245
+ export declare class SchemaContractChangeError extends SchemaContractChangeError_base {
1276
1246
  get message(): string;
1277
1247
  }
1278
1248
  /**
@@ -1350,11 +1320,12 @@ interface SchemaPipelineOptions {
1350
1320
  *
1351
1321
  * **Which findings can actually reach you here.** A `SchemaTarget`
1352
1322
  * carries a `Schema`, so the pipeline's documents come from
1353
- * `StoreDocument.fromSchema` — and the Draft-07 lowering drops every
1354
- * keyword outside its copy-list, so an undeclared keyword never
1355
- * survives to be linted. Through this entry point `UnknownKeyword` is
1356
- * therefore effectively unreachable, and **the engine gate is what
1357
- * blocks in practice**. The lint's warning checks earn their keep on
1323
+ * `StoreDocument.fromSchema` — which never admits an undeclared
1324
+ * keyword: the pipeline supplies no `includeAnnotationKey`, and one
1325
+ * that admitted anything outside the declared families would fail the
1326
+ * build. An undeclared keyword therefore never exists to be linted.
1327
+ * Through this entry point `UnknownKeyword` is effectively unreachable,
1328
+ * and **the engine gate is what blocks in practice**. The lint's warning checks earn their keep on
1358
1329
  * documents this pipeline did not build — a hand-assembled
1359
1330
  * `StoreDocument.draft07`, or one read back off disk — and on depth,
1360
1331
  * which a schema can genuinely exceed.
@@ -1406,7 +1377,7 @@ interface SchemaPipelineOptions {
1406
1377
  *
1407
1378
  * @public
1408
1379
  */
1409
- declare class SchemaPipeline {
1380
+ export declare class SchemaPipeline {
1410
1381
  private constructor();
1411
1382
  /**
1412
1383
  * Run every target: build its document, gather both gates' findings,
@@ -1448,7 +1419,7 @@ declare class SchemaPipeline {
1448
1419
  * );
1449
1420
  * ```
1450
1421
  */
1451
- static run(targets: ReadonlyArray<SchemaTarget>, options?: SchemaPipelineOptions): Effect.Effect<ReadonlyArray<PipelineResult>, SchemaGateError | SchemaContractChangeError | SchemaConversionError | SchemaValidatorError | CanonicalJsonError | SchemaFileReadError | SchemaFileWriteError, SchemaFile | SchemaValidator>;
1422
+ static run(targets: ReadonlyArray<SchemaTarget>, options?: SchemaPipelineOptions): Effect.Effect<ReadonlyArray<PipelineResult>, SchemaGateError | SchemaContractChangeError | SchemaConversionError | UndeclaredAnnotationKeyError | SchemaValidatorError | CanonicalJsonError | SchemaFileReadError | SchemaFileWriteError, SchemaFile | SchemaValidator>;
1452
1423
  /**
1453
1424
  * The same walk with **no writes** — the drift-check counterpart, for a
1454
1425
  * CI job asserting the committed schemas are current.
@@ -1463,19 +1434,19 @@ declare class SchemaPipeline {
1463
1434
  * The error channel is left to the mechanisms that genuinely cannot
1464
1435
  * produce a report (generation, serialization, the engine, the read).
1465
1436
  */
1466
- static check(targets: ReadonlyArray<SchemaTarget>, options?: SchemaPipelineOptions): Effect.Effect<ReadonlyArray<PipelineCheckResult>, SchemaConversionError | SchemaValidatorError | CanonicalJsonError | SchemaFileReadError, SchemaFile | SchemaValidator>;
1437
+ static check(targets: ReadonlyArray<SchemaTarget>, options?: SchemaPipelineOptions): Effect.Effect<ReadonlyArray<PipelineCheckResult>, SchemaConversionError | UndeclaredAnnotationKeyError | SchemaValidatorError | CanonicalJsonError | SchemaFileReadError, SchemaFile | SchemaValidator>;
1467
1438
  /**
1468
1439
  * {@link SchemaPipeline.run} for a single target, answering its one
1469
1440
  * result directly — so a caller with one target does not index into an
1470
1441
  * array and prove to the type system that element zero exists.
1471
1442
  */
1472
- static runOne(target: SchemaTarget, options?: SchemaPipelineOptions): Effect.Effect<PipelineResult, SchemaGateError | SchemaContractChangeError | SchemaConversionError | SchemaValidatorError | CanonicalJsonError | SchemaFileReadError | SchemaFileWriteError, SchemaFile | SchemaValidator>;
1443
+ static runOne(target: SchemaTarget, options?: SchemaPipelineOptions): Effect.Effect<PipelineResult, SchemaGateError | SchemaContractChangeError | SchemaConversionError | UndeclaredAnnotationKeyError | SchemaValidatorError | CanonicalJsonError | SchemaFileReadError | SchemaFileWriteError, SchemaFile | SchemaValidator>;
1473
1444
  /**
1474
1445
  * {@link SchemaPipeline.check} for a single target, answering its one
1475
1446
  * result directly.
1476
1447
  */
1477
- static checkOne(target: SchemaTarget, options?: SchemaPipelineOptions): Effect.Effect<PipelineCheckResult, SchemaConversionError | SchemaValidatorError | CanonicalJsonError | SchemaFileReadError, SchemaFile | SchemaValidator>;
1448
+ static checkOne(target: SchemaTarget, options?: SchemaPipelineOptions): Effect.Effect<PipelineCheckResult, SchemaConversionError | UndeclaredAnnotationKeyError | SchemaValidatorError | CanonicalJsonError | SchemaFileReadError, SchemaFile | SchemaValidator>;
1478
1449
  }
1479
1450
  //#endregion
1480
- export { AnnotationCarriers, CanonicalJson, type CanonicalJsonError, type CanonicalJsonOptions, CarrierDepthExceededError, CatalogEntry, CatalogLintFinding, type CatalogUrls, type CheckResult, type ContractChangePolicy, ContractChangeTarget, DRAFT_07_META_SCHEMA, DocumentDiff, DocumentLint, DocumentLintFinding, InvalidSchemaVersionError, JsonDepthExceededError, KeywordFamilies, NonJsonValueError, type PipelineCheckResult, PipelineFinding, type PipelineResult, type SchemaChange, SchemaContractChangeError, SchemaConversionError, SchemaFile, SchemaFileNotFoundError, SchemaFileReadError, type SchemaFileShape, SchemaFileWriteError, SchemaGateError, SchemaPipeline, type SchemaPipelineOptions, SchemaTarget, SchemaValidator, SchemaValidatorError, type SchemaValidatorOptions, type SchemaValidatorShape, SchemaVersion, SchemaVersioning, type SchemaWriteOptions, StoreDocument, type StoreDocumentOptions, ValidationFinding, type WriteChange, type WriteOutcome, type WriteResult };
1451
+ export type { CanonicalJsonError, CanonicalJsonOptions, CatalogUrls, CheckResult, ContractChangePolicy, PipelineCheckResult, PipelineResult, SchemaChange, SchemaFileShape, SchemaPipelineOptions, SchemaValidatorOptions, SchemaValidatorShape, SchemaWriteOptions, StoreDocumentOptions, WriteChange, WriteOutcome, WriteResult };
1481
1452
  //# sourceMappingURL=index.d.ts.map
package/index.js CHANGED
@@ -1,14 +1,13 @@
1
- import { KeywordFamilies } from "./KeywordFamilies.js";
2
- import { AnnotationCarriers, CarrierDepthExceededError } from "./AnnotationCarriers.js";
3
1
  import { CanonicalJson, JsonDepthExceededError, NonJsonValueError } from "./CanonicalJson.js";
4
2
  import { InvalidSchemaVersionError, SchemaVersion, SchemaVersioning } from "./SchemaVersioning.js";
5
3
  import { CatalogEntry, CatalogLintFinding } from "./CatalogEntry.js";
4
+ import { KeywordFamilies } from "./KeywordFamilies.js";
6
5
  import { DocumentDiff } from "./DocumentDiff.js";
7
6
  import { DocumentLint, DocumentLintFinding } from "./DocumentLint.js";
8
7
  import { SchemaFile, SchemaFileNotFoundError, SchemaFileReadError, SchemaFileWriteError } from "./SchemaFile.js";
9
8
  import { SchemaValidator, SchemaValidatorError, ValidationFinding } from "./SchemaValidator.js";
10
- import { DRAFT_07_META_SCHEMA, SchemaConversionError, StoreDocument } from "./StoreDocument.js";
9
+ import { DRAFT_07_META_SCHEMA, SchemaConversionError, StoreDocument, UndeclaredAnnotationKeyError } from "./StoreDocument.js";
11
10
  import { ContractChangeTarget, PipelineFinding, SchemaContractChangeError, SchemaGateError, SchemaPipeline } from "./SchemaPipeline.js";
12
11
  import { SchemaTarget } from "./SchemaTarget.js";
13
12
 
14
- export { AnnotationCarriers, CanonicalJson, CarrierDepthExceededError, CatalogEntry, CatalogLintFinding, ContractChangeTarget, DRAFT_07_META_SCHEMA, DocumentDiff, DocumentLint, DocumentLintFinding, InvalidSchemaVersionError, JsonDepthExceededError, KeywordFamilies, NonJsonValueError, PipelineFinding, SchemaContractChangeError, SchemaConversionError, SchemaFile, SchemaFileNotFoundError, SchemaFileReadError, SchemaFileWriteError, SchemaGateError, SchemaPipeline, SchemaTarget, SchemaValidator, SchemaValidatorError, SchemaVersion, SchemaVersioning, StoreDocument, ValidationFinding };
13
+ export { CanonicalJson, CatalogEntry, CatalogLintFinding, ContractChangeTarget, DRAFT_07_META_SCHEMA, DocumentDiff, DocumentLint, DocumentLintFinding, InvalidSchemaVersionError, JsonDepthExceededError, KeywordFamilies, NonJsonValueError, PipelineFinding, SchemaContractChangeError, SchemaConversionError, SchemaFile, SchemaFileNotFoundError, SchemaFileReadError, SchemaFileWriteError, SchemaGateError, SchemaPipeline, SchemaTarget, SchemaValidator, SchemaValidatorError, SchemaVersion, SchemaVersioning, StoreDocument, UndeclaredAnnotationKeyError, ValidationFinding };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@effected/schemastore",
3
- "version": "0.5.0",
3
+ "version": "0.6.0",
4
4
  "private": false,
5
5
  "description": "Build, validate, version and publish SchemaStore-shaped Draft-07 JSON Schema documents from Effect Schema sources: document assembly, ajv strict-mode validation, structural lints, catalog entries, canonical JSON and a content-comparing emit pipeline.",
6
6
  "keywords": [
@@ -38,11 +38,11 @@
38
38
  "./package.json": "./package.json"
39
39
  },
40
40
  "dependencies": {
41
- "@effected/semver": "^0.5.1",
41
+ "@effected/semver": "^0.6.0",
42
42
  "ajv": "^8.20.0"
43
43
  },
44
44
  "peerDependencies": {
45
- "effect": "4.0.0-rc.109"
45
+ "effect": "4.0.0-rc.112"
46
46
  },
47
47
  "engines": {
48
48
  "node": ">=24.11.0"
@@ -1,137 +0,0 @@
1
- import { KeywordFamilies } from "./KeywordFamilies.js";
2
- import { Effect, Result, Schema } from "effect";
3
-
4
- //#region src/AnnotationCarriers.ts
5
- /**
6
- * Indicates that the carrier re-graft walk nested past the package's
7
- * hardening cap (256 levels), which also intercepts cyclic inputs before
8
- * they can recurse forever.
9
- *
10
- * Raised by {@link AnnotationCarriers.carry}.
11
- *
12
- * @public
13
- */
14
- var CarrierDepthExceededError = class extends Schema.TaggedError()("CarrierDepthExceededError", {
15
- /** JSON pointer (in the lowered document's coordinates) where the cap was hit. */
16
- path: Schema.String,
17
- /** The nesting cap that was exceeded. */
18
- maxDepth: Schema.Number
19
- }) {
20
- get message() {
21
- return `Carrier re-graft nesting exceeds ${this.maxDepth} levels at "${this.path}"`;
22
- }
23
- };
24
- var CarryFailure = class {
25
- error;
26
- constructor(error) {
27
- this.error = error;
28
- }
29
- };
30
- const escapePointerSegment = (segment) => segment.replace(/~/g, "~0").replace(/\//g, "~1");
31
- const isSchemaObject = (node) => typeof node === "object" && node !== null && !Array.isArray(node);
32
- const graftMap = (source, target, path, depth) => {
33
- if (!isSchemaObject(source) || !isSchemaObject(target)) return target;
34
- const out = { ...target };
35
- for (const [name, subschema] of Object.entries(source)) if (Object.hasOwn(target, name)) out[name] = graft(subschema, target[name], `${path}/${escapePointerSegment(name)}`, depth + 1);
36
- return out;
37
- };
38
- const graftArray = (source, target, path, depth) => {
39
- if (!Array.isArray(source) || !Array.isArray(target)) return target;
40
- return target.map((element, index) => index < source.length ? graft(source[index], element, `${path}/${index}`, depth + 1) : element);
41
- };
42
- const graft = (source, target, path, depth) => {
43
- if (depth >= 256) throw new CarryFailure(CarrierDepthExceededError.make({
44
- path,
45
- maxDepth: 256
46
- }));
47
- if (!isSchemaObject(source) || !isSchemaObject(target)) return target;
48
- const out = { ...target };
49
- for (const [key, value] of Object.entries(source)) {
50
- if (KeywordFamilies.isDeclared(key)) {
51
- out[key] = value;
52
- continue;
53
- }
54
- const keyPath = `${path}/${escapePointerSegment(key)}`;
55
- switch (key) {
56
- case "properties":
57
- case "patternProperties":
58
- if (Object.hasOwn(out, key)) out[key] = graftMap(value, out[key], keyPath, depth);
59
- break;
60
- case "additionalProperties":
61
- case "propertyNames":
62
- if (Object.hasOwn(out, key)) out[key] = graft(value, out[key], keyPath, depth + 1);
63
- break;
64
- case "allOf":
65
- case "anyOf":
66
- case "oneOf":
67
- if (Object.hasOwn(out, key)) out[key] = graftArray(value, out[key], keyPath, depth);
68
- break;
69
- case "prefixItems":
70
- if (Object.hasOwn(out, "items")) out.items = Array.isArray(value) ? graftArray(value, out.items, `${path}/items`, depth) : graft(value, out.items, `${path}/items`, depth + 1);
71
- break;
72
- case "items": if (Object.hasOwn(source, "prefixItems")) {
73
- if (Object.hasOwn(out, "additionalItems")) out.additionalItems = graft(value, out.additionalItems, `${path}/additionalItems`, depth + 1);
74
- } else if (Object.hasOwn(out, "items")) out.items = graft(value, out.items, keyPath, depth + 1);
75
- }
76
- }
77
- return out;
78
- };
79
- /**
80
- * Re-grafts the declared non-standard keyword families
81
- * ({@link KeywordFamilies}) from a Draft 2020-12 schema node onto its
82
- * lowered Draft-07 counterpart.
83
- *
84
- * Why this exists: annotation keys admitted into the Draft 2020-12 document
85
- * (core's `includeAnnotationKey`) are **dropped by core's Draft-07 lowering**,
86
- * whose keyword walk copies a fixed subset — verified against the installed
87
- * beta. Carrying `x-taplo`, `x-tombi-*`, `x-intellij-*` or the vscode set
88
- * into an emitted SchemaStore document therefore requires this post-lowering
89
- * step; it cannot ride `ToJsonSchemaOptions` alone.
90
- *
91
- * The walk mirrors the lowering's own structural rules, so every carrier
92
- * lands on the node the annotation was attached to — including the one
93
- * coordinate move the lowering makes (2020-12 `prefixItems[i]` → Draft-07
94
- * `items[i]`, trailing `items` → `additionalItems`). Only declared-family
95
- * keys are copied; nothing else about the target changes.
96
- *
97
- * `StoreDocument.fromSchema` applies this automatically to the root schema
98
- * and every `$defs` pool entry — annotate a schema node
99
- * (`Schema.String.annotate({ "x-taplo": { hidden: true } })`) and the key
100
- * appears in the built document. Call this directly only when driving core's
101
- * pipeline yourself.
102
- *
103
- * Know the boundary (core behavior, probed at the installed beta): an
104
- * annotation must sit on the schema **definition** node. Annotating a
105
- * hoisted (identifier-carrying) schema at its *usage* site — e.g.
106
- * `Person.annotate({...})` inside a struct field — reaches neither the
107
- * `$ref` node nor the pool entry, even in the 2020-12 document, so there is
108
- * nothing to carry.
109
- *
110
- * @public
111
- */
112
- var AnnotationCarriers = class AnnotationCarriers {
113
- constructor() {}
114
- /**
115
- * Grafts declared-family keys from `source` (a Draft 2020-12 schema
116
- * node) onto `target` (its lowered Draft-07 counterpart), returning a
117
- * new node. Pure and synchronous — the primitive form;
118
- * {@link AnnotationCarriers.carry} is the same walk behind a span.
119
- */
120
- static carryResult(source, target) {
121
- try {
122
- return Result.succeed(graft(source, target, "", 0));
123
- } catch (cause) {
124
- if (cause instanceof CarryFailure) return Result.fail(cause.error);
125
- throw cause;
126
- }
127
- }
128
- /**
129
- * Effect form of {@link AnnotationCarriers.carryResult}, adding only the
130
- * `AnnotationCarriers.carry` span. Defined in terms of the `Result`
131
- * primitive — synchronous callers can use that variant directly.
132
- */
133
- static carry = Effect.fn("AnnotationCarriers.carry")((source, target) => Effect.fromResult(AnnotationCarriers.carryResult(source, target)));
134
- };
135
-
136
- //#endregion
137
- export { AnnotationCarriers, CarrierDepthExceededError };