@orval/core 8.0.3 → 8.1.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.d.mts CHANGED
@@ -99,6 +99,11 @@ type NormalizedOverrideOutput = {
99
99
  suppressReadonlyModifier?: boolean;
100
100
  jsDoc: NormalizedJsDocOptions;
101
101
  aliasCombinedTypes: boolean;
102
+ /**
103
+ * When enabled, optional properties will be typed as `T | null` instead of just `T`.
104
+ * @default false
105
+ */
106
+ useNullForOptional?: boolean;
102
107
  };
103
108
  type NormalizedMutator = {
104
109
  path: string;
@@ -386,6 +391,11 @@ type OverrideOutput = {
386
391
  suppressReadonlyModifier?: boolean;
387
392
  jsDoc?: JsDocOptions;
388
393
  aliasCombinedTypes?: boolean;
394
+ /**
395
+ * When enabled, optional properties will be typed as `T | null` instead of just `T`.
396
+ * @default false
397
+ */
398
+ useNullForOptional?: boolean;
389
399
  };
390
400
  type JsDocOptions = {
391
401
  filter?: (schema: Record<string, any>) => {
@@ -654,6 +664,8 @@ interface PackageJson {
654
664
  dependencies?: Record<string, string>;
655
665
  devDependencies?: Record<string, string>;
656
666
  peerDependencies?: Record<string, string>;
667
+ catalog?: Record<string, string>;
668
+ catalogs?: Record<string, Record<string, string>>;
657
669
  }
658
670
  type GeneratorSchema = {
659
671
  name: string;
@@ -924,6 +936,7 @@ declare const SchemaType: {
924
936
  };
925
937
  type ScalarValue = {
926
938
  value: string;
939
+ useTypeAlias?: boolean;
927
940
  isEnum: boolean;
928
941
  hasReadonlyProps: boolean;
929
942
  type: SchemaType;
@@ -1356,6 +1369,18 @@ declare function getEnumNames(schemaObject: OpenApiSchemaObject | undefined): st
1356
1369
  declare function getEnumDescriptions(schemaObject: OpenApiSchemaObject | undefined): string[] | undefined;
1357
1370
  declare function getEnum(value: string, enumName: string, names: string[] | undefined, enumGenerationType: EnumGeneration, descriptions?: string[], enumNamingConvention?: NamingConvention): string;
1358
1371
  declare function getEnumImplementation(value: string, names?: string[], descriptions?: string[], enumNamingConvention?: NamingConvention): string;
1372
+ type CombinedEnumInput = {
1373
+ value: string;
1374
+ isRef: boolean;
1375
+ schema: OpenApiSchemaObject | undefined;
1376
+ };
1377
+ type CombinedEnumValue = {
1378
+ value: string;
1379
+ valueImports: string[];
1380
+ hasNull: boolean;
1381
+ };
1382
+ declare function getEnumUnionFromSchema(schema: OpenApiSchemaObject | undefined): any;
1383
+ declare function getCombinedEnumValue(inputs: CombinedEnumInput[]): CombinedEnumValue;
1359
1384
  //#endregion
1360
1385
  //#region src/getters/keys.d.ts
1361
1386
  declare function getKey(key: string): string;
@@ -1860,6 +1885,11 @@ declare function escape(str: string | null, char?: string): string | undefined;
1860
1885
  * @param input String to escape
1861
1886
  */
1862
1887
  declare function jsStringEscape(input: string): string;
1888
+ /**
1889
+ * Deduplicates a TypeScript union type string.
1890
+ * Handles types like "A | B | B" → "A | B" and "null | null" → "null".
1891
+ */
1892
+ declare function dedupeUnionType(unionType: string): string;
1863
1893
  //#endregion
1864
1894
  //#region src/utils/tsconfig.d.ts
1865
1895
  declare function isSyntheticDefaultImportsAllow(config?: Tsconfig): boolean;
@@ -1963,5 +1993,5 @@ declare function generateTargetForTags(builder: WriteSpecBuilder, options: Norma
1963
1993
  declare function getOrvalGeneratedTypes(): string;
1964
1994
  declare function getTypedResponse(): string;
1965
1995
  //#endregion
1966
- export { AngularOptions, BODY_TYPE_NAME, BaseUrlFromConstant, BaseUrlFromSpec, ClientBuilder, ClientDependenciesBuilder, ClientExtraFilesBuilder, ClientFileBuilder, ClientFooterBuilder, ClientGeneratorsBuilder, ClientHeaderBuilder, ClientMockBuilder, ClientMockGeneratorBuilder, ClientMockGeneratorImplementation, ClientTitleBuilder, Config, ConfigExternal, ConfigFn, ContextSpec, DeepNonNullable, EnumGeneration, ErrorWithTag, FetchOptions, FormDataArrayHandling, FormDataType, GenerateMockImports, GenerateVerbOptionsParams, GenerateVerbsOptionsParams, GeneratorApiBuilder, GeneratorApiOperations, GeneratorApiResponse, GeneratorClient, GeneratorClientExtra, GeneratorClientFooter, GeneratorClientHeader, GeneratorClientImports, GeneratorClientTitle, GeneratorClients, GeneratorDependency, GeneratorImport, GeneratorMutator, GeneratorMutatorParsingInfo, GeneratorOperation, GeneratorOperations, GeneratorOptions, GeneratorSchema, GeneratorTarget, GeneratorTargetFull, GeneratorVerbOptions, GeneratorVerbsOptions, GetterBody, GetterParam, GetterParameters, GetterParams, GetterProp, GetterPropType, GetterProps, GetterQueryParam, GetterResponse, GlobalMockOptions, GlobalOptions, HonoOptions, Hook, HookCommand, HookFunction, HookOption, HooksOptions, ImportOpenApi, InputFiltersOptions, InputOptions, InputTransformerFn, InvalidateTarget, JsDocOptions, LogLevel, LogLevels, LogOptions, LogType, Logger, LoggerOptions, MockData, MockDataArray, MockDataArrayFn, MockDataObject, MockDataObjectFn, MockOptions, MockProperties, MockPropertiesObject, MockPropertiesObjectFn, MutationInvalidatesConfig, MutationInvalidatesRule, Mutator, MutatorObject, NamingConvention, NormalizedConfig, NormalizedFetchOptions, NormalizedFormDataType, NormalizedHonoOptions, NormalizedHookCommand, NormalizedHookOptions, NormalizedInputOptions, NormalizedJsDocOptions, NormalizedMutator, NormalizedOperationOptions, NormalizedOptions, NormalizedOutputOptions, NormalizedOverrideOutput, NormalizedParamsSerializerOptions, NormalizedQueryOptions, NormalizedSchemaOptions, NormalizedZodOptions, OpenApiComponentsObject, OpenApiDocument, OpenApiEncodingObject, OpenApiExampleObject, OpenApiInfoObject, OpenApiMediaTypeObject, OpenApiOperationObject, OpenApiParameterObject, OpenApiPathItemObject, OpenApiPathsObject, OpenApiReferenceObject, OpenApiRequestBodyObject, OpenApiResponseObject, OpenApiResponsesObject, OpenApiSchemaObject, OpenApiSchemaObjectType, OpenApiSchemasObject, OpenApiServerObject, OperationOptions, Options, OptionsExport, OptionsFn, OutputClient, OutputClientFunc, OutputDocsOptions, OutputHttpClient, OutputMockType, OutputMode, OutputOptions, OverrideInput, OverrideMockOptions, OverrideOutput, OverrideOutputContentType, PackageJson, ParamsSerializerOptions, PropertySortOrder, QueryOptions, RefComponentSuffix, RefInfo, ResReqTypesValue, ResolverValue, ResponseTypeCategory, ScalarValue, SchemaGenerationType, SchemaOptions, SchemaType, SwrOptions, TEMPLATE_TAG_REGEX, TsConfigTarget, Tsconfig, URL_REGEX, VERBS_WITH_BODY, Verbs, WriteModeProps, WriteSpecBuilder, ZodCoerceType, ZodDateTimeOptions, ZodOptions, ZodTimeOptions, _filteredVerbs, addDependency, asyncReduce, camel, combineSchemas, compareVersions, conventionName, count, createDebugger, createLogger, createSuccessMessage, createTypeAliasIfNeeded, dynamicImport, escape, fixCrossDirectoryImports, fixRegularSchemaImports, generalJSTypes, generalJSTypesWithArray, generateAxiosOptions, generateBodyMutatorConfig, generateBodyOptions, generateComponentDefinition, generateDependencyImports, generateFormDataAndUrlEncodedFunction, generateImports, generateModelInline, generateModelsInline, generateMutator, generateMutatorConfig, generateMutatorImports, generateMutatorRequestOptions, generateOptions, generateParameterDefinition, generateQueryParamsAxiosConfig, generateSchemasDefinition, generateTarget, generateTargetForTags, generateVerbImports, generateVerbOptions, generateVerbsOptions, getArray, getBody, getDefaultContentType, getEnum, getEnumDescriptions, getEnumImplementation, getEnumNames, getExtension, getFileInfo, getFormDataFieldFileType, getFullRoute, getIsBodyVerb, getKey, getMockFileExtensionByTypeName, getNumberWord, getObject, getOperationId, getOrvalGeneratedTypes, getParameters, getParams, getParamsInPath, getPropertySafe, getProps, getQueryParams, getRefInfo, getResReqTypes, getResponse, getResponseTypeCategory, getRoute, getRouteAsArray, getScalar, getTypedResponse, isBinaryContentType, isBoolean, isDirectory, isFunction, isModule, isNull, isNumber, isNumeric, isObject, isReference, isSchema, isString, isSyntheticDefaultImportsAllow, isUndefined, isUrl, isVerb, jsDoc, jsStringEscape, kebab, keyValuePairsToJsDoc, log, logError, mergeDeep, mismatchArgsMessage, pascal, removeFilesAndEmptyFolders, resolveDiscriminators, resolveExampleRefs, resolveObject, resolveRef, resolveValue, sanitize, snake, sortByPriority, splitSchemasByType, startMessage, stringify, toObjectString, path_d_exports as upath, upper, writeModelInline, writeModelsInline, writeSchema, writeSchemas, writeSingleMode, writeSplitMode, writeSplitTagsMode, writeTagsMode };
1996
+ export { AngularOptions, BODY_TYPE_NAME, BaseUrlFromConstant, BaseUrlFromSpec, ClientBuilder, ClientDependenciesBuilder, ClientExtraFilesBuilder, ClientFileBuilder, ClientFooterBuilder, ClientGeneratorsBuilder, ClientHeaderBuilder, ClientMockBuilder, ClientMockGeneratorBuilder, ClientMockGeneratorImplementation, ClientTitleBuilder, Config, ConfigExternal, ConfigFn, ContextSpec, DeepNonNullable, EnumGeneration, ErrorWithTag, FetchOptions, FormDataArrayHandling, FormDataType, GenerateMockImports, GenerateVerbOptionsParams, GenerateVerbsOptionsParams, GeneratorApiBuilder, GeneratorApiOperations, GeneratorApiResponse, GeneratorClient, GeneratorClientExtra, GeneratorClientFooter, GeneratorClientHeader, GeneratorClientImports, GeneratorClientTitle, GeneratorClients, GeneratorDependency, GeneratorImport, GeneratorMutator, GeneratorMutatorParsingInfo, GeneratorOperation, GeneratorOperations, GeneratorOptions, GeneratorSchema, GeneratorTarget, GeneratorTargetFull, GeneratorVerbOptions, GeneratorVerbsOptions, GetterBody, GetterParam, GetterParameters, GetterParams, GetterProp, GetterPropType, GetterProps, GetterQueryParam, GetterResponse, GlobalMockOptions, GlobalOptions, HonoOptions, Hook, HookCommand, HookFunction, HookOption, HooksOptions, ImportOpenApi, InputFiltersOptions, InputOptions, InputTransformerFn, InvalidateTarget, JsDocOptions, LogLevel, LogLevels, LogOptions, LogType, Logger, LoggerOptions, MockData, MockDataArray, MockDataArrayFn, MockDataObject, MockDataObjectFn, MockOptions, MockProperties, MockPropertiesObject, MockPropertiesObjectFn, MutationInvalidatesConfig, MutationInvalidatesRule, Mutator, MutatorObject, NamingConvention, NormalizedConfig, NormalizedFetchOptions, NormalizedFormDataType, NormalizedHonoOptions, NormalizedHookCommand, NormalizedHookOptions, NormalizedInputOptions, NormalizedJsDocOptions, NormalizedMutator, NormalizedOperationOptions, NormalizedOptions, NormalizedOutputOptions, NormalizedOverrideOutput, NormalizedParamsSerializerOptions, NormalizedQueryOptions, NormalizedSchemaOptions, NormalizedZodOptions, OpenApiComponentsObject, OpenApiDocument, OpenApiEncodingObject, OpenApiExampleObject, OpenApiInfoObject, OpenApiMediaTypeObject, OpenApiOperationObject, OpenApiParameterObject, OpenApiPathItemObject, OpenApiPathsObject, OpenApiReferenceObject, OpenApiRequestBodyObject, OpenApiResponseObject, OpenApiResponsesObject, OpenApiSchemaObject, OpenApiSchemaObjectType, OpenApiSchemasObject, OpenApiServerObject, OperationOptions, Options, OptionsExport, OptionsFn, OutputClient, OutputClientFunc, OutputDocsOptions, OutputHttpClient, OutputMockType, OutputMode, OutputOptions, OverrideInput, OverrideMockOptions, OverrideOutput, OverrideOutputContentType, PackageJson, ParamsSerializerOptions, PropertySortOrder, QueryOptions, RefComponentSuffix, RefInfo, ResReqTypesValue, ResolverValue, ResponseTypeCategory, ScalarValue, SchemaGenerationType, SchemaOptions, SchemaType, SwrOptions, TEMPLATE_TAG_REGEX, TsConfigTarget, Tsconfig, URL_REGEX, VERBS_WITH_BODY, Verbs, WriteModeProps, WriteSpecBuilder, ZodCoerceType, ZodDateTimeOptions, ZodOptions, ZodTimeOptions, _filteredVerbs, addDependency, asyncReduce, camel, combineSchemas, compareVersions, conventionName, count, createDebugger, createLogger, createSuccessMessage, createTypeAliasIfNeeded, dedupeUnionType, dynamicImport, escape, fixCrossDirectoryImports, fixRegularSchemaImports, generalJSTypes, generalJSTypesWithArray, generateAxiosOptions, generateBodyMutatorConfig, generateBodyOptions, generateComponentDefinition, generateDependencyImports, generateFormDataAndUrlEncodedFunction, generateImports, generateModelInline, generateModelsInline, generateMutator, generateMutatorConfig, generateMutatorImports, generateMutatorRequestOptions, generateOptions, generateParameterDefinition, generateQueryParamsAxiosConfig, generateSchemasDefinition, generateTarget, generateTargetForTags, generateVerbImports, generateVerbOptions, generateVerbsOptions, getArray, getBody, getCombinedEnumValue, getDefaultContentType, getEnum, getEnumDescriptions, getEnumImplementation, getEnumNames, getEnumUnionFromSchema, getExtension, getFileInfo, getFormDataFieldFileType, getFullRoute, getIsBodyVerb, getKey, getMockFileExtensionByTypeName, getNumberWord, getObject, getOperationId, getOrvalGeneratedTypes, getParameters, getParams, getParamsInPath, getPropertySafe, getProps, getQueryParams, getRefInfo, getResReqTypes, getResponse, getResponseTypeCategory, getRoute, getRouteAsArray, getScalar, getTypedResponse, isBinaryContentType, isBoolean, isDirectory, isFunction, isModule, isNull, isNumber, isNumeric, isObject, isReference, isSchema, isString, isSyntheticDefaultImportsAllow, isUndefined, isUrl, isVerb, jsDoc, jsStringEscape, kebab, keyValuePairsToJsDoc, log, logError, mergeDeep, mismatchArgsMessage, pascal, removeFilesAndEmptyFolders, resolveDiscriminators, resolveExampleRefs, resolveObject, resolveRef, resolveValue, sanitize, snake, sortByPriority, splitSchemasByType, startMessage, stringify, toObjectString, path_d_exports as upath, upper, writeModelInline, writeModelsInline, writeSchema, writeSchemas, writeSingleMode, writeSplitMode, writeSplitTagsMode, writeTagsMode };
1967
1997
  //# sourceMappingURL=index.d.mts.map
package/dist/index.mjs CHANGED
@@ -810,6 +810,14 @@ function jsStringEscape(input) {
810
810
  }
811
811
  });
812
812
  }
813
+ /**
814
+ * Deduplicates a TypeScript union type string.
815
+ * Handles types like "A | B | B" → "A | B" and "null | null" → "null".
816
+ */
817
+ function dedupeUnionType(unionType) {
818
+ const parts = unionType.split("|").map((part) => part.trim());
819
+ return [...new Set(parts)].join(" | ");
820
+ }
813
821
 
814
822
  //#endregion
815
823
  //#region src/utils/tsconfig.ts
@@ -895,6 +903,76 @@ const toNumberKey = (value) => {
895
903
  const getUnion = (value, enumName) => {
896
904
  return `export type ${enumName} = ${value};`;
897
905
  };
906
+ function getEnumUnionFromSchema(schema) {
907
+ if (!schema?.enum) return "";
908
+ return schema.enum.filter((val) => val !== null).map((val) => isString(val) ? `'${escape(val)}'` : `${val}`).join(" | ");
909
+ }
910
+ const stripNullUnion = (value) => value.replace(/\s*\|\s*null/g, "").trim();
911
+ const isSpreadableEnumRef = (schema, refName) => {
912
+ if (!schema?.enum || !refName) return false;
913
+ if (!getEnumUnionFromSchema(schema)) return false;
914
+ const type = schema.type;
915
+ if (type === "boolean" || Array.isArray(type) && type.includes("boolean")) return false;
916
+ return /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(refName);
917
+ };
918
+ const buildInlineEnum = (schema, enumValue) => {
919
+ const names = getEnumNames(schema);
920
+ const descriptions = getEnumDescriptions(schema);
921
+ return getEnumImplementation(enumValue ?? getEnumUnionFromSchema(schema), names, descriptions);
922
+ };
923
+ function getCombinedEnumValue(inputs) {
924
+ const valueImports = [];
925
+ const hasNull = inputs.some((input) => {
926
+ if (input.value.includes("| null")) return true;
927
+ const schema = input.schema;
928
+ if (!schema) return false;
929
+ if (schema.nullable === true) return true;
930
+ if (Array.isArray(schema.type) && schema.type.includes("null")) return true;
931
+ return schema.enum?.includes(null) ?? false;
932
+ });
933
+ const addValueImport = (name) => {
934
+ if (!valueImports.includes(name)) valueImports.push(name);
935
+ };
936
+ if (inputs.length === 1) {
937
+ const input = inputs[0];
938
+ if (input.isRef) {
939
+ const refName = stripNullUnion(input.value);
940
+ if (isSpreadableEnumRef(input.schema, refName)) {
941
+ addValueImport(refName);
942
+ return {
943
+ value: refName,
944
+ valueImports,
945
+ hasNull
946
+ };
947
+ }
948
+ return {
949
+ value: `{${buildInlineEnum(input.schema)}} as const`,
950
+ valueImports,
951
+ hasNull
952
+ };
953
+ }
954
+ return {
955
+ value: `{${buildInlineEnum(input.schema, stripNullUnion(input.value))}} as const`,
956
+ valueImports,
957
+ hasNull
958
+ };
959
+ }
960
+ return {
961
+ value: `{${inputs.map((input) => {
962
+ if (input.isRef) {
963
+ const refName = stripNullUnion(input.value);
964
+ if (isSpreadableEnumRef(input.schema, refName)) {
965
+ addValueImport(refName);
966
+ return `...${refName},`;
967
+ }
968
+ return buildInlineEnum(input.schema);
969
+ }
970
+ return buildInlineEnum(input.schema, stripNullUnion(input.value));
971
+ }).join("")}} as const`,
972
+ valueImports,
973
+ hasNull
974
+ };
975
+ }
898
976
 
899
977
  //#endregion
900
978
  //#region src/getters/ref.ts
@@ -1461,13 +1539,20 @@ function combineSchemas({ name, schema, separator: separator$1, context, nullabl
1461
1539
  examples: resolveExampleRefs(schema.examples, context),
1462
1540
  requiredProperties: separator$1 === "allOf" ? schema.required ?? [] : []
1463
1541
  });
1464
- if (resolvedData.isEnum.every(Boolean) && name && items.length > 1 && separator$1 !== "oneOf") {
1465
- const newEnum = `export const ${pascal(name)} = ${getCombineEnumValue(resolvedData)}`;
1542
+ if (resolvedData.isEnum.every(Boolean) && name && items.length > 1 && context.output.override.enumGenerationType !== EnumGeneration.UNION) {
1543
+ const { value: combinedEnumValue, valueImports, hasNull } = getCombinedEnumValue(resolvedData.values.map((value, index) => ({
1544
+ value,
1545
+ isRef: resolvedData.isRef[index],
1546
+ schema: resolvedData.originalSchema[index]
1547
+ })));
1548
+ const newEnum = `export const ${pascal(name)} = ${combinedEnumValue}`;
1549
+ const valueImportSet = new Set(valueImports);
1550
+ const typeSuffix = `${nullable}${hasNull && !nullable.includes("null") ? " | null" : ""}`;
1466
1551
  return {
1467
- value: `typeof ${pascal(name)}[keyof typeof ${pascal(name)}] ${nullable}`,
1552
+ value: `typeof ${pascal(name)}[keyof typeof ${pascal(name)}]${typeSuffix}`,
1468
1553
  imports: [{ name: pascal(name) }],
1469
1554
  schemas: [...resolvedData.schemas, {
1470
- imports: resolvedData.imports.map((toImport) => ({
1555
+ imports: resolvedData.imports.filter((toImport) => valueImportSet.has(toImport.alias ?? toImport.name)).map((toImport) => ({
1471
1556
  ...toImport,
1472
1557
  values: true
1473
1558
  })),
@@ -1500,12 +1585,12 @@ function combineSchemas({ name, schema, separator: separator$1, context, nullabl
1500
1585
  });
1501
1586
  }
1502
1587
  return {
1503
- value: combineValues({
1588
+ value: dedupeUnionType(combineValues({
1504
1589
  resolvedData,
1505
1590
  separator: separator$1,
1506
1591
  resolvedValue,
1507
1592
  context
1508
- }) + nullable,
1593
+ }) + nullable),
1509
1594
  imports: resolvedValue ? [...resolvedData.imports, ...resolvedValue.imports] : resolvedData.imports,
1510
1595
  schemas: resolvedValue ? [...resolvedData.schemas, ...resolvedValue.schemas] : resolvedData.schemas,
1511
1596
  dependencies: resolvedValue ? [...resolvedData.dependencies, ...resolvedValue.dependencies] : resolvedData.dependencies,
@@ -1517,16 +1602,6 @@ function combineSchemas({ name, schema, separator: separator$1, context, nullabl
1517
1602
  examples: resolveExampleRefs(schema.examples, context)
1518
1603
  };
1519
1604
  }
1520
- const getCombineEnumValue = ({ values, isRef, originalSchema }) => {
1521
- if (values.length === 1) {
1522
- if (isRef[0]) return values[0];
1523
- return `{${getEnumImplementation(values[0])}} as const`;
1524
- }
1525
- return `{${values.map((e, i) => {
1526
- if (isRef[i]) return `...${e},`;
1527
- return getEnumImplementation(e, getEnumNames(originalSchema[i]), getEnumDescriptions(originalSchema[i]));
1528
- }).join("")}} as const`;
1529
- };
1530
1605
 
1531
1606
  //#endregion
1532
1607
  //#region src/getters/keys.ts
@@ -1552,6 +1627,11 @@ function getIndexSignatureKey(item) {
1552
1627
  if (enumValues && enumValues.length > 0) return enumValues.map((val) => `'${val}'`).join(" | ");
1553
1628
  return "string";
1554
1629
  }
1630
+ function getPropertyNamesRecordType(item, valueType) {
1631
+ const enumValues = getPropertyNamesEnum(item);
1632
+ if (!enumValues || enumValues.length === 0) return;
1633
+ return `Partial<Record<${enumValues.map((val) => `'${val}'`).join(" | ")}, ${valueType}>>`;
1634
+ }
1555
1635
  /**
1556
1636
  * Return the output type from an object
1557
1637
  *
@@ -1635,23 +1715,39 @@ function getObject({ item, name, context, nullable, propertyOverrides }) {
1635
1715
  imports: aliasedImports
1636
1716
  });
1637
1717
  const propValue = needsValueImport ? alias : constLiteral ?? alias;
1638
- acc.value += `\n ${doc ? `${doc} ` : ""}${isReadOnly && !context.output.override.suppressReadonlyModifier ? "readonly " : ""}${getKey(key)}${isRequired ? "" : "?"}: ${propValue};`;
1718
+ const finalPropValue = isRequired ? propValue : context.output.override.useNullForOptional === true ? `${propValue} | null` : propValue;
1719
+ acc.value += `\n ${doc ? `${doc} ` : ""}${isReadOnly && !context.output.override.suppressReadonlyModifier ? "readonly " : ""}${getKey(key)}${isRequired ? "" : "?"}: ${finalPropValue};`;
1639
1720
  acc.schemas.push(...resolvedValue.schemas);
1640
1721
  acc.dependencies.push(...resolvedValue.dependencies);
1641
1722
  if (arr.length - 1 === index) {
1642
- if (item.additionalProperties) {
1643
- const keyType$1 = getIndexSignatureKey(item);
1644
- if (isBoolean(item.additionalProperties)) acc.value += `\n [key: ${keyType$1}]: unknown;\n }`;
1645
- else {
1646
- const resolvedValue$1 = resolveValue({
1647
- schema: item.additionalProperties,
1648
- name,
1649
- context
1650
- });
1723
+ if (item.additionalProperties) if (isBoolean(item.additionalProperties)) {
1724
+ const recordType$1 = getPropertyNamesRecordType(item, "unknown");
1725
+ if (recordType$1) {
1726
+ acc.value += "\n}";
1727
+ acc.value += ` & ${recordType$1}`;
1728
+ acc.useTypeAlias = true;
1729
+ } else {
1730
+ const keyType$1 = getIndexSignatureKey(item);
1731
+ acc.value += `\n [key: ${keyType$1}]: unknown;\n }`;
1732
+ }
1733
+ } else {
1734
+ const resolvedValue$1 = resolveValue({
1735
+ schema: item.additionalProperties,
1736
+ name,
1737
+ context
1738
+ });
1739
+ const recordType$1 = getPropertyNamesRecordType(item, resolvedValue$1.value);
1740
+ if (recordType$1) {
1741
+ acc.value += "\n}";
1742
+ acc.value += ` & ${recordType$1}`;
1743
+ acc.useTypeAlias = true;
1744
+ } else {
1745
+ const keyType$1 = getIndexSignatureKey(item);
1651
1746
  acc.value += `\n [key: ${keyType$1}]: ${resolvedValue$1.value};\n}`;
1652
- acc.dependencies.push(...resolvedValue$1.dependencies);
1653
1747
  }
1654
- } else acc.value += "\n}";
1748
+ acc.dependencies.push(...resolvedValue$1.dependencies);
1749
+ }
1750
+ else acc.value += "\n}";
1655
1751
  acc.value += nullable;
1656
1752
  }
1657
1753
  return acc;
@@ -1664,36 +1760,64 @@ function getObject({ item, name, context, nullable, propertyOverrides }) {
1664
1760
  isRef: false,
1665
1761
  schema: {},
1666
1762
  hasReadonlyProps: false,
1763
+ useTypeAlias: false,
1667
1764
  dependencies: [],
1668
1765
  example: item.example,
1669
1766
  examples: resolveExampleRefs(item.examples, context)
1670
1767
  });
1671
1768
  }
1672
1769
  if (item.additionalProperties) {
1673
- const keyType$1 = getIndexSignatureKey(item);
1674
- if (isBoolean(item.additionalProperties)) return {
1675
- value: `{ [key: ${keyType$1}]: unknown }` + nullable,
1676
- imports: [],
1677
- schemas: [],
1678
- isEnum: false,
1679
- type: "object",
1680
- isRef: false,
1681
- hasReadonlyProps: item.readOnly || false,
1682
- dependencies: []
1683
- };
1770
+ if (isBoolean(item.additionalProperties)) {
1771
+ const recordType$2 = getPropertyNamesRecordType(item, "unknown");
1772
+ if (recordType$2) return {
1773
+ value: recordType$2 + nullable,
1774
+ imports: [],
1775
+ schemas: [],
1776
+ isEnum: false,
1777
+ type: "object",
1778
+ isRef: false,
1779
+ hasReadonlyProps: item.readOnly || false,
1780
+ useTypeAlias: true,
1781
+ dependencies: []
1782
+ };
1783
+ return {
1784
+ value: `{ [key: ${getIndexSignatureKey(item)}]: unknown }` + nullable,
1785
+ imports: [],
1786
+ schemas: [],
1787
+ isEnum: false,
1788
+ type: "object",
1789
+ isRef: false,
1790
+ hasReadonlyProps: item.readOnly || false,
1791
+ useTypeAlias: false,
1792
+ dependencies: []
1793
+ };
1794
+ }
1684
1795
  const resolvedValue = resolveValue({
1685
1796
  schema: item.additionalProperties,
1686
1797
  name,
1687
1798
  context
1688
1799
  });
1800
+ const recordType$1 = getPropertyNamesRecordType(item, resolvedValue.value);
1801
+ if (recordType$1) return {
1802
+ value: recordType$1 + nullable,
1803
+ imports: resolvedValue.imports ?? [],
1804
+ schemas: resolvedValue.schemas ?? [],
1805
+ isEnum: false,
1806
+ type: "object",
1807
+ isRef: false,
1808
+ hasReadonlyProps: resolvedValue.hasReadonlyProps,
1809
+ useTypeAlias: true,
1810
+ dependencies: resolvedValue.dependencies
1811
+ };
1689
1812
  return {
1690
- value: `{[key: ${keyType$1}]: ${resolvedValue.value}}` + nullable,
1813
+ value: `{[key: ${getIndexSignatureKey(item)}]: ${resolvedValue.value}}` + nullable,
1691
1814
  imports: resolvedValue.imports ?? [],
1692
1815
  schemas: resolvedValue.schemas ?? [],
1693
1816
  isEnum: false,
1694
1817
  type: "object",
1695
1818
  isRef: false,
1696
1819
  hasReadonlyProps: resolvedValue.hasReadonlyProps,
1820
+ useTypeAlias: false,
1697
1821
  dependencies: resolvedValue.dependencies
1698
1822
  };
1699
1823
  }
@@ -1709,6 +1833,18 @@ function getObject({ item, name, context, nullable, propertyOverrides }) {
1709
1833
  dependencies: []
1710
1834
  };
1711
1835
  const keyType = item.type === "object" ? getIndexSignatureKey(item) : "string";
1836
+ const recordType = getPropertyNamesRecordType(item, "unknown");
1837
+ if (item.type === "object" && recordType) return {
1838
+ value: recordType + nullable,
1839
+ imports: [],
1840
+ schemas: [],
1841
+ isEnum: false,
1842
+ type: "object",
1843
+ isRef: false,
1844
+ hasReadonlyProps: item.readOnly || false,
1845
+ useTypeAlias: true,
1846
+ dependencies: []
1847
+ };
1712
1848
  return {
1713
1849
  value: (item.type === "object" ? `{ [key: ${keyType}]: unknown }` : "unknown") + nullable,
1714
1850
  imports: [],
@@ -1717,6 +1853,7 @@ function getObject({ item, name, context, nullable, propertyOverrides }) {
1717
1853
  type: "object",
1718
1854
  isRef: false,
1719
1855
  hasReadonlyProps: item.readOnly || false,
1856
+ useTypeAlias: false,
1720
1857
  dependencies: []
1721
1858
  };
1722
1859
  }
@@ -2240,7 +2377,7 @@ function resolveDiscriminators(schemas, context) {
2240
2377
  //#endregion
2241
2378
  //#region src/getters/operation.ts
2242
2379
  function getOperationId(operation, route, verb) {
2243
- if (operation.operationId) return operation.operationId;
2380
+ if (isString(operation.operationId)) return operation.operationId;
2244
2381
  return pascal([verb, ...route.split("/").map((p) => sanitize(p, {
2245
2382
  dash: true,
2246
2383
  underscore: "-",
@@ -2331,10 +2468,10 @@ function getParams({ route, pathParams = [], operationId, context, output }) {
2331
2468
  function getProps({ body, queryParams, params, operationName, headers, context }) {
2332
2469
  const bodyProp = {
2333
2470
  name: body.implementation,
2334
- definition: `${body.implementation}${body.isOptional ? "?" : ""}: ${body.definition}`,
2335
- implementation: `${body.implementation}${body.isOptional ? "?" : ""}: ${body.definition}`,
2471
+ definition: `${body.implementation}${body.isOptional && !context.output.optionsParamRequired ? "?" : ""}: ${body.definition}`,
2472
+ implementation: `${body.implementation}${body.isOptional && !context.output.optionsParamRequired ? "?" : ""}: ${body.definition}`,
2336
2473
  default: false,
2337
- required: !body.isOptional,
2474
+ required: !body.isOptional || context.output.optionsParamRequired,
2338
2475
  type: GetterPropType.BODY
2339
2476
  };
2340
2477
  const queryParamsProp = {
@@ -2342,15 +2479,15 @@ function getProps({ body, queryParams, params, operationName, headers, context }
2342
2479
  definition: getQueryParamDefinition(queryParams, context),
2343
2480
  implementation: getQueryParamDefinition(queryParams, context),
2344
2481
  default: false,
2345
- required: isUndefined(queryParams?.isOptional) ? !context.output.allParamsOptional : !queryParams?.isOptional && !context.output.allParamsOptional,
2482
+ required: isUndefined(queryParams?.isOptional) ? !context.output.allParamsOptional || context.output.optionsParamRequired : !queryParams?.isOptional && !context.output.allParamsOptional || context.output.optionsParamRequired,
2346
2483
  type: GetterPropType.QUERY_PARAM
2347
2484
  };
2348
2485
  const headersProp = {
2349
2486
  name: "headers",
2350
- definition: `headers${headers?.isOptional ? "?" : ""}: ${headers?.schema.name}`,
2351
- implementation: `headers${headers?.isOptional ? "?" : ""}: ${headers?.schema.name}`,
2487
+ definition: `headers${headers?.isOptional && !context.output.optionsParamRequired ? "?" : ""}: ${headers?.schema.name}`,
2488
+ implementation: `headers${headers?.isOptional && !context.output.optionsParamRequired ? "?" : ""}: ${headers?.schema.name}`,
2352
2489
  default: false,
2353
- required: isUndefined(headers?.isOptional) ? false : !headers?.isOptional,
2490
+ required: isUndefined(headers?.isOptional) ? false : !headers?.isOptional || context.output.optionsParamRequired,
2354
2491
  type: GetterPropType.HEADER
2355
2492
  };
2356
2493
  let paramGetterProps;
@@ -2358,7 +2495,7 @@ function getProps({ body, queryParams, params, operationName, headers, context }
2358
2495
  const parameterTypeName = `${pascal(operationName)}PathParameters`;
2359
2496
  const name = "pathParams";
2360
2497
  const namedParametersTypeDefinition = `export type ${parameterTypeName} = {\n ${params.map((property) => property.definition).join(",\n ")},\n }`;
2361
- const isOptional = params.every((param) => param.default);
2498
+ const isOptional = context.output.optionsParamRequired || params.every((param) => param.default);
2362
2499
  const implementation = `{ ${params.map((property) => property.default ? `${property.name} = ${property.default}` : property.name).join(", ")} }: ${parameterTypeName}${isOptional ? " = {}" : ""}`;
2363
2500
  const destructured = `{ ${params.map((property) => property.name).join(", ")} }`;
2364
2501
  paramGetterProps = [{
@@ -2389,7 +2526,7 @@ function getProps({ body, queryParams, params, operationName, headers, context }
2389
2526
  function getQueryParamDefinition(queryParams, context) {
2390
2527
  let paramType = queryParams?.schema.name;
2391
2528
  if (OutputClient.ANGULAR === context.output.client) paramType = `DeepNonNullable<${paramType}>`;
2392
- return `params${queryParams?.isOptional || context.output.allParamsOptional ? "?" : ""}: ${paramType}`;
2529
+ return `params${(queryParams?.isOptional || context.output.allParamsOptional) && !context.output.optionsParamRequired ? "?" : ""}: ${paramType}`;
2393
2530
  }
2394
2531
 
2395
2532
  //#endregion
@@ -2498,8 +2635,8 @@ function getResponse({ responses, operationName, context, contentType }) {
2498
2635
  success: [],
2499
2636
  errors: []
2500
2637
  });
2501
- const success = groupedByStatus.success.map(({ value, formData }) => formData ? "Blob" : value).join(" | ");
2502
- const errors = groupedByStatus.errors.map(({ value }) => value).join(" | ");
2638
+ const success = dedupeUnionType(groupedByStatus.success.map(({ value, formData }) => formData ? "Blob" : value).join(" | "));
2639
+ const errors = dedupeUnionType(groupedByStatus.errors.map(({ value }) => value).join(" | "));
2503
2640
  const defaultType = filteredTypes.find(({ key }) => key === "default")?.value;
2504
2641
  return {
2505
2642
  imports,
@@ -3043,10 +3180,11 @@ function generateInterface({ name, schema, context }) {
3043
3180
  context
3044
3181
  });
3045
3182
  const isEmptyObject = scalar.value === "{}";
3183
+ const shouldUseTypeAlias = context?.output.override?.useTypeOverInterfaces || scalar.useTypeAlias;
3046
3184
  let model = "";
3047
3185
  model += jsDoc(schema);
3048
3186
  if (isEmptyObject) model += "// eslint-disable-next-line @typescript-eslint/no-empty-interface\n";
3049
- if (scalar.type === "object" && !context?.output.override?.useTypeOverInterfaces) if (scalar.type === "object" && schema.properties && Object.values(schema.properties).length > 0 && Object.values(schema.properties).every((item) => "const" in item)) {
3187
+ if (scalar.type === "object" && !shouldUseTypeAlias) if (scalar.type === "object" && schema.properties && Object.values(schema.properties).length > 0 && Object.values(schema.properties).every((item) => "const" in item)) {
3050
3188
  const mappedScalarValue = scalar.value.replaceAll(";", ",").replaceAll("?:", ":");
3051
3189
  model += `export const ${name}Value = ${mappedScalarValue} as const;\nexport type ${name} = typeof ${name}Value;\n`;
3052
3190
  } else {
@@ -3198,7 +3336,7 @@ function generateSchemaDefinitions(schemaName, schema, context, suffix) {
3198
3336
  async function generateVerbOptions({ verb, output, operation, route, pathRoute, verbParameters = [], context }) {
3199
3337
  const { responses, requestBody, parameters: operationParameters, tags = [], deprecated, description, summary } = operation;
3200
3338
  const operationId = getOperationId(operation, route, verb);
3201
- const overrideOperation = output.override.operations[operation.operationId];
3339
+ const overrideOperation = output.override.operations[operationId];
3202
3340
  const overrideTag = Object.entries(output.override.tags).reduce((acc, [tag, options]) => tags.includes(tag) && options ? mergeDeep(acc, options) : acc, {});
3203
3341
  const override = mergeDeep(mergeDeep(output.override, overrideTag), overrideOperation);
3204
3342
  const overrideOperationName = overrideOperation?.operationName ?? output.override.operationName;
@@ -3518,7 +3656,13 @@ async function writeSchemas({ schemaPath, schemas, target, namingConvention, fil
3518
3656
  const ext = fileExtension.endsWith(".ts") ? fileExtension.slice(0, -3) : fileExtension;
3519
3657
  const conventionNamesSet = new Set(Object.values(schemaGroups).map((group) => conventionName(group[0].name, namingConvention)));
3520
3658
  try {
3521
- const fileContent = `${header}\n${[...conventionNamesSet].map((schemaName) => `export * from './${schemaName}${ext}';`).toSorted((a, b) => a.localeCompare(b)).join("\n")}`;
3659
+ const currentExports = [...conventionNamesSet].map((schemaName) => `export * from './${schemaName}${ext}';`).toSorted((a, b) => a.localeCompare(b));
3660
+ const existingExports = (await fs$1.readFile(schemaFilePath, "utf8")).match(/export\s+\*\s+from\s+['"][^'"]+['"]/g)?.map((statement) => {
3661
+ const match = statement.match(/export\s+\*\s+from\s+['"]([^'"]+)['"]/);
3662
+ if (!match) return void 0;
3663
+ return `export * from '${match[1]}';`;
3664
+ }).filter((statement) => Boolean(statement)) ?? [];
3665
+ const fileContent = `${header}\n${[...new Set([...existingExports, ...currentExports])].toSorted((a, b) => a.localeCompare(b)).join("\n")}`;
3522
3666
  await fs$1.writeFile(schemaFilePath, fileContent, { encoding: "utf8" });
3523
3667
  } catch (error) {
3524
3668
  throw new Error(`Oups... 🍻. An Error occurred while writing schema index file ${schemaFilePath} => ${error}`);
@@ -4104,5 +4248,5 @@ async function writeTagsMode({ builder, output, projectName, header, needSchema
4104
4248
  }
4105
4249
 
4106
4250
  //#endregion
4107
- export { BODY_TYPE_NAME, EnumGeneration, ErrorWithTag, FormDataArrayHandling, GetterPropType, LogLevels, NamingConvention, OutputClient, OutputHttpClient, OutputMockType, OutputMode, PropertySortOrder, RefComponentSuffix, SchemaType, TEMPLATE_TAG_REGEX, URL_REGEX, VERBS_WITH_BODY, Verbs, _filteredVerbs, addDependency, asyncReduce, camel, combineSchemas, compareVersions, conventionName, count, createDebugger, createLogger, createSuccessMessage, createTypeAliasIfNeeded, dynamicImport, escape, fixCrossDirectoryImports, fixRegularSchemaImports, generalJSTypes, generalJSTypesWithArray, generateAxiosOptions, generateBodyMutatorConfig, generateBodyOptions, generateComponentDefinition, generateDependencyImports, generateFormDataAndUrlEncodedFunction, generateImports, generateModelInline, generateModelsInline, generateMutator, generateMutatorConfig, generateMutatorImports, generateMutatorRequestOptions, generateOptions, generateParameterDefinition, generateQueryParamsAxiosConfig, generateSchemasDefinition, generateTarget, generateTargetForTags, generateVerbImports, generateVerbOptions, generateVerbsOptions, getArray, getBody, getDefaultContentType, getEnum, getEnumDescriptions, getEnumImplementation, getEnumNames, getExtension, getFileInfo, getFormDataFieldFileType, getFullRoute, getIsBodyVerb, getKey, getMockFileExtensionByTypeName, getNumberWord, getObject, getOperationId, getOrvalGeneratedTypes, getParameters, getParams, getParamsInPath, getPropertySafe, getProps, getQueryParams, getRefInfo, getResReqTypes, getResponse, getResponseTypeCategory, getRoute, getRouteAsArray, getScalar, getTypedResponse, isBinaryContentType, isBoolean, isDirectory, isFunction, isModule, isNull, isNumber, isNumeric, isObject, isReference, isSchema, isString, isSyntheticDefaultImportsAllow, isUndefined, isUrl, isVerb, jsDoc, jsStringEscape, kebab, keyValuePairsToJsDoc, log, logError, mergeDeep, mismatchArgsMessage, pascal, removeFilesAndEmptyFolders, resolveDiscriminators, resolveExampleRefs, resolveObject, resolveRef, resolveValue, sanitize, snake, sortByPriority, splitSchemasByType, startMessage, stringify, toObjectString, path_exports as upath, upper, writeModelInline, writeModelsInline, writeSchema, writeSchemas, writeSingleMode, writeSplitMode, writeSplitTagsMode, writeTagsMode };
4251
+ export { BODY_TYPE_NAME, EnumGeneration, ErrorWithTag, FormDataArrayHandling, GetterPropType, LogLevels, NamingConvention, OutputClient, OutputHttpClient, OutputMockType, OutputMode, PropertySortOrder, RefComponentSuffix, SchemaType, TEMPLATE_TAG_REGEX, URL_REGEX, VERBS_WITH_BODY, Verbs, _filteredVerbs, addDependency, asyncReduce, camel, combineSchemas, compareVersions, conventionName, count, createDebugger, createLogger, createSuccessMessage, createTypeAliasIfNeeded, dedupeUnionType, dynamicImport, escape, fixCrossDirectoryImports, fixRegularSchemaImports, generalJSTypes, generalJSTypesWithArray, generateAxiosOptions, generateBodyMutatorConfig, generateBodyOptions, generateComponentDefinition, generateDependencyImports, generateFormDataAndUrlEncodedFunction, generateImports, generateModelInline, generateModelsInline, generateMutator, generateMutatorConfig, generateMutatorImports, generateMutatorRequestOptions, generateOptions, generateParameterDefinition, generateQueryParamsAxiosConfig, generateSchemasDefinition, generateTarget, generateTargetForTags, generateVerbImports, generateVerbOptions, generateVerbsOptions, getArray, getBody, getCombinedEnumValue, getDefaultContentType, getEnum, getEnumDescriptions, getEnumImplementation, getEnumNames, getEnumUnionFromSchema, getExtension, getFileInfo, getFormDataFieldFileType, getFullRoute, getIsBodyVerb, getKey, getMockFileExtensionByTypeName, getNumberWord, getObject, getOperationId, getOrvalGeneratedTypes, getParameters, getParams, getParamsInPath, getPropertySafe, getProps, getQueryParams, getRefInfo, getResReqTypes, getResponse, getResponseTypeCategory, getRoute, getRouteAsArray, getScalar, getTypedResponse, isBinaryContentType, isBoolean, isDirectory, isFunction, isModule, isNull, isNumber, isNumeric, isObject, isReference, isSchema, isString, isSyntheticDefaultImportsAllow, isUndefined, isUrl, isVerb, jsDoc, jsStringEscape, kebab, keyValuePairsToJsDoc, log, logError, mergeDeep, mismatchArgsMessage, pascal, removeFilesAndEmptyFolders, resolveDiscriminators, resolveExampleRefs, resolveObject, resolveRef, resolveValue, sanitize, snake, sortByPriority, splitSchemasByType, startMessage, stringify, toObjectString, path_exports as upath, upper, writeModelInline, writeModelsInline, writeSchema, writeSchemas, writeSingleMode, writeSplitMode, writeSplitTagsMode, writeTagsMode };
4108
4252
  //# sourceMappingURL=index.mjs.map