@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.
- package/KeywordFamilies.js +3 -2
- package/README.md +9 -7
- package/StoreDocument.js +61 -15
- package/index.d.ts +95 -124
- package/index.js +3 -4
- package/package.json +3 -3
- package/AnnotationCarriers.js +0 -137
package/KeywordFamilies.js
CHANGED
|
@@ -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
|
-
* `
|
|
61
|
-
*
|
|
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
|
[](https://nodejs.org/)
|
|
6
6
|
[](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),
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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`,
|
|
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
|
-
- `
|
|
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))
|
|
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
|
-
*
|
|
67
|
-
* families ({@link KeywordFamilies})
|
|
68
|
-
*
|
|
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) =>
|
|
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 =
|
|
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] =
|
|
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
|
|
291
|
-
*
|
|
292
|
-
*
|
|
293
|
-
*
|
|
294
|
-
*
|
|
295
|
-
*
|
|
296
|
-
*
|
|
297
|
-
*
|
|
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
|
-
*
|
|
322
|
-
* families ({@link KeywordFamilies})
|
|
323
|
-
*
|
|
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
|
-
* `
|
|
938
|
-
*
|
|
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` —
|
|
1354
|
-
* keyword
|
|
1355
|
-
*
|
|
1356
|
-
*
|
|
1357
|
-
*
|
|
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 {
|
|
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 {
|
|
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.
|
|
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.
|
|
41
|
+
"@effected/semver": "^0.6.0",
|
|
42
42
|
"ajv": "^8.20.0"
|
|
43
43
|
},
|
|
44
44
|
"peerDependencies": {
|
|
45
|
-
"effect": "4.0.0-rc.
|
|
45
|
+
"effect": "4.0.0-rc.112"
|
|
46
46
|
},
|
|
47
47
|
"engines": {
|
|
48
48
|
"node": ">=24.11.0"
|
package/AnnotationCarriers.js
DELETED
|
@@ -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 };
|