orval 8.17.0 → 8.18.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.
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { c as description, i as startWatcher, l as name, n as loadConfigFile, r as generateSpec, s as normalizeOptions, t as findConfigFile, u as version } from "../config-DKT1smAv.mjs";
2
+ import { c as description, i as startWatcher, l as name, n as loadConfigFile, r as generateSpec, s as normalizeOptions, t as findConfigFile, u as version } from "../config-CXPetEiJ.mjs";
3
3
  import path from "node:path";
4
4
  import { Option, program } from "@commander-js/extra-typings";
5
5
  import { ErrorWithTag, OutputClient, OutputMode, SupportedFormatter, getWarningCount, isString, log, logError, resetWarnings, setVerbose, startMessage } from "@orval/core";
@@ -28,7 +28,7 @@ import fs$2 from "node:fs";
28
28
  import { createJiti } from "jiti";
29
29
  //#region package.json
30
30
  var name = "orval";
31
- var version = "8.17.0";
31
+ var version = "8.18.0";
32
32
  var description = "A swagger client generator for typescript";
33
33
  //#endregion
34
34
  //#region src/client.ts
@@ -173,7 +173,8 @@ const generateOperations = (outputClient = DEFAULT_CLIENT, verbsOptions, options
173
173
  type: isFunction(entry) ? OutputMockType.MSW : entry.type,
174
174
  implementation: generated.implementation,
175
175
  imports: generated.imports,
176
- strictMockSchemaTypeNames: generated.strictMockSchemaTypeNames
176
+ strictMockSchemaTypeNames: generated.strictMockSchemaTypeNames,
177
+ strictMockSchemaKinds: generated.strictMockSchemaKinds
177
178
  };
178
179
  });
179
180
  const hasImplementation = client.implementation.trim().length > 0;
@@ -883,17 +884,27 @@ function createFormData(workspace, formData) {
883
884
  function normalizeSchemasOption(schemas, workspace) {
884
885
  if (!schemas) return;
885
886
  if (isString(schemas)) return normalizePath(schemas, workspace);
886
- if (schemas.importPath !== void 0 && !schemas.importPath) throw new Error(`schemas.importPath must be a non-empty package specifier (e.g. '@acme/models'). Received an empty string.`);
887
- if (schemas.importPath?.trim() === "") throw new Error(`schemas.importPath must be a non-empty package specifier (e.g. '@acme/models'). Received a whitespace-only string.`);
888
- if (schemas.importPath && schemas.importPath.trim() !== schemas.importPath) throw new Error(`schemas.importPath must be a non-empty package specifier (e.g. '@acme/models'). Received a value with leading or trailing whitespace: "${schemas.importPath}"`);
889
- if (schemas.importPath?.startsWith(".")) throw new Error(`schemas.importPath must be a package specifier (e.g. '@acme/models'), not a relative path. Received: "${schemas.importPath}"`);
890
- if (schemas.importPath && (path.isAbsolute(schemas.importPath) || /^[A-Za-z]:[\\/]/.test(schemas.importPath) || schemas.importPath.startsWith("\\\\"))) throw new Error(`schemas.importPath must be a package specifier (e.g. '@acme/models'), not an absolute path. Received: "${schemas.importPath}"`);
887
+ validatePackageSpecifier(schemas.importPath, "schemas.importPath");
891
888
  return {
892
889
  path: normalizePath(schemas.path, workspace),
893
- type: schemas.type,
890
+ type: schemas.type ?? "typescript",
894
891
  importPath: schemas.importPath
895
892
  };
896
893
  }
894
+ /**
895
+ * Validates that a config value is a valid package specifier (bare specifier
896
+ * or sub-path import like `@acme/models` / `@acme/models/fakers`). Rejects
897
+ * empty, whitespace-only, relative (`./`, `../`), and absolute paths with a
898
+ * clear, actionable error message. No-op when the value is `undefined`.
899
+ */
900
+ function validatePackageSpecifier(value, fieldName) {
901
+ if (value === void 0) return;
902
+ if (!value) throw new Error(`\`${fieldName}\` must be a non-empty package specifier (e.g. '@acme/models'). Received an empty string.`);
903
+ if (value.trim() === "") throw new Error(`\`${fieldName}\` must be a non-empty package specifier (e.g. '@acme/models'). Received a whitespace-only string.`);
904
+ if (value.trim() !== value) throw new Error(`\`${fieldName}\` must be a non-empty package specifier (e.g. '@acme/models'). Received a value with leading or trailing whitespace: "${value}"`);
905
+ if (value.startsWith(".")) throw new Error(`\`${fieldName}\` must be a package specifier (e.g. '@acme/models'), not a relative path. Received: "${value}"`);
906
+ if (path.isAbsolute(value) || /^[A-Za-z]:[\\/]/.test(value) || value.startsWith("\\\\")) throw new Error(`\`${fieldName}\` must be a package specifier (e.g. '@acme/models'), not an absolute path. Received: "${value}"`);
907
+ }
897
908
  function normalizeEffectOptions(effect) {
898
909
  return {
899
910
  strict: {
@@ -955,6 +966,7 @@ async function normalizeOptions(optionsExport, workspace = process.cwd(), global
955
966
  if (isFunction(entry)) continue;
956
967
  if (seenMockTypes.has(entry.type)) throw new Error(`Duplicate mock generator type "${entry.type}". Each type can only appear once in mock.generators.`);
957
968
  seenMockTypes.add(entry.type);
969
+ if (entry.type === OutputMockType.FAKER) validatePackageSpecifier(entry.schemasImportPath, "mock.generators[faker].schemasImportPath");
958
970
  }
959
971
  const defaultFileExtension = ".ts";
960
972
  const defaultSchemaFileExtension = !!outputOptions.schemas && (!isString(outputOptions.schemas) && outputOptions.schemas.type === "zod" || isString(outputOptions.schemas) && (outputOptions.client ?? client) === "zod" && outputOptions.override?.zod?.generateReusableSchemas === true) ? ".zod.ts" : defaultFileExtension;
@@ -973,7 +985,7 @@ async function normalizeOptions(optionsExport, workspace = process.cwd(), global
973
985
  shouldExportQueryKey: true,
974
986
  shouldFilterQueryKey: false,
975
987
  shouldSplitQueryKey: false,
976
- ...normalizeQueryOptions(outputOptions.override?.query, workspace)
988
+ ...normalizeQueryOptions(outputOptions.override?.query, outputWorkspace)
977
989
  };
978
990
  const normalizedOptions = {
979
991
  input: {
@@ -1071,13 +1083,13 @@ async function normalizeOptions(optionsExport, workspace = process.cwd(), global
1071
1083
  response: outputOptions.override?.zod?.coerce?.response ?? false
1072
1084
  },
1073
1085
  preprocess: {
1074
- ...outputOptions.override?.zod?.preprocess?.param ? { param: normalizeMutator(workspace, outputOptions.override.zod.preprocess.param) } : {},
1075
- ...outputOptions.override?.zod?.preprocess?.query ? { query: normalizeMutator(workspace, outputOptions.override.zod.preprocess.query) } : {},
1076
- ...outputOptions.override?.zod?.preprocess?.header ? { header: normalizeMutator(workspace, outputOptions.override.zod.preprocess.header) } : {},
1077
- ...outputOptions.override?.zod?.preprocess?.body ? { body: normalizeMutator(workspace, outputOptions.override.zod.preprocess.body) } : {},
1078
- ...outputOptions.override?.zod?.preprocess?.response ? { response: normalizeMutator(workspace, outputOptions.override.zod.preprocess.response) } : {}
1086
+ ...outputOptions.override?.zod?.preprocess?.param ? { param: normalizeMutator(outputWorkspace, outputOptions.override.zod.preprocess.param) } : {},
1087
+ ...outputOptions.override?.zod?.preprocess?.query ? { query: normalizeMutator(outputWorkspace, outputOptions.override.zod.preprocess.query) } : {},
1088
+ ...outputOptions.override?.zod?.preprocess?.header ? { header: normalizeMutator(outputWorkspace, outputOptions.override.zod.preprocess.header) } : {},
1089
+ ...outputOptions.override?.zod?.preprocess?.body ? { body: normalizeMutator(outputWorkspace, outputOptions.override.zod.preprocess.body) } : {},
1090
+ ...outputOptions.override?.zod?.preprocess?.response ? { response: normalizeMutator(outputWorkspace, outputOptions.override.zod.preprocess.response) } : {}
1079
1091
  },
1080
- ...outputOptions.override?.zod?.params ? { params: normalizeMutator(workspace, outputOptions.override.zod.params) } : {},
1092
+ ...outputOptions.override?.zod?.params ? { params: normalizeMutator(outputWorkspace, outputOptions.override.zod.params) } : {},
1081
1093
  generateEachHttpStatus: outputOptions.override?.zod?.generateEachHttpStatus ?? false,
1082
1094
  useBrandedTypes: outputOptions.override?.zod?.useBrandedTypes ?? false,
1083
1095
  generateReusableSchemas: outputOptions.override?.zod?.generateReusableSchemas ?? false,
@@ -1121,6 +1133,11 @@ async function normalizeOptions(optionsExport, workspace = process.cwd(), global
1121
1133
  };
1122
1134
  if (!normalizedOptions.input.target) throw new Error(styleText("red", `Config requires an input target.`));
1123
1135
  if (!normalizedOptions.output.target && !normalizedOptions.output.schemas) throw new Error(styleText("red", `Config requires an output target or schemas.`));
1136
+ const fakerWithSchemasImportPath = normalizedOptions.output.mock.generators.find((g) => !isFunction(g) && g.type === OutputMockType.FAKER && !!g.schemasImportPath);
1137
+ if (fakerWithSchemasImportPath) {
1138
+ if (fakerWithSchemasImportPath.schemas !== true) throw new Error(styleText("red", `\`mock.generators[faker].schemasImportPath\` requires \`schemas: true\` on the same generator. Schema-level faker factories are only emitted when \`schemas: true\`.`));
1139
+ if (!(isObject(normalizedOptions.output.schemas) && normalizedOptions.output.schemas.importPath)) throw new Error(styleText("red", `\`mock.generators[faker].schemasImportPath\` requires \`schemas.importPath\` to also be set. It overrides the package specifier used for importing schema-level faker factories.`));
1140
+ }
1124
1141
  const usesAngularGenerator = normalizedOptions.output.client === OutputClient.ANGULAR || normalizedOptions.output.client === OutputClient.ANGULAR_QUERY && normalizedOptions.output.httpClient === OutputHttpClient.ANGULAR;
1125
1142
  if (normalizedOptions.output.override.paramsFilter && !usesAngularGenerator) throw new Error(styleText("red", `\`override.paramsFilter\` is only supported by the Angular generator (the \`angular\` client, or \`angular-query\` with \`httpClient: 'angular'\`). It has no effect for other clients — use \`override.paramsSerializer\` instead.`));
1126
1143
  if (!usesAngularGenerator) {
@@ -1698,8 +1715,8 @@ const groupSchemasByFilePath = (schemas) => {
1698
1715
  }
1699
1716
  return [...grouped.values()].map((group) => [...group].toSorted((a, b) => a.filePath.localeCompare(b.filePath, "en", { numeric: true }))).toSorted((a, b) => a[0].filePath.localeCompare(b[0].filePath, "en", { numeric: true }));
1700
1717
  };
1701
- async function writeZodSchemaIndex(schemasPath, fileExtension, header, schemaNames, namingConvention, shouldMergeExisting = false) {
1702
- const importFileExtension = fileExtension.replace(/\.ts$/, "");
1718
+ async function writeZodSchemaIndex(schemasPath, fileExtension, header, schemaNames, namingConvention, shouldMergeExisting = false, tsconfig) {
1719
+ const importFileExtension = getImportExtension(fileExtension, tsconfig);
1703
1720
  const indexPath = path.join(schemasPath, `index.ts`);
1704
1721
  let existingExports = "";
1705
1722
  if (shouldMergeExisting && await fs.pathExists(indexPath)) {
@@ -1806,7 +1823,7 @@ async function writeZodSchemas(builder, schemasPath, fileExtension, header, outp
1806
1823
  const fileContent = generateZodSchemaFileContent(header, schemaGroup);
1807
1824
  await fs.outputFile(schemaGroup[0].filePath, fileContent);
1808
1825
  }
1809
- if (output.indexFiles) await writeZodSchemaIndex(schemasPath, fileExtension, header, groupedSchemasToWrite.map((schemaGroup) => schemaGroup[0].schemaName), output.namingConvention, false);
1826
+ if (output.indexFiles) await writeZodSchemaIndex(schemasPath, fileExtension, header, groupedSchemasToWrite.map((schemaGroup) => schemaGroup[0].schemaName), output.namingConvention, false, output.tsconfig);
1810
1827
  }
1811
1828
  async function writeZodSchemasReusable(builder, schemasPath, fileExtension, header, output, paramsMutator) {
1812
1829
  const isZodV4 = !!output.packageJson && isZodVersionV4(output.packageJson);
@@ -1833,7 +1850,7 @@ async function writeZodSchemasReusable(builder, schemasPath, fileExtension, head
1833
1850
  for (const entry of rewritten) {
1834
1851
  const fileName = conventionName(entry.name, output.namingConvention);
1835
1852
  const filePath = path.join(schemasPath, `${fileName}${fileExtension}`);
1836
- const importExt = fileExtension.replace(/\.ts$/, "");
1853
+ const importExt = getImportExtension(fileExtension, output.tsconfig);
1837
1854
  const rendered = renderReusableSchemaEntry(entry, context);
1838
1855
  const refImports = buildSiblingImports({
1839
1856
  usedRefs: entry.usedRefs,
@@ -1847,7 +1864,7 @@ async function writeZodSchemasReusable(builder, schemasPath, fileExtension, head
1847
1864
  const fileContent = `${header}import { z as zod } from 'zod';\n` + (imports ? `${imports}\n\n` : "\n") + `${rendered.content}\n`;
1848
1865
  await fs.outputFile(filePath, fileContent);
1849
1866
  }
1850
- if (output.indexFiles && rewritten.length > 0) await writeZodSchemaIndex(schemasPath, fileExtension, header, rewritten.map((e) => e.name), output.namingConvention, true);
1867
+ if (output.indexFiles && rewritten.length > 0) await writeZodSchemaIndex(schemasPath, fileExtension, header, rewritten.map((e) => e.name), output.namingConvention, true, output.tsconfig);
1851
1868
  }
1852
1869
  async function writeZodSchemasFromVerbs(verbOptions, schemasPath, fileExtension, header, output, context) {
1853
1870
  const zodContext = context;
@@ -1931,7 +1948,7 @@ async function writeZodSchemasFromVerbs(verbOptions, schemasPath, fileExtension,
1931
1948
  let importStatements;
1932
1949
  if (useReusableSchemas && parsedZodDefinition.usedRefs.size > 0) {
1933
1950
  zodExpression = rewriteSentinelsToDirect(zodExpression);
1934
- const importExt = fileExtension.replace(/\.ts$/, "");
1951
+ const importExt = getImportExtension(fileExtension, output.tsconfig);
1935
1952
  importStatements = [...parsedZodDefinition.usedRefs].filter((refName) => refName !== name).toSorted().map((refName) => {
1936
1953
  return `import { ${refName} } from './${conventionName(refName, output.namingConvention)}${importExt}';`;
1937
1954
  });
@@ -1949,7 +1966,7 @@ async function writeZodSchemasFromVerbs(verbOptions, schemasPath, fileExtension,
1949
1966
  const fileContent = generateZodSchemaFileContent(header, schemaGroup);
1950
1967
  await fs.outputFile(schemaGroup[0].filePath, fileContent);
1951
1968
  }
1952
- if (output.indexFiles && uniqueVerbsSchemas.length > 0) await writeZodSchemaIndex(schemasPath, fileExtension, header, groupedSchemasToWrite.map((schemaGroup) => schemaGroup[0].schemaName), output.namingConvention, true);
1969
+ if (output.indexFiles && uniqueVerbsSchemas.length > 0) await writeZodSchemaIndex(schemasPath, fileExtension, header, groupedSchemasToWrite.map((schemaGroup) => schemaGroup[0].schemaName), output.namingConvention, true, output.tsconfig);
1953
1970
  }
1954
1971
  //#endregion
1955
1972
  //#region src/write-specs.ts
@@ -1989,6 +2006,10 @@ function getHeader(option, info) {
1989
2006
  /**
1990
2007
  * Add re-export of operation schemas from the main schemas index file.
1991
2008
  * Handles the case where the index file doesn't exist (no regular schemas).
2009
+ *
2010
+ * NOTE: `operationSchemasPath` is a directory, so under NodeNext the re-export
2011
+ * would need an `/index.js` suffix rather than a bare `.js`. That directory-
2012
+ * import case is tracked separately and intentionally left as-is here.
1992
2013
  */
1993
2014
  async function addOperationSchemasReExport(schemaPath, operationSchemasPath, header) {
1994
2015
  const schemaIndexPath = path.join(schemaPath, `index.ts`);
@@ -2016,7 +2037,7 @@ async function writeFakerSchemaMocks(builder, options, header) {
2016
2037
  if (!fakerEntry) return;
2017
2038
  const schemasWithDef = builder.schemas.filter((s) => !!s.schema);
2018
2039
  if (schemasWithDef.length === 0) return;
2019
- const { implementation, imports, strictMockSchemaTypeNames } = generateFakerForSchemas(schemasWithDef, {
2040
+ const { implementation, imports, strictMockSchemaTypeNames, strictMockSchemaKinds } = generateFakerForSchemas(schemasWithDef, {
2020
2041
  spec: builder.spec,
2021
2042
  target: builder.target,
2022
2043
  workspace: "",
@@ -2025,7 +2046,8 @@ async function writeFakerSchemaMocks(builder, options, header) {
2025
2046
  if (!implementation.trim()) return;
2026
2047
  const finalizedImplementation = builder.finalizeMockImplementation ? builder.finalizeMockImplementation(implementation, {
2027
2048
  mockOptions: output.override.mock,
2028
- strictSchemaTypeNames: strictMockSchemaTypeNames
2049
+ strictSchemaTypeNames: strictMockSchemaTypeNames,
2050
+ strictMockSchemaKinds
2029
2051
  }) : implementation;
2030
2052
  let filePath;
2031
2053
  let schemaImportPath;
@@ -2174,7 +2196,11 @@ async function writeSpecs(builder, workspace, options, projectName) {
2174
2196
  const workspacePath = output.workspace;
2175
2197
  const indexFile = path.join(workspacePath, "index.ts");
2176
2198
  const mockExtensions = output.mock.generators.map((g) => getMockFileExtensionByTypeName(g));
2177
- const imports = implementationPaths.filter((p) => mockExtensions.length === 0 || !mockExtensions.some((ext) => p.endsWith(`.${ext}.ts`))).map((p) => upath.getRelativeImportPath(indexFile, getFileInfo(p).pathWithoutExtension, true));
2199
+ const importExtension = getImportExtension(output.fileExtension, output.tsconfig);
2200
+ const imports = implementationPaths.filter((p) => mockExtensions.length === 0 || !mockExtensions.some((ext) => p.endsWith(`.${ext}.ts`))).map((p) => {
2201
+ const relative = upath.getRelativeImportPath(indexFile, p, true);
2202
+ return (relative.endsWith(output.fileExtension) ? relative.slice(0, -output.fileExtension.length) : relative.replace(/\.[^/.]+$/, "")) + importExtension;
2203
+ });
2178
2204
  if (output.schemas) {
2179
2205
  const schemasPath = isString(output.schemas) ? output.schemas : output.schemas.path;
2180
2206
  imports.push(upath.getRelativeImportPath(indexFile, getFileInfo(schemasPath).dirname));
@@ -2326,4 +2352,4 @@ async function loadConfigFile(configFilePath) {
2326
2352
  //#endregion
2327
2353
  export { defineConfig as a, description as c, startWatcher as i, name as l, loadConfigFile as n, defineTransformer as o, generateSpec as r, normalizeOptions as s, findConfigFile as t, version as u };
2328
2354
 
2329
- //# sourceMappingURL=config-DKT1smAv.mjs.map
2355
+ //# sourceMappingURL=config-CXPetEiJ.mjs.map