@amritk/generate-parsers 0.4.0 → 0.6.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/index.js CHANGED
@@ -137,15 +137,15 @@ var refToFilename2 = (ref) => {
137
137
  }
138
138
  return filename;
139
139
  };
140
- var kebabToPascal = (kebab) => {
140
+ var kebabToPascal = (kebab, suffix) => {
141
141
  const words = kebab.split("-");
142
142
  let pascalCase = "";
143
143
  for (const word of words) {
144
144
  pascalCase += word.charAt(0).toUpperCase() + word.slice(1);
145
145
  }
146
- return pascalCase + "Object";
146
+ return pascalCase + suffix;
147
147
  };
148
- var refToName = (ref) => kebabToPascal(refToFilename2(ref));
148
+ var refToName = (ref, suffix = "") => kebabToPascal(refToFilename2(ref), suffix);
149
149
 
150
150
  // ../helpers/dist/resolve-dynamic-refs.js
151
151
  var resolveDynamicRefs = (schema, dynamicRefMap) => {
@@ -439,15 +439,15 @@ var refToFilename4 = (ref) => {
439
439
  }
440
440
  return filename;
441
441
  };
442
- var kebabToPascal2 = (kebab) => {
442
+ var kebabToPascal2 = (kebab, suffix) => {
443
443
  const words = kebab.split("-");
444
444
  let pascalCase = "";
445
445
  for (const word of words) {
446
446
  pascalCase += word.charAt(0).toUpperCase() + word.slice(1);
447
447
  }
448
- return pascalCase + "Object";
448
+ return pascalCase + suffix;
449
449
  };
450
- var refToName2 = (ref) => kebabToPascal2(refToFilename4(ref));
450
+ var refToName2 = (ref, suffix = "") => kebabToPascal2(refToFilename4(ref), suffix);
451
451
  var JS_IDENTIFIER = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/;
452
452
  var safeKey = (key) => {
453
453
  if (JS_IDENTIFIER.test(key)) {
@@ -540,12 +540,13 @@ var buildJsDocBlock = (title, description, commentUrl) => {
540
540
  `;
541
541
  return block;
542
542
  };
543
- var getTypeScriptType = (schema) => {
544
- const base = getUnbrandedType(schema);
543
+ var getTypeScriptType = (schema, options = {}) => {
544
+ const base = getUnbrandedType(schema, options);
545
545
  const brand = getMjstBrand(schema);
546
546
  return brand ? `(${base} & { readonly __brand: '${brand}' })` : base;
547
547
  };
548
- var getUnbrandedType = (schema) => {
548
+ var recordType = (keyType, valueType, options) => options.readonly ? `Readonly<Record<${keyType}, ${valueType}>>` : `Record<${keyType}, ${valueType}>`;
549
+ var getUnbrandedType = (schema, options = {}) => {
549
550
  if (typeof schema === "boolean") {
550
551
  return getBooleanSubSchemaType(schema);
551
552
  }
@@ -564,13 +565,13 @@ var getUnbrandedType = (schema) => {
564
565
  if (!schema.$ref.startsWith("#")) {
565
566
  return "unknown";
566
567
  }
567
- return refToName2(schema.$ref);
568
+ return refToName2(schema.$ref, options.typeSuffix);
568
569
  }
569
570
  if (schema.$dynamicRef) {
570
571
  if (schema.$dynamicRef === "#meta") {
571
- return "Schema";
572
+ return `Schema${options.typeSuffix ?? ""}`;
572
573
  }
573
- return refToName2(schema.$dynamicRef);
574
+ return refToName2(schema.$dynamicRef, options.typeSuffix);
574
575
  }
575
576
  if (schema.const !== undefined) {
576
577
  return JSON.stringify(schema.const);
@@ -593,51 +594,51 @@ var getUnbrandedType = (schema) => {
593
594
  return multiEnumUnion;
594
595
  }
595
596
  if (schema.oneOf && Array.isArray(schema.oneOf) && schema.oneOf.length > 0) {
596
- let oneOfUnion = getTypeScriptType(schema.oneOf[0]);
597
+ let oneOfUnion = getTypeScriptType(schema.oneOf[0], options);
597
598
  for (let i = 1;i < schema.oneOf.length; i++) {
598
- oneOfUnion += " | " + getTypeScriptType(schema.oneOf[i]);
599
+ oneOfUnion += " | " + getTypeScriptType(schema.oneOf[i], options);
599
600
  }
600
601
  return oneOfUnion;
601
602
  }
602
603
  if (schema.anyOf && Array.isArray(schema.anyOf) && schema.anyOf.length > 0) {
603
- let anyOfUnion = getTypeScriptType(schema.anyOf[0]);
604
+ let anyOfUnion = getTypeScriptType(schema.anyOf[0], options);
604
605
  for (let i = 1;i < schema.anyOf.length; i++) {
605
- anyOfUnion += " | " + getTypeScriptType(schema.anyOf[i]);
606
+ anyOfUnion += " | " + getTypeScriptType(schema.anyOf[i], options);
606
607
  }
607
608
  return anyOfUnion;
608
609
  }
609
610
  if (schema.allOf && Array.isArray(schema.allOf) && schema.allOf.length > 0) {
610
- let intersectionTypes = getTypeScriptType(schema.allOf[0]);
611
+ let intersectionTypes = getTypeScriptType(schema.allOf[0], options);
611
612
  for (let i = 1;i < schema.allOf.length; i++) {
612
- intersectionTypes += " & " + getTypeScriptType(schema.allOf[i]);
613
+ intersectionTypes += " & " + getTypeScriptType(schema.allOf[i], options);
613
614
  }
614
615
  return intersectionTypes;
615
616
  }
616
617
  const conditionalResult = getConditionalObjectSchema(schema);
617
618
  if (conditionalResult) {
618
- const baseType = getTypeScriptType(conditionalResult.schema);
619
+ const baseType = getTypeScriptType(conditionalResult.schema, options);
619
620
  if (conditionalResult.thenRef) {
620
- return `(${baseType}) & ${refToName2(conditionalResult.thenRef)}`;
621
+ return `(${baseType}) & ${refToName2(conditionalResult.thenRef, options.typeSuffix)}`;
621
622
  }
622
623
  return baseType;
623
624
  }
624
625
  if (!schema.type) {
625
626
  if (schema.additionalProperties !== undefined) {
626
627
  if (typeof schema.additionalProperties === "boolean") {
627
- return `Record<string, ${getBooleanSubSchemaType(schema.additionalProperties)}>`;
628
+ return recordType("string", getBooleanSubSchemaType(schema.additionalProperties), options);
628
629
  }
629
- return `Record<string, ${getTypeScriptType(schema.additionalProperties)}>`;
630
+ return recordType("string", getTypeScriptType(schema.additionalProperties, options), options);
630
631
  }
631
632
  if (schema.patternProperties && typeof schema.patternProperties === "object") {
632
633
  const firstEntry = Object.entries(schema.patternProperties)[0];
633
634
  if (firstEntry) {
634
635
  const [pattern, value] = firstEntry;
635
636
  if (value !== undefined) {
636
- const valueType = typeof value === "boolean" ? getBooleanSubSchemaType(value) : getTypeScriptType(value);
637
+ const valueType = typeof value === "boolean" ? getBooleanSubSchemaType(value) : getTypeScriptType(value, options);
637
638
  if (pattern === "^x-") {
638
- return `Record<\`x-\${string}\`, ${valueType}>`;
639
+ return recordType("`x-${string}`", valueType, options);
639
640
  }
640
- return `Record<string, ${valueType}>`;
641
+ return recordType("string", valueType, options);
641
642
  }
642
643
  }
643
644
  }
@@ -690,41 +691,42 @@ var getUnbrandedType = (schema) => {
690
691
  return "boolean";
691
692
  case "array":
692
693
  if (schema.items) {
693
- const itemType = getTypeScriptType(schema.items);
694
+ const itemType = getTypeScriptType(schema.items, options);
694
695
  const wrappedItemType = itemType.includes(" | ") ? `(${itemType})` : itemType;
695
- return `${wrappedItemType}[]`;
696
+ return options.readonly ? `readonly ${wrappedItemType}[]` : `${wrappedItemType}[]`;
696
697
  }
697
- return "unknown[]";
698
+ return options.readonly ? "readonly unknown[]" : "unknown[]";
698
699
  case "object":
699
700
  if (schema.properties) {
701
+ const readonlyPrefix = options.readonly ? "readonly " : "";
700
702
  let properties = "";
701
703
  let first = true;
702
704
  for (const key in schema.properties) {
703
705
  const propSchema = schema.properties[key];
704
706
  const isRequired = schema.required?.includes(key) ?? false;
705
707
  const optional = isRequired ? "" : "?";
706
- const propType = getTypeScriptType(propSchema);
708
+ const propType = getTypeScriptType(propSchema, options);
707
709
  if (!first)
708
710
  properties += "; ";
709
- properties += safeKey(key) + optional + ": " + propType;
711
+ properties += readonlyPrefix + safeKey(key) + optional + ": " + propType;
710
712
  first = false;
711
713
  }
712
714
  return "{ " + properties + " }";
713
715
  }
714
716
  if (schema.additionalProperties && typeof schema.additionalProperties === "object") {
715
- const additionalPropType = getTypeScriptType(schema.additionalProperties);
716
- return `Record<string, ${additionalPropType}>`;
717
+ const additionalPropType = getTypeScriptType(schema.additionalProperties, options);
718
+ return recordType("string", additionalPropType, options);
717
719
  }
718
720
  if (schema.patternProperties && typeof schema.patternProperties === "object") {
719
721
  const firstEntry = Object.entries(schema.patternProperties)[0];
720
722
  if (firstEntry) {
721
723
  const [pattern, patternVal] = firstEntry;
722
724
  if (patternVal) {
723
- const valueType = getTypeScriptType(patternVal);
725
+ const valueType = getTypeScriptType(patternVal, options);
724
726
  if (pattern === "^x-") {
725
- return `Record<\`x-\${string}\`, ${valueType}>`;
727
+ return recordType("`x-${string}`", valueType, options);
726
728
  }
727
- return `Record<string, ${valueType}>`;
729
+ return recordType("string", valueType, options);
728
730
  }
729
731
  }
730
732
  }
@@ -733,9 +735,10 @@ var getUnbrandedType = (schema) => {
733
735
  return "unknown";
734
736
  }
735
737
  };
736
- var generateTypeDefinition = (schema, typeName) => {
738
+ var generateTypeDefinition = (schema, typeName, options = {}) => {
739
+ const readonlyPrefix = options.readonly ? "readonly " : "";
737
740
  if (!isObjectLikeSchema(schema)) {
738
- const tsType = getTypeScriptType(schema);
741
+ const tsType = getTypeScriptType(schema, options);
739
742
  let result = "";
740
743
  if (isSchemaObject2(schema) && schema.$comment && typeof schema.$comment === "string") {
741
744
  result += buildJsDocBlock(typeName, schema.$comment);
@@ -763,23 +766,23 @@ var generateTypeDefinition = (schema, typeName) => {
763
766
  if (firstPatternProperty === undefined) {
764
767
  return `export type ${typeName} = Record<string, unknown>;`;
765
768
  }
766
- const patternPropType = typeof firstPatternProperty === "boolean" ? getBooleanSubSchemaType(firstPatternProperty) : getTypeScriptType(firstPatternProperty);
769
+ const patternPropType = typeof firstPatternProperty === "boolean" ? getBooleanSubSchemaType(firstPatternProperty) : getTypeScriptType(firstPatternProperty, options);
767
770
  const keyType = firstPattern === "^x-" ? "`x-${string}`" : "string";
768
771
  let result2 = "";
769
772
  if (jsDocTitle && jsDocDescription) {
770
773
  result2 += buildJsDocBlock(jsDocTitle, jsDocDescription);
771
774
  }
772
- result2 += `export type ${typeName} = Record<${keyType}, ${patternPropType}>;`;
775
+ result2 += `export type ${typeName} = ${recordType(keyType, patternPropType, options)};`;
773
776
  return result2;
774
777
  }
775
778
  if (!hasProperties2 && hasAdditionalProperties2 && normalizedSchema.additionalProperties) {
776
- const additionalPropType = getTypeScriptType(normalizedSchema.additionalProperties);
779
+ const additionalPropType = getTypeScriptType(normalizedSchema.additionalProperties, options);
777
780
  let result2 = "";
778
781
  if (jsDocTitle && jsDocDescription) {
779
782
  result2 += buildJsDocBlock(jsDocTitle, jsDocDescription);
780
783
  }
781
784
  result2 += `export type ${typeName} = {
782
- [key: string]: ${additionalPropType};
785
+ ${readonlyPrefix}[key: string]: ${additionalPropType};
783
786
  };`;
784
787
  return result2;
785
788
  }
@@ -790,8 +793,8 @@ var generateTypeDefinition = (schema, typeName) => {
790
793
  const propSchema = schemaProps[key];
791
794
  const isRequired = normalizedSchema.required?.includes(key) ?? false;
792
795
  const optional = isRequired ? "" : "?";
793
- const propType = getTypeScriptType(propSchema);
794
- const quotedKey = safeKey(key);
796
+ const propType = getTypeScriptType(propSchema, options);
797
+ const quotedKey = readonlyPrefix + safeKey(key);
795
798
  if (!isFirstProp)
796
799
  properties += `
797
800
  `;
@@ -808,12 +811,12 @@ var generateTypeDefinition = (schema, typeName) => {
808
811
  if (isSchemaObject2(schema) && Array.isArray(schema.allOf)) {
809
812
  for (const entry of schema.allOf) {
810
813
  if (isSchemaObject2(entry) && entry.$ref) {
811
- allOfIntersections.push(refToName2(entry.$ref));
814
+ allOfIntersections.push(refToName2(entry.$ref, options.typeSuffix));
812
815
  }
813
816
  }
814
817
  }
815
818
  if (isSchemaObject2(schema) && typeof schema.$ref === "string" && schema.$ref.startsWith("#")) {
816
- allOfIntersections.push(refToName2(schema.$ref));
819
+ allOfIntersections.push(refToName2(schema.$ref, options.typeSuffix));
817
820
  }
818
821
  let result = "";
819
822
  if (jsDocTitle && jsDocDescription) {
@@ -823,7 +826,7 @@ var generateTypeDefinition = (schema, typeName) => {
823
826
  ` + properties + `
824
827
  }`;
825
828
  if (conditionalThenRef) {
826
- typeBody += " & " + refToName2(conditionalThenRef);
829
+ typeBody += " & " + refToName2(conditionalThenRef, options.typeSuffix);
827
830
  }
828
831
  for (const intersectionType of allOfIntersections) {
829
832
  typeBody += " & " + intersectionType;
@@ -841,31 +844,32 @@ var PACKAGE_IMPORTS = {
841
844
  "validate-record": "import { validateRecord } from '@amritk/helpers/validate-record';",
842
845
  "has-ref": "import { hasRef } from '@amritk/helpers/schema-guards';"
843
846
  };
844
- var EMBEDDED_IMPORTS = {
845
- "is-object": "import { isObject } from './_helpers/is-object';",
846
- "validate-array": "import { validateArray } from './_helpers/validate-array';",
847
- "validate-record": "import { validateRecord } from './_helpers/validate-record';",
848
- "has-ref": "import { hasRef } from './_helpers/has-ref';"
847
+ var EMBEDDED_NAMED_EXPORTS = {
848
+ "is-object": "isObject",
849
+ "validate-array": "validateArray",
850
+ "validate-record": "validateRecord",
851
+ "has-ref": "hasRef"
849
852
  };
850
- var collectHelpers = (parserFunction, mode) => {
853
+ var embeddedImport = (helper, prefix) => `import { ${EMBEDDED_NAMED_EXPORTS[helper]} } from '${prefix}_helpers/${helper}';`;
854
+ var collectHelpers = (parserFunction, mode, helpersImportPrefix = "./") => {
851
855
  const imports = [];
852
856
  const used = new Set;
853
- const table = mode === "embedded" ? EMBEDDED_IMPORTS : PACKAGE_IMPORTS;
857
+ const importFor = (helper) => mode === "embedded" ? embeddedImport(helper, helpersImportPrefix) : PACKAGE_IMPORTS[helper];
854
858
  if (parserFunction.includes("validateArray")) {
855
- imports.push(table["validate-array"]);
859
+ imports.push(importFor("validate-array"));
856
860
  used.add("validate-array");
857
861
  }
858
862
  if (parserFunction.includes("validateRecord")) {
859
- imports.push(table["validate-record"]);
863
+ imports.push(importFor("validate-record"));
860
864
  used.add("validate-record");
861
865
  used.add("is-object");
862
866
  }
863
867
  if (parserFunction.includes("isObject")) {
864
- imports.push(table["is-object"]);
868
+ imports.push(importFor("is-object"));
865
869
  used.add("is-object");
866
870
  }
867
871
  if (parserFunction.includes("hasRef(")) {
868
- imports.push(table["has-ref"]);
872
+ imports.push(importFor("has-ref"));
869
873
  used.add("has-ref");
870
874
  }
871
875
  return { imports, used };
@@ -963,6 +967,7 @@ var collectImports = (schema, options) => {
963
967
  const typesOnly = options?.typesOnly === true;
964
968
  const selfFilename = options?.selfRef ? refToFilename(options.selfRef) : undefined;
965
969
  const rootSchema = options?.rootSchema;
970
+ const typeSuffix = options?.typeSuffix;
966
971
  const refs = new Set;
967
972
  const collectRefsFromValue = (value) => {
968
973
  if (typeof value !== "object" || value === null) {
@@ -1090,7 +1095,7 @@ var collectImports = (schema, options) => {
1090
1095
  if (!resolveRef(ref, rootSchema))
1091
1096
  continue;
1092
1097
  }
1093
- const typeName = refToName(ref);
1098
+ const typeName = refToName(ref, typeSuffix);
1094
1099
  const filename = refToFilename(ref);
1095
1100
  if (selfFilename !== undefined && filename === selfFilename) {
1096
1101
  continue;
@@ -1782,33 +1787,33 @@ var isPropertyRequired = (key, schema) => {
1782
1787
  }
1783
1788
  return schema.required.includes(key);
1784
1789
  };
1785
- var generateRequiredRefCall = (key, ref) => {
1790
+ var generateRequiredRefCall = (key, ref, suffix) => {
1786
1791
  const acc = safeAccessor("input", key);
1787
- const parserName = generateParserName(refToName(ref));
1792
+ const parserName = generateParserName(refToName(ref, suffix));
1788
1793
  return `${parserName}(${acc})`;
1789
1794
  };
1790
- var generateOptionalRefCall = (key, ref) => {
1795
+ var generateOptionalRefCall = (key, ref, suffix) => {
1791
1796
  const acc = safeAccessor("input", key);
1792
- const parserName = generateParserName(refToName(ref));
1797
+ const parserName = generateParserName(refToName(ref, suffix));
1793
1798
  return `...(${acc} && { ${safeKey2(key)}: ${parserName}(${acc}) })`;
1794
1799
  };
1795
- var generateRequiredArrayRefCall = (key, ref) => {
1796
- const parserName = generateParserName(refToName(ref));
1800
+ var generateRequiredArrayRefCall = (key, ref, suffix) => {
1801
+ const parserName = generateParserName(refToName(ref, suffix));
1797
1802
  return `validateArray(${safeAccessor("input", key)}, ${parserName})`;
1798
1803
  };
1799
- var generateOptionalArrayRefCall = (key, ref) => {
1800
- const parserName = generateParserName(refToName(ref));
1804
+ var generateOptionalArrayRefCall = (key, ref, suffix) => {
1805
+ const parserName = generateParserName(refToName(ref, suffix));
1801
1806
  const acc = safeAccessor("input", key);
1802
1807
  return `...(${acc} && { ${safeKey2(key)}: validateArray(${acc}, ${parserName}) })`;
1803
1808
  };
1804
- var generateRequiredRecordRefCall = (key, ref) => {
1809
+ var generateRequiredRecordRefCall = (key, ref, suffix) => {
1805
1810
  const acc = safeAccessor("input", key);
1806
- const parserName = generateParserName(refToName(ref));
1811
+ const parserName = generateParserName(refToName(ref, suffix));
1807
1812
  return `validateRecord(${acc}, ${parserName})`;
1808
1813
  };
1809
- var generateOptionalRecordRefCall = (key, ref) => {
1814
+ var generateOptionalRecordRefCall = (key, ref, suffix) => {
1810
1815
  const acc = safeAccessor("input", key);
1811
- const parserName = generateParserName(refToName(ref));
1816
+ const parserName = generateParserName(refToName(ref, suffix));
1812
1817
  return `...(${acc} && { ${safeKey2(key)}: validateRecord(${acc}, ${parserName}) })`;
1813
1818
  };
1814
1819
  var generateOptionalInlineProperty = (key, valueExpression) => {
@@ -1853,20 +1858,20 @@ var shouldUseRecordRefImport = (propSchema, useRefImports) => {
1853
1858
  const additionalProps = propSchema.additionalProperties;
1854
1859
  return isSchemaObject3(additionalProps) && hasRef(additionalProps);
1855
1860
  };
1856
- var generatePropertyValue = (key, propSchema, isRequired, useRefImports) => {
1861
+ var generatePropertyValue = (key, propSchema, isRequired, useRefImports, suffix) => {
1857
1862
  if (shouldUseRefImport(propSchema, useRefImports)) {
1858
1863
  const ref = propSchema.$ref;
1859
- return isRequired ? generateRequiredRefCall(key, ref) : generateOptionalRefCall(key, ref);
1864
+ return isRequired ? generateRequiredRefCall(key, ref, suffix) : generateOptionalRefCall(key, ref, suffix);
1860
1865
  }
1861
1866
  if (shouldUseArrayRefImport(propSchema, useRefImports)) {
1862
1867
  const items = propSchema.items;
1863
1868
  const ref = items.$ref;
1864
- return isRequired ? generateRequiredArrayRefCall(key, ref) : generateOptionalArrayRefCall(key, ref);
1869
+ return isRequired ? generateRequiredArrayRefCall(key, ref, suffix) : generateOptionalArrayRefCall(key, ref, suffix);
1865
1870
  }
1866
1871
  if (shouldUseRecordRefImport(propSchema, useRefImports)) {
1867
1872
  const additionalProps = propSchema.additionalProperties;
1868
1873
  const ref = additionalProps.$ref;
1869
- return isRequired ? generateRequiredRecordRefCall(key, ref) : generateOptionalRecordRefCall(key, ref);
1874
+ return isRequired ? generateRequiredRecordRefCall(key, ref, suffix) : generateOptionalRecordRefCall(key, ref, suffix);
1870
1875
  }
1871
1876
  if (!isSchemaObject3(propSchema)) {
1872
1877
  return isRequired ? "undefined" : generateOptionalInlineProperty(key, "undefined");
@@ -1875,23 +1880,23 @@ var generatePropertyValue = (key, propSchema, isRequired, useRefImports) => {
1875
1880
  const valueExpression = generateValidationExpression(key, propSchema, defaultValue, isRequired);
1876
1881
  return isRequired ? valueExpression : generateOptionalInlineProperty(key, valueExpression);
1877
1882
  };
1878
- var generatePropertyEntries = (schema, useRefImports) => {
1883
+ var generatePropertyEntries = (schema, useRefImports, suffix) => {
1879
1884
  if (!hasProperties(schema)) {
1880
1885
  return [];
1881
1886
  }
1882
1887
  const entries = [];
1883
1888
  for (const [key, propSchema] of Object.entries(schema.properties)) {
1884
1889
  const isRequired = isPropertyRequired(key, schema);
1885
- const value = generatePropertyValue(key, propSchema, isRequired, useRefImports);
1890
+ const value = generatePropertyValue(key, propSchema, isRequired, useRefImports, suffix);
1886
1891
  const isOptional = value.startsWith("...");
1887
1892
  entries.push({ key, value, isOptional });
1888
1893
  }
1889
1894
  return entries;
1890
1895
  };
1891
- var generateFallbackValue = (_, propSchema, useRefImports) => {
1896
+ var generateFallbackValue = (_, propSchema, useRefImports, suffix) => {
1892
1897
  if (useRefImports && hasRef(propSchema)) {
1893
1898
  const ref = propSchema.$ref;
1894
- const parserName = generateParserName(refToName(ref));
1899
+ const parserName = generateParserName(refToName(ref, suffix));
1895
1900
  return `${parserName}(undefined)`;
1896
1901
  }
1897
1902
  if (useRefImports && isSchemaObject3(propSchema) && propSchema.type === "array" && hasItems(propSchema) && hasRef(propSchema.items)) {
@@ -1934,7 +1939,7 @@ var generateFallbackValue = (_, propSchema, useRefImports) => {
1934
1939
  return "undefined";
1935
1940
  }
1936
1941
  };
1937
- var generateFallbackObject = (schema, useRefImports, typeName) => {
1942
+ var generateFallbackObject = (schema, useRefImports, typeName, suffix) => {
1938
1943
  if (!hasProperties(schema)) {
1939
1944
  return `{} as ${typeName}`;
1940
1945
  }
@@ -1945,7 +1950,7 @@ var generateFallbackObject = (schema, useRefImports, typeName) => {
1945
1950
  for (const [key, propSchema] of Object.entries(schema.properties)) {
1946
1951
  const isRequired = isPropertyRequired(key, schema);
1947
1952
  if (isRequired) {
1948
- const fallbackValue = generateFallbackValue(key, propSchema, useRefImports);
1953
+ const fallbackValue = generateFallbackValue(key, propSchema, useRefImports, suffix);
1949
1954
  if (fallbackValue === "undefined") {
1950
1955
  return `{} as ${typeName}`;
1951
1956
  }
@@ -2013,11 +2018,11 @@ var toVarName = (key) => {
2013
2018
  return `_${safe}`;
2014
2019
  };
2015
2020
  var shapeValidatorName = (typeName) => `validate${typeName}Shape`;
2016
- var generatePropertyTypeCheck = (varName, schema, useRefImports) => {
2021
+ var generatePropertyTypeCheck = (varName, schema, useRefImports, suffix) => {
2017
2022
  if (!isSchemaObject3(schema))
2018
2023
  return null;
2019
2024
  if (useRefImports && hasRef(schema)) {
2020
- const refName = refToName(schema.$ref);
2025
+ const refName = refToName(schema.$ref, suffix);
2021
2026
  return `${shapeValidatorName(refName)}(${varName})`;
2022
2027
  }
2023
2028
  if (hasEnum(schema) || hasOneOf(schema) || hasAnyOf(schema) || hasAllOf(schema) || hasRef(schema) || "not" in schema) {
@@ -2026,7 +2031,7 @@ var generatePropertyTypeCheck = (varName, schema, useRefImports) => {
2026
2031
  if (!hasType(schema))
2027
2032
  return null;
2028
2033
  if (useRefImports && schema.type === "array" && hasItems(schema) && isSchemaObject3(schema.items) && hasRef(schema.items)) {
2029
- const refName = refToName(schema.items.$ref);
2034
+ const refName = refToName(schema.items.$ref, suffix);
2030
2035
  return `Array.isArray(${varName}) && ${varName}.every(${shapeValidatorName(refName)})`;
2031
2036
  }
2032
2037
  const checks = [];
@@ -2087,7 +2092,7 @@ var generatePropertyTypeCheck = (varName, schema, useRefImports) => {
2087
2092
  var shouldCacheVariable = (propSchema, _canFastPath, _useRefImports) => {
2088
2093
  return isSchemaObject3(propSchema);
2089
2094
  };
2090
- var generateObjectParser = (schema, typeName, useRefImports, logWarnings, strict) => {
2095
+ var generateObjectParser = (schema, typeName, useRefImports, suffix, logWarnings, strict) => {
2091
2096
  const functionName = generateParserName(typeName);
2092
2097
  if (!hasProperties(schema)) {
2093
2098
  if (strict) {
@@ -2098,7 +2103,7 @@ var generateObjectParser = (schema, typeName, useRefImports, logWarnings, strict
2098
2103
  }
2099
2104
  return `export const ${functionName} = (input: unknown): ${typeName} => isObject(input) ? input as ${typeName} : {} as ${typeName};`;
2100
2105
  }
2101
- const fallbackObject = generateFallbackObject(schema, useRefImports, typeName);
2106
+ const fallbackObject = generateFallbackObject(schema, useRefImports, typeName, suffix);
2102
2107
  const properties = Object.entries(schema.properties);
2103
2108
  const lines = [];
2104
2109
  lines.push(`export const ${functionName} = (input: unknown): ${typeName} => {`);
@@ -2121,7 +2126,7 @@ var generateObjectParser = (schema, typeName, useRefImports, logWarnings, strict
2121
2126
  if (shouldUseRecordRefImport(propSchema, useRefImports)) {
2122
2127
  canFastPath = false;
2123
2128
  } else {
2124
- const check = generatePropertyTypeCheck(varName, propSchema, useRefImports);
2129
+ const check = generatePropertyTypeCheck(varName, propSchema, useRefImports, suffix);
2125
2130
  if (check === null) {
2126
2131
  canFastPath = false;
2127
2132
  } else {
@@ -2160,7 +2165,7 @@ var generateObjectParser = (schema, typeName, useRefImports, logWarnings, strict
2160
2165
  if (useRefImports && isSchemaObject3(schema) && hasAllOf(schema)) {
2161
2166
  for (const entry of schema.allOf) {
2162
2167
  if (isSchemaObject3(entry) && hasRef(entry)) {
2163
- const parserName = generateParserName(refToName(entry.$ref));
2168
+ const parserName = generateParserName(refToName(entry.$ref, suffix));
2164
2169
  objectLines.push(` ...(${parserName}(input) as Record<string, unknown>),`);
2165
2170
  }
2166
2171
  }
@@ -2170,7 +2175,7 @@ var generateObjectParser = (schema, typeName, useRefImports, logWarnings, strict
2170
2175
  const accessor = shouldCache ? varName : safeAccessor("input", key);
2171
2176
  if (shouldUseRefImport(propSchema, useRefImports)) {
2172
2177
  const ref = propSchema.$ref;
2173
- const parserName = generateParserName(refToName(ref));
2178
+ const parserName = generateParserName(refToName(ref, suffix));
2174
2179
  if (isRequired) {
2175
2180
  objectLines.push(` ${safeKey2(key)}: ${parserName}(${accessor}),`);
2176
2181
  } else {
@@ -2181,7 +2186,7 @@ var generateObjectParser = (schema, typeName, useRefImports, logWarnings, strict
2181
2186
  if (shouldUseArrayRefImport(propSchema, useRefImports)) {
2182
2187
  const items = propSchema.items;
2183
2188
  const ref = items.$ref;
2184
- const parserName = generateParserName(refToName(ref));
2189
+ const parserName = generateParserName(refToName(ref, suffix));
2185
2190
  if (isRequired) {
2186
2191
  objectLines.push(` ${safeKey2(key)}: validateArray(${accessor}, ${parserName}),`);
2187
2192
  } else {
@@ -2192,7 +2197,7 @@ var generateObjectParser = (schema, typeName, useRefImports, logWarnings, strict
2192
2197
  if (shouldUseRecordRefImport(propSchema, useRefImports)) {
2193
2198
  const additionalProps = propSchema.additionalProperties;
2194
2199
  const ref = additionalProps.$ref;
2195
- const parserName = generateParserName(refToName(ref));
2200
+ const parserName = generateParserName(refToName(ref, suffix));
2196
2201
  if (isRequired) {
2197
2202
  objectLines.push(` ${safeKey2(key)}: validateRecord(${accessor}, ${parserName}),`);
2198
2203
  } else {
@@ -2231,9 +2236,9 @@ var generateObjectParser = (schema, typeName, useRefImports, logWarnings, strict
2231
2236
  }
2232
2237
  return result;
2233
2238
  };
2234
- var generateCombinedObjectParser = (schema, typeName, useRefImports, logWarnings, strict) => {
2239
+ var generateCombinedObjectParser = (schema, typeName, useRefImports, suffix, logWarnings, strict) => {
2235
2240
  const functionName = generateParserName(typeName);
2236
- const entries = generatePropertyEntries(schema, useRefImports);
2241
+ const entries = generatePropertyEntries(schema, useRefImports, suffix);
2237
2242
  const propertyLines = entries.map((entry) => {
2238
2243
  if (entry.isOptional) {
2239
2244
  return ` ${entry.value},`;
@@ -2241,17 +2246,17 @@ var generateCombinedObjectParser = (schema, typeName, useRefImports, logWarnings
2241
2246
  return ` ${safeKey2(entry.key)}: ${entry.value},`;
2242
2247
  });
2243
2248
  if (!isSchemaObject3(schema) || !("patternProperties" in schema)) {
2244
- return generateObjectParser(schema, typeName, useRefImports, logWarnings, strict);
2249
+ return generateObjectParser(schema, typeName, useRefImports, suffix, logWarnings, strict);
2245
2250
  }
2246
2251
  const patternProps = schema.patternProperties;
2247
2252
  const patterns = Object.entries(patternProps);
2248
2253
  const refPattern = patterns.find(([, ps]) => isSchemaObject3(ps) && hasRef(ps));
2249
2254
  if (!refPattern || !useRefImports) {
2250
- return generateObjectParser(schema, typeName, useRefImports, logWarnings, strict);
2255
+ return generateObjectParser(schema, typeName, useRefImports, suffix, logWarnings, strict);
2251
2256
  }
2252
2257
  const [pattern, patternSchema] = refPattern;
2253
2258
  const ref = patternSchema.$ref;
2254
- const parserName = generateParserName(refToName(ref));
2259
+ const parserName = generateParserName(refToName(ref, suffix));
2255
2260
  const assignmentCode = `(result as Record<string, unknown>)[key] = ${parserName}(value);`;
2256
2261
  const escapedPattern = escapeRegexPattern2(pattern);
2257
2262
  const inputSpread = " ...input,";
@@ -2279,7 +2284,7 @@ ${objectProperties}
2279
2284
  return result;
2280
2285
  };`;
2281
2286
  };
2282
- var generateAdditionalPropertiesParser = (schema, typeName, useRefImports, strict) => {
2287
+ var generateAdditionalPropertiesParser = (schema, typeName, useRefImports, suffix, strict) => {
2283
2288
  const functionName = generateParserName(typeName);
2284
2289
  const additionalProps = schema.additionalProperties;
2285
2290
  if (!additionalProps) {
@@ -2287,7 +2292,7 @@ var generateAdditionalPropertiesParser = (schema, typeName, useRefImports, stric
2287
2292
  }
2288
2293
  if (useRefImports && isSchemaObject3(additionalProps) && hasRef(additionalProps)) {
2289
2294
  const ref = additionalProps.$ref;
2290
- const parserName = generateParserName(refToName(ref));
2295
+ const parserName = generateParserName(refToName(ref, suffix));
2291
2296
  if (strict) {
2292
2297
  return `export const ${functionName} = (input: unknown): ${typeName} => {
2293
2298
  if (!isObject(input)) throw new Error(\`[${typeName}] expected object, got \${input === null ? "null" : typeof input}\`);
@@ -2337,7 +2342,7 @@ var generateInlineValueParser = (schema) => {
2337
2342
  var escapeRegexPattern2 = (pattern) => {
2338
2343
  return pattern.replace(/\\/g, "\\\\").replace(/\//g, "\\/");
2339
2344
  };
2340
- var generatePatternPropertiesParser = (schema, typeName, useRefImports, strict) => {
2345
+ var generatePatternPropertiesParser = (schema, typeName, useRefImports, suffix, strict) => {
2341
2346
  const functionName = generateParserName(typeName);
2342
2347
  if (!("patternProperties" in schema) || typeof schema.patternProperties !== "object") {
2343
2348
  return generateEmptyObjectParser(typeName, strict);
@@ -2351,7 +2356,7 @@ var generatePatternPropertiesParser = (schema, typeName, useRefImports, strict)
2351
2356
  let patternAssignment = "(result as Record<string, unknown>)[key] = value;";
2352
2357
  if (useRefImports && isSchemaObject3(patternSchema) && hasRef(patternSchema)) {
2353
2358
  const ref = patternSchema.$ref;
2354
- const parserName = generateParserName(refToName(ref));
2359
+ const parserName = generateParserName(refToName(ref, suffix));
2355
2360
  patternAssignment = `(result as Record<string, unknown>)[key] = ${parserName}(value);`;
2356
2361
  } else if (patternSchema === false) {
2357
2362
  patternAssignment = "";
@@ -2374,7 +2379,7 @@ ${notObjectBranch}
2374
2379
  return result;
2375
2380
  };`;
2376
2381
  };
2377
- var generateConditionalParser = (schema, typeName) => {
2382
+ var generateConditionalParser = (schema, typeName, suffix) => {
2378
2383
  const functionName = generateParserName(typeName);
2379
2384
  const ifSchema = schema.if;
2380
2385
  const thenSchema = schema.then;
@@ -2384,7 +2389,7 @@ var generateConditionalParser = (schema, typeName) => {
2384
2389
  if (!thenHasRef || !elseHasRef) {
2385
2390
  const mergedSchema = getConditionalObjectSchema2(schema);
2386
2391
  if (mergedSchema) {
2387
- return generateObjectParser(mergedSchema, typeName, false);
2392
+ return generateObjectParser(mergedSchema, typeName, false, suffix);
2388
2393
  }
2389
2394
  return generateEmptyObjectParser(typeName);
2390
2395
  }
@@ -2392,15 +2397,15 @@ var generateConditionalParser = (schema, typeName) => {
2392
2397
  if (!isRefCondition) {
2393
2398
  const mergedSchema = getConditionalObjectSchema2(schema);
2394
2399
  if (mergedSchema) {
2395
- return generateObjectParser(mergedSchema, typeName, false);
2400
+ return generateObjectParser(mergedSchema, typeName, false, suffix);
2396
2401
  }
2397
2402
  return generateEmptyObjectParser(typeName);
2398
2403
  }
2399
2404
  const thenRef = thenSchema.$ref;
2400
2405
  const elseRef = elseSchema.$ref;
2401
- const thenParserName = generateParserName(refToName(thenRef));
2402
- const elseParserName = generateParserName(refToName(elseRef));
2403
- const thenTypeName = refToName(thenRef);
2406
+ const thenParserName = generateParserName(refToName(thenRef, suffix));
2407
+ const elseParserName = generateParserName(refToName(elseRef, suffix));
2408
+ const thenTypeName = refToName(thenRef, suffix);
2404
2409
  return `export const ${functionName} = (input: unknown): ${typeName} | ${thenTypeName} =>
2405
2410
  hasRef(input) ? ${thenParserName}(input) : ${elseParserName}(input)
2406
2411
  `;
@@ -2473,7 +2478,8 @@ var selectParserStrategy = (schema, typeName, options) => {
2473
2478
  const useRefImports = options?.useRefImports ?? false;
2474
2479
  const logWarnings = options?.logWarnings ?? false;
2475
2480
  const strict = options?.strict ?? false;
2476
- if (typeName === "SchemaObject") {
2481
+ const suffix = options?.typeSuffix ?? "";
2482
+ if (typeName === `Schema${suffix}`) {
2477
2483
  return generateSchemaObjectParser(typeName);
2478
2484
  }
2479
2485
  const isObjectLikeSchema2 = isObjectSchema2(schema) || isSchemaObject3(schema) && (("patternProperties" in schema) || ("additionalProperties" in schema));
@@ -2481,30 +2487,30 @@ var selectParserStrategy = (schema, typeName, options) => {
2481
2487
  return generateNonObjectParser(typeName, schema, strict);
2482
2488
  }
2483
2489
  if (hasProperties(schema) && isSchemaObject3(schema) && "patternProperties" in schema) {
2484
- return generateCombinedObjectParser(schema, typeName, useRefImports, logWarnings, strict);
2490
+ return generateCombinedObjectParser(schema, typeName, useRefImports, suffix, logWarnings, strict);
2485
2491
  }
2486
2492
  if (hasProperties(schema)) {
2487
- return generateObjectParser(schema, typeName, useRefImports, logWarnings, strict);
2493
+ return generateObjectParser(schema, typeName, useRefImports, suffix, logWarnings, strict);
2488
2494
  }
2489
2495
  if (isSchemaObject3(schema) && "if" in schema && "then" in schema && "else" in schema) {
2490
- return generateConditionalParser(schema, typeName);
2496
+ return generateConditionalParser(schema, typeName, suffix);
2491
2497
  }
2492
2498
  const conditionalObjectSchema = getConditionalObjectSchema2(schema);
2493
2499
  if (conditionalObjectSchema) {
2494
- return generateObjectParser(conditionalObjectSchema, typeName, useRefImports, logWarnings, strict);
2500
+ return generateObjectParser(conditionalObjectSchema, typeName, useRefImports, suffix, logWarnings, strict);
2495
2501
  }
2496
2502
  if (!isObjectLikeSchema2) {
2497
2503
  return generateNonObjectParser(typeName, schema, strict);
2498
2504
  }
2499
2505
  if ("patternProperties" in schema) {
2500
- return generatePatternPropertiesParser(schema, typeName, useRefImports, strict);
2506
+ return generatePatternPropertiesParser(schema, typeName, useRefImports, suffix, strict);
2501
2507
  }
2502
2508
  if ("additionalProperties" in schema && !hasProperties(schema)) {
2503
2509
  const additionalProps = schema.additionalProperties;
2504
2510
  if (additionalProps === true || additionalProps === false) {
2505
2511
  return generateEmptyObjectParser(typeName, strict);
2506
2512
  }
2507
- return generateAdditionalPropertiesParser(schema, typeName, useRefImports, strict);
2513
+ return generateAdditionalPropertiesParser(schema, typeName, useRefImports, suffix, strict);
2508
2514
  }
2509
2515
  if ("type" in schema && schema.type === "object" && !hasProperties(schema)) {
2510
2516
  return generateEmptyObjectParser(typeName, strict);
@@ -2514,7 +2520,7 @@ var selectParserStrategy = (schema, typeName, options) => {
2514
2520
  var generateParserFunction = (schema, typeName, options) => {
2515
2521
  return selectParserStrategy(schema, typeName, options);
2516
2522
  };
2517
- var generateShapeValidator = (schema, typeName, useRefImports) => {
2523
+ var generateShapeValidator = (schema, typeName, useRefImports, suffix = "") => {
2518
2524
  const fnName = shapeValidatorName(typeName);
2519
2525
  const stub = `export const ${fnName} = (_input: unknown): boolean => false;`;
2520
2526
  if (!isSchemaObject3(schema))
@@ -2532,7 +2538,7 @@ var generateShapeValidator = (schema, typeName, useRefImports) => {
2532
2538
  }
2533
2539
  const accessor = safeAccessor("input", key);
2534
2540
  const isRequired = isPropertyRequired(key, schema);
2535
- const check = generatePropertyTypeCheck(accessor, propSchema, useRefImports);
2541
+ const check = generatePropertyTypeCheck(accessor, propSchema, useRefImports, suffix);
2536
2542
  if (check === null) {
2537
2543
  return stub;
2538
2544
  }
@@ -2562,9 +2568,10 @@ var generateFile = (schema, typeName, options) => {
2562
2568
  const selfRef = options?.selfRef;
2563
2569
  const rootSchema = options?.rootSchema;
2564
2570
  const helpersMode = options?.helpersMode ?? "package";
2565
- const typeDefinition = generateTypeDefinition(schema, typeName);
2571
+ const typeSuffix = options?.typeSuffix ?? "";
2572
+ const typeDefinition = generateTypeDefinition(schema, typeName, { readonly: options?.readonly ?? false, typeSuffix });
2566
2573
  if (typesOnly) {
2567
- const imports2 = collectImports(schema, { typesOnly: true, selfRef, rootSchema });
2574
+ const imports2 = collectImports(schema, { typesOnly: true, selfRef, rootSchema, typeSuffix });
2568
2575
  let result2 = "";
2569
2576
  if (imports2.length > 0) {
2570
2577
  result2 += imports2[0];
@@ -2580,15 +2587,16 @@ var generateFile = (schema, typeName, options) => {
2580
2587
  }
2581
2588
  const parserFunction = generateParserFunction(schema, typeName, {
2582
2589
  useRefImports: true,
2590
+ typeSuffix,
2583
2591
  ...options?.logWarnings !== undefined ? { logWarnings: options.logWarnings } : {},
2584
2592
  ...options?.strict !== undefined ? { strict: options.strict } : {}
2585
2593
  });
2586
- const shapeValidator = generateShapeValidator(schema, typeName, true);
2594
+ const shapeValidator = generateShapeValidator(schema, typeName, true, typeSuffix);
2587
2595
  const combinedFunctions = `${shapeValidator}
2588
2596
 
2589
2597
  ${parserFunction}`;
2590
- const helpers = collectHelpers(combinedFunctions, helpersMode);
2591
- const imports = [...collectImports(schema, { selfRef, rootSchema }), ...helpers.imports];
2598
+ const helpers = collectHelpers(combinedFunctions, helpersMode, options?.helpersImportPrefix);
2599
+ const imports = [...collectImports(schema, { selfRef, rootSchema, typeSuffix }), ...helpers.imports];
2592
2600
  let result = "";
2593
2601
  if (imports.length > 0) {
2594
2602
  result += imports[0];
@@ -2631,7 +2639,7 @@ var extractDynamicAnchorDefs = (schema) => {
2631
2639
  }
2632
2640
  return refs;
2633
2641
  };
2634
- var buildSchema = async (rootSchema, rootTypeName, extensions, typesOnly, logWarnings, strict, helpersMode = "package") => {
2642
+ var buildSchema = async (rootSchema, rootTypeName, extensions, typesOnly, logWarnings, strict, helpersMode = "package", helpersImportPrefix = "./", readonly = false, typeSuffix = "") => {
2635
2643
  rootSchema = upgradeDraft07Schema(rootSchema);
2636
2644
  const files = [];
2637
2645
  const processedRefs = new Set;
@@ -2645,6 +2653,9 @@ var buildSchema = async (rootSchema, rootTypeName, extensions, typesOnly, logWar
2645
2653
  typesOnly: typesOnly ?? false,
2646
2654
  rootSchema,
2647
2655
  helpersMode,
2656
+ helpersImportPrefix,
2657
+ readonly,
2658
+ typeSuffix,
2648
2659
  ...logWarnings !== undefined ? { logWarnings } : {},
2649
2660
  ...strict !== undefined ? { strict } : {}
2650
2661
  });
@@ -2671,7 +2682,7 @@ var buildSchema = async (rootSchema, rootTypeName, extensions, typesOnly, logWar
2671
2682
  console.warn(`Warning: Could not resolve ref: ${ref}`);
2672
2683
  continue;
2673
2684
  }
2674
- const typeName = refToName(ref);
2685
+ const typeName = refToName(ref, typeSuffix);
2675
2686
  const filename = refToFilename(ref);
2676
2687
  const processedSchema = resolveDynamicRefs(resolvedSchema, dynamicRefMap);
2677
2688
  const extendedSchema = extensions ? applySchemaExtensions(processedSchema, filename, extensions) : processedSchema;
@@ -2680,6 +2691,9 @@ var buildSchema = async (rootSchema, rootTypeName, extensions, typesOnly, logWar
2680
2691
  selfRef: ref,
2681
2692
  rootSchema,
2682
2693
  helpersMode,
2694
+ helpersImportPrefix,
2695
+ readonly,
2696
+ typeSuffix,
2683
2697
  ...logWarnings !== undefined ? { logWarnings } : {},
2684
2698
  ...strict !== undefined ? { strict } : {}
2685
2699
  });