orval 8.2.0 → 8.4.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
  import path from "node:path";
2
- import { FormDataArrayHandling, GetterPropType, NamingConvention, OutputClient, OutputHttpClient, OutputMode, PropertySortOrder, RefComponentSuffix, asyncReduce, conventionName, createLogger, createSuccessMessage, dynamicImport, fixCrossDirectoryImports, fixRegularSchemaImports, generateComponentDefinition, generateDependencyImports, generateParameterDefinition, generateSchemasDefinition, generateVerbsOptions, getFileInfo, getFullRoute, getMockFileExtensionByTypeName, getRoute, isBoolean, isFunction, isObject, isReference, isString, isUndefined, isUrl, jsDoc, log, logError, pascal, removeFilesAndEmptyFolders, resolveRef, splitSchemasByType, upath, writeSchemas, writeSingleMode, writeSplitMode, writeSplitTagsMode, writeTagsMode } from "@orval/core";
2
+ import { FormDataArrayHandling, GetterPropType, NamingConvention, OutputClient, OutputHttpClient, OutputMode, PropertySortOrder, RefComponentSuffix, asyncReduce, conventionName, createLogger, createSuccessMessage, dynamicImport, fixCrossDirectoryImports, fixRegularSchemaImports, generateComponentDefinition, generateDependencyImports, generateParameterDefinition, generateSchemasDefinition, generateVerbsOptions, getFileInfo, getFullRoute, getMockFileExtensionByTypeName, getRoute, isBoolean, isFunction, isNullish, isObject, isReference, isString, isUrl, jsDoc, log, logError, pascal, removeFilesAndEmptyFolders, resolveInstalledVersions, resolveRef, splitSchemasByType, upath, writeSchemas, writeSingleMode, writeSplitMode, writeSplitTagsMode, writeTagsMode } from "@orval/core";
3
3
  import { bundle } from "@scalar/json-magic/bundle";
4
4
  import { fetchUrls, parseJson, parseYaml, readFiles } from "@scalar/json-magic/bundle/plugins/node";
5
5
  import { upgrade, validate } from "@scalar/openapi-parser";
@@ -28,7 +28,7 @@ import { createJiti } from "jiti";
28
28
  //#region package.json
29
29
  var name = "orval";
30
30
  var description = "A swagger client generator for typescript";
31
- var version = "8.2.0";
31
+ var version = "8.4.0";
32
32
 
33
33
  //#endregion
34
34
  //#region src/client.ts
@@ -65,9 +65,7 @@ const getGeneratorClient = (outputClient, output) => {
65
65
  fetch: fetchClient()(),
66
66
  mcp: mcp()()
67
67
  };
68
- const generator = isFunction(outputClient) ? outputClient(GENERATOR_CLIENT) : GENERATOR_CLIENT[outputClient];
69
- if (!generator) throw new Error(`Oups... 🍻. Client not found: ${outputClient}`);
70
- return generator;
68
+ return isFunction(outputClient) ? outputClient(GENERATOR_CLIENT) : GENERATOR_CLIENT[outputClient];
71
69
  };
72
70
  const generateClientImports = ({ client, implementation, imports, projectName, hasSchemaDir, isAllowSyntheticDefaultImports, hasGlobalMutator, hasTagsMutator, hasParamsSerializerOptions, packageJson, output }) => {
73
71
  const { dependencies } = getGeneratorClient(client, output);
@@ -157,7 +155,7 @@ const generateOperations = (outputClient = DEFAULT_CLIENT, verbsOptions, options
157
155
  const client = await generatorClient(verbOption, options, outputClient, output);
158
156
  if (!client.implementation) return acc;
159
157
  const generatedMock = generateMock(verbOption, options);
160
- acc[verbOption.operationId] = {
158
+ acc[verbOption.operationName] = {
161
159
  implementation: verbOption.doc + client.implementation,
162
160
  imports: client.imports,
163
161
  implementationMock: generatedMock.implementation,
@@ -187,7 +185,7 @@ async function getApiBuilder({ input, output, context }) {
187
185
  const route = getRoute(pathRoute);
188
186
  let resolvedVerbs = verbs;
189
187
  if (isReference(verbs)) {
190
- const { schema, imports } = resolveRef(verbs, context);
188
+ const { schema } = resolveRef(verbs, context);
191
189
  resolvedVerbs = schema;
192
190
  }
193
191
  let verbsOptions = await generateVerbsOptions({
@@ -201,13 +199,13 @@ async function getApiBuilder({ input, output, context }) {
201
199
  if (output.override.useDeprecatedOperations === false) verbsOptions = verbsOptions.filter((verb) => {
202
200
  return !verb.deprecated;
203
201
  });
204
- const schemas = verbsOptions.reduce((acc$1, { queryParams, headers, body, response, props }) => {
205
- if (props) acc$1.push(...props.flatMap((param) => param.type === GetterPropType.NAMED_PATH_PARAMS ? param.schema : []));
206
- if (queryParams) acc$1.push(queryParams.schema, ...queryParams.deps);
207
- if (headers) acc$1.push(headers.schema, ...headers.deps);
208
- acc$1.push(...body.schemas, ...response.schemas);
209
- return acc$1;
210
- }, []);
202
+ const schemas = [];
203
+ for (const { queryParams, headers, body, response, props } of verbsOptions) {
204
+ schemas.push(...props.flatMap((param) => param.type === GetterPropType.NAMED_PATH_PARAMS ? param.schema : []));
205
+ if (queryParams) schemas.push(queryParams.schema, ...queryParams.deps);
206
+ if (headers) schemas.push(headers.schema, ...headers.deps);
207
+ schemas.push(...body.schemas, ...response.schemas);
208
+ }
211
209
  const fullRoute = getFullRoute(route, verbs.servers ?? context.spec.servers, output.baseUrl);
212
210
  if (!output.target) throw new Error("Output does not have a target");
213
211
  const pathOperations = await generateOperations(output.client, verbsOptions, {
@@ -342,7 +340,7 @@ function dereferenceExternalRef(data) {
342
340
  function scrub(obj) {
343
341
  if (obj === null || obj === void 0) return obj;
344
342
  if (Array.isArray(obj)) return obj.map((x) => scrub(x));
345
- if (typeof obj === "object") {
343
+ if (isObject(obj)) {
346
344
  const rec = obj;
347
345
  const out = {};
348
346
  for (const [k, v] of Object.entries(rec)) {
@@ -355,17 +353,17 @@ function dereferenceExternalRef(data) {
355
353
  }
356
354
  function replaceRefs(obj) {
357
355
  if (obj === null || obj === void 0) return obj;
358
- if (typeof obj === "object") {
359
- if (Array.isArray(obj)) return obj.map((element) => replaceRefs(element));
356
+ if (Array.isArray(obj)) return obj.map((element) => replaceRefs(element));
357
+ if (isObject(obj)) {
360
358
  const record = obj;
361
- if ("$ref" in record && typeof record.$ref === "string") {
359
+ if ("$ref" in record && isString(record.$ref)) {
362
360
  const refValue = record.$ref;
363
361
  if (refValue.startsWith("#/x-ext/")) {
364
362
  const parts = refValue.replace("#/x-ext/", "").split("/");
365
363
  const extKey = parts.shift();
366
364
  if (extKey) {
367
365
  let refObj = extensions[extKey];
368
- for (const p of parts) if (refObj && typeof refObj === "object" && p in refObj) refObj = refObj[p];
366
+ for (const p of parts) if (refObj && (isObject(refObj) || Array.isArray(refObj)) && p in refObj) refObj = refObj[p];
369
367
  else {
370
368
  refObj = void 0;
371
369
  break;
@@ -414,7 +412,7 @@ const loadPackageJson = async (packageJson, workspace = process.cwd()) => {
414
412
  const pkgPath = await findUp(["package.json"], { cwd: workspace });
415
413
  if (pkgPath) {
416
414
  const pkg = await dynamicImport(pkgPath, workspace);
417
- if (isPackageJson(pkg)) return await maybeReplaceCatalog(pkg, workspace);
415
+ if (isPackageJson(pkg)) return resolveAndAttachVersions(await maybeReplaceCatalog(pkg, workspace), workspace);
418
416
  else throw new Error("Invalid package.json file");
419
417
  }
420
418
  return;
@@ -422,11 +420,19 @@ const loadPackageJson = async (packageJson, workspace = process.cwd()) => {
422
420
  const normalizedPath = normalizePath(packageJson, workspace);
423
421
  if (fs.existsSync(normalizedPath)) {
424
422
  const pkg = await dynamicImport(normalizedPath);
425
- if (isPackageJson(pkg)) return await maybeReplaceCatalog(pkg, workspace);
423
+ if (isPackageJson(pkg)) return resolveAndAttachVersions(await maybeReplaceCatalog(pkg, workspace), workspace);
426
424
  else throw new Error(`Invalid package.json file: ${normalizedPath}`);
427
425
  }
428
426
  };
429
- const isPackageJson = (obj) => typeof obj === "object" && obj !== null;
427
+ const isPackageJson = (obj) => isObject(obj);
428
+ const resolveAndAttachVersions = (pkg, workspace) => {
429
+ const resolved = resolveInstalledVersions(pkg, workspace);
430
+ if (Object.keys(resolved).length > 0) {
431
+ pkg.resolvedVersions = resolved;
432
+ for (const [name$1, version$1] of Object.entries(resolved)) log(` ${chalk.cyan("Detected")} ${chalk.green(name$1)} ${chalk.cyan(`v${version$1}`)} ${chalk.dim("(from node_modules)")}`);
433
+ }
434
+ return pkg;
435
+ };
430
436
  const hasCatalogReferences = (pkg) => {
431
437
  return [
432
438
  ...Object.entries(pkg.dependencies ?? {}),
@@ -453,7 +459,7 @@ const loadPackageJsonCatalog = async (workspace) => {
453
459
  const filePaths = await findUpMultiple("package.json", { cwd: workspace });
454
460
  for (const filePath of filePaths) try {
455
461
  const pkg = await fs.readJson(filePath);
456
- if (pkg?.catalog || pkg?.catalogs) return {
462
+ if (pkg.catalog || pkg.catalogs) return {
457
463
  catalog: pkg.catalog,
458
464
  catalogs: pkg.catalogs
459
465
  };
@@ -518,7 +524,7 @@ const performSubstitution = (dependencies, catalogData) => {
518
524
  //#endregion
519
525
  //#region src/utils/tsconfig.ts
520
526
  const loadTsconfig = async (tsconfig, workspace = process.cwd()) => {
521
- if (isUndefined(tsconfig)) {
527
+ if (isNullish(tsconfig)) {
522
528
  const configPath = await findUp(["tsconfig.json", "jsconfig.json"], { cwd: workspace });
523
529
  if (configPath) return (await parse(configPath)).tsconfig;
524
530
  return;
@@ -527,7 +533,7 @@ const loadTsconfig = async (tsconfig, workspace = process.cwd()) => {
527
533
  const normalizedPath = normalizePath(tsconfig, workspace);
528
534
  if (fs.existsSync(normalizedPath)) {
529
535
  const config = await parse(normalizedPath);
530
- return config.referenced?.find(({ tsconfigFile }) => tsconfigFile === normalizedPath)?.tsconfig || config.tsconfig;
536
+ return config.referenced?.find(({ tsconfigFile }) => tsconfigFile === normalizedPath)?.tsconfig ?? config.tsconfig;
531
537
  }
532
538
  return;
533
539
  }
@@ -583,13 +589,13 @@ async function normalizeOptions(optionsExport, workspace = process.cwd(), global
583
589
  if (!options.output) throw new Error(chalk.red(`Config require an output`));
584
590
  const inputOptions = isString(options.input) ? { target: options.input } : options.input;
585
591
  const outputOptions = isString(options.output) ? { target: options.output } : options.output;
586
- const outputWorkspace = normalizePath(outputOptions.workspace || "", workspace);
592
+ const outputWorkspace = normalizePath(outputOptions.workspace ?? "", workspace);
587
593
  const { clean, prettier, client, httpClient, mode, biome } = globalOptions;
588
- const tsconfig = await loadTsconfig(outputOptions.tsconfig || globalOptions.tsconfig, workspace);
589
- const packageJson = await loadPackageJson(outputOptions.packageJson || globalOptions.packageJson, workspace);
594
+ const tsconfig = await loadTsconfig(outputOptions.tsconfig ?? globalOptions.tsconfig, workspace);
595
+ const packageJson = await loadPackageJson(outputOptions.packageJson ?? globalOptions.packageJson, workspace);
590
596
  const mockOption = outputOptions.mock ?? globalOptions.mock;
591
597
  let mock$1;
592
- if (typeof mockOption === "boolean" && mockOption) mock$1 = DEFAULT_MOCK_OPTIONS;
598
+ if (isBoolean(mockOption) && mockOption) mock$1 = DEFAULT_MOCK_OPTIONS;
593
599
  else if (isFunction(mockOption)) mock$1 = mockOption;
594
600
  else if (mockOption) mock$1 = {
595
601
  ...DEFAULT_MOCK_OPTIONS,
@@ -618,8 +624,8 @@ async function normalizeOptions(optionsExport, workspace = process.cwd(), global
618
624
  target: globalOptions.output ? normalizePath(globalOptions.output, process.cwd()) : normalizePath(outputOptions.target, outputWorkspace),
619
625
  schemas: normalizeSchemasOption(outputOptions.schemas, outputWorkspace),
620
626
  operationSchemas: outputOptions.operationSchemas ? normalizePath(outputOptions.operationSchemas, outputWorkspace) : void 0,
621
- namingConvention: outputOptions.namingConvention || NamingConvention.CAMEL_CASE,
622
- fileExtension: outputOptions.fileExtension || defaultFileExtension,
627
+ namingConvention: outputOptions.namingConvention ?? NamingConvention.CAMEL_CASE,
628
+ fileExtension: outputOptions.fileExtension ?? defaultFileExtension,
623
629
  workspace: outputOptions.workspace ? outputWorkspace : void 0,
624
630
  client: outputOptions.client ?? client ?? OutputClient.AXIOS_FUNCTIONS,
625
631
  httpClient: outputOptions.httpClient ?? httpClient ?? ((outputOptions.client ?? client) === OutputClient.ANGULAR_QUERY ? OutputHttpClient.ANGULAR : OutputHttpClient.FETCH),
@@ -649,9 +655,9 @@ async function normalizeOptions(optionsExport, workspace = process.cwd(), global
649
655
  tags: normalizeOperationsAndTags(outputOptions.override?.tags ?? {}, outputWorkspace, { query: globalQueryOptions }),
650
656
  mutator: normalizeMutator(outputWorkspace, outputOptions.override?.mutator),
651
657
  formData: createFormData(outputWorkspace, outputOptions.override?.formData),
652
- formUrlEncoded: (isBoolean(outputOptions.override?.formUrlEncoded) ? outputOptions.override?.formUrlEncoded : normalizeMutator(outputWorkspace, outputOptions.override?.formUrlEncoded)) ?? true,
658
+ formUrlEncoded: (isBoolean(outputOptions.override?.formUrlEncoded) ? outputOptions.override.formUrlEncoded : normalizeMutator(outputWorkspace, outputOptions.override?.formUrlEncoded)) ?? true,
653
659
  paramsSerializer: normalizeMutator(outputWorkspace, outputOptions.override?.paramsSerializer),
654
- header: outputOptions.override?.header === false ? false : isFunction(outputOptions.override?.header) ? outputOptions.override?.header : getDefaultFilesHeader,
660
+ header: outputOptions.override?.header === false ? false : isFunction(outputOptions.override?.header) ? outputOptions.override.header : getDefaultFilesHeader,
655
661
  requestOptions: outputOptions.override?.requestOptions ?? true,
656
662
  namingConvention: outputOptions.override?.namingConvention ?? {},
657
663
  components: {
@@ -720,10 +726,10 @@ async function normalizeOptions(optionsExport, workspace = process.cwd(), global
720
726
  runtimeValidation: outputOptions.override?.fetch?.runtimeValidation ?? false,
721
727
  ...outputOptions.override?.fetch
722
728
  },
723
- useDates: outputOptions.override?.useDates || false,
729
+ useDates: outputOptions.override?.useDates ?? false,
724
730
  useDeprecatedOperations: outputOptions.override?.useDeprecatedOperations ?? true,
725
731
  enumGenerationType: outputOptions.override?.enumGenerationType ?? "const",
726
- suppressReadonlyModifier: outputOptions.override?.suppressReadonlyModifier || false,
732
+ suppressReadonlyModifier: outputOptions.override?.suppressReadonlyModifier ?? false,
727
733
  aliasCombinedTypes: outputOptions.override?.aliasCombinedTypes ?? false
728
734
  },
729
735
  allParamsOptional: outputOptions.allParamsOptional ?? false,
@@ -743,7 +749,7 @@ function normalizeMutator(workspace, mutator) {
743
749
  return {
744
750
  ...mutator,
745
751
  path: upath.resolve(workspace, mutator.path),
746
- default: (mutator.default || !mutator.name) ?? false
752
+ default: mutator.default ?? !mutator.name
747
753
  };
748
754
  }
749
755
  if (isString(mutator)) return {
@@ -794,9 +800,9 @@ function normalizeOperationsAndTags(operationsOrTags, workspace, global) {
794
800
  ...zod$1.preprocess?.body ? { body: normalizeMutator(workspace, zod$1.preprocess.body) } : {},
795
801
  ...zod$1.preprocess?.response ? { response: normalizeMutator(workspace, zod$1.preprocess.response) } : {}
796
802
  },
797
- generateEachHttpStatus: zod$1?.generateEachHttpStatus ?? false,
798
- dateTimeOptions: zod$1?.dateTimeOptions ?? {},
799
- timeOptions: zod$1?.timeOptions ?? {}
803
+ generateEachHttpStatus: zod$1.generateEachHttpStatus ?? false,
804
+ dateTimeOptions: zod$1.dateTimeOptions ?? {},
805
+ timeOptions: zod$1.timeOptions ?? {}
800
806
  } } : {},
801
807
  ...transformer ? { transformer: normalizePath(transformer, workspace) } : {},
802
808
  ...mutator ? { mutator: normalizeMutator(workspace, mutator) } : {},
@@ -815,25 +821,13 @@ function normalizeOutputMode(mode) {
815
821
  return mode;
816
822
  }
817
823
  function normalizeHooks(hooks) {
818
- return Object.keys(hooks).reduce((acc, key) => {
819
- if (isString(hooks[key])) return {
820
- ...acc,
821
- [key]: [hooks[key]]
822
- };
823
- else if (Array.isArray(hooks[key])) return {
824
- ...acc,
825
- [key]: hooks[key]
826
- };
827
- else if (isFunction(hooks[key])) return {
828
- ...acc,
829
- [key]: [hooks[key]]
830
- };
831
- else if (isObject(hooks[key])) return {
832
- ...acc,
833
- [key]: [hooks[key]]
834
- };
835
- return acc;
836
- }, {});
824
+ const keys = Object.keys(hooks);
825
+ const result = {};
826
+ for (const key of keys) if (isString(hooks[key])) result[key] = [hooks[key]];
827
+ else if (Array.isArray(hooks[key])) result[key] = hooks[key];
828
+ else if (isFunction(hooks[key])) result[key] = [hooks[key]];
829
+ else if (isObject(hooks[key])) result[key] = [hooks[key]];
830
+ return result;
837
831
  }
838
832
  function normalizeHonoOptions(hono$1 = {}, workspace) {
839
833
  return {
@@ -849,37 +843,39 @@ function normalizeJSDocOptions(jsdoc = {}) {
849
843
  function normalizeQueryOptions(queryOptions = {}, outputWorkspace, globalOptions = {}) {
850
844
  if (queryOptions.options) console.warn("[WARN] Using query options is deprecated and will be removed in a future major release. Please use queryOptions or mutationOptions instead.");
851
845
  return {
852
- ...isUndefined(queryOptions.usePrefetch) ? {} : { usePrefetch: queryOptions.usePrefetch },
853
- ...isUndefined(queryOptions.useInvalidate) ? {} : { useInvalidate: queryOptions.useInvalidate },
854
- ...isUndefined(queryOptions.useQuery) ? {} : { useQuery: queryOptions.useQuery },
855
- ...isUndefined(queryOptions.useSuspenseQuery) ? {} : { useSuspenseQuery: queryOptions.useSuspenseQuery },
856
- ...isUndefined(queryOptions.useMutation) ? {} : { useMutation: queryOptions.useMutation },
857
- ...isUndefined(queryOptions.useInfinite) ? {} : { useInfinite: queryOptions.useInfinite },
858
- ...isUndefined(queryOptions.useSuspenseInfiniteQuery) ? {} : { useSuspenseInfiniteQuery: queryOptions.useSuspenseInfiniteQuery },
846
+ ...isNullish(queryOptions.usePrefetch) ? {} : { usePrefetch: queryOptions.usePrefetch },
847
+ ...isNullish(queryOptions.useInvalidate) ? {} : { useInvalidate: queryOptions.useInvalidate },
848
+ ...isNullish(queryOptions.useQuery) ? {} : { useQuery: queryOptions.useQuery },
849
+ ...isNullish(queryOptions.useSuspenseQuery) ? {} : { useSuspenseQuery: queryOptions.useSuspenseQuery },
850
+ ...isNullish(queryOptions.useMutation) ? {} : { useMutation: queryOptions.useMutation },
851
+ ...isNullish(queryOptions.useInfinite) ? {} : { useInfinite: queryOptions.useInfinite },
852
+ ...isNullish(queryOptions.useSuspenseInfiniteQuery) ? {} : { useSuspenseInfiniteQuery: queryOptions.useSuspenseInfiniteQuery },
859
853
  ...queryOptions.useInfiniteQueryParam ? { useInfiniteQueryParam: queryOptions.useInfiniteQueryParam } : {},
860
854
  ...queryOptions.options ? { options: queryOptions.options } : {},
861
855
  ...globalOptions.queryKey ? { queryKey: globalOptions.queryKey } : {},
862
- ...queryOptions?.queryKey ? { queryKey: normalizeMutator(outputWorkspace, queryOptions?.queryKey) } : {},
856
+ ...queryOptions.queryKey ? { queryKey: normalizeMutator(outputWorkspace, queryOptions.queryKey) } : {},
863
857
  ...globalOptions.queryOptions ? { queryOptions: globalOptions.queryOptions } : {},
864
- ...queryOptions?.queryOptions ? { queryOptions: normalizeMutator(outputWorkspace, queryOptions?.queryOptions) } : {},
858
+ ...queryOptions.queryOptions ? { queryOptions: normalizeMutator(outputWorkspace, queryOptions.queryOptions) } : {},
865
859
  ...globalOptions.mutationOptions ? { mutationOptions: globalOptions.mutationOptions } : {},
866
- ...queryOptions?.mutationOptions ? { mutationOptions: normalizeMutator(outputWorkspace, queryOptions?.mutationOptions) } : {},
867
- ...isUndefined(globalOptions.shouldExportQueryKey) ? {} : { shouldExportQueryKey: globalOptions.shouldExportQueryKey },
868
- ...isUndefined(queryOptions.shouldExportQueryKey) ? {} : { shouldExportQueryKey: queryOptions.shouldExportQueryKey },
869
- ...isUndefined(globalOptions.shouldExportHttpClient) ? {} : { shouldExportHttpClient: globalOptions.shouldExportHttpClient },
870
- ...isUndefined(queryOptions.shouldExportHttpClient) ? {} : { shouldExportHttpClient: queryOptions.shouldExportHttpClient },
871
- ...isUndefined(globalOptions.shouldExportMutatorHooks) ? {} : { shouldExportMutatorHooks: globalOptions.shouldExportMutatorHooks },
872
- ...isUndefined(queryOptions.shouldExportMutatorHooks) ? {} : { shouldExportMutatorHooks: queryOptions.shouldExportMutatorHooks },
873
- ...isUndefined(globalOptions.shouldSplitQueryKey) ? {} : { shouldSplitQueryKey: globalOptions.shouldSplitQueryKey },
874
- ...isUndefined(queryOptions.shouldSplitQueryKey) ? {} : { shouldSplitQueryKey: queryOptions.shouldSplitQueryKey },
875
- ...isUndefined(globalOptions.signal) ? {} : { signal: globalOptions.signal },
876
- ...isUndefined(globalOptions.useOperationIdAsQueryKey) ? {} : { useOperationIdAsQueryKey: globalOptions.useOperationIdAsQueryKey },
877
- ...isUndefined(queryOptions.useOperationIdAsQueryKey) ? {} : { useOperationIdAsQueryKey: queryOptions.useOperationIdAsQueryKey },
878
- ...isUndefined(globalOptions.signal) ? {} : { signal: globalOptions.signal },
879
- ...isUndefined(queryOptions.signal) ? {} : { signal: queryOptions.signal },
880
- ...isUndefined(globalOptions.version) ? {} : { version: globalOptions.version },
881
- ...isUndefined(queryOptions.version) ? {} : { version: queryOptions.version },
882
- ...queryOptions.mutationInvalidates ? { mutationInvalidates: queryOptions.mutationInvalidates } : {}
860
+ ...queryOptions.mutationOptions ? { mutationOptions: normalizeMutator(outputWorkspace, queryOptions.mutationOptions) } : {},
861
+ ...isNullish(globalOptions.shouldExportQueryKey) ? {} : { shouldExportQueryKey: globalOptions.shouldExportQueryKey },
862
+ ...isNullish(queryOptions.shouldExportQueryKey) ? {} : { shouldExportQueryKey: queryOptions.shouldExportQueryKey },
863
+ ...isNullish(globalOptions.shouldExportHttpClient) ? {} : { shouldExportHttpClient: globalOptions.shouldExportHttpClient },
864
+ ...isNullish(queryOptions.shouldExportHttpClient) ? {} : { shouldExportHttpClient: queryOptions.shouldExportHttpClient },
865
+ ...isNullish(globalOptions.shouldExportMutatorHooks) ? {} : { shouldExportMutatorHooks: globalOptions.shouldExportMutatorHooks },
866
+ ...isNullish(queryOptions.shouldExportMutatorHooks) ? {} : { shouldExportMutatorHooks: queryOptions.shouldExportMutatorHooks },
867
+ ...isNullish(globalOptions.shouldSplitQueryKey) ? {} : { shouldSplitQueryKey: globalOptions.shouldSplitQueryKey },
868
+ ...isNullish(queryOptions.shouldSplitQueryKey) ? {} : { shouldSplitQueryKey: queryOptions.shouldSplitQueryKey },
869
+ ...isNullish(globalOptions.signal) ? {} : { signal: globalOptions.signal },
870
+ ...isNullish(globalOptions.useOperationIdAsQueryKey) ? {} : { useOperationIdAsQueryKey: globalOptions.useOperationIdAsQueryKey },
871
+ ...isNullish(queryOptions.useOperationIdAsQueryKey) ? {} : { useOperationIdAsQueryKey: queryOptions.useOperationIdAsQueryKey },
872
+ ...isNullish(globalOptions.signal) ? {} : { signal: globalOptions.signal },
873
+ ...isNullish(queryOptions.signal) ? {} : { signal: queryOptions.signal },
874
+ ...isNullish(globalOptions.version) ? {} : { version: globalOptions.version },
875
+ ...isNullish(queryOptions.version) ? {} : { version: queryOptions.version },
876
+ ...queryOptions.mutationInvalidates ? { mutationInvalidates: queryOptions.mutationInvalidates } : {},
877
+ ...isNullish(globalOptions.runtimeValidation) ? {} : { runtimeValidation: globalOptions.runtimeValidation },
878
+ ...isNullish(queryOptions.runtimeValidation) ? {} : { runtimeValidation: queryOptions.runtimeValidation }
883
879
  };
884
880
  }
885
881
  function getDefaultFilesHeader({ title, description: description$1, version: version$1 } = {}) {
@@ -914,7 +910,7 @@ async function startWatcher(watchOptions, watchFn, defaultTarget = ".") {
914
910
  if (!watchOptions) return;
915
911
  const { watch } = await import("chokidar");
916
912
  const ignored = ["**/{.git,node_modules}/**"];
917
- const watchPaths = typeof watchOptions === "boolean" ? defaultTarget : watchOptions;
913
+ const watchPaths = isBoolean(watchOptions) ? defaultTarget : watchOptions;
918
914
  log(`Watching for changes in ${Array.isArray(watchPaths) ? watchPaths.map((v) => "\"" + v + "\"").join(" | ") : "\"" + watchPaths + "\""}`);
919
915
  watch(watchPaths, {
920
916
  ignorePermissionErrors: true,
@@ -929,14 +925,40 @@ async function startWatcher(watchOptions, watchFn, defaultTarget = ".") {
929
925
 
930
926
  //#endregion
931
927
  //#region src/write-zod-specs.ts
932
- function generateZodSchemaFileContent(header, schemaName, zodContent) {
928
+ function generateZodSchemaFileContent(header, schemas) {
933
929
  return `${header}import { z as zod } from 'zod';
934
930
 
935
- export const ${schemaName} = ${zodContent}
931
+ ${schemas.map(({ schemaName, consts, zodExpression }) => {
932
+ return `${consts ? `${consts}\n` : ""}export const ${schemaName} = ${zodExpression}
936
933
 
937
- export type ${schemaName} = zod.infer<typeof ${schemaName}>;
934
+ export type ${schemaName} = zod.infer<typeof ${schemaName}>;`;
935
+ }).join("\n\n")}
938
936
  `;
939
937
  }
938
+ const isValidSchemaIdentifier = (name$1) => /^[A-Za-z_][A-Za-z0-9_]*$/.test(name$1);
939
+ const isPrimitiveSchemaName = (name$1) => [
940
+ "string",
941
+ "number",
942
+ "boolean",
943
+ "void",
944
+ "unknown",
945
+ "Blob"
946
+ ].includes(name$1);
947
+ const dedupeSchemasByName = (schemas) => {
948
+ const uniqueSchemas = /* @__PURE__ */ new Map();
949
+ for (const schema of schemas) if (!uniqueSchemas.has(schema.name)) uniqueSchemas.set(schema.name, schema);
950
+ return [...uniqueSchemas.values()];
951
+ };
952
+ const groupSchemasByFilePath = (schemas) => {
953
+ const grouped = /* @__PURE__ */ new Map();
954
+ for (const schema of schemas) {
955
+ const key = schema.filePath.toLowerCase();
956
+ const existingGroup = grouped.get(key);
957
+ if (existingGroup) existingGroup.push(schema);
958
+ else grouped.set(key, [schema]);
959
+ }
960
+ return [...grouped.values()].map((group) => [...group].toSorted((a, b) => a.filePath.localeCompare(b.filePath))).toSorted((a, b) => a[0].filePath.localeCompare(b[0].filePath));
961
+ };
940
962
  async function writeZodSchemaIndex(schemasPath, fileExtension, header, schemaNames, namingConvention, shouldMergeExisting = false) {
941
963
  const importFileExtension = fileExtension.replace(/\.ts$/, "");
942
964
  const indexPath = upath.join(schemasPath, `index${fileExtension}`);
@@ -949,16 +971,20 @@ async function writeZodSchemaIndex(schemasPath, fileExtension, header, schemaNam
949
971
  }
950
972
  const newExports = schemaNames.map((schemaName) => {
951
973
  return `export * from './${conventionName(schemaName, namingConvention)}${importFileExtension}';`;
952
- }).sort().join("\n");
974
+ }).toSorted().join("\n");
953
975
  const allExports = existingExports ? `${existingExports}\n${newExports}` : newExports;
954
- const uniqueExports = [...new Set(allExports.split("\n"))].filter((line) => line.trim()).sort().join("\n");
976
+ const uniqueExports = [...new Set(allExports.split("\n"))].filter((line) => line.trim()).toSorted().join("\n");
955
977
  await fs.outputFile(indexPath, `${header}\n${uniqueExports}\n`);
956
978
  }
957
979
  async function writeZodSchemas(builder, schemasPath, fileExtension, header, output) {
958
980
  const schemasWithOpenApiDef = builder.schemas.filter((s) => s.schema);
959
- await Promise.all(schemasWithOpenApiDef.map(async (generatorSchema) => {
981
+ const schemasToWrite = [];
982
+ const isZodV4 = !!output.packageJson && isZodVersionV4(output.packageJson);
983
+ const strict = output.override.zod.strict.body;
984
+ const coerce = output.override.zod.coerce.body;
985
+ for (const generatorSchema of schemasWithOpenApiDef) {
960
986
  const { name: name$1, schema: schemaObject } = generatorSchema;
961
- if (!schemaObject) return;
987
+ if (!schemaObject) continue;
962
988
  const fileName = conventionName(name$1, output.namingConvention);
963
989
  const filePath = upath.join(schemasPath, `${fileName}${fileExtension}`);
964
990
  const context = {
@@ -967,60 +993,84 @@ async function writeZodSchemas(builder, schemasPath, fileExtension, header, outp
967
993
  workspace: "",
968
994
  output
969
995
  };
970
- const isZodV4 = !!output.packageJson && isZodVersionV4(output.packageJson);
971
- const strict = typeof output.override?.zod?.strict === "object" ? output.override.zod.strict.body ?? false : output.override?.zod?.strict ?? false;
972
- const coerce = typeof output.override?.zod?.coerce === "object" ? output.override.zod.coerce.body ?? false : output.override?.zod?.coerce ?? false;
973
996
  const parsedZodDefinition = parseZodValidationSchemaDefinition(generateZodValidationSchemaDefinition(dereference(schemaObject, context), context, name$1, strict, isZodV4, { required: true }), context, coerce, strict, isZodV4);
974
- const fileContent = generateZodSchemaFileContent(header, name$1, parsedZodDefinition.consts ? `${parsedZodDefinition.consts}\n${parsedZodDefinition.zod}` : parsedZodDefinition.zod);
975
- await fs.outputFile(filePath, fileContent);
976
- }));
977
- if (output.indexFiles) await writeZodSchemaIndex(schemasPath, fileExtension, header, schemasWithOpenApiDef.map((schema) => schema.name), output.namingConvention, false);
997
+ schemasToWrite.push({
998
+ schemaName: name$1,
999
+ filePath,
1000
+ consts: parsedZodDefinition.consts,
1001
+ zodExpression: parsedZodDefinition.zod
1002
+ });
1003
+ }
1004
+ const groupedSchemasToWrite = groupSchemasByFilePath(schemasToWrite);
1005
+ for (const schemaGroup of groupedSchemasToWrite) {
1006
+ const fileContent = generateZodSchemaFileContent(header, schemaGroup);
1007
+ await fs.outputFile(schemaGroup[0].filePath, fileContent);
1008
+ }
1009
+ if (output.indexFiles) await writeZodSchemaIndex(schemasPath, fileExtension, header, groupedSchemasToWrite.map((schemaGroup) => schemaGroup[0].schemaName), output.namingConvention, false);
978
1010
  }
979
1011
  async function writeZodSchemasFromVerbs(verbOptions, schemasPath, fileExtension, header, output, context) {
1012
+ const zodContext = context;
980
1013
  const verbOptionsArray = Object.values(verbOptions);
981
1014
  if (verbOptionsArray.length === 0) return;
982
1015
  const isZodV4 = !!output.packageJson && isZodVersionV4(output.packageJson);
983
- const strict = typeof output.override?.zod?.strict === "object" ? output.override.zod.strict.body ?? false : output.override?.zod?.strict ?? false;
984
- const coerce = typeof output.override?.zod?.coerce === "object" ? output.override.zod.coerce.body ?? false : output.override?.zod?.coerce ?? false;
985
- const generateVerbsSchemas = verbOptionsArray.flatMap((verbOption) => {
1016
+ const strict = output.override.zod.strict.body;
1017
+ const coerce = output.override.zod.coerce.body;
1018
+ const uniqueVerbsSchemas = dedupeSchemasByName(verbOptionsArray.flatMap((verbOption) => {
986
1019
  const operation = verbOption.originalOperation;
987
- const bodySchema = operation.requestBody && "content" in operation.requestBody ? operation.requestBody.content["application/json"]?.schema : void 0;
1020
+ const requestBody = operation.requestBody;
1021
+ const bodySchema = (requestBody && "content" in requestBody ? requestBody.content : void 0)?.["application/json"]?.schema;
988
1022
  const bodySchemas = bodySchema ? [{
989
1023
  name: `${pascal(verbOption.operationName)}Body`,
990
- schema: dereference(bodySchema, context)
1024
+ schema: dereference(bodySchema, zodContext)
991
1025
  }] : [];
992
- const queryParams = operation.parameters?.filter((p) => "in" in p && p.in === "query");
1026
+ const parameters = operation.parameters;
1027
+ const queryParams = parameters?.filter((p) => "in" in p && p.in === "query");
993
1028
  const queryParamsSchemas = queryParams && queryParams.length > 0 ? [{
994
1029
  name: `${pascal(verbOption.operationName)}Params`,
995
1030
  schema: {
996
1031
  type: "object",
997
- properties: Object.fromEntries(queryParams.filter((p) => "schema" in p && p.schema).map((p) => [p.name, dereference(p.schema, context)])),
998
- required: queryParams.filter((p) => p.required).map((p) => p.name)
1032
+ properties: Object.fromEntries(queryParams.filter((p) => "schema" in p && p.schema).map((p) => [p.name, dereference(p.schema, zodContext)])),
1033
+ required: queryParams.filter((p) => p.required).map((p) => p.name).filter((name$1) => name$1 !== void 0)
999
1034
  }
1000
1035
  }] : [];
1001
- const headerParams = operation.parameters?.filter((p) => "in" in p && p.in === "header");
1036
+ const headerParams = parameters?.filter((p) => "in" in p && p.in === "header");
1002
1037
  const headerParamsSchemas = headerParams && headerParams.length > 0 ? [{
1003
1038
  name: `${pascal(verbOption.operationName)}Headers`,
1004
1039
  schema: {
1005
1040
  type: "object",
1006
- properties: Object.fromEntries(headerParams.filter((p) => "schema" in p && p.schema).map((p) => [p.name, dereference(p.schema, context)])),
1007
- required: headerParams.filter((p) => p.required).map((p) => p.name)
1041
+ properties: Object.fromEntries(headerParams.filter((p) => "schema" in p && p.schema).map((p) => [p.name, dereference(p.schema, zodContext)])),
1042
+ required: headerParams.filter((p) => p.required).map((p) => p.name).filter((name$1) => name$1 !== void 0)
1008
1043
  }
1009
1044
  }] : [];
1010
- return [
1045
+ const responseSchemas = [...verbOption.response.types.success, ...verbOption.response.types.errors].filter((responseType) => !!responseType.originalSchema && !responseType.isRef && isValidSchemaIdentifier(responseType.value) && !isPrimitiveSchemaName(responseType.value)).map((responseType) => ({
1046
+ name: responseType.value,
1047
+ schema: dereference(responseType.originalSchema, zodContext)
1048
+ }));
1049
+ return dedupeSchemasByName([
1011
1050
  ...bodySchemas,
1012
1051
  ...queryParamsSchemas,
1013
- ...headerParamsSchemas
1014
- ];
1015
- });
1016
- await Promise.all(generateVerbsSchemas.map(async ({ name: name$1, schema }) => {
1052
+ ...headerParamsSchemas,
1053
+ ...responseSchemas
1054
+ ]);
1055
+ }));
1056
+ const schemasToWrite = [];
1057
+ for (const { name: name$1, schema } of uniqueVerbsSchemas) {
1017
1058
  const fileName = conventionName(name$1, output.namingConvention);
1018
1059
  const filePath = upath.join(schemasPath, `${fileName}${fileExtension}`);
1019
- const parsedZodDefinition = parseZodValidationSchemaDefinition(generateZodValidationSchemaDefinition(schema, context, name$1, strict, isZodV4, { required: true }), context, coerce, strict, isZodV4);
1020
- const fileContent = generateZodSchemaFileContent(header, name$1, parsedZodDefinition.consts ? `${parsedZodDefinition.consts}\n${parsedZodDefinition.zod}` : parsedZodDefinition.zod);
1021
- await fs.outputFile(filePath, fileContent);
1022
- }));
1023
- if (output.indexFiles && generateVerbsSchemas.length > 0) await writeZodSchemaIndex(schemasPath, fileExtension, header, generateVerbsSchemas.map((s) => s.name), output.namingConvention, true);
1060
+ const parsedZodDefinition = parseZodValidationSchemaDefinition(generateZodValidationSchemaDefinition(schema, zodContext, name$1, strict, isZodV4, { required: true }), zodContext, coerce, strict, isZodV4);
1061
+ schemasToWrite.push({
1062
+ schemaName: name$1,
1063
+ filePath,
1064
+ consts: parsedZodDefinition.consts,
1065
+ zodExpression: parsedZodDefinition.zod
1066
+ });
1067
+ }
1068
+ const groupedSchemasToWrite = groupSchemasByFilePath(schemasToWrite);
1069
+ for (const schemaGroup of groupedSchemasToWrite) {
1070
+ const fileContent = generateZodSchemaFileContent(header, schemaGroup);
1071
+ await fs.outputFile(schemaGroup[0].filePath, fileContent);
1072
+ }
1073
+ if (output.indexFiles && uniqueVerbsSchemas.length > 0) await writeZodSchemaIndex(schemasPath, fileExtension, header, groupedSchemasToWrite.map((schemaGroup) => schemaGroup[0].schemaName), output.namingConvention, true);
1024
1074
  }
1025
1075
 
1026
1076
  //#endregion
@@ -1038,12 +1088,12 @@ async function addOperationSchemasReExport(schemaPath, operationSchemasPath, fil
1038
1088
  const relativePath = upath.relativeSafe(schemaPath, operationSchemasPath);
1039
1089
  const schemaIndexPath = upath.join(schemaPath, `index${fileExtension}`);
1040
1090
  const exportLine = `export * from '${relativePath}';\n`;
1041
- if (!await fs.pathExists(schemaIndexPath)) {
1091
+ if (await fs.pathExists(schemaIndexPath)) {
1092
+ const existingContent = await fs.readFile(schemaIndexPath, "utf8");
1093
+ if (!new RegExp(String.raw`export\s*\*\s*from\s*['"]${relativePath.replaceAll(/[.*+?^${}()|[\]\\]/g, String.raw`\$&`)}['"]`).test(existingContent)) await fs.appendFile(schemaIndexPath, exportLine);
1094
+ } else {
1042
1095
  const content = header && header.trim().length > 0 ? `${header}\n${exportLine}` : exportLine;
1043
1096
  await fs.outputFile(schemaIndexPath, content);
1044
- } else {
1045
- const existingContent = await fs.readFile(schemaIndexPath, "utf8");
1046
- if (!(/* @__PURE__ */ new RegExp(`export\\s*\\*\\s*from\\s*['"]${relativePath.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}['"]`)).test(existingContent)) await fs.appendFile(schemaIndexPath, exportLine);
1047
1097
  }
1048
1098
  }
1049
1099
  async function writeSpecs(builder, workspace, options, projectName) {
@@ -1058,8 +1108,8 @@ async function writeSpecs(builder, workspace, options, projectName) {
1058
1108
  const { regularSchemas, operationSchemas: opSchemas } = splitSchemasByType(schemas);
1059
1109
  const regularSchemaNames = new Set(regularSchemas.map((s) => s.name));
1060
1110
  const operationSchemaNames = new Set(opSchemas.map((s) => s.name));
1061
- fixCrossDirectoryImports(opSchemas, regularSchemaNames, schemaPath, output.operationSchemas, output.namingConvention);
1062
- fixRegularSchemaImports(regularSchemas, operationSchemaNames, schemaPath, output.operationSchemas, output.namingConvention);
1111
+ fixCrossDirectoryImports(opSchemas, regularSchemaNames, schemaPath, output.operationSchemas, output.namingConvention, fileExtension);
1112
+ fixRegularSchemaImports(regularSchemas, operationSchemaNames, schemaPath, output.operationSchemas, output.namingConvention, fileExtension);
1063
1113
  if (regularSchemas.length > 0) await writeSchemas({
1064
1114
  schemaPath,
1065
1115
  schemas: regularSchemas,
@@ -1090,56 +1140,53 @@ async function writeSpecs(builder, workspace, options, projectName) {
1090
1140
  header,
1091
1141
  indexFiles: output.indexFiles
1092
1142
  });
1093
- } else {
1094
- const schemaType = output.schemas.type;
1095
- if (schemaType === "typescript") {
1096
- const fileExtension = output.fileExtension || ".ts";
1097
- if (output.operationSchemas) {
1098
- const { regularSchemas, operationSchemas: opSchemas } = splitSchemasByType(schemas);
1099
- const regularSchemaNames = new Set(regularSchemas.map((s) => s.name));
1100
- const operationSchemaNames = new Set(opSchemas.map((s) => s.name));
1101
- fixCrossDirectoryImports(opSchemas, regularSchemaNames, output.schemas.path, output.operationSchemas, output.namingConvention);
1102
- fixRegularSchemaImports(regularSchemas, operationSchemaNames, output.schemas.path, output.operationSchemas, output.namingConvention);
1103
- if (regularSchemas.length > 0) await writeSchemas({
1104
- schemaPath: output.schemas.path,
1105
- schemas: regularSchemas,
1106
- target,
1107
- namingConvention: output.namingConvention,
1108
- fileExtension,
1109
- header,
1110
- indexFiles: output.indexFiles
1111
- });
1112
- if (opSchemas.length > 0) {
1113
- await writeSchemas({
1114
- schemaPath: output.operationSchemas,
1115
- schemas: opSchemas,
1116
- target,
1117
- namingConvention: output.namingConvention,
1118
- fileExtension,
1119
- header,
1120
- indexFiles: output.indexFiles
1121
- });
1122
- if (output.indexFiles) await addOperationSchemasReExport(output.schemas.path, output.operationSchemas, fileExtension, header);
1123
- }
1124
- } else await writeSchemas({
1143
+ } else if (output.schemas.type === "typescript") {
1144
+ const fileExtension = output.fileExtension || ".ts";
1145
+ if (output.operationSchemas) {
1146
+ const { regularSchemas, operationSchemas: opSchemas } = splitSchemasByType(schemas);
1147
+ const regularSchemaNames = new Set(regularSchemas.map((s) => s.name));
1148
+ const operationSchemaNames = new Set(opSchemas.map((s) => s.name));
1149
+ fixCrossDirectoryImports(opSchemas, regularSchemaNames, output.schemas.path, output.operationSchemas, output.namingConvention, fileExtension);
1150
+ fixRegularSchemaImports(regularSchemas, operationSchemaNames, output.schemas.path, output.operationSchemas, output.namingConvention, fileExtension);
1151
+ if (regularSchemas.length > 0) await writeSchemas({
1125
1152
  schemaPath: output.schemas.path,
1126
- schemas,
1153
+ schemas: regularSchemas,
1127
1154
  target,
1128
1155
  namingConvention: output.namingConvention,
1129
1156
  fileExtension,
1130
1157
  header,
1131
1158
  indexFiles: output.indexFiles
1132
1159
  });
1133
- } else if (schemaType === "zod") {
1134
- const fileExtension = ".zod.ts";
1135
- await writeZodSchemas(builder, output.schemas.path, fileExtension, header, output);
1136
- if (builder.verbOptions) await writeZodSchemasFromVerbs(builder.verbOptions, output.schemas.path, fileExtension, header, output, {
1137
- spec: builder.spec,
1138
- target: builder.target,
1139
- workspace,
1140
- output
1141
- });
1142
- }
1160
+ if (opSchemas.length > 0) {
1161
+ await writeSchemas({
1162
+ schemaPath: output.operationSchemas,
1163
+ schemas: opSchemas,
1164
+ target,
1165
+ namingConvention: output.namingConvention,
1166
+ fileExtension,
1167
+ header,
1168
+ indexFiles: output.indexFiles
1169
+ });
1170
+ if (output.indexFiles) await addOperationSchemasReExport(output.schemas.path, output.operationSchemas, fileExtension, header);
1171
+ }
1172
+ } else await writeSchemas({
1173
+ schemaPath: output.schemas.path,
1174
+ schemas,
1175
+ target,
1176
+ namingConvention: output.namingConvention,
1177
+ fileExtension,
1178
+ header,
1179
+ indexFiles: output.indexFiles
1180
+ });
1181
+ } else {
1182
+ const fileExtension = ".zod.ts";
1183
+ await writeZodSchemas(builder, output.schemas.path, fileExtension, header, output);
1184
+ await writeZodSchemasFromVerbs(builder.verbOptions, output.schemas.path, fileExtension, header, output, {
1185
+ spec: builder.spec,
1186
+ target: builder.target,
1187
+ workspace,
1188
+ output
1189
+ });
1143
1190
  }
1144
1191
  let implementationPaths = [];
1145
1192
  if (output.target) implementationPaths = await getWriteMode(output.mode)({
@@ -1154,7 +1201,7 @@ async function writeSpecs(builder, workspace, options, projectName) {
1154
1201
  const workspacePath = output.workspace;
1155
1202
  const imports = implementationPaths.filter((path$1) => !output.mock || !path$1.endsWith(`.${getMockFileExtensionByTypeName(output.mock)}.ts`)).map((path$1) => upath.relativeSafe(workspacePath, getFileInfo(path$1).pathWithoutExtension));
1156
1203
  if (output.schemas) {
1157
- const schemasPath = typeof output.schemas === "string" ? output.schemas : output.schemas.path;
1204
+ const schemasPath = isString(output.schemas) ? output.schemas : output.schemas.path;
1158
1205
  imports.push(upath.relativeSafe(workspacePath, getFileInfo(schemasPath).dirname));
1159
1206
  }
1160
1207
  if (output.operationSchemas) imports.push(upath.relativeSafe(workspacePath, getFileInfo(output.operationSchemas).dirname));
@@ -1173,7 +1220,7 @@ async function writeSpecs(builder, workspace, options, projectName) {
1173
1220
  implementationPaths = [...implementationPaths, ...builder.extraFiles.map((file) => file.path)];
1174
1221
  }
1175
1222
  const paths = [
1176
- ...output.schemas ? [getFileInfo(typeof output.schemas === "string" ? output.schemas : output.schemas.path).dirname] : [],
1223
+ ...output.schemas ? [getFileInfo(isString(output.schemas) ? output.schemas : output.schemas.path).dirname] : [],
1177
1224
  ...output.operationSchemas ? [getFileInfo(output.operationSchemas).dirname] : [],
1178
1225
  ...implementationPaths
1179
1226
  ];
@@ -1196,9 +1243,9 @@ async function writeSpecs(builder, workspace, options, projectName) {
1196
1243
  }
1197
1244
  if (output.docs) try {
1198
1245
  let config = {};
1199
- let configPath = null;
1200
- if (typeof output.docs === "object") {
1201
- ({configPath = null, ...config} = output.docs);
1246
+ let configPath;
1247
+ if (isObject(output.docs)) {
1248
+ ({configPath, ...config} = output.docs);
1202
1249
  if (configPath) config.options = configPath;
1203
1250
  }
1204
1251
  const getTypedocApplication = async () => {
@@ -1227,7 +1274,6 @@ function getWriteMode(mode) {
1227
1274
  case OutputMode.SPLIT: return writeSplitMode;
1228
1275
  case OutputMode.TAGS: return writeTagsMode;
1229
1276
  case OutputMode.TAGS_SPLIT: return writeSplitTagsMode;
1230
- case OutputMode.SINGLE:
1231
1277
  default: return writeSingleMode;
1232
1278
  }
1233
1279
  }
@@ -1253,11 +1299,14 @@ async function generateSpec(workspace, options, projectName) {
1253
1299
  "!**/*.d.ts",
1254
1300
  ...extraPatterns
1255
1301
  ], getFileInfo(options.output.target).dirname);
1256
- if (options.output.schemas) await removeFilesAndEmptyFolders([
1257
- "**/*",
1258
- "!**/*.d.ts",
1259
- ...extraPatterns
1260
- ], getFileInfo(options.output.schemas).dirname);
1302
+ if (options.output.schemas) {
1303
+ const schemasPath = isString(options.output.schemas) ? options.output.schemas : options.output.schemas.path;
1304
+ await removeFilesAndEmptyFolders([
1305
+ "**/*",
1306
+ "!**/*.d.ts",
1307
+ ...extraPatterns
1308
+ ], getFileInfo(schemasPath).dirname);
1309
+ }
1261
1310
  log(`${projectName} Cleaning output folder`);
1262
1311
  }
1263
1312
  await writeSpecs(await importSpecs(workspace, options, projectName), workspace, options, projectName);
@@ -1316,4 +1365,4 @@ async function loadConfigFile(configFilePath) {
1316
1365
 
1317
1366
  //#endregion
1318
1367
  export { defineConfig as a, name as c, startWatcher as i, version as l, loadConfigFile as n, normalizeOptions as o, generateSpec as r, description as s, findConfigFile as t };
1319
- //# sourceMappingURL=config-CfalXEai.mjs.map
1368
+ //# sourceMappingURL=config-FnusrAiH.mjs.map