@toolproof-npm/schema 0.1.46 → 0.1.47

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.
@@ -82,13 +82,11 @@ export type ExtractionSchema =
82
82
  {
83
83
  } & {
84
84
  $schema: "https://json-schema.org/draft/2020-12/schema";
85
- $defs?: {
86
- };
85
+ $defs?: Record<string, unknown>;
87
86
  type: "object";
88
- allOf?: [{type: "array"; items: {type: "object"}}];
89
- properties?: {
90
- };
91
- required?: [{type: "array"; items: {type: "string"}; uniqueItems: true}];
87
+ allOf?: Array<{[k: string]: unknown}>;
88
+ properties?: Record<string, unknown>;
89
+ required?: string[];
92
90
  additionalProperties?: false;
93
91
  unevaluatedProperties?: false;
94
92
  $anchor: string;
@@ -123,7 +121,10 @@ export type IdentitySchema =
123
121
  type: "string" | "number" | "integer" | "boolean";
124
122
  $anchor?: string;
125
123
  $comment?: string;
126
- enum?: [{type: "array"; minItems: 1; uniqueItems: true}];
124
+ /**
125
+ * @minItems 1
126
+ */
127
+ enum?: [unknown, ...unknown[]];
127
128
  format?: string;
128
129
  maxLength?: number;
129
130
  minLength?: number;
@@ -180,7 +181,10 @@ export type MeritSchema =
180
181
  type?: "number" | "integer";
181
182
  $anchor?: string;
182
183
  $comment?: string;
183
- enum?: [{type: "array"; items: {type: "number"}; minItems: 1; uniqueItems: true}];
184
+ /**
185
+ * @minItems 1
186
+ */
187
+ enum?: [number, ...number[]];
184
188
  exclusiveMaximum?: number;
185
189
  exclusiveMinimum?: number;
186
190
  maximum?: number;
@@ -192,7 +196,10 @@ export type MeritSchema1 =
192
196
  type: "number" | "integer";
193
197
  }
194
198
  | {
195
- enum: [{type: "array"; items: {type: "number"}; minItems: 1}];
199
+ /**
200
+ * @minItems 1
201
+ */
202
+ enum: [number, ...number[]];
196
203
  };
197
204
  /**
198
205
  * This interface was referenced by `GenesisJson`'s JSON-Schema
@@ -416,12 +423,11 @@ export interface ExtractionSchemaWrapper {
416
423
  * via the `definition` "IdentityProp".
417
424
  */
418
425
  export interface IdentityProp {
419
- $defs: {
420
- };
426
+ $defs: Record<string, unknown>;
421
427
  properties: {
422
428
  identity: IdentitySchemaRef;
423
429
  };
424
- required?: string[];
430
+ required: string[];
425
431
  additionalProperties?: unknown;
426
432
  }
427
433
  /**
@@ -456,12 +462,11 @@ export type RoleMap = Record<ResourceRoleIdentity, ResourceRoleValue>;
456
462
  * via the `definition` "MeritProp".
457
463
  */
458
464
  export interface MeritProp {
459
- $defs: {
460
- };
465
+ $defs: Record<string, unknown>;
461
466
  properties: {
462
467
  merit: MeritSchemaRef;
463
468
  };
464
- required: [{type: "array"; items: {type: "string"}; uniqueItems: true}];
469
+ required: string[];
465
470
  additionalProperties?: unknown;
466
471
  }
467
472
  /**
@@ -577,13 +582,11 @@ export type ExtractionSchema =
577
582
  {
578
583
  } & {
579
584
  $schema: "https://json-schema.org/draft/2020-12/schema";
580
- $defs?: {
581
- };
585
+ $defs?: Record<string, unknown>;
582
586
  type: "object";
583
- allOf?: [{type: "array"; items: {type: "object"}}];
584
- properties?: {
585
- };
586
- required?: [{type: "array"; items: {type: "string"}; uniqueItems: true}];
587
+ allOf?: Array<{[k: string]: unknown}>;
588
+ properties?: Record<string, unknown>;
589
+ required?: string[];
587
590
  additionalProperties?: false;
588
591
  unevaluatedProperties?: false;
589
592
  $anchor: string;
@@ -187,24 +187,38 @@ async function main() {
187
187
  try {
188
188
  const rawSchema = fs.readFileSync(schemaPath, 'utf8');
189
189
  const parsedSchema = JSON.parse(rawSchema);
190
- function normalizeArrays(node) {
190
+ function normalizeArrays(node, parentKey) {
191
191
  if (Array.isArray(node)) {
192
192
  for (let i = 0; i < node.length; i++)
193
- normalizeArrays(node[i]);
193
+ normalizeArrays(node[i], parentKey);
194
194
  return;
195
195
  }
196
196
  if (!node || typeof node !== 'object')
197
197
  return;
198
- const arrayKeys = ['anyOf', 'allOf', 'oneOf', 'required', 'enum'];
199
- for (const k of arrayKeys) {
200
- if (k in node) {
201
- const v = node[k];
202
- if (!Array.isArray(v))
203
- node[k] = [v];
198
+ // IMPORTANT:
199
+ // In meta-schemas we often have `properties: { required: { ...schema... } }`.
200
+ // Here, the key "required" is a *property name*, not the JSON-Schema keyword
201
+ // "required". Blindly normalizing would wrap that schema object into an array,
202
+ // causing json-schema-to-typescript to emit the schema-shape instead of `string[]`.
203
+ //
204
+ // So: only coerce array-keywords when we're not inside a map of property names.
205
+ const isPropertyNameMap = parentKey === 'properties'
206
+ || parentKey === 'patternProperties'
207
+ || parentKey === '$defs'
208
+ || parentKey === 'definitions'
209
+ || parentKey === 'dependentSchemas';
210
+ if (!isPropertyNameMap) {
211
+ const arrayKeys = ['anyOf', 'allOf', 'oneOf', 'required', 'enum'];
212
+ for (const k of arrayKeys) {
213
+ if (k in node) {
214
+ const v = node[k];
215
+ if (!Array.isArray(v))
216
+ node[k] = [v];
217
+ }
204
218
  }
205
219
  }
206
- for (const val of Object.values(node))
207
- normalizeArrays(val);
220
+ for (const [k, v] of Object.entries(node))
221
+ normalizeArrays(v, k);
208
222
  }
209
223
  // Normalize expected arrays to prevent traversal crashes
210
224
  normalizeArrays(parsedSchema);
@@ -245,15 +259,24 @@ async function main() {
245
259
  // Robust single-pass: delete the entire line (with optional trailing newline) where the signature appears.
246
260
  // This avoids introducing extra blank lines while handling CRLF/LF and varying indentation.
247
261
  ts = ts.replace(/^\s*\[k:\s*string\]:\s*unknown;\s*(?:\r?\n)?/gm, '');
248
- // Fix meta-schema types where json-schema-to-typescript incorrectly interprets
249
- // schema definitions as literal values. ExtractionSchemaValue describes what
250
- // an extraction schema looks like, not what the schema meta-properties should be.
251
- ts = ts.replace(/^(export type ExtractionSchemaValue =[\s\S]*?)(\$defs\?:\s*\{[\s\S]*?};)/gm, '$1$defs?: {\n [k: string]: unknown;\n };');
252
- ts = ts.replace(/^(export type ExtractionSchemaValue =[\s\S]*?)(properties\?:\s*\{[\s\S]*?};)/gm, '$1properties?: {\n [k: string]: unknown;\n };');
253
- ts = ts.replace(/^(export type ExtractionSchemaValue =[\s\S]*?)(allOf\?:\s*\[\{type:\s*"array";\s*items:\s*\{type:\s*"object"\}\}\];)/gm, '$1allOf?: Array<{[k: string]: unknown}>;');
254
- ts = ts.replace(/^(export type ExtractionSchemaValue =[\s\S]*?)(required\?:\s*\[\{type:\s*"array";\s*items:\s*\{type:\s*"string"\};\s*uniqueItems:\s*true\}\];)/gm, '$1required?: string[];');
255
- // Similarly fix IdentityProp which has the same issue
262
+ // Fix meta-schema types where json-schema-to-typescript can still incorrectly interpret
263
+ // schema definitions as literal values (or emit overly-restrictive `{}` objects).
264
+ // We do this as a broad post-pass on the emitted TS because the generator output varies
265
+ // (e.g. `allOf?: { }[];` vs `allOf?: [{type:"array"; ...}]`).
266
+ // `$defs?: { }` or `$defs: { }` -> map type (preserve required/optional marker)
267
+ // NOTE: We emit `Record<...>` instead of an index signature because later cleanup
268
+ // strips standalone `[k: string]: unknown;` lines.
269
+ ts = ts.replace(/^(\s*)(\$defs\??:\s*)\{\s*\r?\n\s*\};/gm, (_m, indent, head) => `${indent}${head}Record<string, unknown>;`);
270
+ // `properties?: { }` or `properties: { }` -> map type
271
+ ts = ts.replace(/^(\s*)(properties\??:\s*)\{\s*\r?\n\s*\};/gm, (_m, indent, head) => `${indent}${head}Record<string, unknown>;`);
272
+ // `allOf?: { }[];` (and similar for anyOf/oneOf) -> array of schema-ish objects
273
+ ts = ts.replace(/^(\s*)((?:allOf|anyOf|oneOf)\??:\s*)\{\s*\r?\n\s*\}\[\];/gm, (_m, indent, head) => `${indent}${head}Array<{[k: string]: unknown}>;`);
274
+ // Older broken shapes from earlier normalization (keep for backwards compatibility)
275
+ ts = ts.replace(/((?:allOf|anyOf|oneOf)\??:\s*)\[\{type:\s*"array";\s*items:\s*\{type:\s*"object"\}\}\];/g, '$1Array<{[k: string]: unknown}>;');
276
+ ts = ts.replace(/required\?:\s*\[\{type:\s*"array";\s*items:\s*\{type:\s*"string"\};\s*uniqueItems:\s*true\}\];/g, 'required?: string[];');
277
+ // Similarly fix IdentityProp/MeritProp which have the same issue
256
278
  ts = ts.replace(/^(export interface IdentityProp[\s\S]*?)(required:\s*\[\{type:\s*"array";\s*contains:\s*\{const:\s*"identity"\};\s*items:\s*\{type:\s*"string"\};\s*uniqueItems:\s*true\}\];)/gm, '$1required?: string[];');
279
+ ts = ts.replace(/^(export interface MeritProp[\s\S]*?)(required:\s*\[\{type:\s*"array";\s*items:\s*\{type:\s*"string"\};\s*uniqueItems:\s*true\}\];)/gm, '$1required?: string[];');
257
280
  // Prune verbose type/interface names produced from absolute $id URLs.
258
281
  // Deterministic pruning based on original $id -> baseName map
259
282
  // This avoids heuristic truncation that dropped prefixes.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@toolproof-npm/schema",
3
- "version": "0.1.46",
3
+ "version": "0.1.47",
4
4
  "description": "JSON schemas and TypeScript types for ToolProof",
5
5
  "keywords": [
6
6
  "toolproof",