@effected/schemastore 0.7.0 → 0.8.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/README.md CHANGED
@@ -71,10 +71,12 @@ console.log(Effect.runSync(program));
71
71
  // "required": [
72
72
  // "name"
73
73
  // ],
74
- // "additionalProperties": false
74
+ // "additionalProperties": true
75
75
  // }
76
76
  ```
77
77
 
78
+ `additionalProperties: true` is core's default for a struct: `Schema.toJsonSchemaDocument` emits open objects unless told otherwise. A config schema usually wants the closed form, and `jsonSchema: { onExcessProperty: "error" }` in the options produces it; the same option lives on a pipeline target, below.
79
+
78
80
  `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
81
 
80
82
  ## Annotate at the definition site
@@ -243,6 +245,7 @@ const targets = [
243
245
  schema: Schema.Struct({ name: Schema.String }),
244
246
  $id: "https://example.com/config.schema.json",
245
247
  path: "schemas/config.schema.json",
248
+ jsonSchema: { onExcessProperty: "error" },
246
249
  }),
247
250
  ];
248
251
 
@@ -268,6 +271,8 @@ provide the same value cannot disagree about what the layer contains.
268
271
 
269
272
  A target names its schema, its `$id` and where the file goes. `name` is optional and only catalog naming reads it, so a file-only target like the one above does not repeat its path's basename; supply it when you also pass a `version`, since versioned naming is `<name>-<version>.json`.
270
273
 
274
+ `jsonSchema` is optional too, and carries core's `Schema.ToJsonSchemaOptions` for that one target. Set it when the document's shape must not follow core's defaults: `onExcessProperty: "error"` keeps a published closed-object document closed, where the open-by-default generator would otherwise flip every struct's `additionalProperties` and the contract gate would refuse the rewrite. Living on the target rather than in the pipeline options keeps each document's generation contract self-describing.
275
+
271
276
  Both gates' findings normalize into one `PipelineFinding` shape, so a single predicate judges them. Gating is **policy, not mechanism**: `blocking` defaults to `severity === "warning"`, which is what `UnresolvedRef`, `UnknownKeyword` and `DepthExceeded` are. Replace the predicate rather than the loop when you disagree.
272
277
 
273
278
  ```ts
@@ -326,7 +331,7 @@ The classification is key-order insensitive and keyword-position aware, like the
326
331
  - `DocumentDiff` — `classify` puts two documents in `"none"` / `"annotations"` / `"contract"`, the signal for whether a change needs a new schema version, plus `isClean` for the clean case.
327
332
  - `SchemaPipeline` — the emit loop over a target manifest, two-phase and all-or-nothing across targets: `run` and `check`, the single-target `runOne` and `checkOne`, `PipelineFinding`, `SchemaGateError` and an overridable gating predicate, plus the contract gate (`ContractChangePolicy`, `ContractChangeTarget`, `SchemaContractChangeError`, `PipelineCheckResult.contractBlocked`) that refuses to rewrite a published document's validation contract in place.
328
333
  - `SchemaFile` — write-if-changed IO over core `FileSystem` / `Path`, comparing by content and answering what changed as a value; `check` is the non-writing drift half, answering `wouldWrite` alongside `change`.
329
- - `SchemaTarget` — the target manifest vocabulary: schema, `$id`, destination path, an optional name and an optional version that requires one.
334
+ - `SchemaTarget` — the target manifest vocabulary: schema, `$id`, destination path, an optional name, an optional version that requires one, and optional per-target `jsonSchema` generation options.
330
335
  - `CanonicalJson` — the deterministic serializer with typed failures (`NonJsonValueError`, `JsonDepthExceededError`).
331
336
 
332
337
  ## License
package/SchemaPipeline.js CHANGED
@@ -195,7 +195,10 @@ var SchemaPipeline = class SchemaPipeline {
195
195
  const held = [];
196
196
  const blocked = [];
197
197
  for (const target of targets) {
198
- const document = yield* StoreDocument.fromSchema(target.schema, { $id: target.$id });
198
+ const document = yield* StoreDocument.fromSchema(target.schema, {
199
+ $id: target.$id,
200
+ ...target.jsonSchema !== void 0 ? { jsonSchema: target.jsonSchema } : {}
201
+ });
199
202
  const findings = yield* gather(document, options);
200
203
  yield* gate(target, findings, options);
201
204
  const version = target.version;
@@ -248,7 +251,10 @@ var SchemaPipeline = class SchemaPipeline {
248
251
  const files = yield* SchemaFile;
249
252
  const results = [];
250
253
  for (const target of targets) {
251
- const document = yield* StoreDocument.fromSchema(target.schema, { $id: target.$id });
254
+ const document = yield* StoreDocument.fromSchema(target.schema, {
255
+ $id: target.$id,
256
+ ...target.jsonSchema !== void 0 ? { jsonSchema: target.jsonSchema } : {}
257
+ });
252
258
  const findings = yield* gather(document, options);
253
259
  const { wouldWrite, change } = yield* files.check(target.path, document, options?.write);
254
260
  results.push({
package/SchemaTarget.js CHANGED
@@ -21,7 +21,8 @@ var SchemaTarget = class {
21
21
  $id: options.$id,
22
22
  path: options.path,
23
23
  ...options.name !== void 0 ? { name: options.name } : {},
24
- ...options.version !== void 0 ? { version: options.version } : {}
24
+ ...options.version !== void 0 ? { version: options.version } : {},
25
+ ...options.jsonSchema !== void 0 ? { jsonSchema: options.jsonSchema } : {}
25
26
  };
26
27
  }
27
28
  };
package/index.d.ts CHANGED
@@ -969,6 +969,19 @@ export interface SchemaTarget {
969
969
  * rewritten in place.
970
970
  */
971
971
  readonly version?: SchemaVersion;
972
+ /**
973
+ * Options passed through to {@link StoreDocument.fromSchema} (and, from
974
+ * there, core's `Schema.toJsonSchemaDocument`).
975
+ *
976
+ * A target-level field rather than a pipeline-wide default keeps each
977
+ * document's generation contract self-describing, so
978
+ * {@link SchemaPipeline} reproduces a document deterministically
979
+ * regardless of core's own default — for example, an `onExcessProperty`
980
+ * setting of `error` restores closed objects after rc.113 flipped that
981
+ * default open. See {@link StoreDocumentOptions.jsonSchema} for the
982
+ * `includeAnnotationKey` gate this option is also subject to.
983
+ */
984
+ readonly jsonSchema?: Schema.ToJsonSchemaOptions;
972
985
  }
973
986
  /**
974
987
  * Constructors for `SchemaTarget` values.
@@ -986,6 +999,7 @@ export declare class SchemaTarget {
986
999
  readonly $id: string;
987
1000
  readonly name?: string;
988
1001
  readonly path: string;
1002
+ readonly jsonSchema?: Schema.ToJsonSchemaOptions;
989
1003
  }): SchemaTarget;
990
1004
  /**
991
1005
  * Builds a versioned target. `name` is **required** here: versioned
@@ -999,6 +1013,7 @@ export declare class SchemaTarget {
999
1013
  readonly name: string;
1000
1014
  readonly path: string;
1001
1015
  readonly version: SchemaVersion;
1016
+ readonly jsonSchema?: Schema.ToJsonSchemaOptions;
1002
1017
  }): SchemaTarget;
1003
1018
  }
1004
1019
  //#endregion
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@effected/schemastore",
3
- "version": "0.7.0",
3
+ "version": "0.8.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": [