@amritk/mjst 0.5.1 → 0.7.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/dist/cli.js CHANGED
@@ -2,8 +2,8 @@
2
2
 
3
3
  // src/cli.ts
4
4
  import { execFile } from "node:child_process";
5
- import { mkdir, readFile as readFile3, unlink, writeFile } from "node:fs/promises";
6
- import { dirname as dirname2, join as join8, resolve as resolve3 } from "node:path";
5
+ import { mkdir, readdir, readFile as readFile4, unlink, writeFile } from "node:fs/promises";
6
+ import { basename, dirname as dirname2, join as join8, relative, resolve as resolve3, sep } from "node:path";
7
7
  import { promisify } from "node:util";
8
8
 
9
9
  // ../adapters/dist/get-adapter.js
@@ -89888,15 +89888,15 @@ var refToFilename2 = (ref) => {
89888
89888
  }
89889
89889
  return filename;
89890
89890
  };
89891
- var kebabToPascal = (kebab) => {
89891
+ var kebabToPascal = (kebab, suffix) => {
89892
89892
  const words = kebab.split("-");
89893
89893
  let pascalCase = "";
89894
89894
  for (const word of words) {
89895
89895
  pascalCase += word.charAt(0).toUpperCase() + word.slice(1);
89896
89896
  }
89897
- return pascalCase + "Object";
89897
+ return pascalCase + suffix;
89898
89898
  };
89899
- var refToName = (ref) => kebabToPascal(refToFilename2(ref));
89899
+ var refToName = (ref, suffix = "") => kebabToPascal(refToFilename2(ref), suffix);
89900
89900
  var resolveDynamicRefs = (schema, dynamicRefMap) => {
89901
89901
  if (typeof schema !== "object" || schema === null) {
89902
89902
  return schema;
@@ -90180,15 +90180,15 @@ var refToFilename4 = (ref) => {
90180
90180
  }
90181
90181
  return filename;
90182
90182
  };
90183
- var kebabToPascal2 = (kebab) => {
90183
+ var kebabToPascal2 = (kebab, suffix) => {
90184
90184
  const words = kebab.split("-");
90185
90185
  let pascalCase = "";
90186
90186
  for (const word of words) {
90187
90187
  pascalCase += word.charAt(0).toUpperCase() + word.slice(1);
90188
90188
  }
90189
- return pascalCase + "Object";
90189
+ return pascalCase + suffix;
90190
90190
  };
90191
- var refToName2 = (ref) => kebabToPascal2(refToFilename4(ref));
90191
+ var refToName2 = (ref, suffix = "") => kebabToPascal2(refToFilename4(ref), suffix);
90192
90192
  var JS_IDENTIFIER = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/;
90193
90193
  var safeKey = (key) => {
90194
90194
  if (JS_IDENTIFIER.test(key)) {
@@ -90281,12 +90281,13 @@ var buildJsDocBlock = (title, description, commentUrl) => {
90281
90281
  `;
90282
90282
  return block;
90283
90283
  };
90284
- var getTypeScriptType = (schema) => {
90285
- const base = getUnbrandedType(schema);
90284
+ var getTypeScriptType = (schema, options = {}) => {
90285
+ const base = getUnbrandedType(schema, options);
90286
90286
  const brand2 = getMjstBrand(schema);
90287
90287
  return brand2 ? `(${base} & { readonly __brand: '${brand2}' })` : base;
90288
90288
  };
90289
- var getUnbrandedType = (schema) => {
90289
+ var recordType = (keyType, valueType, options) => options.readonly ? `Readonly<Record<${keyType}, ${valueType}>>` : `Record<${keyType}, ${valueType}>`;
90290
+ var getUnbrandedType = (schema, options = {}) => {
90290
90291
  if (typeof schema === "boolean") {
90291
90292
  return getBooleanSubSchemaType(schema);
90292
90293
  }
@@ -90305,13 +90306,13 @@ var getUnbrandedType = (schema) => {
90305
90306
  if (!schema.$ref.startsWith("#")) {
90306
90307
  return "unknown";
90307
90308
  }
90308
- return refToName2(schema.$ref);
90309
+ return refToName2(schema.$ref, options.typeSuffix);
90309
90310
  }
90310
90311
  if (schema.$dynamicRef) {
90311
90312
  if (schema.$dynamicRef === "#meta") {
90312
- return "Schema";
90313
+ return `Schema${options.typeSuffix ?? ""}`;
90313
90314
  }
90314
- return refToName2(schema.$dynamicRef);
90315
+ return refToName2(schema.$dynamicRef, options.typeSuffix);
90315
90316
  }
90316
90317
  if (schema.const !== undefined) {
90317
90318
  return JSON.stringify(schema.const);
@@ -90334,51 +90335,51 @@ var getUnbrandedType = (schema) => {
90334
90335
  return multiEnumUnion;
90335
90336
  }
90336
90337
  if (schema.oneOf && Array.isArray(schema.oneOf) && schema.oneOf.length > 0) {
90337
- let oneOfUnion = getTypeScriptType(schema.oneOf[0]);
90338
+ let oneOfUnion = getTypeScriptType(schema.oneOf[0], options);
90338
90339
  for (let i = 1;i < schema.oneOf.length; i++) {
90339
- oneOfUnion += " | " + getTypeScriptType(schema.oneOf[i]);
90340
+ oneOfUnion += " | " + getTypeScriptType(schema.oneOf[i], options);
90340
90341
  }
90341
90342
  return oneOfUnion;
90342
90343
  }
90343
90344
  if (schema.anyOf && Array.isArray(schema.anyOf) && schema.anyOf.length > 0) {
90344
- let anyOfUnion = getTypeScriptType(schema.anyOf[0]);
90345
+ let anyOfUnion = getTypeScriptType(schema.anyOf[0], options);
90345
90346
  for (let i = 1;i < schema.anyOf.length; i++) {
90346
- anyOfUnion += " | " + getTypeScriptType(schema.anyOf[i]);
90347
+ anyOfUnion += " | " + getTypeScriptType(schema.anyOf[i], options);
90347
90348
  }
90348
90349
  return anyOfUnion;
90349
90350
  }
90350
90351
  if (schema.allOf && Array.isArray(schema.allOf) && schema.allOf.length > 0) {
90351
- let intersectionTypes = getTypeScriptType(schema.allOf[0]);
90352
+ let intersectionTypes = getTypeScriptType(schema.allOf[0], options);
90352
90353
  for (let i = 1;i < schema.allOf.length; i++) {
90353
- intersectionTypes += " & " + getTypeScriptType(schema.allOf[i]);
90354
+ intersectionTypes += " & " + getTypeScriptType(schema.allOf[i], options);
90354
90355
  }
90355
90356
  return intersectionTypes;
90356
90357
  }
90357
90358
  const conditionalResult = getConditionalObjectSchema(schema);
90358
90359
  if (conditionalResult) {
90359
- const baseType = getTypeScriptType(conditionalResult.schema);
90360
+ const baseType = getTypeScriptType(conditionalResult.schema, options);
90360
90361
  if (conditionalResult.thenRef) {
90361
- return `(${baseType}) & ${refToName2(conditionalResult.thenRef)}`;
90362
+ return `(${baseType}) & ${refToName2(conditionalResult.thenRef, options.typeSuffix)}`;
90362
90363
  }
90363
90364
  return baseType;
90364
90365
  }
90365
90366
  if (!schema.type) {
90366
90367
  if (schema.additionalProperties !== undefined) {
90367
90368
  if (typeof schema.additionalProperties === "boolean") {
90368
- return `Record<string, ${getBooleanSubSchemaType(schema.additionalProperties)}>`;
90369
+ return recordType("string", getBooleanSubSchemaType(schema.additionalProperties), options);
90369
90370
  }
90370
- return `Record<string, ${getTypeScriptType(schema.additionalProperties)}>`;
90371
+ return recordType("string", getTypeScriptType(schema.additionalProperties, options), options);
90371
90372
  }
90372
90373
  if (schema.patternProperties && typeof schema.patternProperties === "object") {
90373
90374
  const firstEntry = Object.entries(schema.patternProperties)[0];
90374
90375
  if (firstEntry) {
90375
90376
  const [pattern2, value10] = firstEntry;
90376
90377
  if (value10 !== undefined) {
90377
- const valueType = typeof value10 === "boolean" ? getBooleanSubSchemaType(value10) : getTypeScriptType(value10);
90378
+ const valueType = typeof value10 === "boolean" ? getBooleanSubSchemaType(value10) : getTypeScriptType(value10, options);
90378
90379
  if (pattern2 === "^x-") {
90379
- return `Record<\`x-\${string}\`, ${valueType}>`;
90380
+ return recordType("`x-${string}`", valueType, options);
90380
90381
  }
90381
- return `Record<string, ${valueType}>`;
90382
+ return recordType("string", valueType, options);
90382
90383
  }
90383
90384
  }
90384
90385
  }
@@ -90431,41 +90432,42 @@ var getUnbrandedType = (schema) => {
90431
90432
  return "boolean";
90432
90433
  case "array":
90433
90434
  if (schema.items) {
90434
- const itemType = getTypeScriptType(schema.items);
90435
+ const itemType = getTypeScriptType(schema.items, options);
90435
90436
  const wrappedItemType = itemType.includes(" | ") ? `(${itemType})` : itemType;
90436
- return `${wrappedItemType}[]`;
90437
+ return options.readonly ? `readonly ${wrappedItemType}[]` : `${wrappedItemType}[]`;
90437
90438
  }
90438
- return "unknown[]";
90439
+ return options.readonly ? "readonly unknown[]" : "unknown[]";
90439
90440
  case "object":
90440
90441
  if (schema.properties) {
90442
+ const readonlyPrefix = options.readonly ? "readonly " : "";
90441
90443
  let properties = "";
90442
90444
  let first5 = true;
90443
90445
  for (const key in schema.properties) {
90444
90446
  const propSchema = schema.properties[key];
90445
90447
  const isRequired = schema.required?.includes(key) ?? false;
90446
90448
  const optional3 = isRequired ? "" : "?";
90447
- const propType = getTypeScriptType(propSchema);
90449
+ const propType = getTypeScriptType(propSchema, options);
90448
90450
  if (!first5)
90449
90451
  properties += "; ";
90450
- properties += safeKey(key) + optional3 + ": " + propType;
90452
+ properties += readonlyPrefix + safeKey(key) + optional3 + ": " + propType;
90451
90453
  first5 = false;
90452
90454
  }
90453
90455
  return "{ " + properties + " }";
90454
90456
  }
90455
90457
  if (schema.additionalProperties && typeof schema.additionalProperties === "object") {
90456
- const additionalPropType = getTypeScriptType(schema.additionalProperties);
90457
- return `Record<string, ${additionalPropType}>`;
90458
+ const additionalPropType = getTypeScriptType(schema.additionalProperties, options);
90459
+ return recordType("string", additionalPropType, options);
90458
90460
  }
90459
90461
  if (schema.patternProperties && typeof schema.patternProperties === "object") {
90460
90462
  const firstEntry = Object.entries(schema.patternProperties)[0];
90461
90463
  if (firstEntry) {
90462
90464
  const [pattern2, patternVal] = firstEntry;
90463
90465
  if (patternVal) {
90464
- const valueType = getTypeScriptType(patternVal);
90466
+ const valueType = getTypeScriptType(patternVal, options);
90465
90467
  if (pattern2 === "^x-") {
90466
- return `Record<\`x-\${string}\`, ${valueType}>`;
90468
+ return recordType("`x-${string}`", valueType, options);
90467
90469
  }
90468
- return `Record<string, ${valueType}>`;
90470
+ return recordType("string", valueType, options);
90469
90471
  }
90470
90472
  }
90471
90473
  }
@@ -90474,9 +90476,10 @@ var getUnbrandedType = (schema) => {
90474
90476
  return "unknown";
90475
90477
  }
90476
90478
  };
90477
- var generateTypeDefinition = (schema, typeName) => {
90479
+ var generateTypeDefinition = (schema, typeName, options = {}) => {
90480
+ const readonlyPrefix = options.readonly ? "readonly " : "";
90478
90481
  if (!isObjectLikeSchema(schema)) {
90479
- const tsType = getTypeScriptType(schema);
90482
+ const tsType = getTypeScriptType(schema, options);
90480
90483
  let result = "";
90481
90484
  if (isSchemaObject2(schema) && schema.$comment && typeof schema.$comment === "string") {
90482
90485
  result += buildJsDocBlock(typeName, schema.$comment);
@@ -90504,23 +90507,23 @@ var generateTypeDefinition = (schema, typeName) => {
90504
90507
  if (firstPatternProperty === undefined) {
90505
90508
  return `export type ${typeName} = Record<string, unknown>;`;
90506
90509
  }
90507
- const patternPropType = typeof firstPatternProperty === "boolean" ? getBooleanSubSchemaType(firstPatternProperty) : getTypeScriptType(firstPatternProperty);
90510
+ const patternPropType = typeof firstPatternProperty === "boolean" ? getBooleanSubSchemaType(firstPatternProperty) : getTypeScriptType(firstPatternProperty, options);
90508
90511
  const keyType = firstPattern === "^x-" ? "`x-${string}`" : "string";
90509
90512
  let result2 = "";
90510
90513
  if (jsDocTitle && jsDocDescription) {
90511
90514
  result2 += buildJsDocBlock(jsDocTitle, jsDocDescription);
90512
90515
  }
90513
- result2 += `export type ${typeName} = Record<${keyType}, ${patternPropType}>;`;
90516
+ result2 += `export type ${typeName} = ${recordType(keyType, patternPropType, options)};`;
90514
90517
  return result2;
90515
90518
  }
90516
90519
  if (!hasProperties2 && hasAdditionalProperties2 && normalizedSchema.additionalProperties) {
90517
- const additionalPropType = getTypeScriptType(normalizedSchema.additionalProperties);
90520
+ const additionalPropType = getTypeScriptType(normalizedSchema.additionalProperties, options);
90518
90521
  let result2 = "";
90519
90522
  if (jsDocTitle && jsDocDescription) {
90520
90523
  result2 += buildJsDocBlock(jsDocTitle, jsDocDescription);
90521
90524
  }
90522
90525
  result2 += `export type ${typeName} = {
90523
- [key: string]: ${additionalPropType};
90526
+ ${readonlyPrefix}[key: string]: ${additionalPropType};
90524
90527
  };`;
90525
90528
  return result2;
90526
90529
  }
@@ -90531,8 +90534,8 @@ var generateTypeDefinition = (schema, typeName) => {
90531
90534
  const propSchema = schemaProps[key];
90532
90535
  const isRequired = normalizedSchema.required?.includes(key) ?? false;
90533
90536
  const optional3 = isRequired ? "" : "?";
90534
- const propType = getTypeScriptType(propSchema);
90535
- const quotedKey = safeKey(key);
90537
+ const propType = getTypeScriptType(propSchema, options);
90538
+ const quotedKey = readonlyPrefix + safeKey(key);
90536
90539
  if (!isFirstProp)
90537
90540
  properties += `
90538
90541
  `;
@@ -90549,12 +90552,12 @@ var generateTypeDefinition = (schema, typeName) => {
90549
90552
  if (isSchemaObject2(schema) && Array.isArray(schema.allOf)) {
90550
90553
  for (const entry of schema.allOf) {
90551
90554
  if (isSchemaObject2(entry) && entry.$ref) {
90552
- allOfIntersections.push(refToName2(entry.$ref));
90555
+ allOfIntersections.push(refToName2(entry.$ref, options.typeSuffix));
90553
90556
  }
90554
90557
  }
90555
90558
  }
90556
90559
  if (isSchemaObject2(schema) && typeof schema.$ref === "string" && schema.$ref.startsWith("#")) {
90557
- allOfIntersections.push(refToName2(schema.$ref));
90560
+ allOfIntersections.push(refToName2(schema.$ref, options.typeSuffix));
90558
90561
  }
90559
90562
  let result = "";
90560
90563
  if (jsDocTitle && jsDocDescription) {
@@ -90564,7 +90567,7 @@ var generateTypeDefinition = (schema, typeName) => {
90564
90567
  ` + properties + `
90565
90568
  }`;
90566
90569
  if (conditionalThenRef) {
90567
- typeBody += " & " + refToName2(conditionalThenRef);
90570
+ typeBody += " & " + refToName2(conditionalThenRef, options.typeSuffix);
90568
90571
  }
90569
90572
  for (const intersectionType of allOfIntersections) {
90570
90573
  typeBody += " & " + intersectionType;
@@ -90580,31 +90583,32 @@ var PACKAGE_IMPORTS = {
90580
90583
  "validate-record": "import { validateRecord } from '@amritk/helpers/validate-record';",
90581
90584
  "has-ref": "import { hasRef } from '@amritk/helpers/schema-guards';"
90582
90585
  };
90583
- var EMBEDDED_IMPORTS = {
90584
- "is-object": "import { isObject } from './_helpers/is-object';",
90585
- "validate-array": "import { validateArray } from './_helpers/validate-array';",
90586
- "validate-record": "import { validateRecord } from './_helpers/validate-record';",
90587
- "has-ref": "import { hasRef } from './_helpers/has-ref';"
90586
+ var EMBEDDED_NAMED_EXPORTS = {
90587
+ "is-object": "isObject",
90588
+ "validate-array": "validateArray",
90589
+ "validate-record": "validateRecord",
90590
+ "has-ref": "hasRef"
90588
90591
  };
90589
- var collectHelpers = (parserFunction, mode) => {
90592
+ var embeddedImport = (helper, prefix) => `import { ${EMBEDDED_NAMED_EXPORTS[helper]} } from '${prefix}_helpers/${helper}';`;
90593
+ var collectHelpers = (parserFunction, mode, helpersImportPrefix = "./") => {
90590
90594
  const imports = [];
90591
90595
  const used = new Set;
90592
- const table3 = mode === "embedded" ? EMBEDDED_IMPORTS : PACKAGE_IMPORTS;
90596
+ const importFor = (helper) => mode === "embedded" ? embeddedImport(helper, helpersImportPrefix) : PACKAGE_IMPORTS[helper];
90593
90597
  if (parserFunction.includes("validateArray")) {
90594
- imports.push(table3["validate-array"]);
90598
+ imports.push(importFor("validate-array"));
90595
90599
  used.add("validate-array");
90596
90600
  }
90597
90601
  if (parserFunction.includes("validateRecord")) {
90598
- imports.push(table3["validate-record"]);
90602
+ imports.push(importFor("validate-record"));
90599
90603
  used.add("validate-record");
90600
90604
  used.add("is-object");
90601
90605
  }
90602
90606
  if (parserFunction.includes("isObject")) {
90603
- imports.push(table3["is-object"]);
90607
+ imports.push(importFor("is-object"));
90604
90608
  used.add("is-object");
90605
90609
  }
90606
90610
  if (parserFunction.includes("hasRef(")) {
90607
- imports.push(table3["has-ref"]);
90611
+ imports.push(importFor("has-ref"));
90608
90612
  used.add("has-ref");
90609
90613
  }
90610
90614
  return { imports, used };
@@ -90698,6 +90702,7 @@ var collectImports = (schema, options) => {
90698
90702
  const typesOnly = options?.typesOnly === true;
90699
90703
  const selfFilename = options?.selfRef ? refToFilename(options.selfRef) : undefined;
90700
90704
  const rootSchema = options?.rootSchema;
90705
+ const typeSuffix = options?.typeSuffix;
90701
90706
  const refs = new Set;
90702
90707
  const collectRefsFromValue = (value10) => {
90703
90708
  if (typeof value10 !== "object" || value10 === null) {
@@ -90825,7 +90830,7 @@ var collectImports = (schema, options) => {
90825
90830
  if (!resolveRef2(ref, rootSchema))
90826
90831
  continue;
90827
90832
  }
90828
- const typeName = refToName(ref);
90833
+ const typeName = refToName(ref, typeSuffix);
90829
90834
  const filename = refToFilename(ref);
90830
90835
  if (selfFilename !== undefined && filename === selfFilename) {
90831
90836
  continue;
@@ -91491,33 +91496,33 @@ var isPropertyRequired = (key, schema) => {
91491
91496
  }
91492
91497
  return schema.required.includes(key);
91493
91498
  };
91494
- var generateRequiredRefCall = (key, ref) => {
91499
+ var generateRequiredRefCall = (key, ref, suffix) => {
91495
91500
  const acc = safeAccessor("input", key);
91496
- const parserName = generateParserName(refToName(ref));
91501
+ const parserName = generateParserName(refToName(ref, suffix));
91497
91502
  return `${parserName}(${acc})`;
91498
91503
  };
91499
- var generateOptionalRefCall = (key, ref) => {
91504
+ var generateOptionalRefCall = (key, ref, suffix) => {
91500
91505
  const acc = safeAccessor("input", key);
91501
- const parserName = generateParserName(refToName(ref));
91506
+ const parserName = generateParserName(refToName(ref, suffix));
91502
91507
  return `...(${acc} && { ${safeKey2(key)}: ${parserName}(${acc}) })`;
91503
91508
  };
91504
- var generateRequiredArrayRefCall = (key, ref) => {
91505
- const parserName = generateParserName(refToName(ref));
91509
+ var generateRequiredArrayRefCall = (key, ref, suffix) => {
91510
+ const parserName = generateParserName(refToName(ref, suffix));
91506
91511
  return `validateArray(${safeAccessor("input", key)}, ${parserName})`;
91507
91512
  };
91508
- var generateOptionalArrayRefCall = (key, ref) => {
91509
- const parserName = generateParserName(refToName(ref));
91513
+ var generateOptionalArrayRefCall = (key, ref, suffix) => {
91514
+ const parserName = generateParserName(refToName(ref, suffix));
91510
91515
  const acc = safeAccessor("input", key);
91511
91516
  return `...(${acc} && { ${safeKey2(key)}: validateArray(${acc}, ${parserName}) })`;
91512
91517
  };
91513
- var generateRequiredRecordRefCall = (key, ref) => {
91518
+ var generateRequiredRecordRefCall = (key, ref, suffix) => {
91514
91519
  const acc = safeAccessor("input", key);
91515
- const parserName = generateParserName(refToName(ref));
91520
+ const parserName = generateParserName(refToName(ref, suffix));
91516
91521
  return `validateRecord(${acc}, ${parserName})`;
91517
91522
  };
91518
- var generateOptionalRecordRefCall = (key, ref) => {
91523
+ var generateOptionalRecordRefCall = (key, ref, suffix) => {
91519
91524
  const acc = safeAccessor("input", key);
91520
- const parserName = generateParserName(refToName(ref));
91525
+ const parserName = generateParserName(refToName(ref, suffix));
91521
91526
  return `...(${acc} && { ${safeKey2(key)}: validateRecord(${acc}, ${parserName}) })`;
91522
91527
  };
91523
91528
  var generateOptionalInlineProperty = (key, valueExpression) => {
@@ -91562,20 +91567,20 @@ var shouldUseRecordRefImport = (propSchema, useRefImports) => {
91562
91567
  const additionalProps = propSchema.additionalProperties;
91563
91568
  return isSchemaObject3(additionalProps) && hasRef(additionalProps);
91564
91569
  };
91565
- var generatePropertyValue = (key, propSchema, isRequired, useRefImports) => {
91570
+ var generatePropertyValue = (key, propSchema, isRequired, useRefImports, suffix) => {
91566
91571
  if (shouldUseRefImport(propSchema, useRefImports)) {
91567
91572
  const ref = propSchema.$ref;
91568
- return isRequired ? generateRequiredRefCall(key, ref) : generateOptionalRefCall(key, ref);
91573
+ return isRequired ? generateRequiredRefCall(key, ref, suffix) : generateOptionalRefCall(key, ref, suffix);
91569
91574
  }
91570
91575
  if (shouldUseArrayRefImport(propSchema, useRefImports)) {
91571
91576
  const items = propSchema.items;
91572
91577
  const ref = items.$ref;
91573
- return isRequired ? generateRequiredArrayRefCall(key, ref) : generateOptionalArrayRefCall(key, ref);
91578
+ return isRequired ? generateRequiredArrayRefCall(key, ref, suffix) : generateOptionalArrayRefCall(key, ref, suffix);
91574
91579
  }
91575
91580
  if (shouldUseRecordRefImport(propSchema, useRefImports)) {
91576
91581
  const additionalProps = propSchema.additionalProperties;
91577
91582
  const ref = additionalProps.$ref;
91578
- return isRequired ? generateRequiredRecordRefCall(key, ref) : generateOptionalRecordRefCall(key, ref);
91583
+ return isRequired ? generateRequiredRecordRefCall(key, ref, suffix) : generateOptionalRecordRefCall(key, ref, suffix);
91579
91584
  }
91580
91585
  if (!isSchemaObject3(propSchema)) {
91581
91586
  return isRequired ? "undefined" : generateOptionalInlineProperty(key, "undefined");
@@ -91584,23 +91589,23 @@ var generatePropertyValue = (key, propSchema, isRequired, useRefImports) => {
91584
91589
  const valueExpression = generateValidationExpression(key, propSchema, defaultValue, isRequired);
91585
91590
  return isRequired ? valueExpression : generateOptionalInlineProperty(key, valueExpression);
91586
91591
  };
91587
- var generatePropertyEntries = (schema, useRefImports) => {
91592
+ var generatePropertyEntries = (schema, useRefImports, suffix) => {
91588
91593
  if (!hasProperties(schema)) {
91589
91594
  return [];
91590
91595
  }
91591
91596
  const entries8 = [];
91592
91597
  for (const [key, propSchema] of Object.entries(schema.properties)) {
91593
91598
  const isRequired = isPropertyRequired(key, schema);
91594
- const value10 = generatePropertyValue(key, propSchema, isRequired, useRefImports);
91599
+ const value10 = generatePropertyValue(key, propSchema, isRequired, useRefImports, suffix);
91595
91600
  const isOptional = value10.startsWith("...");
91596
91601
  entries8.push({ key, value: value10, isOptional });
91597
91602
  }
91598
91603
  return entries8;
91599
91604
  };
91600
- var generateFallbackValue = (_, propSchema, useRefImports) => {
91605
+ var generateFallbackValue = (_, propSchema, useRefImports, suffix) => {
91601
91606
  if (useRefImports && hasRef(propSchema)) {
91602
91607
  const ref = propSchema.$ref;
91603
- const parserName = generateParserName(refToName(ref));
91608
+ const parserName = generateParserName(refToName(ref, suffix));
91604
91609
  return `${parserName}(undefined)`;
91605
91610
  }
91606
91611
  if (useRefImports && isSchemaObject3(propSchema) && propSchema.type === "array" && hasItems(propSchema) && hasRef(propSchema.items)) {
@@ -91643,7 +91648,7 @@ var generateFallbackValue = (_, propSchema, useRefImports) => {
91643
91648
  return "undefined";
91644
91649
  }
91645
91650
  };
91646
- var generateFallbackObject = (schema, useRefImports, typeName) => {
91651
+ var generateFallbackObject = (schema, useRefImports, typeName, suffix) => {
91647
91652
  if (!hasProperties(schema)) {
91648
91653
  return `{} as ${typeName}`;
91649
91654
  }
@@ -91654,7 +91659,7 @@ var generateFallbackObject = (schema, useRefImports, typeName) => {
91654
91659
  for (const [key, propSchema] of Object.entries(schema.properties)) {
91655
91660
  const isRequired = isPropertyRequired(key, schema);
91656
91661
  if (isRequired) {
91657
- const fallbackValue = generateFallbackValue(key, propSchema, useRefImports);
91662
+ const fallbackValue = generateFallbackValue(key, propSchema, useRefImports, suffix);
91658
91663
  if (fallbackValue === "undefined") {
91659
91664
  return `{} as ${typeName}`;
91660
91665
  }
@@ -91722,11 +91727,11 @@ var toVarName = (key) => {
91722
91727
  return `_${safe}`;
91723
91728
  };
91724
91729
  var shapeValidatorName = (typeName) => `validate${typeName}Shape`;
91725
- var generatePropertyTypeCheck = (varName, schema, useRefImports) => {
91730
+ var generatePropertyTypeCheck = (varName, schema, useRefImports, suffix) => {
91726
91731
  if (!isSchemaObject3(schema))
91727
91732
  return null;
91728
91733
  if (useRefImports && hasRef(schema)) {
91729
- const refName = refToName(schema.$ref);
91734
+ const refName = refToName(schema.$ref, suffix);
91730
91735
  return `${shapeValidatorName(refName)}(${varName})`;
91731
91736
  }
91732
91737
  if (hasEnum(schema) || hasOneOf(schema) || hasAnyOf(schema) || hasAllOf(schema) || hasRef(schema) || "not" in schema) {
@@ -91735,7 +91740,7 @@ var generatePropertyTypeCheck = (varName, schema, useRefImports) => {
91735
91740
  if (!hasType(schema))
91736
91741
  return null;
91737
91742
  if (useRefImports && schema.type === "array" && hasItems(schema) && isSchemaObject3(schema.items) && hasRef(schema.items)) {
91738
- const refName = refToName(schema.items.$ref);
91743
+ const refName = refToName(schema.items.$ref, suffix);
91739
91744
  return `Array.isArray(${varName}) && ${varName}.every(${shapeValidatorName(refName)})`;
91740
91745
  }
91741
91746
  const checks = [];
@@ -91796,7 +91801,7 @@ var generatePropertyTypeCheck = (varName, schema, useRefImports) => {
91796
91801
  var shouldCacheVariable = (propSchema, _canFastPath, _useRefImports) => {
91797
91802
  return isSchemaObject3(propSchema);
91798
91803
  };
91799
- var generateObjectParser = (schema, typeName, useRefImports, logWarnings, strict2) => {
91804
+ var generateObjectParser = (schema, typeName, useRefImports, suffix, logWarnings, strict2) => {
91800
91805
  const functionName = generateParserName(typeName);
91801
91806
  if (!hasProperties(schema)) {
91802
91807
  if (strict2) {
@@ -91807,7 +91812,7 @@ var generateObjectParser = (schema, typeName, useRefImports, logWarnings, strict
91807
91812
  }
91808
91813
  return `export const ${functionName} = (input: unknown): ${typeName} => isObject(input) ? input as ${typeName} : {} as ${typeName};`;
91809
91814
  }
91810
- const fallbackObject = generateFallbackObject(schema, useRefImports, typeName);
91815
+ const fallbackObject = generateFallbackObject(schema, useRefImports, typeName, suffix);
91811
91816
  const properties = Object.entries(schema.properties);
91812
91817
  const lines = [];
91813
91818
  lines.push(`export const ${functionName} = (input: unknown): ${typeName} => {`);
@@ -91830,7 +91835,7 @@ var generateObjectParser = (schema, typeName, useRefImports, logWarnings, strict
91830
91835
  if (shouldUseRecordRefImport(propSchema, useRefImports)) {
91831
91836
  canFastPath = false;
91832
91837
  } else {
91833
- const check7 = generatePropertyTypeCheck(varName, propSchema, useRefImports);
91838
+ const check7 = generatePropertyTypeCheck(varName, propSchema, useRefImports, suffix);
91834
91839
  if (check7 === null) {
91835
91840
  canFastPath = false;
91836
91841
  } else {
@@ -91869,7 +91874,7 @@ var generateObjectParser = (schema, typeName, useRefImports, logWarnings, strict
91869
91874
  if (useRefImports && isSchemaObject3(schema) && hasAllOf(schema)) {
91870
91875
  for (const entry of schema.allOf) {
91871
91876
  if (isSchemaObject3(entry) && hasRef(entry)) {
91872
- const parserName = generateParserName(refToName(entry.$ref));
91877
+ const parserName = generateParserName(refToName(entry.$ref, suffix));
91873
91878
  objectLines.push(` ...(${parserName}(input) as Record<string, unknown>),`);
91874
91879
  }
91875
91880
  }
@@ -91879,7 +91884,7 @@ var generateObjectParser = (schema, typeName, useRefImports, logWarnings, strict
91879
91884
  const accessor = shouldCache ? varName : safeAccessor("input", key);
91880
91885
  if (shouldUseRefImport(propSchema, useRefImports)) {
91881
91886
  const ref = propSchema.$ref;
91882
- const parserName = generateParserName(refToName(ref));
91887
+ const parserName = generateParserName(refToName(ref, suffix));
91883
91888
  if (isRequired) {
91884
91889
  objectLines.push(` ${safeKey2(key)}: ${parserName}(${accessor}),`);
91885
91890
  } else {
@@ -91890,7 +91895,7 @@ var generateObjectParser = (schema, typeName, useRefImports, logWarnings, strict
91890
91895
  if (shouldUseArrayRefImport(propSchema, useRefImports)) {
91891
91896
  const items = propSchema.items;
91892
91897
  const ref = items.$ref;
91893
- const parserName = generateParserName(refToName(ref));
91898
+ const parserName = generateParserName(refToName(ref, suffix));
91894
91899
  if (isRequired) {
91895
91900
  objectLines.push(` ${safeKey2(key)}: validateArray(${accessor}, ${parserName}),`);
91896
91901
  } else {
@@ -91901,7 +91906,7 @@ var generateObjectParser = (schema, typeName, useRefImports, logWarnings, strict
91901
91906
  if (shouldUseRecordRefImport(propSchema, useRefImports)) {
91902
91907
  const additionalProps = propSchema.additionalProperties;
91903
91908
  const ref = additionalProps.$ref;
91904
- const parserName = generateParserName(refToName(ref));
91909
+ const parserName = generateParserName(refToName(ref, suffix));
91905
91910
  if (isRequired) {
91906
91911
  objectLines.push(` ${safeKey2(key)}: validateRecord(${accessor}, ${parserName}),`);
91907
91912
  } else {
@@ -91940,9 +91945,9 @@ var generateObjectParser = (schema, typeName, useRefImports, logWarnings, strict
91940
91945
  }
91941
91946
  return result;
91942
91947
  };
91943
- var generateCombinedObjectParser = (schema, typeName, useRefImports, logWarnings, strict2) => {
91948
+ var generateCombinedObjectParser = (schema, typeName, useRefImports, suffix, logWarnings, strict2) => {
91944
91949
  const functionName = generateParserName(typeName);
91945
- const entries8 = generatePropertyEntries(schema, useRefImports);
91950
+ const entries8 = generatePropertyEntries(schema, useRefImports, suffix);
91946
91951
  const propertyLines = entries8.map((entry) => {
91947
91952
  if (entry.isOptional) {
91948
91953
  return ` ${entry.value},`;
@@ -91950,17 +91955,17 @@ var generateCombinedObjectParser = (schema, typeName, useRefImports, logWarnings
91950
91955
  return ` ${safeKey2(entry.key)}: ${entry.value},`;
91951
91956
  });
91952
91957
  if (!isSchemaObject3(schema) || !("patternProperties" in schema)) {
91953
- return generateObjectParser(schema, typeName, useRefImports, logWarnings, strict2);
91958
+ return generateObjectParser(schema, typeName, useRefImports, suffix, logWarnings, strict2);
91954
91959
  }
91955
91960
  const patternProps = schema.patternProperties;
91956
91961
  const patterns = Object.entries(patternProps);
91957
91962
  const refPattern = patterns.find(([, ps]) => isSchemaObject3(ps) && hasRef(ps));
91958
91963
  if (!refPattern || !useRefImports) {
91959
- return generateObjectParser(schema, typeName, useRefImports, logWarnings, strict2);
91964
+ return generateObjectParser(schema, typeName, useRefImports, suffix, logWarnings, strict2);
91960
91965
  }
91961
91966
  const [pattern2, patternSchema] = refPattern;
91962
91967
  const ref = patternSchema.$ref;
91963
- const parserName = generateParserName(refToName(ref));
91968
+ const parserName = generateParserName(refToName(ref, suffix));
91964
91969
  const assignmentCode = `(result as Record<string, unknown>)[key] = ${parserName}(value);`;
91965
91970
  const escapedPattern = escapeRegexPattern2(pattern2);
91966
91971
  const inputSpread = " ...input,";
@@ -91988,7 +91993,7 @@ ${objectProperties}
91988
91993
  return result;
91989
91994
  };`;
91990
91995
  };
91991
- var generateAdditionalPropertiesParser = (schema, typeName, useRefImports, strict2) => {
91996
+ var generateAdditionalPropertiesParser = (schema, typeName, useRefImports, suffix, strict2) => {
91992
91997
  const functionName = generateParserName(typeName);
91993
91998
  const additionalProps = schema.additionalProperties;
91994
91999
  if (!additionalProps) {
@@ -91996,7 +92001,7 @@ var generateAdditionalPropertiesParser = (schema, typeName, useRefImports, stric
91996
92001
  }
91997
92002
  if (useRefImports && isSchemaObject3(additionalProps) && hasRef(additionalProps)) {
91998
92003
  const ref = additionalProps.$ref;
91999
- const parserName = generateParserName(refToName(ref));
92004
+ const parserName = generateParserName(refToName(ref, suffix));
92000
92005
  if (strict2) {
92001
92006
  return `export const ${functionName} = (input: unknown): ${typeName} => {
92002
92007
  if (!isObject(input)) throw new Error(\`[${typeName}] expected object, got \${input === null ? "null" : typeof input}\`);
@@ -92046,7 +92051,7 @@ var generateInlineValueParser = (schema) => {
92046
92051
  var escapeRegexPattern2 = (pattern2) => {
92047
92052
  return pattern2.replace(/\\/g, "\\\\").replace(/\//g, "\\/");
92048
92053
  };
92049
- var generatePatternPropertiesParser = (schema, typeName, useRefImports, strict2) => {
92054
+ var generatePatternPropertiesParser = (schema, typeName, useRefImports, suffix, strict2) => {
92050
92055
  const functionName = generateParserName(typeName);
92051
92056
  if (!("patternProperties" in schema) || typeof schema.patternProperties !== "object") {
92052
92057
  return generateEmptyObjectParser(typeName, strict2);
@@ -92060,7 +92065,7 @@ var generatePatternPropertiesParser = (schema, typeName, useRefImports, strict2)
92060
92065
  let patternAssignment = "(result as Record<string, unknown>)[key] = value;";
92061
92066
  if (useRefImports && isSchemaObject3(patternSchema) && hasRef(patternSchema)) {
92062
92067
  const ref = patternSchema.$ref;
92063
- const parserName = generateParserName(refToName(ref));
92068
+ const parserName = generateParserName(refToName(ref, suffix));
92064
92069
  patternAssignment = `(result as Record<string, unknown>)[key] = ${parserName}(value);`;
92065
92070
  } else if (patternSchema === false) {
92066
92071
  patternAssignment = "";
@@ -92083,7 +92088,7 @@ ${notObjectBranch}
92083
92088
  return result;
92084
92089
  };`;
92085
92090
  };
92086
- var generateConditionalParser = (schema, typeName) => {
92091
+ var generateConditionalParser = (schema, typeName, suffix) => {
92087
92092
  const functionName = generateParserName(typeName);
92088
92093
  const ifSchema = schema.if;
92089
92094
  const thenSchema = schema.then;
@@ -92093,7 +92098,7 @@ var generateConditionalParser = (schema, typeName) => {
92093
92098
  if (!thenHasRef || !elseHasRef) {
92094
92099
  const mergedSchema = getConditionalObjectSchema2(schema);
92095
92100
  if (mergedSchema) {
92096
- return generateObjectParser(mergedSchema, typeName, false);
92101
+ return generateObjectParser(mergedSchema, typeName, false, suffix);
92097
92102
  }
92098
92103
  return generateEmptyObjectParser(typeName);
92099
92104
  }
@@ -92101,15 +92106,15 @@ var generateConditionalParser = (schema, typeName) => {
92101
92106
  if (!isRefCondition) {
92102
92107
  const mergedSchema = getConditionalObjectSchema2(schema);
92103
92108
  if (mergedSchema) {
92104
- return generateObjectParser(mergedSchema, typeName, false);
92109
+ return generateObjectParser(mergedSchema, typeName, false, suffix);
92105
92110
  }
92106
92111
  return generateEmptyObjectParser(typeName);
92107
92112
  }
92108
92113
  const thenRef = thenSchema.$ref;
92109
92114
  const elseRef = elseSchema.$ref;
92110
- const thenParserName = generateParserName(refToName(thenRef));
92111
- const elseParserName = generateParserName(refToName(elseRef));
92112
- const thenTypeName = refToName(thenRef);
92115
+ const thenParserName = generateParserName(refToName(thenRef, suffix));
92116
+ const elseParserName = generateParserName(refToName(elseRef, suffix));
92117
+ const thenTypeName = refToName(thenRef, suffix);
92113
92118
  return `export const ${functionName} = (input: unknown): ${typeName} | ${thenTypeName} =>
92114
92119
  hasRef(input) ? ${thenParserName}(input) : ${elseParserName}(input)
92115
92120
  `;
@@ -92182,7 +92187,8 @@ var selectParserStrategy = (schema, typeName, options) => {
92182
92187
  const useRefImports = options?.useRefImports ?? false;
92183
92188
  const logWarnings = options?.logWarnings ?? false;
92184
92189
  const strict2 = options?.strict ?? false;
92185
- if (typeName === "SchemaObject") {
92190
+ const suffix = options?.typeSuffix ?? "";
92191
+ if (typeName === `Schema${suffix}`) {
92186
92192
  return generateSchemaObjectParser(typeName);
92187
92193
  }
92188
92194
  const isObjectLikeSchema2 = isObjectSchema2(schema) || isSchemaObject3(schema) && (("patternProperties" in schema) || ("additionalProperties" in schema));
@@ -92190,30 +92196,30 @@ var selectParserStrategy = (schema, typeName, options) => {
92190
92196
  return generateNonObjectParser(typeName, schema, strict2);
92191
92197
  }
92192
92198
  if (hasProperties(schema) && isSchemaObject3(schema) && "patternProperties" in schema) {
92193
- return generateCombinedObjectParser(schema, typeName, useRefImports, logWarnings, strict2);
92199
+ return generateCombinedObjectParser(schema, typeName, useRefImports, suffix, logWarnings, strict2);
92194
92200
  }
92195
92201
  if (hasProperties(schema)) {
92196
- return generateObjectParser(schema, typeName, useRefImports, logWarnings, strict2);
92202
+ return generateObjectParser(schema, typeName, useRefImports, suffix, logWarnings, strict2);
92197
92203
  }
92198
92204
  if (isSchemaObject3(schema) && "if" in schema && "then" in schema && "else" in schema) {
92199
- return generateConditionalParser(schema, typeName);
92205
+ return generateConditionalParser(schema, typeName, suffix);
92200
92206
  }
92201
92207
  const conditionalObjectSchema = getConditionalObjectSchema2(schema);
92202
92208
  if (conditionalObjectSchema) {
92203
- return generateObjectParser(conditionalObjectSchema, typeName, useRefImports, logWarnings, strict2);
92209
+ return generateObjectParser(conditionalObjectSchema, typeName, useRefImports, suffix, logWarnings, strict2);
92204
92210
  }
92205
92211
  if (!isObjectLikeSchema2) {
92206
92212
  return generateNonObjectParser(typeName, schema, strict2);
92207
92213
  }
92208
92214
  if ("patternProperties" in schema) {
92209
- return generatePatternPropertiesParser(schema, typeName, useRefImports, strict2);
92215
+ return generatePatternPropertiesParser(schema, typeName, useRefImports, suffix, strict2);
92210
92216
  }
92211
92217
  if ("additionalProperties" in schema && !hasProperties(schema)) {
92212
92218
  const additionalProps = schema.additionalProperties;
92213
92219
  if (additionalProps === true || additionalProps === false) {
92214
92220
  return generateEmptyObjectParser(typeName, strict2);
92215
92221
  }
92216
- return generateAdditionalPropertiesParser(schema, typeName, useRefImports, strict2);
92222
+ return generateAdditionalPropertiesParser(schema, typeName, useRefImports, suffix, strict2);
92217
92223
  }
92218
92224
  if ("type" in schema && schema.type === "object" && !hasProperties(schema)) {
92219
92225
  return generateEmptyObjectParser(typeName, strict2);
@@ -92223,7 +92229,7 @@ var selectParserStrategy = (schema, typeName, options) => {
92223
92229
  var generateParserFunction = (schema, typeName, options) => {
92224
92230
  return selectParserStrategy(schema, typeName, options);
92225
92231
  };
92226
- var generateShapeValidator = (schema, typeName, useRefImports) => {
92232
+ var generateShapeValidator = (schema, typeName, useRefImports, suffix = "") => {
92227
92233
  const fnName = shapeValidatorName(typeName);
92228
92234
  const stub = `export const ${fnName} = (_input: unknown): boolean => false;`;
92229
92235
  if (!isSchemaObject3(schema))
@@ -92241,7 +92247,7 @@ var generateShapeValidator = (schema, typeName, useRefImports) => {
92241
92247
  }
92242
92248
  const accessor = safeAccessor("input", key);
92243
92249
  const isRequired = isPropertyRequired(key, schema);
92244
- const check7 = generatePropertyTypeCheck(accessor, propSchema, useRefImports);
92250
+ const check7 = generatePropertyTypeCheck(accessor, propSchema, useRefImports, suffix);
92245
92251
  if (check7 === null) {
92246
92252
  return stub;
92247
92253
  }
@@ -92269,9 +92275,10 @@ var generateFile = (schema, typeName, options) => {
92269
92275
  const selfRef = options?.selfRef;
92270
92276
  const rootSchema = options?.rootSchema;
92271
92277
  const helpersMode = options?.helpersMode ?? "package";
92272
- const typeDefinition = generateTypeDefinition(schema, typeName);
92278
+ const typeSuffix = options?.typeSuffix ?? "";
92279
+ const typeDefinition = generateTypeDefinition(schema, typeName, { readonly: options?.readonly ?? false, typeSuffix });
92273
92280
  if (typesOnly) {
92274
- const imports2 = collectImports(schema, { typesOnly: true, selfRef, rootSchema });
92281
+ const imports2 = collectImports(schema, { typesOnly: true, selfRef, rootSchema, typeSuffix });
92275
92282
  let result2 = "";
92276
92283
  if (imports2.length > 0) {
92277
92284
  result2 += imports2[0];
@@ -92287,15 +92294,16 @@ var generateFile = (schema, typeName, options) => {
92287
92294
  }
92288
92295
  const parserFunction = generateParserFunction(schema, typeName, {
92289
92296
  useRefImports: true,
92297
+ typeSuffix,
92290
92298
  ...options?.logWarnings !== undefined ? { logWarnings: options.logWarnings } : {},
92291
92299
  ...options?.strict !== undefined ? { strict: options.strict } : {}
92292
92300
  });
92293
- const shapeValidator = generateShapeValidator(schema, typeName, true);
92301
+ const shapeValidator = generateShapeValidator(schema, typeName, true, typeSuffix);
92294
92302
  const combinedFunctions = `${shapeValidator}
92295
92303
 
92296
92304
  ${parserFunction}`;
92297
- const helpers = collectHelpers(combinedFunctions, helpersMode);
92298
- const imports = [...collectImports(schema, { selfRef, rootSchema }), ...helpers.imports];
92305
+ const helpers = collectHelpers(combinedFunctions, helpersMode, options?.helpersImportPrefix);
92306
+ const imports = [...collectImports(schema, { selfRef, rootSchema, typeSuffix }), ...helpers.imports];
92299
92307
  let result = "";
92300
92308
  if (imports.length > 0) {
92301
92309
  result += imports[0];
@@ -92336,7 +92344,7 @@ var extractDynamicAnchorDefs = (schema) => {
92336
92344
  }
92337
92345
  return refs;
92338
92346
  };
92339
- var buildSchema = async (rootSchema, rootTypeName, extensions, typesOnly, logWarnings, strict2, helpersMode = "package") => {
92347
+ var buildSchema = async (rootSchema, rootTypeName, extensions, typesOnly, logWarnings, strict2, helpersMode = "package", helpersImportPrefix = "./", readonly2 = false, typeSuffix = "") => {
92340
92348
  rootSchema = upgradeDraft07Schema(rootSchema);
92341
92349
  const files = [];
92342
92350
  const processedRefs = new Set;
@@ -92350,6 +92358,9 @@ var buildSchema = async (rootSchema, rootTypeName, extensions, typesOnly, logWar
92350
92358
  typesOnly: typesOnly ?? false,
92351
92359
  rootSchema,
92352
92360
  helpersMode,
92361
+ helpersImportPrefix,
92362
+ readonly: readonly2,
92363
+ typeSuffix,
92353
92364
  ...logWarnings !== undefined ? { logWarnings } : {},
92354
92365
  ...strict2 !== undefined ? { strict: strict2 } : {}
92355
92366
  });
@@ -92376,7 +92387,7 @@ var buildSchema = async (rootSchema, rootTypeName, extensions, typesOnly, logWar
92376
92387
  console.warn(`Warning: Could not resolve ref: ${ref}`);
92377
92388
  continue;
92378
92389
  }
92379
- const typeName = refToName(ref);
92390
+ const typeName = refToName(ref, typeSuffix);
92380
92391
  const filename = refToFilename(ref);
92381
92392
  const processedSchema = resolveDynamicRefs(resolvedSchema, dynamicRefMap);
92382
92393
  const extendedSchema = extensions ? applySchemaExtensions(processedSchema, filename, extensions) : processedSchema;
@@ -92385,6 +92396,9 @@ var buildSchema = async (rootSchema, rootTypeName, extensions, typesOnly, logWar
92385
92396
  selfRef: ref,
92386
92397
  rootSchema,
92387
92398
  helpersMode,
92399
+ helpersImportPrefix,
92400
+ readonly: readonly2,
92401
+ typeSuffix,
92388
92402
  ...logWarnings !== undefined ? { logWarnings } : {},
92389
92403
  ...strict2 !== undefined ? { strict: strict2 } : {}
92390
92404
  });
@@ -92458,6 +92472,41 @@ var deriveRootTypeName = (schema) => {
92458
92472
  return name || "Document";
92459
92473
  };
92460
92474
 
92475
+ // src/combine-files.ts
92476
+ var IMPORT_RE = /^import\s/;
92477
+ var RELATIVE_IMPORT_RE = /\bfrom\s+['"]\.\.?\//;
92478
+ var combineGeneratedFiles = (files) => {
92479
+ const externalImports = new Set;
92480
+ const bodies = [];
92481
+ for (const file2 of files) {
92482
+ if (file2.filename === "index.ts")
92483
+ continue;
92484
+ const bodyLines = [];
92485
+ for (const line of file2.content.split(`
92486
+ `)) {
92487
+ if (IMPORT_RE.test(line.trimStart())) {
92488
+ if (RELATIVE_IMPORT_RE.test(line))
92489
+ continue;
92490
+ externalImports.add(line.trim());
92491
+ continue;
92492
+ }
92493
+ bodyLines.push(line);
92494
+ }
92495
+ const body = bodyLines.join(`
92496
+ `).trim();
92497
+ if (body)
92498
+ bodies.push(body);
92499
+ }
92500
+ const importBlock = [...externalImports].sort().join(`
92501
+ `);
92502
+ return [importBlock, bodies.join(`
92503
+
92504
+ `)].filter(Boolean).join(`
92505
+
92506
+ `) + `
92507
+ `;
92508
+ };
92509
+
92461
92510
  // src/detect-helpers-mode.ts
92462
92511
  import { createRequire as createRequire2 } from "node:module";
92463
92512
  import { resolve } from "node:path";
@@ -92486,13 +92535,16 @@ var loadConfig = async (configPath) => {
92486
92535
  const obj = parsed;
92487
92536
  return {
92488
92537
  ...typeof obj["schema"] === "string" && { schema: obj["schema"] },
92538
+ ...typeof obj["schemaDir"] === "string" && { schemaDir: obj["schemaDir"] },
92489
92539
  ...typeof obj["outDir"] === "string" && { outDir: obj["outDir"] },
92540
+ ...typeof obj["outFile"] === "string" && { outFile: obj["outFile"] },
92490
92541
  ...isSourceFormat(obj["input"]) && { input: obj["input"] },
92491
92542
  ...typeof obj["export"] === "string" && { export: obj["export"] },
92492
92543
  ...typeof obj["typesOnly"] === "boolean" && { typesOnly: obj["typesOnly"] },
92493
92544
  ...typeof obj["build"] === "boolean" && { build: obj["build"] },
92494
92545
  ...typeof obj["logWarnings"] === "boolean" && { logWarnings: obj["logWarnings"] },
92495
- ...typeof obj["strict"] === "boolean" && { strict: obj["strict"] }
92546
+ ...typeof obj["strict"] === "boolean" && { strict: obj["strict"] },
92547
+ ...typeof obj["readonly"] === "boolean" && { readonly: obj["readonly"] }
92496
92548
  };
92497
92549
  };
92498
92550
 
@@ -92527,99 +92579,126 @@ ${String(error54)}`);
92527
92579
 
92528
92580
  // src/parse-cli-args.ts
92529
92581
  var SOURCE_FORMATS2 = ["json", "typebox", "zod", "valibot", "effect"];
92582
+ var BOOLEAN_KEYS = new Set(["typesOnly", "build", "logWarnings", "strict", "readonly"]);
92583
+ var VALUE_KEYS = new Set([
92584
+ "schema",
92585
+ "schemaDir",
92586
+ "outDir",
92587
+ "outFile",
92588
+ "input",
92589
+ "export",
92590
+ "helpers",
92591
+ "typeSuffix"
92592
+ ]);
92593
+ var toCamelCase = (key) => key.replace(/-([a-z])/g, (_, c) => c.toUpperCase());
92594
+ var parseHelpersValue = (value10) => {
92595
+ if (value10 === "package" || value10 === "embedded")
92596
+ return value10;
92597
+ return;
92598
+ };
92599
+ var parseInputValue = (value10) => SOURCE_FORMATS2.includes(value10) ? value10 : undefined;
92600
+ var assignValue = (config3, key, value10) => {
92601
+ switch (key) {
92602
+ case "schema":
92603
+ config3.schema = value10;
92604
+ return true;
92605
+ case "schemaDir":
92606
+ config3.schemaDir = value10;
92607
+ return true;
92608
+ case "outDir":
92609
+ config3.outDir = value10;
92610
+ return true;
92611
+ case "outFile":
92612
+ config3.outFile = value10;
92613
+ return true;
92614
+ case "export":
92615
+ config3.export = value10;
92616
+ return true;
92617
+ case "typeSuffix":
92618
+ config3.typeSuffix = value10;
92619
+ return true;
92620
+ case "input": {
92621
+ const parsed = parseInputValue(value10);
92622
+ if (parsed)
92623
+ config3.input = parsed;
92624
+ return true;
92625
+ }
92626
+ case "helpers": {
92627
+ const parsed = parseHelpersValue(value10);
92628
+ if (parsed)
92629
+ config3.helpers = parsed;
92630
+ return true;
92631
+ }
92632
+ default:
92633
+ return false;
92634
+ }
92635
+ };
92636
+ var assignBoolean = (config3, key, value10) => {
92637
+ switch (key) {
92638
+ case "typesOnly":
92639
+ config3.typesOnly = value10;
92640
+ return true;
92641
+ case "build":
92642
+ config3.build = value10;
92643
+ return true;
92644
+ case "logWarnings":
92645
+ config3.logWarnings = value10;
92646
+ return true;
92647
+ case "strict":
92648
+ config3.strict = value10;
92649
+ return true;
92650
+ case "readonly":
92651
+ config3.readonly = value10;
92652
+ return true;
92653
+ default:
92654
+ return false;
92655
+ }
92656
+ };
92530
92657
  var parseCliArgs = (args2) => {
92531
92658
  const config3 = {};
92532
- const parseHelpersValue = (value10) => {
92533
- if (value10 === "package" || value10 === "embedded")
92534
- return value10;
92535
- return;
92536
- };
92537
- const parseInputValue = (value10) => SOURCE_FORMATS2.includes(value10) ? value10 : undefined;
92538
92659
  for (let i = 0;i < args2.length; i++) {
92539
92660
  const arg = args2[i];
92540
- if (!arg) {
92661
+ if (!arg || !arg.startsWith("--")) {
92541
92662
  continue;
92542
92663
  }
92543
- if (arg.startsWith("--") && arg.includes("=")) {
92544
- const equalsIndex = arg.indexOf("=");
92545
- const key = arg.slice(2, equalsIndex);
92664
+ const equalsIndex = arg.indexOf("=");
92665
+ if (equalsIndex !== -1) {
92666
+ const key2 = toCamelCase(arg.slice(2, equalsIndex));
92546
92667
  const value10 = arg.slice(equalsIndex + 1);
92547
- if (key === "schema") {
92548
- config3.schema = value10;
92549
- } else if (key === "outDir") {
92550
- config3.outDir = value10;
92551
- } else if (key === "input") {
92552
- const parsed = parseInputValue(value10);
92553
- if (parsed)
92554
- config3.input = parsed;
92555
- } else if (key === "export") {
92556
- config3.export = value10;
92557
- } else if (key === "types-only") {
92558
- config3.typesOnly = value10 !== "false";
92559
- } else if (key === "build") {
92560
- config3.build = value10 !== "false";
92561
- } else if (key === "log-warnings") {
92562
- config3.logWarnings = value10 !== "false";
92563
- } else if (key === "strict") {
92564
- config3.strict = value10 !== "false";
92565
- } else if (key === "helpers") {
92566
- const parsed = parseHelpersValue(value10);
92567
- if (parsed)
92568
- config3.helpers = parsed;
92668
+ if (BOOLEAN_KEYS.has(key2)) {
92669
+ assignBoolean(config3, key2, value10 !== "false");
92670
+ } else {
92671
+ assignValue(config3, key2, value10);
92569
92672
  }
92570
92673
  continue;
92571
92674
  }
92572
- if (arg === "--schema") {
92573
- const value10 = args2[i + 1];
92574
- if (value10 && !value10.startsWith("--")) {
92575
- config3.schema = value10;
92576
- i++;
92577
- }
92578
- } else if (arg === "--outDir") {
92579
- const value10 = args2[i + 1];
92580
- if (value10 && !value10.startsWith("--")) {
92581
- config3.outDir = value10;
92582
- i++;
92583
- }
92584
- } else if (arg === "--input") {
92585
- const value10 = args2[i + 1];
92586
- if (value10 && !value10.startsWith("--")) {
92587
- const parsed = parseInputValue(value10);
92588
- if (parsed) {
92589
- config3.input = parsed;
92590
- i++;
92591
- }
92592
- }
92593
- } else if (arg === "--export") {
92675
+ const key = toCamelCase(arg.slice(2));
92676
+ if (BOOLEAN_KEYS.has(key)) {
92677
+ assignBoolean(config3, key, true);
92678
+ continue;
92679
+ }
92680
+ if (VALUE_KEYS.has(key)) {
92594
92681
  const value10 = args2[i + 1];
92595
92682
  if (value10 && !value10.startsWith("--")) {
92596
- config3.export = value10;
92683
+ assignValue(config3, key, value10);
92597
92684
  i++;
92598
92685
  }
92599
- } else if (arg === "--types-only") {
92600
- config3.typesOnly = true;
92601
- } else if (arg === "--build") {
92602
- config3.build = true;
92603
- } else if (arg === "--log-warnings") {
92604
- config3.logWarnings = true;
92605
- } else if (arg === "--strict") {
92606
- config3.strict = true;
92607
- } else if (arg === "--helpers") {
92608
- const value10 = args2[i + 1];
92609
- if (value10 && !value10.startsWith("--")) {
92610
- const parsed = parseHelpersValue(value10);
92611
- if (parsed) {
92612
- config3.helpers = parsed;
92613
- i++;
92614
- }
92615
- }
92616
92686
  }
92617
92687
  }
92618
92688
  return config3;
92619
92689
  };
92620
92690
 
92691
+ // src/read-version.ts
92692
+ import { readFile as readFile3 } from "node:fs/promises";
92693
+ var readVersion = async () => {
92694
+ const pkgUrl = new URL("../package.json", import.meta.url);
92695
+ const pkg = JSON.parse(await readFile3(pkgUrl, "utf-8"));
92696
+ return pkg.version ?? "0.0.0";
92697
+ };
92698
+
92621
92699
  // src/cli.ts
92622
92700
  var execFileAsync = promisify(execFile);
92701
+ var isVersionRequest = (args2) => args2[0] === "version" || args2.includes("--version") || args2.includes("-v");
92623
92702
  var extractConfigPath = (args2) => {
92624
92703
  for (let i = 0;i < args2.length; i++) {
92625
92704
  const arg = args2[i];
@@ -92632,77 +92711,190 @@ var extractConfigPath = (args2) => {
92632
92711
  }
92633
92712
  return;
92634
92713
  };
92635
- var run10 = async () => {
92636
- const args2 = process.argv.slice(2);
92637
- const configPath = extractConfigPath(args2);
92638
- const fileConfig = configPath ? await loadConfig(configPath) : {};
92639
- const cliConfig = parseCliArgs(args2);
92640
- const config3 = { ...fileConfig, ...cliConfig };
92641
- if (!config3.schema) {
92642
- console.error("Error: --schema is required. Provide a path to a JSON Schema file.");
92643
- process.exit(1);
92644
- }
92645
- if (!config3.outDir) {
92646
- console.error("Error: --outDir is required. Provide an output directory for generated files.");
92647
- process.exit(1);
92648
- }
92649
- const schemaPath = resolve3(config3.schema);
92714
+ var loadSchema = async (config3, schemaPath) => {
92650
92715
  const inputFormat = config3.input ?? "json";
92651
- let schema;
92652
92716
  if (inputFormat === "json") {
92653
- schema = JSON.parse(await readFile3(schemaPath, "utf-8"));
92654
- } else {
92655
- console.log(`Input format: ${inputFormat}`);
92656
- const source = await loadSchemaModule(schemaPath, config3.export);
92657
- schema = await getAdapter(inputFormat).toJSONSchema(source);
92717
+ return JSON.parse(await readFile4(schemaPath, "utf-8"));
92718
+ }
92719
+ console.log(`Input format: ${inputFormat}`);
92720
+ const source = await loadSchemaModule(schemaPath, config3.export);
92721
+ return getAdapter(inputFormat).toJSONSchema(source);
92722
+ };
92723
+ var writeGeneratedFile = async (baseDir, filename, content) => {
92724
+ const filePath = join8(baseDir, filename);
92725
+ await mkdir(dirname2(filePath), { recursive: true });
92726
+ await writeFile(filePath, content, "utf-8");
92727
+ };
92728
+ var buildOutput = async (outputDir, tsFiles, typesOnly) => {
92729
+ const tsconfigContent = JSON.stringify({
92730
+ compilerOptions: {
92731
+ target: "ESNext",
92732
+ module: "ESNext",
92733
+ moduleResolution: "bundler",
92734
+ declaration: true,
92735
+ emitDeclarationOnly: typesOnly,
92736
+ skipLibCheck: true
92737
+ },
92738
+ include: tsFiles.map((file2) => `./${file2}`)
92739
+ }, null, 2);
92740
+ const tsconfigPath = join8(outputDir, ".tsconfig-mjst-build.json");
92741
+ await writeFile(tsconfigPath, tsconfigContent, "utf-8");
92742
+ try {
92743
+ await execFileAsync("npx", ["tsc", "--project", tsconfigPath]);
92744
+ } catch {
92745
+ throw new Error("TypeScript compilation failed. Check the generated files for errors.");
92746
+ } finally {
92747
+ await unlink(tsconfigPath);
92658
92748
  }
92659
- const outputDir = resolve3(config3.outDir);
92749
+ for (const file2 of tsFiles) {
92750
+ await unlink(join8(outputDir, file2));
92751
+ console.log(`Built: ${file2.replace(/\.ts$/, ".js")}`);
92752
+ console.log(`Built: ${file2.replace(/\.ts$/, ".d.ts")}`);
92753
+ }
92754
+ console.log(`
92755
+ Total files built: ${tsFiles.length * 2}`);
92756
+ };
92757
+ var findJsonSchemas = async (dir3) => {
92758
+ const entries8 = await readdir(dir3, { withFileTypes: true });
92759
+ const results = [];
92760
+ for (const entry of entries8) {
92761
+ const full = join8(dir3, entry.name);
92762
+ if (entry.isDirectory()) {
92763
+ results.push(...await findJsonSchemas(full));
92764
+ } else if (entry.isFile() && entry.name.endsWith(".json")) {
92765
+ results.push(full);
92766
+ }
92767
+ }
92768
+ return results;
92769
+ };
92770
+ var runSingle = async (config3, schemaPath, outputDir) => {
92771
+ const schema = await loadSchema(config3, schemaPath);
92660
92772
  await mkdir(outputDir, { recursive: true });
92661
92773
  const helpersMode = config3.helpers ?? detectHelpersMode(outputDir);
92662
92774
  console.log(`Helpers mode: ${helpersMode}${config3.helpers ? " (explicit)" : " (auto-detected)"}`);
92663
92775
  const rootTypeName = deriveRootTypeName(schema);
92664
92776
  console.log(`Root type: ${rootTypeName}`);
92665
- const files = await buildSchema(schema, rootTypeName, undefined, config3.typesOnly, config3.logWarnings, config3.strict, helpersMode);
92777
+ const files = await buildSchema(schema, rootTypeName, undefined, config3.typesOnly, config3.logWarnings, config3.strict, helpersMode, undefined, config3.readonly, config3.typeSuffix);
92666
92778
  for (const file2 of files) {
92667
- const filePath = join8(outputDir, file2.filename);
92668
- await mkdir(dirname2(filePath), { recursive: true });
92669
- await writeFile(filePath, file2.content, "utf-8");
92779
+ await writeGeneratedFile(outputDir, file2.filename, file2.content);
92670
92780
  console.log(`Generated: ${file2.filename}`);
92671
92781
  }
92672
92782
  if (config3.build) {
92673
- const tsconfigContent = JSON.stringify({
92674
- compilerOptions: {
92675
- target: "ESNext",
92676
- module: "ESNext",
92677
- moduleResolution: "bundler",
92678
- declaration: true,
92679
- emitDeclarationOnly: config3.typesOnly,
92680
- skipLibCheck: true
92681
- },
92682
- include: ["./**/*.ts"]
92683
- }, null, 2);
92684
- const tsconfigPath = join8(outputDir, ".tsconfig-mjst-build.json");
92685
- await writeFile(tsconfigPath, tsconfigContent, "utf-8");
92686
- try {
92687
- await execFileAsync("npx", ["tsc", "--project", tsconfigPath]);
92688
- } catch {
92689
- throw new Error("TypeScript compilation failed. Check the generated files for errors.");
92690
- } finally {
92691
- await unlink(tsconfigPath);
92692
- }
92783
+ await buildOutput(outputDir, files.map((f) => f.filename), config3.typesOnly);
92784
+ } else {
92785
+ console.log(`
92786
+ Total files generated: ${files.length}`);
92787
+ }
92788
+ };
92789
+ var runSingleFile = async (config3, schemaPath, outFilePath) => {
92790
+ const schema = await loadSchema(config3, schemaPath);
92791
+ const outputDir = dirname2(outFilePath);
92792
+ await mkdir(outputDir, { recursive: true });
92793
+ const rootTypeName = deriveRootTypeName(schema);
92794
+ console.log(`Root type: ${rootTypeName}`);
92795
+ const files = await buildSchema(schema, rootTypeName, undefined, config3.typesOnly, config3.logWarnings, config3.strict, config3.helpers ?? "package", undefined, config3.readonly, config3.typeSuffix);
92796
+ await writeFile(outFilePath, combineGeneratedFiles(files), "utf-8");
92797
+ console.log(`Generated: ${relative(process.cwd(), outFilePath)}`);
92798
+ if (config3.build) {
92799
+ await buildOutput(outputDir, [basename(outFilePath)], config3.typesOnly);
92800
+ } else {
92801
+ console.log(`
92802
+ Total files generated: 1`);
92803
+ }
92804
+ };
92805
+ var runRecursive = async (config3, schemaDir, outputDir) => {
92806
+ if (config3.input && config3.input !== "json") {
92807
+ console.error("Error: --schemaDir only supports JSON Schema files; remove --input or set it to 'json'.");
92808
+ process.exit(1);
92809
+ }
92810
+ const schemaFiles = await findJsonSchemas(schemaDir);
92811
+ if (schemaFiles.length === 0) {
92812
+ console.error(`Error: no .json schema files found under ${schemaDir}.`);
92813
+ process.exit(1);
92814
+ }
92815
+ await mkdir(outputDir, { recursive: true });
92816
+ const helpersMode = config3.helpers ?? detectHelpersMode(outputDir);
92817
+ console.log(`Helpers mode: ${helpersMode}${config3.helpers ? " (explicit)" : " (auto-detected)"}`);
92818
+ const sharedHelpers = new Map;
92819
+ const writtenTsFiles = [];
92820
+ for (const schemaFile of schemaFiles) {
92821
+ const relPath = relative(schemaDir, schemaFile);
92822
+ const relNoExt = relPath.slice(0, -".json".length);
92823
+ const schemaSubDir = join8(outputDir, relNoExt);
92824
+ const depth = relNoExt.split(sep).filter(Boolean).length;
92825
+ const helpersImportPrefix = "../".repeat(depth);
92826
+ const schema = await loadSchema(config3, schemaFile);
92827
+ const rootTypeName = deriveRootTypeName(schema);
92828
+ console.log(`
92829
+ ${relPath} → ${relNoExt}/ (root type: ${rootTypeName})`);
92830
+ const files = await buildSchema(schema, rootTypeName, undefined, config3.typesOnly, config3.logWarnings, config3.strict, helpersMode, helpersImportPrefix, config3.readonly, config3.typeSuffix);
92693
92831
  for (const file2 of files) {
92694
- await unlink(join8(outputDir, file2.filename));
92695
- const jsFilename = file2.filename.replace(/\.ts$/, ".js");
92696
- const dtsFilename = file2.filename.replace(/\.ts$/, ".d.ts");
92697
- console.log(`Built: ${jsFilename}`);
92698
- console.log(`Built: ${dtsFilename}`);
92832
+ if (file2.filename.startsWith("_helpers/")) {
92833
+ sharedHelpers.set(file2.filename, file2.content);
92834
+ continue;
92835
+ }
92836
+ await writeGeneratedFile(schemaSubDir, file2.filename, file2.content);
92837
+ const relativeFilename = join8(relNoExt, file2.filename);
92838
+ writtenTsFiles.push(relativeFilename);
92839
+ console.log(`Generated: ${relativeFilename}`);
92699
92840
  }
92700
- console.log(`
92701
- Total files built: ${files.length * 2}`);
92841
+ }
92842
+ for (const [filename, content] of sharedHelpers) {
92843
+ await writeGeneratedFile(outputDir, filename, content);
92844
+ writtenTsFiles.push(filename);
92845
+ console.log(`Generated: ${filename}`);
92846
+ }
92847
+ if (config3.build) {
92848
+ await buildOutput(outputDir, writtenTsFiles, config3.typesOnly);
92702
92849
  } else {
92703
92850
  console.log(`
92704
- Total files generated: ${files.length}`);
92851
+ Total files generated: ${writtenTsFiles.length}`);
92852
+ }
92853
+ };
92854
+ var run10 = async () => {
92855
+ const args2 = process.argv.slice(2);
92856
+ if (isVersionRequest(args2)) {
92857
+ console.log(await readVersion());
92858
+ return;
92859
+ }
92860
+ const configPath = extractConfigPath(args2);
92861
+ const fileConfig = configPath ? await loadConfig(configPath) : {};
92862
+ const cliConfig = parseCliArgs(args2);
92863
+ const config3 = { ...fileConfig, ...cliConfig };
92864
+ if (config3.outDir && config3.outFile) {
92865
+ console.error("Error: provide only one of --out-dir or --out-file, not both.");
92866
+ process.exit(1);
92867
+ }
92868
+ if (config3.outFile) {
92869
+ if (!config3.typesOnly) {
92870
+ console.error("Error: --out-file currently supports only --types-only output. Add --types-only or use --out-dir.");
92871
+ process.exit(1);
92872
+ }
92873
+ if (config3.schemaDir) {
92874
+ console.error("Error: --out-file cannot be combined with --schema-dir; use --out-dir for recursive output.");
92875
+ process.exit(1);
92876
+ }
92877
+ if (!config3.schema) {
92878
+ console.error("Error: --schema is required. Provide a path to a JSON Schema.");
92879
+ process.exit(1);
92880
+ }
92881
+ await runSingleFile(config3, resolve3(config3.schema), resolve3(config3.outFile));
92882
+ return;
92883
+ }
92884
+ if (!config3.outDir) {
92885
+ console.error("Error: --out-dir or --out-file is required. Provide an output destination for generated files.");
92886
+ process.exit(1);
92887
+ }
92888
+ const outputDir = resolve3(config3.outDir);
92889
+ if (config3.schemaDir) {
92890
+ await runRecursive(config3, resolve3(config3.schemaDir), outputDir);
92891
+ return;
92892
+ }
92893
+ if (!config3.schema) {
92894
+ console.error("Error: --schema (or --schemaDir) is required. Provide a path to a JSON Schema.");
92895
+ process.exit(1);
92705
92896
  }
92897
+ await runSingle(config3, resolve3(config3.schema), outputDir);
92706
92898
  };
92707
92899
  run10().catch((error54) => {
92708
92900
  console.error(error54 instanceof Error ? error54.message : error54);