@amritk/generate-parsers 0.11.1 → 0.12.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.
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { escapeRegexPattern } from '@amritk/helpers/escape-regex-pattern';
|
|
2
2
|
import { refToName } from '@amritk/helpers/ref-to-name';
|
|
3
3
|
import { safeAccessor, safeKey } from '@amritk/helpers/safe-accessor';
|
|
4
|
-
import { hasAdditionalProperties, hasAllOf, hasAnyOf, hasConst,
|
|
4
|
+
import { hasAdditionalProperties, hasAllOf, hasAnyOf, hasConst, hasEnum, hasExclusiveMaximum, hasExclusiveMinimum, hasItems, hasMaxItems, hasMaximum, hasMaxLength, hasMinItems, hasMinimum, hasMinLength, hasMultipleOf, hasOneOf, hasPattern, hasProperties, hasRef, hasType, hasUniqueItems, isObjectSchema, isSchemaObject, } from '@amritk/helpers/schema-guards';
|
|
5
5
|
import { unknownKeyCheck } from '@amritk/helpers/unknown-key-check';
|
|
6
6
|
import { getDefaultValue } from '../helpers/get-default-value.js';
|
|
7
7
|
import { generateObjectStrictAssertion, generateScalarStrictAssertion } from './generate-strict-assertion.js';
|
|
8
|
-
import { generateValidationExpression } from './generate-validation-expression.js';
|
|
8
|
+
import { generateValidationExpression, scalarItemTypeCheck } from './generate-validation-expression.js';
|
|
9
9
|
/**
|
|
10
10
|
* Generates the parser function name from a type name.
|
|
11
11
|
* Converts "UserObject" to "parseUserObject".
|
|
@@ -213,41 +213,10 @@ const generateFallbackValue = (_, propSchema, useRefImports, suffix) => {
|
|
|
213
213
|
return '{}';
|
|
214
214
|
}
|
|
215
215
|
}
|
|
216
|
-
//
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
// Use explicit default if provided
|
|
221
|
-
if (hasDefault(propSchema)) {
|
|
222
|
-
return JSON.stringify(propSchema.default);
|
|
223
|
-
}
|
|
224
|
-
// Use first enum value if available
|
|
225
|
-
if (hasEnum(propSchema) && propSchema.enum.length > 0) {
|
|
226
|
-
return JSON.stringify(propSchema.enum[0]);
|
|
227
|
-
}
|
|
228
|
-
// Use first example if available
|
|
229
|
-
if (hasExamples(propSchema) && propSchema.examples.length > 0) {
|
|
230
|
-
return JSON.stringify(propSchema.examples[0]);
|
|
231
|
-
}
|
|
232
|
-
// Return simple type-based defaults without pattern inference
|
|
233
|
-
if (!hasType(propSchema)) {
|
|
234
|
-
return 'undefined';
|
|
235
|
-
}
|
|
236
|
-
switch (propSchema.type) {
|
|
237
|
-
case 'string':
|
|
238
|
-
return '""';
|
|
239
|
-
case 'number':
|
|
240
|
-
case 'integer':
|
|
241
|
-
return '0';
|
|
242
|
-
case 'boolean':
|
|
243
|
-
return 'false';
|
|
244
|
-
case 'array':
|
|
245
|
-
return '[]';
|
|
246
|
-
case 'object':
|
|
247
|
-
return '{}';
|
|
248
|
-
default:
|
|
249
|
-
return 'undefined';
|
|
250
|
-
}
|
|
216
|
+
// Everything else (default/const/enum/examples/union, the null type, and a
|
|
217
|
+
// recursively-defaulted object) shares one source of truth so the fallback
|
|
218
|
+
// object is itself a valid instance — `getDefaultValue` handles them all.
|
|
219
|
+
return getDefaultValue(propSchema);
|
|
251
220
|
};
|
|
252
221
|
/**
|
|
253
222
|
* Generates a fallback object with required properties filled with default values.
|
|
@@ -296,12 +265,85 @@ const generateFallbackObject = (schema, useRefImports, typeName, suffix, subType
|
|
|
296
265
|
* Generates a parser for non-object schemas (string, number, boolean, array, etc.)
|
|
297
266
|
* that validates the input matches the expected primitive type before casting.
|
|
298
267
|
*/
|
|
268
|
+
/**
|
|
269
|
+
* A default value literal (as source text) for `schema`, used as the fallback a
|
|
270
|
+
* top-level union coerces an unmatched value to. Prefers a `const`/`enum` member,
|
|
271
|
+
* then a per-type empty value.
|
|
272
|
+
*/
|
|
273
|
+
const scalarDefaultLiteral = (schema) => {
|
|
274
|
+
if (!isSchemaObject(schema))
|
|
275
|
+
return '{}';
|
|
276
|
+
if (hasConst(schema))
|
|
277
|
+
return JSON.stringify(schema.const);
|
|
278
|
+
if (hasEnum(schema) && schema.enum.length > 0)
|
|
279
|
+
return JSON.stringify(schema.enum[0]);
|
|
280
|
+
if (hasType(schema)) {
|
|
281
|
+
switch (schema.type) {
|
|
282
|
+
case 'string':
|
|
283
|
+
return '""';
|
|
284
|
+
case 'number':
|
|
285
|
+
case 'integer':
|
|
286
|
+
return '0';
|
|
287
|
+
case 'boolean':
|
|
288
|
+
return 'false';
|
|
289
|
+
case 'null':
|
|
290
|
+
return 'null';
|
|
291
|
+
case 'array':
|
|
292
|
+
return '[]';
|
|
293
|
+
case 'object':
|
|
294
|
+
return '{}';
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
return '{}';
|
|
298
|
+
};
|
|
299
299
|
const generateNonObjectParser = (typeName, schema, strict) => {
|
|
300
300
|
const functionName = generateParserName(typeName);
|
|
301
|
+
// `const`/`enum` define the value space directly (the generated type is a
|
|
302
|
+
// literal / literal-union), so a non-member must coerce to a valid member —
|
|
303
|
+
// otherwise the returned value would not be of the declared type. This runs
|
|
304
|
+
// before the `type` switch so e.g. `{ type: 'string', enum: [...] }` is covered,
|
|
305
|
+
// and before the no-`type` bail so a bare `const`/`enum` schema is covered too.
|
|
306
|
+
if (!strict && isSchemaObject(schema)) {
|
|
307
|
+
if (hasConst(schema)) {
|
|
308
|
+
const literal = JSON.stringify(schema.const);
|
|
309
|
+
// The const is the only valid value, so the parser always yields it. For a
|
|
310
|
+
// primitive we can keep the caller's value when it already equals the const
|
|
311
|
+
// (`===` is a correct comparison); for an object/array, `===` would be a
|
|
312
|
+
// (always-false) reference comparison, so just return the const literal.
|
|
313
|
+
const isPrimitive = schema.const === null || typeof schema.const !== 'object';
|
|
314
|
+
return isPrimitive
|
|
315
|
+
? `export const ${functionName} = (input: unknown): ${typeName} => input === ${literal} ? input as ${typeName} : ${literal} as ${typeName};`
|
|
316
|
+
: `export const ${functionName} = (input: unknown): ${typeName} => ${literal} as ${typeName};`;
|
|
317
|
+
}
|
|
318
|
+
if (hasEnum(schema) && schema.enum.length > 0) {
|
|
319
|
+
const values = JSON.stringify(schema.enum);
|
|
320
|
+
const fallback = JSON.stringify(schema.enum[0]);
|
|
321
|
+
return `export const ${functionName} = (input: unknown): ${typeName} => ${values}.includes(input as never) ? input as ${typeName} : ${fallback} as ${typeName};`;
|
|
322
|
+
}
|
|
323
|
+
// A top-level union must validate membership: an unmatched value is not of
|
|
324
|
+
// the declared union type, so coerce it to a member-shaped default. Reuse the
|
|
325
|
+
// same union validation the property path uses. A `$ref` branch can't be
|
|
326
|
+
// validated inline here (the membership test would silently drop it and
|
|
327
|
+
// wrongly coerce a valid ref-shaped value), so fall through to a passthrough
|
|
328
|
+
// cast rather than discarding valid input.
|
|
329
|
+
if (hasOneOf(schema) || hasAnyOf(schema)) {
|
|
330
|
+
const branches = hasOneOf(schema) ? schema.oneOf : hasAnyOf(schema) ? schema.anyOf : [];
|
|
331
|
+
const hasRefBranch = branches.some((b) => isSchemaObject(b) && hasRef(b));
|
|
332
|
+
if (branches.length > 0 && !hasRefBranch) {
|
|
333
|
+
const fallback = scalarDefaultLiteral(branches[0]);
|
|
334
|
+
const expr = generateValidationExpression('', schema, fallback, true, undefined, undefined, 'input', true);
|
|
335
|
+
return `export const ${functionName} = (input: unknown): ${typeName} => (${expr}) as ${typeName};`;
|
|
336
|
+
}
|
|
337
|
+
return `export const ${functionName} = (input: unknown): ${typeName} => input as ${typeName};`;
|
|
338
|
+
}
|
|
339
|
+
}
|
|
301
340
|
if (!isSchemaObject(schema) || !hasType(schema)) {
|
|
302
341
|
// Schema without type information cannot be validated beyond a cast
|
|
303
342
|
return `export const ${functionName} = (input: unknown): ${typeName} => input as ${typeName};`;
|
|
304
343
|
}
|
|
344
|
+
if (!strict && schema.type === 'null') {
|
|
345
|
+
return `export const ${functionName} = (input: unknown): ${typeName} => null as ${typeName};`;
|
|
346
|
+
}
|
|
305
347
|
if (strict) {
|
|
306
348
|
const assertion = generateScalarStrictAssertion(schema, typeName);
|
|
307
349
|
if (assertion === null) {
|
|
@@ -318,8 +360,15 @@ const generateNonObjectParser = (typeName, schema, strict) => {
|
|
|
318
360
|
return `export const ${functionName} = (input: unknown): ${typeName} => typeof input === "number" ? input as ${typeName} : 0 as ${typeName};`;
|
|
319
361
|
case 'boolean':
|
|
320
362
|
return `export const ${functionName} = (input: unknown): ${typeName} => typeof input === "boolean" ? input as ${typeName} : false as ${typeName};`;
|
|
321
|
-
case 'array':
|
|
363
|
+
case 'array': {
|
|
364
|
+
// Coerce each element when the item schema is a single scalar type.
|
|
365
|
+
if (hasItems(schema) && !Array.isArray(schema.items) && scalarItemTypeCheck(schema.items, '_it') !== null) {
|
|
366
|
+
const item = schema.items;
|
|
367
|
+
const itemExpr = generateValidationExpression('', item, getDefaultValue(item), true, undefined, undefined, '_it', true);
|
|
368
|
+
return `export const ${functionName} = (input: unknown): ${typeName} => Array.isArray(input) ? (input as unknown[]).map((_it) => ${itemExpr}) as ${typeName} : [] as ${typeName};`;
|
|
369
|
+
}
|
|
322
370
|
return `export const ${functionName} = (input: unknown): ${typeName} => Array.isArray(input) ? [...input] as ${typeName} : [] as ${typeName};`;
|
|
371
|
+
}
|
|
323
372
|
default:
|
|
324
373
|
return `export const ${functionName} = (input: unknown): ${typeName} => input as ${typeName};`;
|
|
325
374
|
}
|
|
@@ -493,6 +542,14 @@ const generatePropertyTypeCheck = (varName, schema, useRefImports, suffix) => {
|
|
|
493
542
|
if (hasUniqueItems(schema) && schema.uniqueItems === true) {
|
|
494
543
|
checks.push(`new Set(${varName}).size === ${varName}.length`);
|
|
495
544
|
}
|
|
545
|
+
// For a scalar item type, every element must already be well-typed to take
|
|
546
|
+
// the fast path; a mistyped element routes the array to the slow path where
|
|
547
|
+
// each element is coerced.
|
|
548
|
+
if (hasItems(schema) && !Array.isArray(schema.items)) {
|
|
549
|
+
const itemCheck = scalarItemTypeCheck(schema.items, '_it');
|
|
550
|
+
if (itemCheck)
|
|
551
|
+
checks.push(`${varName}.every((_it) => ${itemCheck})`);
|
|
552
|
+
}
|
|
496
553
|
break;
|
|
497
554
|
}
|
|
498
555
|
case 'object':
|
|
@@ -1,4 +1,11 @@
|
|
|
1
1
|
import type { JSONSchema } from 'json-schema-typed/draft-2020-12';
|
|
2
|
+
/**
|
|
3
|
+
* A boolean type check for an array element whose schema is a single scalar type
|
|
4
|
+
* (the cases the element coercion below can handle). `integer` is treated as
|
|
5
|
+
* `number` because the generated TS element type is `number`. Returns `null` for
|
|
6
|
+
* objects, arrays, unions, `$ref`s, and anything richer.
|
|
7
|
+
*/
|
|
8
|
+
export declare const scalarItemTypeCheck: (itemSchema: JSONSchema, accessor: string) => string | null;
|
|
2
9
|
/**
|
|
3
10
|
* Generates a validation expression that checks if a value matches the expected type.
|
|
4
11
|
* Returns the value if valid, coerces to the correct type if invalid, or uses default if required and missing.
|
|
@@ -2,8 +2,9 @@ import { escapeRegexPattern } from '@amritk/helpers/escape-regex-pattern';
|
|
|
2
2
|
import { getMjstInstanceOf, getMjstPrimitive } from '@amritk/helpers/mjst-extension';
|
|
3
3
|
import { resolveRef } from '@amritk/helpers/resolve-ref';
|
|
4
4
|
import { safeAccessor } from '@amritk/helpers/safe-accessor';
|
|
5
|
-
import { hasAdditionalProperties, hasAllOf, hasAnyOf, hasConst, hasEnum, hasExclusiveMaximum, hasExclusiveMinimum, hasMaxItems, hasMaximum, hasMaxLength, hasMaxProperties, hasMinItems, hasMinimum, hasMinLength, hasMinProperties, hasMultipleOf, hasOneOf, hasPattern, hasProperties, hasRef, hasRequired, hasType, hasUniqueItems, isSchemaObject, } from '@amritk/helpers/schema-guards';
|
|
5
|
+
import { hasAdditionalProperties, hasAllOf, hasAnyOf, hasConst, hasEnum, hasExclusiveMaximum, hasExclusiveMinimum, hasItems, hasMaxItems, hasMaximum, hasMaxLength, hasMaxProperties, hasMinItems, hasMinimum, hasMinLength, hasMinProperties, hasMultipleOf, hasOneOf, hasPattern, hasProperties, hasRef, hasRequired, hasType, hasUniqueItems, isSchemaObject, } from '@amritk/helpers/schema-guards';
|
|
6
6
|
import { findDiscriminator } from '../helpers/find-discriminator.js';
|
|
7
|
+
import { getDefaultValue } from '../helpers/get-default-value.js';
|
|
7
8
|
import { generateDiscriminatedUnionValidation } from './generate-discriminated-union-validation.js';
|
|
8
9
|
import { generateEnumCheck } from './generate-enum-check.js';
|
|
9
10
|
import { generateNonDiscriminatedUnionValidation } from './generate-non-discriminated-union-validation.js';
|
|
@@ -19,6 +20,29 @@ const getInstanceCoercion = (accessor, instanceOf) => {
|
|
|
19
20
|
return `new Date(${accessor} as string | number | Date)`;
|
|
20
21
|
return null;
|
|
21
22
|
};
|
|
23
|
+
/**
|
|
24
|
+
* A boolean type check for an array element whose schema is a single scalar type
|
|
25
|
+
* (the cases the element coercion below can handle). `integer` is treated as
|
|
26
|
+
* `number` because the generated TS element type is `number`. Returns `null` for
|
|
27
|
+
* objects, arrays, unions, `$ref`s, and anything richer.
|
|
28
|
+
*/
|
|
29
|
+
export const scalarItemTypeCheck = (itemSchema, accessor) => {
|
|
30
|
+
if (!isSchemaObject(itemSchema) || !hasType(itemSchema) || hasEnum(itemSchema))
|
|
31
|
+
return null;
|
|
32
|
+
switch (itemSchema.type) {
|
|
33
|
+
case 'string':
|
|
34
|
+
return `typeof ${accessor} === "string"`;
|
|
35
|
+
case 'number':
|
|
36
|
+
case 'integer':
|
|
37
|
+
return `typeof ${accessor} === "number"`;
|
|
38
|
+
case 'boolean':
|
|
39
|
+
return `typeof ${accessor} === "boolean"`;
|
|
40
|
+
case 'null':
|
|
41
|
+
return `${accessor} === null`;
|
|
42
|
+
default:
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
};
|
|
22
46
|
/**
|
|
23
47
|
* Generates a type coercion expression for converting a value to the expected type.
|
|
24
48
|
*/
|
|
@@ -41,7 +65,9 @@ const getTypeCoercion = (accessor, schema, defaultValue) => {
|
|
|
41
65
|
case 'array':
|
|
42
66
|
return `[]`;
|
|
43
67
|
case 'object':
|
|
44
|
-
|
|
68
|
+
// Fall back to the schema's default (which fills required properties)
|
|
69
|
+
// rather than a bare `{}`, so a coerced object is a valid instance.
|
|
70
|
+
return `typeof ${accessor} === "object" && ${accessor} !== null ? ${accessor} : ${defaultValue}`;
|
|
45
71
|
default:
|
|
46
72
|
return null;
|
|
47
73
|
}
|
|
@@ -148,6 +174,20 @@ export const generateValidationExpression = (key, schema, defaultValue, isRequir
|
|
|
148
174
|
if (!hasType(schema) && !hasEnum(schema)) {
|
|
149
175
|
return `${accessor} ?? ${defaultValue}`;
|
|
150
176
|
}
|
|
177
|
+
// An array of scalar items: coerce each element so e.g. `number[]` actually
|
|
178
|
+
// contains numbers. The fast path only takes a well-typed array, so a mistyped
|
|
179
|
+
// element reaches here. ($ref items use the caller's validateArray path;
|
|
180
|
+
// object/union items still pass through.)
|
|
181
|
+
if (hasType(schema) &&
|
|
182
|
+
schema.type === 'array' &&
|
|
183
|
+
hasItems(schema) &&
|
|
184
|
+
!Array.isArray(schema.items) &&
|
|
185
|
+
scalarItemTypeCheck(schema.items, '_it') !== null) {
|
|
186
|
+
const itemSchema = schema.items;
|
|
187
|
+
const itemExpr = generateValidationExpression('', itemSchema, getDefaultValue(itemSchema), true, rootSchema, visitedRefs, '_it', true);
|
|
188
|
+
const mapped = `(Array.isArray(${accessor}) ? (${accessor} as unknown[]).map((_it) => ${itemExpr}) : ${defaultValue})`;
|
|
189
|
+
return isRequired ? mapped : `(${accessor} !== undefined ? ${mapped} : undefined)`;
|
|
190
|
+
}
|
|
151
191
|
// Build type-specific checks
|
|
152
192
|
if (hasType(schema)) {
|
|
153
193
|
switch (schema.type) {
|
|
@@ -187,6 +227,9 @@ export const generateValidationExpression = (key, schema, defaultValue, isRequir
|
|
|
187
227
|
case 'boolean':
|
|
188
228
|
checks.push(`typeof ${accessor} === "boolean"`);
|
|
189
229
|
break;
|
|
230
|
+
case 'null':
|
|
231
|
+
checks.push(`${accessor} === null`);
|
|
232
|
+
break;
|
|
190
233
|
case 'array': {
|
|
191
234
|
checks.push(`Array.isArray(${accessor})`);
|
|
192
235
|
if (hasMinItems(schema)) {
|
|
@@ -241,7 +284,12 @@ export const generateValidationExpression = (key, schema, defaultValue, isRequir
|
|
|
241
284
|
// Generate the fallback value
|
|
242
285
|
// If the value exists but fails validation, try to coerce it
|
|
243
286
|
// If the value is missing and required, use the default
|
|
244
|
-
|
|
287
|
+
//
|
|
288
|
+
// `enum` constrains the value to a fixed set, so type coercion (e.g.
|
|
289
|
+
// `String(x)`) can't rescue a non-member — `String("z")` is still not in the
|
|
290
|
+
// enum. Fall back to the default (the first enum value) so the result is always
|
|
291
|
+
// a valid member of the declared literal-union type.
|
|
292
|
+
const typeCoercion = hasEnum(schema) ? null : getTypeCoercion(accessor, schema, defaultValue);
|
|
245
293
|
if (isRequired) {
|
|
246
294
|
// For required fields: valid ? use_value : (exists ? coerce : default)
|
|
247
295
|
if (typeCoercion) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { getMjstPrimitive } from '@amritk/helpers/mjst-extension';
|
|
2
|
-
import { hasAllOf, hasAnyOf, hasDefault, hasEnum, hasExamples, hasOneOf, hasPattern, hasType, isSchemaObject, } from '@amritk/helpers/schema-guards';
|
|
2
|
+
import { hasAllOf, hasAnyOf, hasConst, hasDefault, hasEnum, hasExamples, hasOneOf, hasPattern, hasProperties, hasRequired, hasType, isSchemaObject, } from '@amritk/helpers/schema-guards';
|
|
3
3
|
import { generateDefaultFromPattern } from '../generators/generate-default-from-pattern.js';
|
|
4
4
|
/**
|
|
5
5
|
* Returns the default value for a JSON Schema property.
|
|
@@ -14,6 +14,10 @@ export const getDefaultValue = (schema) => {
|
|
|
14
14
|
if (hasDefault(schema)) {
|
|
15
15
|
return JSON.stringify(schema.default);
|
|
16
16
|
}
|
|
17
|
+
// A `const` value is the only valid value, so it is also the default.
|
|
18
|
+
if (hasConst(schema)) {
|
|
19
|
+
return JSON.stringify(schema.const);
|
|
20
|
+
}
|
|
17
21
|
// Use first enum value if available
|
|
18
22
|
if (hasEnum(schema) && schema.enum.length > 0) {
|
|
19
23
|
return JSON.stringify(schema.enum[0]);
|
|
@@ -64,10 +68,28 @@ export const getDefaultValue = (schema) => {
|
|
|
64
68
|
return '0';
|
|
65
69
|
case 'boolean':
|
|
66
70
|
return 'false';
|
|
71
|
+
case 'null':
|
|
72
|
+
return 'null';
|
|
67
73
|
case 'array':
|
|
68
74
|
return '[]';
|
|
69
|
-
case 'object':
|
|
75
|
+
case 'object': {
|
|
76
|
+
// A bare `{}` omits required properties, leaving the default invalid against
|
|
77
|
+
// its own type. Populate each required property with its own default so the
|
|
78
|
+
// fallback object is itself a valid instance.
|
|
79
|
+
if (hasProperties(schema) && hasRequired(schema)) {
|
|
80
|
+
const props = schema.properties;
|
|
81
|
+
const required = schema.required.filter((key) => Object.hasOwn(props, key));
|
|
82
|
+
const defaults = required.map((key) => getDefaultValue(props[key]));
|
|
83
|
+
// A required property whose schema has no concrete default (a `$ref` we
|
|
84
|
+
// can't resolve here, or a type-less schema) would otherwise emit
|
|
85
|
+
// `"key": undefined` — i.e. a *missing* required key. Don't build a
|
|
86
|
+
// partial object with holes; fall back to a bare `{}` for the whole node.
|
|
87
|
+
if (defaults.length > 0 && !defaults.includes('undefined')) {
|
|
88
|
+
return `{ ${required.map((key, i) => `${JSON.stringify(key)}: ${defaults[i]}`).join(', ')} }`;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
70
91
|
return '{}';
|
|
92
|
+
}
|
|
71
93
|
default:
|
|
72
94
|
return 'undefined';
|
|
73
95
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@amritk/generate-parsers",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.12.1",
|
|
4
4
|
"description": "Generate TypeScript parsers and type definitions from JSON Schemas.",
|
|
5
5
|
"module": "./dist/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -48,11 +48,12 @@
|
|
|
48
48
|
},
|
|
49
49
|
"dependencies": {
|
|
50
50
|
"json-schema-typed": "^8.0.1",
|
|
51
|
-
"@amritk/helpers": "0.10.
|
|
52
|
-
"@amritk/generate-markdown": "0.
|
|
51
|
+
"@amritk/helpers": "0.10.1",
|
|
52
|
+
"@amritk/generate-markdown": "0.3.0"
|
|
53
53
|
},
|
|
54
54
|
"devDependencies": {
|
|
55
55
|
"@sinclair/typebox": "^0.34.49",
|
|
56
|
+
"ajv": "^8.17.1",
|
|
56
57
|
"zod": "^4.4.3"
|
|
57
58
|
}
|
|
58
59
|
}
|