@orval/core 8.5.1 → 8.5.2

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
@@ -8,7 +8,7 @@ import { TypeDocOptions } from "typedoc";
8
8
  //#region src/types.d.ts
9
9
  interface Options {
10
10
  output?: string | OutputOptions;
11
- input?: string | InputOptions;
11
+ input?: string | string[] | InputOptions;
12
12
  hooks?: Partial<HooksOptions>;
13
13
  }
14
14
  type OptionsFn = () => Options | Promise<Options>;
@@ -222,7 +222,7 @@ type InputFiltersOptions = {
222
222
  schemas?: (string | RegExp)[];
223
223
  };
224
224
  type InputOptions = {
225
- target: string | Record<string, unknown> | OpenApiDocument;
225
+ target: string | string[] | Record<string, unknown> | OpenApiDocument;
226
226
  override?: OverrideInput;
227
227
  filters?: InputFiltersOptions;
228
228
  parserOptions?: {
@@ -654,7 +654,7 @@ interface GlobalOptions {
654
654
  mode?: OutputMode;
655
655
  tsconfig?: string | Tsconfig;
656
656
  packageJson?: string;
657
- input?: string;
657
+ input?: string | string[];
658
658
  output?: string;
659
659
  verbose?: boolean;
660
660
  }
@@ -1031,10 +1031,7 @@ type GeneratorClientFooter = (data: {
1031
1031
  type GeneratorClientImports = (data: {
1032
1032
  client: OutputClient | OutputClientFunc;
1033
1033
  implementation: string;
1034
- imports: {
1035
- exports: GeneratorImport[];
1036
- dependency: string;
1037
- }[];
1034
+ imports: readonly GeneratorDependency[];
1038
1035
  projectName?: string;
1039
1036
  hasSchemaDir: boolean;
1040
1037
  isAllowSyntheticDefaultImports: boolean;
@@ -1046,10 +1043,7 @@ type GeneratorClientImports = (data: {
1046
1043
  }) => string;
1047
1044
  type GenerateMockImports = (data: {
1048
1045
  implementation: string;
1049
- imports: {
1050
- exports: GeneratorImport[];
1051
- dependency: string;
1052
- }[];
1046
+ imports: readonly GeneratorDependency[];
1053
1047
  projectName?: string;
1054
1048
  hasSchemaDir: boolean;
1055
1049
  isAllowSyntheticDefaultImports: boolean;
@@ -1676,13 +1670,24 @@ declare function resolveObject({
1676
1670
  }: ResolveOptions): ResolverValue;
1677
1671
  //#endregion
1678
1672
  //#region src/resolvers/ref.d.ts
1679
- declare function resolveRef<TSchema extends OpenApiComponentsObject = OpenApiComponentsObject>(schema: OpenApiComponentsObject, context: ContextSpec, imports?: GeneratorImport[]): {
1673
+ type Example = OpenApiExampleObject | OpenApiReferenceObject;
1674
+ type ResolvedExample = unknown;
1675
+ type Examples = Example[] | Record<string, Example> | ResolvedExample[] | Record<string, ResolvedExample> | undefined;
1676
+ /**
1677
+ * Recursively resolves a `$ref` in an OpenAPI document, following
1678
+ * nested schema refs and collecting imports along the way.
1679
+ *
1680
+ * Handles OpenAPI 3.0 `nullable` and 3.1 type-array hints on direct refs.
1681
+ *
1682
+ * @see https://spec.openapis.org/oas/v3.0.3#reference-object
1683
+ * @see https://spec.openapis.org/oas/v3.1.0#reference-object
1684
+ */
1685
+ declare function resolveRef<TSchema extends object = OpenApiComponentsObject>(schema: OpenApiComponentsObject | OpenApiReferenceObject, context: ContextSpec, imports?: GeneratorImport[]): {
1680
1686
  schema: TSchema;
1681
1687
  imports: GeneratorImport[];
1682
1688
  };
1683
- type Example = OpenApiExampleObject | OpenApiReferenceObject;
1684
- type Examples = Example[] | Record<string, Example> | undefined;
1685
- declare function resolveExampleRefs(examples: Examples, context: ContextSpec): Examples;
1689
+ /** Recursively resolves `$ref` entries in an examples array or record. */
1690
+ declare function resolveExampleRefs(examples: Examples, context: ContextSpec): ResolvedExample[] | Record<string, ResolvedExample> | undefined;
1686
1691
  //#endregion
1687
1692
  //#region src/resolvers/value.d.ts
1688
1693
  interface ResolveValueOptions {
@@ -1897,9 +1902,10 @@ declare function mergeDeep<T extends Record<string, unknown>, U extends Record<s
1897
1902
  //#region src/utils/occurrence.d.ts
1898
1903
  declare function count(str: string | undefined, key: string): number;
1899
1904
  declare namespace path_d_exports {
1900
- export { basename, dirname, extname, getSchemaFileName, isAbsolute, join, joinSafe, normalizeSafe, relativeSafe, resolve, separator$1 as separator };
1905
+ export { getRelativeImportPath, getSchemaFileName, join, joinSafe, normalizeSafe, relativeSafe, separator$1 as separator, toUnix };
1901
1906
  }
1902
- declare const join: (...paths: string[]) => string, resolve: (...paths: string[]) => string, extname: (path: string) => string, dirname: (path: string) => string, basename: (path: string, suffix?: string) => string, isAbsolute: (path: string) => boolean;
1907
+ declare function toUnix(value: string): string;
1908
+ declare function join(...args: string[]): string;
1903
1909
  /**
1904
1910
  * Behaves exactly like `path.relative(from, to)`, but keeps the first meaningful "./"
1905
1911
  */
@@ -1908,6 +1914,29 @@ declare function getSchemaFileName(path: string): string;
1908
1914
  declare const separator$1 = "/";
1909
1915
  declare function normalizeSafe(value: string): string;
1910
1916
  declare function joinSafe(...values: string[]): string;
1917
+ /**
1918
+ * Given two absolute file paths, generates a valid ESM relative import path
1919
+ * from the 'importer' file to the 'exporter' file.
1920
+ *
1921
+ * @example
1922
+ * ```ts
1923
+ * getRelativeImportPath('/path/to/importer.ts', '/path/to/exporter.ts')
1924
+ * // => './exporter'
1925
+ * getRelativeImportPath('/path/to/importer.ts', '/path/to/sub/exporter.ts')
1926
+ * // => './sub/exporter'
1927
+ * getRelativeImportPath('/path/to/importer.ts', '/path/sibling/exporter.ts')
1928
+ * // => '../sibling/exporter'
1929
+ * ```
1930
+ *
1931
+ * This function handles path normalization, cross-platform separators, and
1932
+ * ensures the path is a valid ESM relative specifier (e.g., starts with './').
1933
+ *
1934
+ * @param importerFilePath - The absolute path of the file that will contain the import statement.
1935
+ * @param exporterFilePath - The absolute path of the file being imported.
1936
+ * @param [includeFileExtension=false] - Whether the import path should include the file extension, defaults to false.
1937
+ * @returns The relative import path string.
1938
+ */
1939
+ declare function getRelativeImportPath(importerFilePath: string, exporterFilePath: string, includeFileExtension?: boolean): string;
1911
1940
  //#endregion
1912
1941
  //#region src/utils/resolve-version.d.ts
1913
1942
  declare function resolveInstalledVersion(packageName: string, fromDir: string): string | undefined;
package/dist/index.mjs CHANGED
@@ -678,51 +678,43 @@ function count(str = "", key) {
678
678
  //#endregion
679
679
  //#region src/utils/path.ts
680
680
  var path_exports = /* @__PURE__ */ __exportAll({
681
- basename: () => basename,
682
- dirname: () => dirname,
683
- extname: () => extname,
681
+ getRelativeImportPath: () => getRelativeImportPath,
684
682
  getSchemaFileName: () => getSchemaFileName,
685
- isAbsolute: () => isAbsolute,
686
683
  join: () => join,
687
684
  joinSafe: () => joinSafe,
688
685
  normalizeSafe: () => normalizeSafe,
689
686
  relativeSafe: () => relativeSafe,
690
- resolve: () => resolve,
691
- separator: () => separator
687
+ separator: () => separator,
688
+ toUnix: () => toUnix
692
689
  });
693
- function wrapPathFn(fn) {
694
- return (...args) => {
695
- const result = fn(...args.map((p) => isStringLike(p) ? toUnix(p) : p));
696
- return isStringLike(result) ? toUnix(result) : result;
697
- };
690
+ function toUnix(value) {
691
+ value = value.replaceAll("\\", "/");
692
+ value = value.replaceAll(/(?<!^)\/+/g, "/");
693
+ return value;
694
+ }
695
+ function join(...args) {
696
+ return toUnix(path.join(...args.map((a) => toUnix(a))));
698
697
  }
699
- const path$1 = Object.fromEntries(Object.entries(path).map(([key, value]) => [key, isFunction(value) ? wrapPathFn(value) : value]));
700
- const { join, resolve, extname, dirname, basename, isAbsolute } = path$1;
701
698
  /**
702
699
  * Behaves exactly like `path.relative(from, to)`, but keeps the first meaningful "./"
703
700
  */
704
701
  function relativeSafe(from, to) {
705
- return normalizeSafe(`.${separator}${path$1.relative(from, to)}`);
702
+ return normalizeSafe(`.${separator}${toUnix(path.relative(toUnix(from), toUnix(to)))}`);
706
703
  }
707
704
  function getSchemaFileName(path) {
708
705
  return path.replace(`.${getExtension(path)}`, "").slice(path.lastIndexOf("/") + 1);
709
706
  }
710
707
  const separator = "/";
711
- const toUnix = function(value) {
712
- value = value.replaceAll("\\", "/");
713
- value = value.replaceAll(/(?<!^)\/+/g, "/");
714
- return value;
715
- };
716
708
  function normalizeSafe(value) {
717
709
  let result;
718
710
  value = toUnix(value);
719
- result = path$1.normalize(value);
711
+ result = toUnix(path.normalize(value));
720
712
  if (value.startsWith("./") && !result.startsWith("./") && !result.startsWith("..")) result = "./" + result;
721
713
  else if (value.startsWith("//") && !result.startsWith("//")) result = value.startsWith("//./") ? "//." + result : "/" + result;
722
714
  return result;
723
715
  }
724
716
  function joinSafe(...values) {
725
- let result = path$1.join(...values);
717
+ let result = toUnix(path.join(...values.map((v) => toUnix(v))));
726
718
  if (values.length > 0) {
727
719
  const firstValue = toUnix(values[0]);
728
720
  if (firstValue.startsWith("./") && !result.startsWith("./") && !result.startsWith("..")) result = "./" + result;
@@ -730,6 +722,41 @@ function joinSafe(...values) {
730
722
  }
731
723
  return result;
732
724
  }
725
+ /**
726
+ * Given two absolute file paths, generates a valid ESM relative import path
727
+ * from the 'importer' file to the 'exporter' file.
728
+ *
729
+ * @example
730
+ * ```ts
731
+ * getRelativeImportPath('/path/to/importer.ts', '/path/to/exporter.ts')
732
+ * // => './exporter'
733
+ * getRelativeImportPath('/path/to/importer.ts', '/path/to/sub/exporter.ts')
734
+ * // => './sub/exporter'
735
+ * getRelativeImportPath('/path/to/importer.ts', '/path/sibling/exporter.ts')
736
+ * // => '../sibling/exporter'
737
+ * ```
738
+ *
739
+ * This function handles path normalization, cross-platform separators, and
740
+ * ensures the path is a valid ESM relative specifier (e.g., starts with './').
741
+ *
742
+ * @param importerFilePath - The absolute path of the file that will contain the import statement.
743
+ * @param exporterFilePath - The absolute path of the file being imported.
744
+ * @param [includeFileExtension=false] - Whether the import path should include the file extension, defaults to false.
745
+ * @returns The relative import path string.
746
+ */
747
+ function getRelativeImportPath(importerFilePath, exporterFilePath, includeFileExtension = false) {
748
+ if (!path.isAbsolute(importerFilePath)) throw new Error(`'importerFilePath' is not an absolute path. "${importerFilePath}"`);
749
+ if (!path.isAbsolute(exporterFilePath)) throw new Error(`'exporterFilePath' is not an absolute path. "${exporterFilePath}"`);
750
+ const importerDir = path.dirname(importerFilePath);
751
+ const relativePath = path.relative(importerDir, exporterFilePath);
752
+ let posixPath = path.posix.join(...relativePath.split(path.sep));
753
+ if (!posixPath.startsWith("./") && !posixPath.startsWith("../")) posixPath = `./${posixPath}`;
754
+ if (!includeFileExtension) {
755
+ const ext = path.extname(posixPath);
756
+ if (ext && posixPath.endsWith(ext)) posixPath = posixPath.slice(0, -ext.length);
757
+ }
758
+ return posixPath;
759
+ }
733
760
 
734
761
  //#endregion
735
762
  //#region src/utils/resolve-version.ts
@@ -1174,48 +1201,80 @@ function getRefInfo($ref, context) {
1174
1201
 
1175
1202
  //#endregion
1176
1203
  //#region src/resolvers/ref.ts
1204
+ const REF_NOT_FOUND_PREFIX = "Oops... 🍻. Ref not found";
1205
+ /**
1206
+ * Recursively resolves a `$ref` in an OpenAPI document, following
1207
+ * nested schema refs and collecting imports along the way.
1208
+ *
1209
+ * Handles OpenAPI 3.0 `nullable` and 3.1 type-array hints on direct refs.
1210
+ *
1211
+ * @see https://spec.openapis.org/oas/v3.0.3#reference-object
1212
+ * @see https://spec.openapis.org/oas/v3.1.0#reference-object
1213
+ */
1177
1214
  function resolveRef(schema, context, imports = []) {
1178
- if ("schema" in schema && schema.schema?.$ref) {
1179
- const resolvedRef = resolveRef(schema.schema, context, imports);
1180
- if ("examples" in schema) schema.examples = resolveExampleRefs(schema.examples, context);
1181
- if ("examples" in resolvedRef.schema) resolvedRef.schema.examples = resolveExampleRefs(resolvedRef.schema.examples, context);
1215
+ const refPath = "$ref" in schema ? schema.$ref : void 0;
1216
+ const nestedSchema = "schema" in schema ? schema.schema : void 0;
1217
+ if (isObject(nestedSchema) && isReference(nestedSchema) && typeof nestedSchema.$ref === "string") {
1218
+ const resolvedRef = resolveRef(nestedSchema, context, imports);
1219
+ if ("examples" in schema) {
1220
+ const schemaWithExamples = schema;
1221
+ schemaWithExamples.examples = resolveExampleRefs(schemaWithExamples.examples, context);
1222
+ }
1223
+ if ("examples" in resolvedRef.schema) {
1224
+ const resolvedWithExamples = resolvedRef.schema;
1225
+ resolvedWithExamples.examples = resolveExampleRefs(resolvedWithExamples.examples, context);
1226
+ }
1182
1227
  return {
1183
1228
  schema: {
1184
1229
  ...schema,
1185
1230
  schema: resolvedRef.schema
1186
1231
  },
1187
- imports
1232
+ imports: resolvedRef.imports
1188
1233
  };
1189
1234
  }
1190
1235
  if (isDereferenced(schema)) {
1191
- if ("examples" in schema) schema.examples = resolveExampleRefs(schema.examples, context);
1236
+ if ("examples" in schema) {
1237
+ const schemaWithExamples = schema;
1238
+ schemaWithExamples.examples = resolveExampleRefs(schemaWithExamples.examples, context);
1239
+ }
1192
1240
  return {
1193
1241
  schema,
1194
1242
  imports
1195
1243
  };
1196
1244
  }
1245
+ if (!refPath) throw new Error(`${REF_NOT_FOUND_PREFIX}: missing $ref`);
1197
1246
  const { currentSchema, refInfo: { name, originalName } } = getSchema$1(schema, context);
1198
- if (!currentSchema) throw new Error(`Oops... 🍻. Ref not found: ${schema.$ref}`);
1247
+ if (!currentSchema) throw new Error(`${REF_NOT_FOUND_PREFIX}: ${refPath}`);
1199
1248
  return resolveRef(currentSchema, { ...context }, [...imports, {
1200
1249
  name,
1201
1250
  schemaName: originalName
1202
1251
  }]);
1203
1252
  }
1253
+ /**
1254
+ * Looks up a schema by its `$ref` path in the spec, applying suffix resolution.
1255
+ *
1256
+ * Preserves OpenAPI 3.0 `nullable` and 3.1 type-array (`["object", "null"]`)
1257
+ * hints from the referencing schema onto the resolved target.
1258
+ *
1259
+ * @see https://spec.openapis.org/oas/v3.0.3#fixed-fields-18 (nullable)
1260
+ * @see https://spec.openapis.org/oas/v3.1.0#schema-object (type as array)
1261
+ */
1204
1262
  function getSchema$1(schema, context) {
1263
+ if (!schema.$ref) throw new Error(`${REF_NOT_FOUND_PREFIX}: missing $ref`);
1205
1264
  const refInfo = getRefInfo(schema.$ref, context);
1206
1265
  const { refPaths } = refInfo;
1207
1266
  let schemaByRefPaths = Array.isArray(refPaths) ? prop(context.spec, ...refPaths) : void 0;
1208
1267
  schemaByRefPaths ??= context.spec;
1209
1268
  if (isReference(schemaByRefPaths)) return getSchema$1(schemaByRefPaths, context);
1210
1269
  let currentSchema = schemaByRefPaths || context.spec;
1211
- if ("nullable" in schema) {
1270
+ if (isObject(currentSchema) && "nullable" in schema) {
1212
1271
  const nullable = schema.nullable;
1213
1272
  currentSchema = {
1214
1273
  ...currentSchema,
1215
1274
  nullable
1216
1275
  };
1217
1276
  }
1218
- if ("type" in schema && Array.isArray(schema.type)) {
1277
+ if (isObject(currentSchema) && "type" in schema && Array.isArray(schema.type)) {
1219
1278
  const type = schema.type;
1220
1279
  currentSchema = {
1221
1280
  ...currentSchema,
@@ -1227,17 +1286,18 @@ function getSchema$1(schema, context) {
1227
1286
  refInfo
1228
1287
  };
1229
1288
  }
1289
+ /** Recursively resolves `$ref` entries in an examples array or record. */
1230
1290
  function resolveExampleRefs(examples, context) {
1231
1291
  if (!examples) return;
1232
1292
  return Array.isArray(examples) ? examples.map((example) => {
1233
- if (isReference(example)) {
1293
+ if (isObject(example) && isReference(example)) {
1234
1294
  const { schema } = resolveRef(example, context);
1235
1295
  return schema.value;
1236
1296
  }
1237
1297
  return example;
1238
1298
  }) : (() => {
1239
1299
  const result = {};
1240
- for (const [key, example] of Object.entries(examples)) result[key] = isReference(example) ? resolveRef(example, context).schema.value : example;
1300
+ for (const [key, example] of Object.entries(examples)) result[key] = isObject(example) && isReference(example) ? resolveRef(example, context).schema.value : example;
1241
1301
  return result;
1242
1302
  })();
1243
1303
  }
@@ -3120,7 +3180,7 @@ function generateModelsInline(obj) {
3120
3180
  //#region src/generators/mutator-info.ts
3121
3181
  async function getMutatorInfo(filePath, options) {
3122
3182
  const { root = process.cwd(), namedExport = "default", alias, external, tsconfig } = options ?? {};
3123
- return parseFile(await bundleFile(root, path.resolve(filePath), alias, external, tsconfig?.compilerOptions), namedExport, getEcmaVersion(tsconfig?.compilerOptions?.target));
3183
+ return parseFile(await bundleFile(root, filePath, alias, external, tsconfig?.compilerOptions), namedExport, getEcmaVersion(tsconfig?.compilerOptions?.target));
3124
3184
  }
3125
3185
  async function bundleFile(root, fileName, alias, external, compilerOptions) {
3126
3186
  const { text } = (await build({
@@ -3217,10 +3277,8 @@ function getEcmaVersion(target) {
3217
3277
  //#region src/generators/mutator.ts
3218
3278
  const BODY_TYPE_NAME = "BodyType";
3219
3279
  const getImport = (output, mutator) => {
3220
- const outputFileInfo = getFileInfo(output);
3221
- const mutatorFileInfo = getFileInfo(mutator.path);
3222
- const { pathWithoutExtension } = getFileInfo(relativeSafe(outputFileInfo.dirname, mutatorFileInfo.path));
3223
- return `${pathWithoutExtension}${mutator.extension ?? ""}`;
3280
+ const outputFile = getFileInfo(output).path;
3281
+ return `${getRelativeImportPath(outputFile, mutator.path)}${mutator.extension ?? ""}`;
3224
3282
  };
3225
3283
  async function generateMutator({ output, mutator, name, workspace, tsconfig }) {
3226
3284
  if (!mutator || !output) return;
@@ -3236,7 +3294,7 @@ async function generateMutator({ output, mutator, name, workspace, tsconfig }) {
3236
3294
  const errorTypeName = mutator.default ? `${pascal(name)}ErrorType` : "ErrorType";
3237
3295
  const bodyTypeName = mutator.default ? `${pascal(name)}${BODY_TYPE_NAME}` : BODY_TYPE_NAME;
3238
3296
  const mutatorInfo = await getMutatorInfo(importPath, {
3239
- root: path.resolve(workspace),
3297
+ root: workspace,
3240
3298
  namedExport: mutatorInfoName,
3241
3299
  alias: mutator.alias,
3242
3300
  external: mutator.external,
@@ -3962,8 +4020,8 @@ function getSchema({ schema: { imports, model }, target, header, namingConventio
3962
4020
  file += model;
3963
4021
  return file;
3964
4022
  }
3965
- function getPath(path, name, fileExtension) {
3966
- return join(path, `/${name}${fileExtension}`);
4023
+ function getPath(path$1, name, fileExtension) {
4024
+ return path.join(path$1, `${name}${fileExtension}`);
3967
4025
  }
3968
4026
  function writeModelInline(acc, model) {
3969
4027
  return acc + `${model}\n`;
@@ -4011,7 +4069,7 @@ async function writeSchemas({ schemaPath, schemas, target, namingConvention, fil
4011
4069
  });
4012
4070
  }
4013
4071
  if (indexFiles) {
4014
- const schemaFilePath = join(schemaPath, `/index${fileExtension}`);
4072
+ const schemaFilePath = path.join(schemaPath, `index${fileExtension}`);
4015
4073
  await fs$1.ensureFile(schemaFilePath);
4016
4074
  const ext = fileExtension.endsWith(".ts") ? fileExtension.slice(0, -3) : fileExtension;
4017
4075
  const conventionNamesSet = new Set(Object.values(schemaGroups).map((group) => conventionName(group[0].name, namingConvention)));
@@ -4043,7 +4101,7 @@ function generateImportsForBuilder(output, imports, relativeSchemasPath) {
4043
4101
  dependency: relativeSchemasPath
4044
4102
  }];
4045
4103
  else schemaImports = uniqueBy(imports.filter((i) => !i.importPath), (x) => x.name).map((i) => {
4046
- const name = conventionName(i.schemaName ?? i.name, output.namingConvention);
4104
+ const name = conventionName(isZodSchemaOutput ? i.name : i.schemaName ?? i.name, output.namingConvention);
4047
4105
  const suffix = isZodSchemaOutput ? ".zod" : "";
4048
4106
  const importExtension = output.fileExtension.replace(/\.ts$/, "") || "";
4049
4107
  return {
@@ -4051,7 +4109,7 @@ function generateImportsForBuilder(output, imports, relativeSchemasPath) {
4051
4109
  dependency: joinSafe(relativeSchemasPath, `${name}${suffix}${importExtension}`)
4052
4110
  };
4053
4111
  });
4054
- const otherImports = uniqueBy(imports.filter((i) => !!i.importPath), (x) => x.name + (x.importPath ?? "")).map((i) => {
4112
+ const otherImports = uniqueBy(imports.filter((i) => !!i.importPath), (x) => x.name + x.importPath).map((i) => {
4055
4113
  return {
4056
4114
  exports: [i],
4057
4115
  dependency: i.importPath
@@ -4180,13 +4238,13 @@ interface TypedResponse<T> extends Response {
4180
4238
  //#region src/writers/single-mode.ts
4181
4239
  async function writeSingleMode({ builder, output, projectName, header, needSchema }) {
4182
4240
  try {
4183
- const { path, dirname } = getFileInfo(output.target, {
4241
+ const { path } = getFileInfo(output.target, {
4184
4242
  backupFilename: conventionName(builder.info.title, output.namingConvention),
4185
4243
  extension: output.fileExtension
4186
4244
  });
4187
4245
  const { imports, importsMock, implementation, implementationMock, mutators, clientMutators, formData, formUrlEncoded, paramsSerializer, fetchReviver } = generateTarget(builder, output);
4188
4246
  let data = header;
4189
- const schemasPath = output.schemas ? relativeSafe(dirname, getFileInfo(isString(output.schemas) ? output.schemas : output.schemas.path, { extension: output.fileExtension }).dirname) : void 0;
4247
+ const schemasPath = output.schemas ? getRelativeImportPath(path, getFileInfo(isString(output.schemas) ? output.schemas : output.schemas.path, { extension: output.fileExtension }).dirname) : void 0;
4190
4248
  const isAllowSyntheticDefaultImports = isSyntheticDefaultImportsAllow(output.tsconfig);
4191
4249
  const importsForBuilder = schemasPath ? generateImportsForBuilder(output, imports.filter((imp) => !importsMock.some((impMock) => imp.name === impMock.name)), schemasPath) : [];
4192
4250
  data += builder.imports({
@@ -4248,14 +4306,14 @@ async function writeSingleMode({ builder, output, projectName, header, needSchem
4248
4306
  //#region src/writers/split-mode.ts
4249
4307
  async function writeSplitMode({ builder, output, projectName, header, needSchema }) {
4250
4308
  try {
4251
- const { filename, dirname, extension } = getFileInfo(output.target, {
4309
+ const { path: targetPath, filename, dirname, extension } = getFileInfo(output.target, {
4252
4310
  backupFilename: conventionName(builder.info.title, output.namingConvention),
4253
4311
  extension: output.fileExtension
4254
4312
  });
4255
4313
  const { imports, implementation, implementationMock, importsMock, mutators, clientMutators, formData, formUrlEncoded, paramsSerializer, fetchReviver } = generateTarget(builder, output);
4256
4314
  let implementationData = header;
4257
4315
  let mockData = header;
4258
- const relativeSchemasPath = output.schemas ? relativeSafe(dirname, getFileInfo(isString(output.schemas) ? output.schemas : output.schemas.path, { extension: output.fileExtension }).dirname) : "./" + filename + ".schemas";
4316
+ const relativeSchemasPath = output.schemas ? getRelativeImportPath(targetPath, getFileInfo(isString(output.schemas) ? output.schemas : output.schemas.path, { extension: output.fileExtension }).dirname) : "./" + filename + ".schemas";
4259
4317
  const isAllowSyntheticDefaultImports = isSyntheticDefaultImportsAllow(output.tsconfig);
4260
4318
  const importsForBuilder = generateImportsForBuilder(output, imports, relativeSchemasPath);
4261
4319
  implementationData += builder.imports({
@@ -4280,10 +4338,10 @@ async function writeSplitMode({ builder, output, projectName, header, needSchema
4280
4338
  isAllowSyntheticDefaultImports,
4281
4339
  options: isFunction(output.mock) ? void 0 : output.mock
4282
4340
  });
4283
- const schemasPath = output.schemas ? void 0 : join(dirname, filename + ".schemas" + extension);
4341
+ const schemasPath = output.schemas ? void 0 : path.join(dirname, filename + ".schemas" + extension);
4284
4342
  if (schemasPath && needSchema) {
4285
4343
  const schemasData = header + generateModelsInline(builder.schemas);
4286
- await fs$1.outputFile(join(dirname, filename + ".schemas" + extension), schemasData);
4344
+ await fs$1.outputFile(schemasPath, schemasData);
4287
4345
  }
4288
4346
  if (mutators) implementationData += generateMutatorImports({
4289
4347
  mutators,
@@ -4305,9 +4363,9 @@ async function writeSplitMode({ builder, output, projectName, header, needSchema
4305
4363
  implementationData += `\n${implementation}`;
4306
4364
  mockData += `\n${implementationMock}`;
4307
4365
  const implementationFilename = filename + (OutputClient.ANGULAR === output.client ? ".service" : "") + extension;
4308
- const implementationPath = join(dirname, implementationFilename);
4309
- await fs$1.outputFile(join(dirname, implementationFilename), implementationData);
4310
- const mockPath = output.mock ? join(dirname, filename + "." + getMockFileExtensionByTypeName(output.mock) + extension) : void 0;
4366
+ const implementationPath = path.join(dirname, implementationFilename);
4367
+ await fs$1.outputFile(implementationPath, implementationData);
4368
+ const mockPath = output.mock ? path.join(dirname, filename + "." + getMockFileExtensionByTypeName(output.mock) + extension) : void 0;
4311
4369
  if (mockPath) await fs$1.outputFile(mockPath, mockData);
4312
4370
  return [
4313
4371
  implementationPath,
@@ -4444,7 +4502,7 @@ async function writeSplitTagsMode({ builder, output, projectName, header, needSc
4444
4502
  const target = generateTargetForTags(builder, output);
4445
4503
  const isAllowSyntheticDefaultImports = isSyntheticDefaultImportsAllow(output.tsconfig);
4446
4504
  const mockOption = output.mock && !isFunction(output.mock) ? output.mock : void 0;
4447
- const indexFilePath = mockOption?.indexMockFiles ? join(dirname, "index." + getMockFileExtensionByTypeName(mockOption) + extension) : void 0;
4505
+ const indexFilePath = mockOption?.indexMockFiles ? path.join(dirname, "index." + getMockFileExtensionByTypeName(mockOption) + extension) : void 0;
4448
4506
  if (indexFilePath) await fs$1.outputFile(indexFilePath, "");
4449
4507
  const tagEntries = Object.entries(target);
4450
4508
  const generatedFilePathsArray = await Promise.all(tagEntries.map(async ([tag, target]) => {
@@ -4452,7 +4510,8 @@ async function writeSplitTagsMode({ builder, output, projectName, header, needSc
4452
4510
  const { imports, implementation, implementationMock, importsMock, mutators, clientMutators, formData, fetchReviver, formUrlEncoded, paramsSerializer } = target;
4453
4511
  let implementationData = header;
4454
4512
  let mockData = header;
4455
- const relativeSchemasPath = output.schemas ? "../" + relativeSafe(dirname, getFileInfo(isString(output.schemas) ? output.schemas : output.schemas.path, { extension: output.fileExtension }).dirname) : "../" + filename + ".schemas";
4513
+ const importerPath = path.join(dirname, tag, tag + extension);
4514
+ const relativeSchemasPath = output.schemas ? getRelativeImportPath(importerPath, getFileInfo(isString(output.schemas) ? output.schemas : output.schemas.path, { extension: output.fileExtension }).dirname) : "../" + filename + ".schemas";
4456
4515
  const importsForBuilder = generateImportsForBuilder(output, imports, relativeSchemasPath);
4457
4516
  implementationData += builder.imports({
4458
4517
  client: output.client,
@@ -4476,7 +4535,7 @@ async function writeSplitTagsMode({ builder, output, projectName, header, needSc
4476
4535
  isAllowSyntheticDefaultImports,
4477
4536
  options: isFunction(output.mock) ? void 0 : output.mock
4478
4537
  });
4479
- const schemasPath = output.schemas ? void 0 : join(dirname, filename + ".schemas" + extension);
4538
+ const schemasPath = output.schemas ? void 0 : path.join(dirname, filename + ".schemas" + extension);
4480
4539
  if (schemasPath && needSchema) {
4481
4540
  const schemasData = header + generateModelsInline(builder.schemas);
4482
4541
  await fs$1.outputFile(schemasPath, schemasData);
@@ -4517,9 +4576,9 @@ async function writeSplitTagsMode({ builder, output, projectName, header, needSc
4517
4576
  implementationData += `\n${implementation}`;
4518
4577
  mockData += `\n${implementationMock}`;
4519
4578
  const implementationFilename = tag + (OutputClient.ANGULAR === output.client ? ".service" : "") + extension;
4520
- const implementationPath = join(dirname, tag, implementationFilename);
4579
+ const implementationPath = path.join(dirname, tag, implementationFilename);
4521
4580
  await fs$1.outputFile(implementationPath, implementationData);
4522
- const mockPath = output.mock ? join(dirname, tag, tag + "." + getMockFileExtensionByTypeName(output.mock) + extension) : void 0;
4581
+ const mockPath = output.mock ? path.join(dirname, tag, tag + "." + getMockFileExtensionByTypeName(output.mock) + extension) : void 0;
4523
4582
  if (mockPath) await fs$1.outputFile(mockPath, mockData);
4524
4583
  return [
4525
4584
  implementationPath,
@@ -4543,7 +4602,7 @@ async function writeSplitTagsMode({ builder, output, projectName, header, needSc
4543
4602
  //#endregion
4544
4603
  //#region src/writers/tags-mode.ts
4545
4604
  async function writeTagsMode({ builder, output, projectName, header, needSchema }) {
4546
- const { filename, dirname, extension } = getFileInfo(output.target, {
4605
+ const { path: targetPath, filename, dirname, extension } = getFileInfo(output.target, {
4547
4606
  backupFilename: conventionName(builder.info.title, output.namingConvention),
4548
4607
  extension: output.fileExtension
4549
4608
  });
@@ -4553,7 +4612,7 @@ async function writeTagsMode({ builder, output, projectName, header, needSchema
4553
4612
  try {
4554
4613
  const { imports, implementation, implementationMock, importsMock, mutators, clientMutators, formData, formUrlEncoded, fetchReviver, paramsSerializer } = target;
4555
4614
  let data = header;
4556
- const schemasPathRelative = output.schemas ? relativeSafe(dirname, getFileInfo(isString(output.schemas) ? output.schemas : output.schemas.path, { extension: output.fileExtension }).dirname) : "./" + filename + ".schemas";
4615
+ const schemasPathRelative = output.schemas ? getRelativeImportPath(targetPath, getFileInfo(isString(output.schemas) ? output.schemas : output.schemas.path, { extension: output.fileExtension }).dirname) : "./" + filename + ".schemas";
4557
4616
  const importsForBuilder = generateImportsForBuilder(output, imports.filter((imp) => !importsMock.some((impMock) => imp.name === impMock.name)), schemasPathRelative);
4558
4617
  data += builder.imports({
4559
4618
  client: output.client,
@@ -4579,7 +4638,7 @@ async function writeTagsMode({ builder, output, projectName, header, needSchema
4579
4638
  options: isFunction(output.mock) ? void 0 : output.mock
4580
4639
  });
4581
4640
  }
4582
- const schemasPath = output.schemas ? void 0 : join(dirname, filename + ".schemas" + extension);
4641
+ const schemasPath = output.schemas ? void 0 : path.join(dirname, filename + ".schemas" + extension);
4583
4642
  if (schemasPath && needSchema) {
4584
4643
  const schemasData = header + generateModelsInline(builder.schemas);
4585
4644
  await fs$1.outputFile(schemasPath, schemasData);
@@ -4607,7 +4666,7 @@ async function writeTagsMode({ builder, output, projectName, header, needSchema
4607
4666
  data += "\n\n";
4608
4667
  data += implementationMock;
4609
4668
  }
4610
- const implementationPath = join(dirname, `${kebab(tag)}${extension}`);
4669
+ const implementationPath = path.join(dirname, `${kebab(tag)}${extension}`);
4611
4670
  await fs$1.outputFile(implementationPath, data);
4612
4671
  return [implementationPath, ...schemasPath ? [schemasPath] : []];
4613
4672
  } catch (error) {