@effected/schemastore 0.17.0 → 0.19.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/CatalogEntry.js +1 -1
- package/DriftPolicy.js +12 -0
- package/InstanceValidator.js +106 -0
- package/README.md +4 -4
- package/SchemaPipeline.js +1 -1
- package/SchemastoreConfig.js +15 -0
- package/StoreDocument.js +3 -5
- package/index.d.ts +173 -20
- package/index.js +2 -1
- package/package.json +3 -3
package/CatalogEntry.js
CHANGED
|
@@ -133,7 +133,7 @@ var CatalogEntry = class CatalogEntry extends Schema.Class("CatalogEntry")({
|
|
|
133
133
|
return CatalogEntry.lintFileMatch(this.fileMatch);
|
|
134
134
|
}
|
|
135
135
|
/**
|
|
136
|
-
* {@link CatalogEntry.
|
|
136
|
+
* {@link CatalogEntry.lintFileMatch} over a bare pattern list, for callers
|
|
137
137
|
* checking patterns before an entry exists.
|
|
138
138
|
*/
|
|
139
139
|
static lintFileMatch(patterns) {
|
package/DriftPolicy.js
CHANGED
|
@@ -18,6 +18,18 @@ var DriftPolicy = class {
|
|
|
18
18
|
policy: "semantic",
|
|
19
19
|
onDrift: "error"
|
|
20
20
|
};
|
|
21
|
+
/**
|
|
22
|
+
* Answer `"write"` or `"drift"` for one target, given whether it is
|
|
23
|
+
* published and how its content changed.
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* ```ts
|
|
27
|
+
* import { DriftPolicy } from "@effected/schemastore";
|
|
28
|
+
*
|
|
29
|
+
* DriftPolicy.classify({ published: true, change: "contract" }, "semantic");
|
|
30
|
+
* // => "drift"
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
21
33
|
static classify(input, policy) {
|
|
22
34
|
if (!input.published || policy === "allow") return "write";
|
|
23
35
|
if (input.change === "contract") return "drift";
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { Context, Effect, Layer, Schema } from "effect";
|
|
2
|
+
|
|
3
|
+
//#region src/InstanceValidator.ts
|
|
4
|
+
/**
|
|
5
|
+
* Indicates that the validation engine behind the {@link InstanceValidator}
|
|
6
|
+
* contract failed as a *mechanism* — it could not run at all.
|
|
7
|
+
*
|
|
8
|
+
* By convention the error channel is reserved for exactly that: an instance
|
|
9
|
+
* that fails the document is an {@link InstanceFinding} list (a value),
|
|
10
|
+
* never an error. A document the engine cannot compile also lands here —
|
|
11
|
+
* unlike {@link SchemaValidatorError}, whose subject IS the document, this
|
|
12
|
+
* contract's subject is the instance, so a document that yields no verdict
|
|
13
|
+
* means the engine could not run against that instance. Raised by
|
|
14
|
+
* implementations of {@link InstanceValidatorShape.validate}.
|
|
15
|
+
*
|
|
16
|
+
* @public
|
|
17
|
+
*/
|
|
18
|
+
var InstanceValidatorError = class extends Schema.TaggedError()("InstanceValidatorError", {
|
|
19
|
+
/** The underlying engine failure, preserved structurally. */
|
|
20
|
+
cause: Schema.Defect() }) {
|
|
21
|
+
get message() {
|
|
22
|
+
return "Instance validation engine failed";
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* One problem a validation engine found with an instance: a value in a
|
|
27
|
+
* report, never an error channel — the consumer decides what a finding
|
|
28
|
+
* gates. Structurally the same report {@link ValidationFinding} is for a
|
|
29
|
+
* schema document, but its pointer addresses the INSTANCE, so the two stay
|
|
30
|
+
* separate types: a caller that mixes them up is a compile error, not a
|
|
31
|
+
* silently misread pointer.
|
|
32
|
+
*
|
|
33
|
+
* @public
|
|
34
|
+
*/
|
|
35
|
+
var InstanceFinding = class extends Schema.Class("InstanceFinding")({
|
|
36
|
+
/** JSON pointer into the instance (`""` is the instance root). */
|
|
37
|
+
path: Schema.String,
|
|
38
|
+
/** Human-readable explanation from the engine. */
|
|
39
|
+
message: Schema.String,
|
|
40
|
+
/** The JSON Schema keyword the finding is about, when the engine names one. */
|
|
41
|
+
keyword: Schema.optionalKey(Schema.String)
|
|
42
|
+
}) {};
|
|
43
|
+
/** The default for an unstubbed {@link InstanceValidator.makeTest} member. */
|
|
44
|
+
const notStubbed = (method) => () => Effect.die(/* @__PURE__ */ new Error(`InstanceValidator.makeTest: ${method}() was called but not stubbed — no honest default exists for a test double; pass a \`${method}\` override.`));
|
|
45
|
+
/**
|
|
46
|
+
* The payload-against-document validation contract — the question
|
|
47
|
+
* {@link SchemaValidator} does not answer: not "is this document valid JSON
|
|
48
|
+
* Schema", but "does this instance conform to the published document it
|
|
49
|
+
* names in `$schema`". Decoding with the source Effect Schema is not a
|
|
50
|
+
* substitute: that proves the instance matches the CODE, not the committed
|
|
51
|
+
* document consumers actually fetch, and the two can drift.
|
|
52
|
+
*
|
|
53
|
+
* Like {@link SchemaValidator}, this package ships the contract and its
|
|
54
|
+
* doubles only: skip validation with {@link InstanceValidator.noop}, stub it
|
|
55
|
+
* with {@link InstanceValidator.layerTest}. The one real implementation is
|
|
56
|
+
* `@effected/schemastore-cli`'s `AjvInstanceValidator.layer` — the same ajv
|
|
57
|
+
* strict-mode setup `AjvValidator` gates documents with, pointed at an
|
|
58
|
+
* instance — which the `schemastore validate` command composes for you and
|
|
59
|
+
* which that package also exports for a program that drives the contract
|
|
60
|
+
* itself. Keeping the engine there keeps `ajv` out of every application
|
|
61
|
+
* that imports this package at runtime.
|
|
62
|
+
*
|
|
63
|
+
* @example
|
|
64
|
+
* ```ts
|
|
65
|
+
* import { InstanceValidator } from "@effected/schemastore";
|
|
66
|
+
* import { Effect } from "effect";
|
|
67
|
+
*
|
|
68
|
+
* const program = Effect.gen(function* () {
|
|
69
|
+
* const validator = yield* InstanceValidator;
|
|
70
|
+
* return yield* validator.validate({ type: "object" }, { any: "payload" });
|
|
71
|
+
* });
|
|
72
|
+
*
|
|
73
|
+
* // Provide the engine at the edge — the CLI does this for you:
|
|
74
|
+
* // Effect.provide(program, AjvInstanceValidator.layer) (from @effected/schemastore-cli)
|
|
75
|
+
* Effect.runPromise(Effect.provide(program, InstanceValidator.noop));
|
|
76
|
+
* // => []
|
|
77
|
+
* ```
|
|
78
|
+
*
|
|
79
|
+
* @public
|
|
80
|
+
*/
|
|
81
|
+
var InstanceValidator = class InstanceValidator extends Context.Service()("@effected/schemastore/InstanceValidator") {
|
|
82
|
+
/**
|
|
83
|
+
* No-op: `validate` always succeeds with no findings, never consulting an
|
|
84
|
+
* engine. A pure `Layer.succeed`, bound to a const so the layer memoizes
|
|
85
|
+
* by reference. Use it to switch validation off deliberately — for the
|
|
86
|
+
* real engine, provide `AjvInstanceValidator.layer` from
|
|
87
|
+
* `@effected/schemastore-cli`.
|
|
88
|
+
*/
|
|
89
|
+
static noop = Layer.succeed(InstanceValidator, { validate: () => Effect.succeed([]) });
|
|
90
|
+
/**
|
|
91
|
+
* An in-memory double: stub only the members the test exercises; every
|
|
92
|
+
* other member **dies** with a defect naming itself. No member has an
|
|
93
|
+
* honest default — a fabricated clean pass would leak into consumer
|
|
94
|
+
* logic as fact (use {@link InstanceValidator.noop} when a test genuinely
|
|
95
|
+
* wants an always-clean validator).
|
|
96
|
+
*/
|
|
97
|
+
static makeTest = (overrides = {}) => ({
|
|
98
|
+
validate: notStubbed("validate"),
|
|
99
|
+
...overrides
|
|
100
|
+
});
|
|
101
|
+
/** {@link InstanceValidator.makeTest} behind `Layer.succeed`. */
|
|
102
|
+
static layerTest = (overrides = {}) => Layer.succeed(InstanceValidator, InstanceValidator.makeTest(overrides));
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
//#endregion
|
|
106
|
+
export { InstanceFinding, InstanceValidator, InstanceValidatorError };
|
package/README.md
CHANGED
|
@@ -7,10 +7,10 @@
|
|
|
7
7
|
|
|
8
8
|
Publish Effect Schemas as SchemaStore-shaped Draft-07 JSON Schema documents. Core `effect` already generates JSON Schema (`Schema.toJsonSchemaDocument`) and lowers it to Draft-07 (`JsonSchema.toDocumentDraft07`); this package owns what [SchemaStore](https://www.schemastore.org) and the editors expect around that output — the publication shape, the hosted identity a document is published under, the keyword-family gate, catalog entries, lints, versioning, canonical JSON and content-comparing file IO — and the [`schemastore`](https://www.npmjs.com/package/@effected/schemastore-cli) command runs all of it from one config file.
|
|
9
9
|
|
|
10
|
-
> **Pre
|
|
11
|
-
>
|
|
12
|
-
> `1.0.0`
|
|
13
|
-
>
|
|
10
|
+
> **Pre-`1.0.0`.** This package is part of the `@effected/*` kit, built on stable
|
|
11
|
+
> Effect v4 (`effect` `^4.0.0`) and still in `0.x` development. Stable Effect
|
|
12
|
+
> makes a kit `1.0.0` possible, not automatic. To keep your `effect` and
|
|
13
|
+
> `@effect/*` versions on the line the kit is built and tested against, install
|
|
14
14
|
> [`@effected/pnpm-plugin-effect`](https://www.npmjs.com/package/@effected/pnpm-plugin-effect).
|
|
15
15
|
>
|
|
16
16
|
> **Stability: unstable.** This package's API surface is not yet considered
|
package/SchemaPipeline.js
CHANGED
|
@@ -116,7 +116,7 @@ const gate = (target, findings, options) => {
|
|
|
116
116
|
};
|
|
117
117
|
/**
|
|
118
118
|
* The emit pipeline over a target manifest: generate, lint, validate, gate,
|
|
119
|
-
* write
|
|
119
|
+
* and write each schema document.
|
|
120
120
|
*
|
|
121
121
|
* Requires `SchemaFile` and `SchemaValidator` in `R`; provide
|
|
122
122
|
* `SchemaFile.layer` and an engine — `AjvValidator.layer` from
|
package/SchemastoreConfig.js
CHANGED
|
@@ -209,6 +209,21 @@ const assertUniquePaths = (paths) => {
|
|
|
209
209
|
* re-checks on the resolved absolute paths. Branding the result lets a loader recognise a config
|
|
210
210
|
* module's default export via {@link isSchemastoreConfig}.
|
|
211
211
|
*
|
|
212
|
+
* @example
|
|
213
|
+
* ```ts
|
|
214
|
+
* import { defineConfig } from "@effected/schemastore";
|
|
215
|
+
* import { Schema } from "effect";
|
|
216
|
+
*
|
|
217
|
+
* const Config = Schema.Struct({ name: Schema.String });
|
|
218
|
+
*
|
|
219
|
+
* export default defineConfig({
|
|
220
|
+
* name: "my-tool",
|
|
221
|
+
* outputDir: "schemas",
|
|
222
|
+
* baseUrl: "https://example.com/schemas",
|
|
223
|
+
* schemas: { config: { schema: Config } },
|
|
224
|
+
* });
|
|
225
|
+
* ```
|
|
226
|
+
*
|
|
212
227
|
* @public
|
|
213
228
|
*/
|
|
214
229
|
const defineConfig = (input) => {
|
package/StoreDocument.js
CHANGED
|
@@ -7,8 +7,7 @@ import { Effect, JsonPointer, JsonSchema, Result, Schema } from "effect";
|
|
|
7
7
|
* The Draft-07 meta-schema URL SchemaStore documents declare as `$schema`.
|
|
8
8
|
*
|
|
9
9
|
* Deliberately carries the trailing `#` fragment: the SchemaStore corpus
|
|
10
|
-
*
|
|
11
|
-
* where core's `JsonSchema.META_SCHEMA_URI_DRAFT_07` omits it.
|
|
10
|
+
* uses the fragment form, where core's `JsonSchema.META_SCHEMA_URI_DRAFT_07` omits it.
|
|
12
11
|
*
|
|
13
12
|
* @public
|
|
14
13
|
*/
|
|
@@ -185,7 +184,7 @@ const collapseUniformTuples = (node, depth) => {
|
|
|
185
184
|
* `#/$defs` `$ref` rewrite the lowering makes necessary — so every `$ref`
|
|
186
185
|
* in a built document already resolves against the `$defs` pool — the
|
|
187
186
|
* uniform-tuple collapse that keeps open-ended `NonEmptyArray`-shaped
|
|
188
|
-
* arrays publishable through the strict ajv gate
|
|
187
|
+
* arrays publishable through the strict ajv gate, and the gate that
|
|
189
188
|
* holds the document's non-standard surface to the declared keyword
|
|
190
189
|
* families ({@link KeywordFamilies}). The package owns assembly and
|
|
191
190
|
* publication shape, not a JSON Schema engine.
|
|
@@ -299,8 +298,7 @@ var StoreDocument = class StoreDocument extends Schema.Class("StoreDocument")({
|
|
|
299
298
|
/**
|
|
300
299
|
* The flat SchemaStore publication shape: `$schema`, `$id`, the root
|
|
301
300
|
* schema's keywords spread at the top level, then the `$defs` pool.
|
|
302
|
-
* `$defs` is omitted when the pool is empty
|
|
303
|
-
* from the extraction source, which always emitted the key).
|
|
301
|
+
* `$defs` is omitted when the pool is empty.
|
|
304
302
|
*/
|
|
305
303
|
toJson() {
|
|
306
304
|
return {
|
package/index.d.ts
CHANGED
|
@@ -52,8 +52,8 @@ type CanonicalJsonError = NonJsonValueError | JsonDepthExceededError;
|
|
|
52
52
|
*/
|
|
53
53
|
interface CanonicalJsonOptions {
|
|
54
54
|
/**
|
|
55
|
-
* Indentation unit: `"tab"` (the default, matching the
|
|
56
|
-
* convention
|
|
55
|
+
* Indentation unit: `"tab"` (the default, matching the formatter
|
|
56
|
+
* convention of most JSON schema repos) or a
|
|
57
57
|
* space count — a non-negative integer (`0` emits multi-line output
|
|
58
58
|
* with no leading indentation). Counts above 10 are honored as given,
|
|
59
59
|
* deliberately diverging from `JSON.stringify`'s silent clamp to 10.
|
|
@@ -195,8 +195,7 @@ export declare class DocumentDiff {
|
|
|
195
195
|
* The Draft-07 meta-schema URL SchemaStore documents declare as `$schema`.
|
|
196
196
|
*
|
|
197
197
|
* Deliberately carries the trailing `#` fragment: the SchemaStore corpus
|
|
198
|
-
*
|
|
199
|
-
* where core's `JsonSchema.META_SCHEMA_URI_DRAFT_07` omits it.
|
|
198
|
+
* uses the fragment form, where core's `JsonSchema.META_SCHEMA_URI_DRAFT_07` omits it.
|
|
200
199
|
*
|
|
201
200
|
* @public
|
|
202
201
|
*/
|
|
@@ -341,7 +340,7 @@ declare const StoreDocument_base: Schema.Class<StoreDocument, Schema.Struct<{
|
|
|
341
340
|
* `#/$defs` `$ref` rewrite the lowering makes necessary — so every `$ref`
|
|
342
341
|
* in a built document already resolves against the `$defs` pool — the
|
|
343
342
|
* uniform-tuple collapse that keeps open-ended `NonEmptyArray`-shaped
|
|
344
|
-
* arrays publishable through the strict ajv gate
|
|
343
|
+
* arrays publishable through the strict ajv gate, and the gate that
|
|
345
344
|
* holds the document's non-standard surface to the declared keyword
|
|
346
345
|
* families ({@link KeywordFamilies}). The package owns assembly and
|
|
347
346
|
* publication shape, not a JSON Schema engine.
|
|
@@ -404,8 +403,7 @@ export declare class StoreDocument extends StoreDocument_base {
|
|
|
404
403
|
/**
|
|
405
404
|
* The flat SchemaStore publication shape: `$schema`, `$id`, the root
|
|
406
405
|
* schema's keywords spread at the top level, then the `$defs` pool.
|
|
407
|
-
* `$defs` is omitted when the pool is empty
|
|
408
|
-
* from the extraction source, which always emitted the key).
|
|
406
|
+
* `$defs` is omitted when the pool is empty.
|
|
409
407
|
*/
|
|
410
408
|
toJson(): Record<string, unknown>;
|
|
411
409
|
/**
|
|
@@ -913,7 +911,7 @@ export declare class CatalogEntry extends CatalogEntry_base {
|
|
|
913
911
|
*/
|
|
914
912
|
lint(): ReadonlyArray<CatalogLintFinding>;
|
|
915
913
|
/**
|
|
916
|
-
* {@link CatalogEntry.
|
|
914
|
+
* {@link CatalogEntry.lintFileMatch} over a bare pattern list, for callers
|
|
917
915
|
* checking patterns before an entry exists.
|
|
918
916
|
*/
|
|
919
917
|
static lintFileMatch(patterns: ReadonlyArray<string>): ReadonlyArray<CatalogLintFinding>;
|
|
@@ -1001,7 +999,9 @@ type OnDrift = "error" | "warn";
|
|
|
1001
999
|
* @public
|
|
1002
1000
|
*/
|
|
1003
1001
|
interface DriftOptions {
|
|
1002
|
+
/** How much change a published document may absorb. */
|
|
1004
1003
|
readonly policy: DriftTolerance;
|
|
1004
|
+
/** What a build does when it finds drift. */
|
|
1005
1005
|
readonly onDrift: OnDrift;
|
|
1006
1006
|
}
|
|
1007
1007
|
/**
|
|
@@ -1026,6 +1026,18 @@ export declare class DriftPolicy {
|
|
|
1026
1026
|
private constructor();
|
|
1027
1027
|
/** `{ policy: "semantic", onDrift: "error" }` — what a config gets when it says nothing. */
|
|
1028
1028
|
static readonly defaults: DriftOptions;
|
|
1029
|
+
/**
|
|
1030
|
+
* Answer `"write"` or `"drift"` for one target, given whether it is
|
|
1031
|
+
* published and how its content changed.
|
|
1032
|
+
*
|
|
1033
|
+
* @example
|
|
1034
|
+
* ```ts
|
|
1035
|
+
* import { DriftPolicy } from "@effected/schemastore";
|
|
1036
|
+
*
|
|
1037
|
+
* DriftPolicy.classify({ published: true, change: "contract" }, "semantic");
|
|
1038
|
+
* // => "drift"
|
|
1039
|
+
* ```
|
|
1040
|
+
*/
|
|
1029
1041
|
static classify(input: {
|
|
1030
1042
|
readonly published: boolean;
|
|
1031
1043
|
readonly change: WriteChange;
|
|
@@ -1161,6 +1173,135 @@ export declare class HostedSchema extends HostedSchema_base {
|
|
|
1161
1173
|
private parseLabel;
|
|
1162
1174
|
}
|
|
1163
1175
|
//#endregion
|
|
1176
|
+
//#region src/InstanceValidator.d.ts
|
|
1177
|
+
declare const InstanceValidatorError_base: Schema.Class<InstanceValidatorError, Schema.TaggedStruct<"InstanceValidatorError", {
|
|
1178
|
+
/** The underlying engine failure, preserved structurally. */
|
|
1179
|
+
readonly cause: Schema.Defect;
|
|
1180
|
+
}>, import("effect/Cause").YieldableError>;
|
|
1181
|
+
/**
|
|
1182
|
+
* Indicates that the validation engine behind the {@link InstanceValidator}
|
|
1183
|
+
* contract failed as a *mechanism* — it could not run at all.
|
|
1184
|
+
*
|
|
1185
|
+
* By convention the error channel is reserved for exactly that: an instance
|
|
1186
|
+
* that fails the document is an {@link InstanceFinding} list (a value),
|
|
1187
|
+
* never an error. A document the engine cannot compile also lands here —
|
|
1188
|
+
* unlike {@link SchemaValidatorError}, whose subject IS the document, this
|
|
1189
|
+
* contract's subject is the instance, so a document that yields no verdict
|
|
1190
|
+
* means the engine could not run against that instance. Raised by
|
|
1191
|
+
* implementations of {@link InstanceValidatorShape.validate}.
|
|
1192
|
+
*
|
|
1193
|
+
* @public
|
|
1194
|
+
*/
|
|
1195
|
+
export declare class InstanceValidatorError extends InstanceValidatorError_base {
|
|
1196
|
+
get message(): string;
|
|
1197
|
+
}
|
|
1198
|
+
declare const InstanceFinding_base: Schema.Class<InstanceFinding, Schema.Struct<{
|
|
1199
|
+
/** JSON pointer into the instance (`""` is the instance root). */
|
|
1200
|
+
readonly path: Schema.String;
|
|
1201
|
+
/** Human-readable explanation from the engine. */
|
|
1202
|
+
readonly message: Schema.String;
|
|
1203
|
+
/** The JSON Schema keyword the finding is about, when the engine names one. */
|
|
1204
|
+
readonly keyword: Schema.optionalKey<Schema.String>;
|
|
1205
|
+
}>, {}>;
|
|
1206
|
+
/**
|
|
1207
|
+
* One problem a validation engine found with an instance: a value in a
|
|
1208
|
+
* report, never an error channel — the consumer decides what a finding
|
|
1209
|
+
* gates. Structurally the same report {@link ValidationFinding} is for a
|
|
1210
|
+
* schema document, but its pointer addresses the INSTANCE, so the two stay
|
|
1211
|
+
* separate types: a caller that mixes them up is a compile error, not a
|
|
1212
|
+
* silently misread pointer.
|
|
1213
|
+
*
|
|
1214
|
+
* @public
|
|
1215
|
+
*/
|
|
1216
|
+
export declare class InstanceFinding extends InstanceFinding_base {}
|
|
1217
|
+
/**
|
|
1218
|
+
* Options for {@link InstanceValidatorShape.validate}.
|
|
1219
|
+
*
|
|
1220
|
+
* @public
|
|
1221
|
+
*/
|
|
1222
|
+
interface InstanceValidatorOptions {
|
|
1223
|
+
/**
|
|
1224
|
+
* Whether the engine runs its strictest mode (ajv `strict: true` — the
|
|
1225
|
+
* SchemaStore default gate) when compiling the document. Defaults to
|
|
1226
|
+
* `true`; implementations treat an omitted value as strict.
|
|
1227
|
+
*/
|
|
1228
|
+
readonly strict?: boolean;
|
|
1229
|
+
}
|
|
1230
|
+
/**
|
|
1231
|
+
* The shape of the {@link InstanceValidator} service — what an implementation
|
|
1232
|
+
* provides.
|
|
1233
|
+
*
|
|
1234
|
+
* @public
|
|
1235
|
+
*/
|
|
1236
|
+
interface InstanceValidatorShape {
|
|
1237
|
+
/**
|
|
1238
|
+
* Validates an arbitrary JSON instance against a schema document with a
|
|
1239
|
+
* real JSON Schema engine. An empty array is a clean pass; an instance
|
|
1240
|
+
* the document rejects answers findings as values, each carrying a JSON
|
|
1241
|
+
* pointer into the instance. The error channel is reserved for the
|
|
1242
|
+
* engine failing as a mechanism ({@link InstanceValidatorError}),
|
|
1243
|
+
* including a document the engine cannot compile.
|
|
1244
|
+
*/
|
|
1245
|
+
readonly validate: (document: Record<string, unknown>, instance: unknown, options?: InstanceValidatorOptions) => Effect.Effect<ReadonlyArray<InstanceFinding>, InstanceValidatorError>;
|
|
1246
|
+
}
|
|
1247
|
+
declare const InstanceValidator_base: Context.ServiceClass<InstanceValidator, "@effected/schemastore/InstanceValidator", InstanceValidatorShape>;
|
|
1248
|
+
/**
|
|
1249
|
+
* The payload-against-document validation contract — the question
|
|
1250
|
+
* {@link SchemaValidator} does not answer: not "is this document valid JSON
|
|
1251
|
+
* Schema", but "does this instance conform to the published document it
|
|
1252
|
+
* names in `$schema`". Decoding with the source Effect Schema is not a
|
|
1253
|
+
* substitute: that proves the instance matches the CODE, not the committed
|
|
1254
|
+
* document consumers actually fetch, and the two can drift.
|
|
1255
|
+
*
|
|
1256
|
+
* Like {@link SchemaValidator}, this package ships the contract and its
|
|
1257
|
+
* doubles only: skip validation with {@link InstanceValidator.noop}, stub it
|
|
1258
|
+
* with {@link InstanceValidator.layerTest}. The one real implementation is
|
|
1259
|
+
* `@effected/schemastore-cli`'s `AjvInstanceValidator.layer` — the same ajv
|
|
1260
|
+
* strict-mode setup `AjvValidator` gates documents with, pointed at an
|
|
1261
|
+
* instance — which the `schemastore validate` command composes for you and
|
|
1262
|
+
* which that package also exports for a program that drives the contract
|
|
1263
|
+
* itself. Keeping the engine there keeps `ajv` out of every application
|
|
1264
|
+
* that imports this package at runtime.
|
|
1265
|
+
*
|
|
1266
|
+
* @example
|
|
1267
|
+
* ```ts
|
|
1268
|
+
* import { InstanceValidator } from "@effected/schemastore";
|
|
1269
|
+
* import { Effect } from "effect";
|
|
1270
|
+
*
|
|
1271
|
+
* const program = Effect.gen(function* () {
|
|
1272
|
+
* const validator = yield* InstanceValidator;
|
|
1273
|
+
* return yield* validator.validate({ type: "object" }, { any: "payload" });
|
|
1274
|
+
* });
|
|
1275
|
+
*
|
|
1276
|
+
* // Provide the engine at the edge — the CLI does this for you:
|
|
1277
|
+
* // Effect.provide(program, AjvInstanceValidator.layer) (from @effected/schemastore-cli)
|
|
1278
|
+
* Effect.runPromise(Effect.provide(program, InstanceValidator.noop));
|
|
1279
|
+
* // => []
|
|
1280
|
+
* ```
|
|
1281
|
+
*
|
|
1282
|
+
* @public
|
|
1283
|
+
*/
|
|
1284
|
+
export declare class InstanceValidator extends InstanceValidator_base {
|
|
1285
|
+
/**
|
|
1286
|
+
* No-op: `validate` always succeeds with no findings, never consulting an
|
|
1287
|
+
* engine. A pure `Layer.succeed`, bound to a const so the layer memoizes
|
|
1288
|
+
* by reference. Use it to switch validation off deliberately — for the
|
|
1289
|
+
* real engine, provide `AjvInstanceValidator.layer` from
|
|
1290
|
+
* `@effected/schemastore-cli`.
|
|
1291
|
+
*/
|
|
1292
|
+
static readonly noop: Layer.Layer<InstanceValidator>;
|
|
1293
|
+
/**
|
|
1294
|
+
* An in-memory double: stub only the members the test exercises; every
|
|
1295
|
+
* other member **dies** with a defect naming itself. No member has an
|
|
1296
|
+
* honest default — a fabricated clean pass would leak into consumer
|
|
1297
|
+
* logic as fact (use {@link InstanceValidator.noop} when a test genuinely
|
|
1298
|
+
* wants an always-clean validator).
|
|
1299
|
+
*/
|
|
1300
|
+
static readonly makeTest: (overrides?: Partial<InstanceValidatorShape>) => InstanceValidatorShape;
|
|
1301
|
+
/** {@link InstanceValidator.makeTest} behind `Layer.succeed`. */
|
|
1302
|
+
static readonly layerTest: (overrides?: Partial<InstanceValidatorShape>) => Layer.Layer<InstanceValidator>;
|
|
1303
|
+
}
|
|
1304
|
+
//#endregion
|
|
1164
1305
|
//#region src/KeywordFamilies.d.ts
|
|
1165
1306
|
/**
|
|
1166
1307
|
* The one owner of the declared non-standard keyword families, in two
|
|
@@ -1246,8 +1387,7 @@ export declare class KeywordFamilies {
|
|
|
1246
1387
|
/**
|
|
1247
1388
|
* A single schema publication target: an Effect Schema source paired with
|
|
1248
1389
|
* the identity and destination it is serialized under. A repo generating
|
|
1249
|
-
* SchemaStore artifacts declares one target per emitted document
|
|
1250
|
-
* extraction source's `{schema, $id, path}` triples, generalized).
|
|
1390
|
+
* SchemaStore artifacts declares one target per emitted document.
|
|
1251
1391
|
*
|
|
1252
1392
|
* Not a `Schema.Class`: a target carries a live Effect Schema value, which
|
|
1253
1393
|
* is program wiring rather than serializable data.
|
|
@@ -1263,9 +1403,7 @@ export interface SchemaTarget {
|
|
|
1263
1403
|
* The catalog/file base name (`name.json` / `name-<version>.json`).
|
|
1264
1404
|
*
|
|
1265
1405
|
* Only the catalog path consumes it — a target that merely emits a file
|
|
1266
|
-
* to `path` needs no name
|
|
1267
|
-
* satisfy the constructor duplicates the basename with no invariant
|
|
1268
|
-
* tying the two together. Required whenever `version` is present, since
|
|
1406
|
+
* to `path` needs no name. Required whenever `version` is present, since
|
|
1269
1407
|
* versioned catalog naming is defined in terms of it.
|
|
1270
1408
|
*/
|
|
1271
1409
|
readonly name?: string;
|
|
@@ -1538,8 +1676,7 @@ export declare class SchemaGateError extends SchemaGateError_base {
|
|
|
1538
1676
|
* any write. A target with no `version`, or with a prerelease label, is a
|
|
1539
1677
|
* document that replaces its predecessor in place and is rewritten as
|
|
1540
1678
|
* before.
|
|
1541
|
-
* - `"allow"` — classify and report only, never refuse
|
|
1542
|
-
* behaviour. Also the sanctioned REPAIR path for a published file whose
|
|
1679
|
+
* - `"allow"` — classify and report only, never refuse. Also the sanctioned REPAIR path for a published file whose
|
|
1543
1680
|
* text no longer parses — `SchemaFile` classifies unparseable text as
|
|
1544
1681
|
* `"contract"` so it stays regenerable, and under the default that
|
|
1545
1682
|
* classification is refused.
|
|
@@ -1686,7 +1823,7 @@ interface SchemaPipelineOptions {
|
|
|
1686
1823
|
}
|
|
1687
1824
|
/**
|
|
1688
1825
|
* The emit pipeline over a target manifest: generate, lint, validate, gate,
|
|
1689
|
-
* write
|
|
1826
|
+
* and write each schema document.
|
|
1690
1827
|
*
|
|
1691
1828
|
* Requires `SchemaFile` and `SchemaValidator` in `R`; provide
|
|
1692
1829
|
* `SchemaFile.layer` and an engine — `AjvValidator.layer` from
|
|
@@ -1916,9 +2053,10 @@ interface SchemastoreConfigInput {
|
|
|
1916
2053
|
* file in it is read as a slice, so it holds nothing else, must not be
|
|
1917
2054
|
* `outputDir` itself, and must not be the merged catalog's own path.
|
|
1918
2055
|
* Every config that shares a merged catalog must share the same
|
|
1919
|
-
* `catalogDir`, under a `name` unique case-insensitively among them: two
|
|
1920
|
-
* `schemas/more`) both merge into
|
|
1921
|
-
* slice sets and overwrite each
|
|
2056
|
+
* `catalogDir`, under a `name` unique case-insensitively among them: two
|
|
2057
|
+
* sibling directories (`schemas/catalogs`, `schemas/more`) both merge into
|
|
2058
|
+
* `schemas/catalog.json` from different slice sets and overwrite each
|
|
2059
|
+
* other — no single config can detect it.
|
|
1922
2060
|
*/
|
|
1923
2061
|
readonly catalogDir?: string;
|
|
1924
2062
|
/**
|
|
@@ -2022,6 +2160,21 @@ interface SchemastoreConfig {
|
|
|
2022
2160
|
* re-checks on the resolved absolute paths. Branding the result lets a loader recognise a config
|
|
2023
2161
|
* module's default export via {@link isSchemastoreConfig}.
|
|
2024
2162
|
*
|
|
2163
|
+
* @example
|
|
2164
|
+
* ```ts
|
|
2165
|
+
* import { defineConfig } from "@effected/schemastore";
|
|
2166
|
+
* import { Schema } from "effect";
|
|
2167
|
+
*
|
|
2168
|
+
* const Config = Schema.Struct({ name: Schema.String });
|
|
2169
|
+
*
|
|
2170
|
+
* export default defineConfig({
|
|
2171
|
+
* name: "my-tool",
|
|
2172
|
+
* outputDir: "schemas",
|
|
2173
|
+
* baseUrl: "https://example.com/schemas",
|
|
2174
|
+
* schemas: { config: { schema: Config } },
|
|
2175
|
+
* });
|
|
2176
|
+
* ```
|
|
2177
|
+
*
|
|
2025
2178
|
* @public
|
|
2026
2179
|
*/
|
|
2027
2180
|
export declare const defineConfig: (input: SchemastoreConfigInput) => SchemastoreConfig;
|
|
@@ -2033,5 +2186,5 @@ export declare const defineConfig: (input: SchemastoreConfigInput) => Schemastor
|
|
|
2033
2186
|
*/
|
|
2034
2187
|
export declare const isSchemastoreConfig: (value: unknown) => value is SchemastoreConfig;
|
|
2035
2188
|
//#endregion
|
|
2036
|
-
export type { CanonicalJsonError, CanonicalJsonOptions, CatalogInput, CatalogUrls, CheckResult, ContractChangePolicy, CustomHostedSchemaInput, DriftOptions, DriftTolerance, DriftVerdict, FrozenVersion, GitHubHostedSchemaInput, HostedSchemaVersionsInput, OnDrift, PipelineCheckResult, PipelineResult, ResolvedSchema, SchemaChange, SchemaEntryInput, SchemaFileShape, SchemaLayout, SchemaPipelineOptions, SchemaValidatorOptions, SchemaValidatorShape, SchemaWriteOptions, SchemastoreConfig, SchemastoreConfigInput, StoreDocumentOptions, WriteChange, WriteOutcome, WriteResult };
|
|
2189
|
+
export type { CanonicalJsonError, CanonicalJsonOptions, CatalogInput, CatalogUrls, CheckResult, ContractChangePolicy, CustomHostedSchemaInput, DriftOptions, DriftTolerance, DriftVerdict, FrozenVersion, GitHubHostedSchemaInput, HostedSchemaVersionsInput, InstanceValidatorOptions, InstanceValidatorShape, OnDrift, PipelineCheckResult, PipelineResult, ResolvedSchema, SchemaChange, SchemaEntryInput, SchemaFileShape, SchemaLayout, SchemaPipelineOptions, SchemaValidatorOptions, SchemaValidatorShape, SchemaWriteOptions, SchemastoreConfig, SchemastoreConfigInput, StoreDocumentOptions, WriteChange, WriteOutcome, WriteResult };
|
|
2037
2190
|
//# sourceMappingURL=index.d.ts.map
|
package/index.js
CHANGED
|
@@ -6,6 +6,7 @@ import { DocumentDiff } from "./DocumentDiff.js";
|
|
|
6
6
|
import { DocumentLint, DocumentLintFinding } from "./DocumentLint.js";
|
|
7
7
|
import { DriftPolicy } from "./DriftPolicy.js";
|
|
8
8
|
import { HostedSchema, SCHEMASTORE_CATALOG_BASE, SCHEMASTORE_ID_BASE } from "./HostedSchema.js";
|
|
9
|
+
import { InstanceFinding, InstanceValidator, InstanceValidatorError } from "./InstanceValidator.js";
|
|
9
10
|
import { SchemaFile, SchemaFileNotFoundError, SchemaFileReadError, SchemaFileWriteError } from "./SchemaFile.js";
|
|
10
11
|
import { SchemaValidator, SchemaValidatorError, ValidationFinding } from "./SchemaValidator.js";
|
|
11
12
|
import { DRAFT_07_META_SCHEMA, SchemaConversionError, StoreDocument, UndeclaredAnnotationKeyError } from "./StoreDocument.js";
|
|
@@ -13,4 +14,4 @@ import { ContractChangeTarget, PipelineFinding, SchemaContractChangeError, Schem
|
|
|
13
14
|
import { SchemaTarget } from "./SchemaTarget.js";
|
|
14
15
|
import { defineConfig, isSchemastoreConfig } from "./SchemastoreConfig.js";
|
|
15
16
|
|
|
16
|
-
export { CanonicalJson, CatalogEntry, CatalogLintFinding, ContractChangeTarget, DRAFT_07_META_SCHEMA, DocumentDiff, DocumentLint, DocumentLintFinding, DriftPolicy, HostedSchema, InvalidSchemaVersionError, JsonDepthExceededError, KeywordFamilies, NonJsonValueError, PipelineFinding, SCHEMASTORE_CATALOG_BASE, SCHEMASTORE_ID_BASE, SchemaContractChangeError, SchemaConversionError, SchemaFile, SchemaFileNotFoundError, SchemaFileReadError, SchemaFileWriteError, SchemaGateError, SchemaPipeline, SchemaTarget, SchemaValidator, SchemaValidatorError, SchemaVersion, SchemaVersioning, StoreDocument, UndeclaredAnnotationKeyError, ValidationFinding, defineConfig, isSchemastoreConfig };
|
|
17
|
+
export { CanonicalJson, CatalogEntry, CatalogLintFinding, ContractChangeTarget, DRAFT_07_META_SCHEMA, DocumentDiff, DocumentLint, DocumentLintFinding, DriftPolicy, HostedSchema, InstanceFinding, InstanceValidator, InstanceValidatorError, InvalidSchemaVersionError, JsonDepthExceededError, KeywordFamilies, NonJsonValueError, PipelineFinding, SCHEMASTORE_CATALOG_BASE, SCHEMASTORE_ID_BASE, SchemaContractChangeError, SchemaConversionError, SchemaFile, SchemaFileNotFoundError, SchemaFileReadError, SchemaFileWriteError, SchemaGateError, SchemaPipeline, SchemaTarget, SchemaValidator, SchemaValidatorError, SchemaVersion, SchemaVersioning, StoreDocument, UndeclaredAnnotationKeyError, ValidationFinding, defineConfig, isSchemastoreConfig };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@effected/schemastore",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.19.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,10 +38,10 @@
|
|
|
38
38
|
"./package.json": "./package.json"
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
|
-
"@effected/semver": "^0.
|
|
41
|
+
"@effected/semver": "^0.11.0"
|
|
42
42
|
},
|
|
43
43
|
"peerDependencies": {
|
|
44
|
-
"effect": "4.0.0
|
|
44
|
+
"effect": "^4.0.0"
|
|
45
45
|
},
|
|
46
46
|
"engines": {
|
|
47
47
|
"node": ">=24.11.0"
|