@effected/schemastore 0.15.2 → 0.16.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/StoreDocument.js CHANGED
@@ -128,6 +128,52 @@ const restoreDefsRefs = (node, depth) => {
128
128
  }
129
129
  return node;
130
130
  };
131
+ const SCHEMA_KEYWORDS = /* @__PURE__ */ new Set([
132
+ "items",
133
+ "additionalItems",
134
+ "contains",
135
+ "additionalProperties",
136
+ "propertyNames",
137
+ "not",
138
+ "if",
139
+ "then",
140
+ "else"
141
+ ]);
142
+ const SCHEMA_ARRAY_KEYWORDS = /* @__PURE__ */ new Set([
143
+ "allOf",
144
+ "anyOf",
145
+ "oneOf"
146
+ ]);
147
+ const SCHEMA_MAP_KEYWORDS = /* @__PURE__ */ new Set([
148
+ "properties",
149
+ "patternProperties",
150
+ "definitions",
151
+ "$defs",
152
+ "dependencies"
153
+ ]);
154
+ const isPlainObject = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
155
+ const collapseSchemaMap = (node, depth) => {
156
+ if (!isPlainObject(node)) return node;
157
+ const out = Object.create(null);
158
+ for (const [key, value] of Object.entries(node)) out[key] = isPlainObject(value) ? collapseUniformTuples(value, depth + 1) : value;
159
+ return out;
160
+ };
161
+ const collapseUniformTuples = (node, depth) => {
162
+ if (depth >= 256) throw new RewriteDepthExceeded();
163
+ if (!isPlainObject(node)) return node;
164
+ const out = Object.create(null);
165
+ for (const [key, value] of Object.entries(node)) if (SCHEMA_KEYWORDS.has(key)) out[key] = Array.isArray(value) ? value.map((item) => collapseUniformTuples(item, depth + 1)) : collapseUniformTuples(value, depth + 1);
166
+ else if (SCHEMA_ARRAY_KEYWORDS.has(key) && Array.isArray(value)) out[key] = value.map((item) => collapseUniformTuples(item, depth + 1));
167
+ else if (SCHEMA_MAP_KEYWORDS.has(key)) out[key] = collapseSchemaMap(value, depth + 1);
168
+ else out[key] = value;
169
+ const tuple = out.items;
170
+ const rest = out.additionalItems;
171
+ if (Array.isArray(tuple) && tuple.length > 0 && isPlainObject(rest) && tuple.every((element) => CanonicalJson.equals(element, rest))) {
172
+ out.items = rest;
173
+ delete out.additionalItems;
174
+ }
175
+ return out;
176
+ };
131
177
  /**
132
178
  * A SchemaStore-shaped Draft-07 JSON Schema document assembled from an
133
179
  * Effect Schema source: `$schema` (the Draft-07 meta-schema) + `$id` + the
@@ -137,9 +183,11 @@ const restoreDefsRefs = (node, depth) => {
137
183
  * `Schema.toJsonSchemaDocument` (Draft 2020-12), core's
138
184
  * `JsonSchema.toDocumentDraft07` lowering, the `#/definitions` →
139
185
  * `#/$defs` `$ref` rewrite the lowering makes necessary — so every `$ref`
140
- * in a built document already resolves against the `$defs` pool — and the
141
- * gate that holds the document's non-standard surface to the declared
142
- * keyword families ({@link KeywordFamilies}). The package owns assembly and
186
+ * in a built document already resolves against the `$defs` pool — the
187
+ * uniform-tuple collapse that keeps open-ended `NonEmptyArray`-shaped
188
+ * arrays publishable through the strict ajv gate (#818), and the gate that
189
+ * holds the document's non-standard surface to the declared keyword
190
+ * families ({@link KeywordFamilies}). The package owns assembly and
143
191
  * publication shape, not a JSON Schema engine.
144
192
  *
145
193
  * Annotated declared-family keys survive into the built document because
@@ -148,7 +196,12 @@ const restoreDefsRefs = (node, depth) => {
148
196
  * (2020-12 `prefixItems[i]` → Draft-07 `items[i]`, trailing `items` →
149
197
  * `additionalItems`). This package therefore does no re-grafting of its
150
198
  * own; it only declines to rewrite `$ref`-shaped strings *inside* those
151
- * opaque payloads.
199
+ * opaque payloads. The one structural normalization it does own is the
200
+ * uniform-tuple collapse: when every tuple element is content-equal to the
201
+ * open rest schema — always true for `NonEmptyArray` — the tuple is
202
+ * rewritten to a single-schema `items` with core's `minItems` untouched,
203
+ * the shape ajv's strictTuples rule accepts; a heterogeneous head keeps the
204
+ * tuple form.
152
205
  *
153
206
  * @public
154
207
  */
@@ -220,9 +273,9 @@ var StoreDocument = class StoreDocument extends Schema.Class("StoreDocument")({
220
273
  keys: [...undeclared].sort()
221
274
  }));
222
275
  const lowered = JsonSchema.toDocumentDraft07(document);
223
- const root = restoreDefsRefs(lowered.schema, 0);
276
+ const root = collapseUniformTuples(restoreDefsRefs(lowered.schema, 0), 0);
224
277
  const defs = Object.create(null);
225
- for (const [name, definition] of Object.entries(lowered.definitions)) defs[name] = restoreDefsRefs(definition, 1);
278
+ for (const [name, definition] of Object.entries(lowered.definitions)) defs[name] = collapseUniformTuples(restoreDefsRefs(definition, 1), 1);
226
279
  if (options.rootAnnotations !== void 0) applyRootAnnotations(root, defs, options.rootAnnotations);
227
280
  return Result.succeed(StoreDocument.make({
228
281
  $schema: DRAFT_07_META_SCHEMA,
package/index.d.ts CHANGED
@@ -339,9 +339,11 @@ declare const StoreDocument_base: Schema.Class<StoreDocument, Schema.Struct<{
339
339
  * `Schema.toJsonSchemaDocument` (Draft 2020-12), core's
340
340
  * `JsonSchema.toDocumentDraft07` lowering, the `#/definitions` →
341
341
  * `#/$defs` `$ref` rewrite the lowering makes necessary — so every `$ref`
342
- * in a built document already resolves against the `$defs` pool — and the
343
- * gate that holds the document's non-standard surface to the declared
344
- * keyword families ({@link KeywordFamilies}). The package owns assembly and
342
+ * in a built document already resolves against the `$defs` pool — the
343
+ * uniform-tuple collapse that keeps open-ended `NonEmptyArray`-shaped
344
+ * arrays publishable through the strict ajv gate (#818), and the gate that
345
+ * holds the document's non-standard surface to the declared keyword
346
+ * families ({@link KeywordFamilies}). The package owns assembly and
345
347
  * publication shape, not a JSON Schema engine.
346
348
  *
347
349
  * Annotated declared-family keys survive into the built document because
@@ -350,7 +352,12 @@ declare const StoreDocument_base: Schema.Class<StoreDocument, Schema.Struct<{
350
352
  * (2020-12 `prefixItems[i]` → Draft-07 `items[i]`, trailing `items` →
351
353
  * `additionalItems`). This package therefore does no re-grafting of its
352
354
  * own; it only declines to rewrite `$ref`-shaped strings *inside* those
353
- * opaque payloads.
355
+ * opaque payloads. The one structural normalization it does own is the
356
+ * uniform-tuple collapse: when every tuple element is content-equal to the
357
+ * open rest schema — always true for `NonEmptyArray` — the tuple is
358
+ * rewritten to a single-schema `items` with core's `minItems` untouched,
359
+ * the shape ajv's strictTuples rule accepts; a heterogeneous head keeps the
360
+ * tuple form.
354
361
  *
355
362
  * @public
356
363
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@effected/schemastore",
3
- "version": "0.15.2",
3
+ "version": "0.16.1",
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.9.0"
41
+ "@effected/semver": "^0.10.1"
42
42
  },
43
43
  "peerDependencies": {
44
- "effect": "4.0.0-rc.117"
44
+ "effect": "4.0.0-rc.118"
45
45
  },
46
46
  "engines": {
47
47
  "node": ">=24.11.0"