@orval/core 7.4.0 → 7.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -112,6 +112,7 @@ type NormalizedMutator = {
112
112
  name?: string;
113
113
  default: boolean;
114
114
  alias?: Record<string, string>;
115
+ extension?: string;
115
116
  };
116
117
  type NormalizedOperationOptions = {
117
118
  transformer?: OutputTransformer;
@@ -242,6 +243,7 @@ type GlobalMockOptions = {
242
243
  delayFunctionLazyExecute?: boolean;
243
244
  baseUrl?: string;
244
245
  locale?: keyof typeof allLocales;
246
+ indexMockFiles?: boolean;
245
247
  };
246
248
  type OverrideMockOptions = Partial<GlobalMockOptions> & {
247
249
  arrayMin?: number;
@@ -278,6 +280,7 @@ type MutatorObject = {
278
280
  name?: string;
279
281
  default?: boolean;
280
282
  alias?: Record<string, string>;
283
+ extension?: string;
281
284
  };
282
285
  type Mutator = string | MutatorObject;
283
286
  type ParamsSerializerOptions = {
@@ -337,7 +340,9 @@ type OverrideOutputContentType = {
337
340
  };
338
341
  type NormalizedHonoOptions = {
339
342
  handlers?: string;
343
+ compositeRoute: string;
340
344
  validator: boolean | 'hono';
345
+ validatorOutputPath: string;
341
346
  };
342
347
  type ZodOptions = {
343
348
  strict?: {
@@ -404,7 +409,9 @@ type NormalizedZodOptions = {
404
409
  };
405
410
  type HonoOptions = {
406
411
  handlers?: string;
412
+ compositeRoute?: string;
407
413
  validator?: boolean | 'hono';
414
+ validatorOutputPath?: string;
408
415
  };
409
416
  type NormalizedQueryOptions = {
410
417
  useQuery?: boolean;
@@ -498,7 +505,7 @@ declare const Verbs: {
498
505
  };
499
506
  type ImportOpenApi = {
500
507
  data: Record<string, unknown | OpenAPIObject>;
501
- input: InputOptions;
508
+ input: NormalizedInputOptions;
502
509
  output: NormalizedOutputOptions;
503
510
  target: string;
504
511
  workspace: string;
package/dist/index.js CHANGED
@@ -49474,19 +49474,25 @@ var resolveUrl = (from, to) => {
49474
49474
  };
49475
49475
  var getRefInfo = ($ref, context) => {
49476
49476
  const [pathname, ref] = $ref.split("#");
49477
- const refPaths = ref?.slice(1).split("/").map((part) => part.replace(regex2, "/"));
49477
+ const refPaths = ref?.slice(1).split("/").map((part) => decodeURIComponent(part.replace(regex2, "/")));
49478
49478
  const suffix = refPaths ? (0, import_lodash3.default)(context.output.override, [...refPaths.slice(0, 2), "suffix"], "") : "";
49479
49479
  const originalName = ref ? refPaths[refPaths.length - 1] : path_exports.getSchemaFileName(pathname);
49480
49480
  if (!pathname) {
49481
49481
  return {
49482
- name: pascal(originalName) + suffix,
49482
+ name: sanitize(pascal(originalName) + suffix, {
49483
+ es5keyword: true,
49484
+ es5IdentifierName: true
49485
+ }),
49483
49486
  originalName,
49484
49487
  refPaths
49485
49488
  };
49486
49489
  }
49487
49490
  const path2 = isUrl(context.specKey) ? resolveUrl(context.specKey, pathname) : path_exports.resolve(getFileInfo(context.specKey).dirname, pathname);
49488
49491
  return {
49489
- name: pascal(originalName) + suffix,
49492
+ name: sanitize(pascal(originalName) + suffix, {
49493
+ es5keyword: true,
49494
+ es5IdentifierName: true
49495
+ }),
49490
49496
  originalName,
49491
49497
  specKey: path2,
49492
49498
  refPaths
@@ -49671,7 +49677,7 @@ var resolveObjectOriginal = ({
49671
49677
  context.output.override.useNativeEnums
49672
49678
  );
49673
49679
  return {
49674
- value: context.output.override.useNativeEnums ? `keyof typeof ${propName}` : propName,
49680
+ value: context.output.override.useNativeEnums ? `(keyof typeof ${propName})` : propName,
49675
49681
  imports: [{ name: propName }],
49676
49682
  schemas: [
49677
49683
  ...resolvedValue.schemas,
@@ -50293,7 +50299,7 @@ var getObject = ({
50293
50299
  acc.hasReadonlyProps ||= isReadOnly || false;
50294
50300
  acc.imports.push(...resolvedValue.imports);
50295
50301
  acc.value += `
50296
- ${doc ? `${doc} ` : ""}${isReadOnly && !context.output.override.suppressReadonlyModifier ? "readonly " : ""}${getKey(key)}${isRequired ? "" : "?"}: ${resolvedValue.value};`;
50302
+ ${doc ? `${doc} ` : ""}${isReadOnly && !context.output.override.suppressReadonlyModifier ? "readonly " : ""}${getKey(key)}${isRequired ? "" : "?"}: ${resolvedValue.isEnum && context.output.override.useNativeEnums ? `(keyof typeof ${resolvedValue.value})` : resolvedValue.value};`;
50297
50303
  acc.schemas.push(...resolvedValue.schemas);
50298
50304
  if (arr.length - 1 === index3) {
50299
50305
  if (item.additionalProperties) {
@@ -50389,8 +50395,7 @@ var getScalar = ({
50389
50395
  context
50390
50396
  }) => {
50391
50397
  const isAngularClient = context.output.client === OutputClient.ANGULAR;
50392
- const typeIncludesNull = Array.isArray(item.type) && item.type.includes("null");
50393
- const nullable = (typeIncludesNull || item.nullable) && !isAngularClient ? " | null" : "";
50398
+ const nullable = item.nullable && !isAngularClient ? " | null" : "";
50394
50399
  const enumItems = item.enum?.filter((enumItem) => enumItem !== null);
50395
50400
  if (!item.type && item.items) {
50396
50401
  item.type = "array";
@@ -50493,6 +50498,20 @@ var getScalar = ({
50493
50498
  };
50494
50499
  case "object":
50495
50500
  default: {
50501
+ if (Array.isArray(item.type)) {
50502
+ return combineSchemas({
50503
+ schema: {
50504
+ anyOf: item.type.map((type) => ({
50505
+ ...item,
50506
+ type
50507
+ }))
50508
+ },
50509
+ name,
50510
+ separator: "anyOf",
50511
+ context,
50512
+ nullable
50513
+ });
50514
+ }
50496
50515
  if (enumItems) {
50497
50516
  const value3 = `${enumItems.map(
50498
50517
  (enumItem) => isString2(enumItem) ? `'${escape2(enumItem)}'` : `${enumItem}`
@@ -50533,7 +50552,11 @@ var combineValues = ({
50533
50552
  return `${resolvedData.values.join(` | `)}${resolvedValue ? ` | ${resolvedValue.value}` : ""}`;
50534
50553
  }
50535
50554
  if (separator2 === "allOf") {
50536
- return `${resolvedData.values.join(` & `)}${resolvedValue ? ` & ${resolvedValue.value}` : ""}`;
50555
+ const joined = `${resolvedData.values.join(` & `)}${resolvedValue ? ` & ${resolvedValue.value}` : ""}`;
50556
+ if (resolvedData.requiredProperties.length) {
50557
+ return `${joined} & Required<Pick<${joined}, '${resolvedData.requiredProperties.join("' | '")}'>>`;
50558
+ }
50559
+ return joined;
50537
50560
  }
50538
50561
  let values = resolvedData.values;
50539
50562
  const hasObjectSubschemas = resolvedData.allProperties.length;
@@ -50574,15 +50597,8 @@ var combineSchemas = ({
50574
50597
  if (propName && acc.schemas.length) {
50575
50598
  propName = propName + pascal(getNumberWord(acc.schemas.length + 1));
50576
50599
  }
50577
- if (separator2 === "allOf" && schema.required) {
50578
- if (isSchema(subSchema) && subSchema.required) {
50579
- subSchema = {
50580
- ...subSchema,
50581
- required: [...schema.required, ...subSchema.required]
50582
- };
50583
- } else {
50584
- subSchema = { ...subSchema, required: schema.required };
50585
- }
50600
+ if (separator2 === "allOf" && isSchema(subSchema) && subSchema.required) {
50601
+ acc.requiredProperties.push(...subSchema.required);
50586
50602
  }
50587
50603
  const resolvedValue2 = resolveObject({
50588
50604
  schema: subSchema,
@@ -50617,7 +50633,8 @@ var combineSchemas = ({
50617
50633
  allProperties: [],
50618
50634
  hasReadonlyProps: false,
50619
50635
  example: schema.example,
50620
- examples: resolveExampleRefs(schema.examples, context)
50636
+ examples: resolveExampleRefs(schema.examples, context),
50637
+ requiredProperties: separator2 === "allOf" ? schema.required ?? [] : []
50621
50638
  }
50622
50639
  );
50623
50640
  const isAllEnums = resolvedData.isEnum.every((v2) => v2);
@@ -50708,7 +50725,7 @@ var resolveDiscriminators = (schemas, context) => {
50708
50725
  try {
50709
50726
  const { originalName } = getRefInfo(mappingValue, context);
50710
50727
  const name = pascal(originalName);
50711
- subTypeSchema = transformedSchemas[name];
50728
+ subTypeSchema = transformedSchemas[name] ?? transformedSchemas[originalName];
50712
50729
  } catch (e3) {
50713
50730
  subTypeSchema = transformedSchemas[mappingValue];
50714
50731
  }
@@ -51352,11 +51369,15 @@ var addDependency = ({
51352
51369
  });
51353
51370
  }
51354
51371
  if (types) {
51372
+ let uniqueTypes = types;
51355
51373
  if (values) {
51374
+ uniqueTypes = types.filter(
51375
+ (t3) => !values.some((v2) => v2.name === t3.name)
51376
+ );
51356
51377
  dep += "\n";
51357
51378
  }
51358
51379
  dep += generateDependency({
51359
- deps: types,
51380
+ deps: uniqueTypes,
51360
51381
  isAllowSyntheticDefaultImports,
51361
51382
  dependency,
51362
51383
  specsName,
@@ -51415,7 +51436,7 @@ var generateVerbImports = ({
51415
51436
  var generateModelInline = (acc, model) => acc + `${model}
51416
51437
  `;
51417
51438
  var generateModelsInline = (obj) => {
51418
- const schemas = Object.values(obj).flatMap((it) => it).sort((a3, b3) => a3.imports.some((i3) => i3.name === b3.name) ? 1 : -1);
51439
+ const schemas = Object.values(obj).flatMap((it) => it);
51419
51440
  return schemas.reduce(
51420
51441
  (acc, { model }) => generateModelInline(acc, model),
51421
51442
  ""
@@ -51433,7 +51454,7 @@ var getImport = (output, mutator) => {
51433
51454
  const { pathWithoutExtension } = getFileInfo(
51434
51455
  path_exports.relativeSafe(outputFileInfo.dirname, mutatorFileInfo.path)
51435
51456
  );
51436
- return pathWithoutExtension;
51457
+ return `${pathWithoutExtension}${mutator.extension || ""}`;
51437
51458
  };
51438
51459
  var generateMutator = async ({
51439
51460
  output,
@@ -51599,6 +51620,12 @@ var parseFunction = (ast, name) => {
51599
51620
  numberOfParams: node.params.length,
51600
51621
  returnNumberOfParams: returnStatement2.argument.params.length
51601
51622
  };
51623
+ } else if (returnStatement2?.argument?.type === "CallExpression" && returnStatement2.argument.arguments?.[0]?.type === "ArrowFunctionExpression") {
51624
+ const arrowFn = returnStatement2.argument.arguments[0];
51625
+ return {
51626
+ numberOfParams: node.params.length,
51627
+ returnNumberOfParams: arrowFn.params.length
51628
+ };
51602
51629
  }
51603
51630
  return {
51604
51631
  numberOfParams: node.params.length
@@ -51622,6 +51649,12 @@ var parseFunction = (ast, name) => {
51622
51649
  numberOfParams: declaration.init.params.length,
51623
51650
  returnNumberOfParams: returnStatement.argument.params.length
51624
51651
  };
51652
+ } else if (returnStatement?.argument?.type === "CallExpression" && returnStatement.argument.arguments?.[0]?.type === "ArrowFunctionExpression") {
51653
+ const arrowFn = returnStatement.argument.arguments[0];
51654
+ return {
51655
+ numberOfParams: declaration.init.params.length,
51656
+ returnNumberOfParams: arrowFn.params.length
51657
+ };
51625
51658
  }
51626
51659
  return {
51627
51660
  numberOfParams: declaration.init.params.length
@@ -52697,56 +52730,55 @@ var addDefaultTagIfEmpty = (operation) => ({
52697
52730
  ...operation,
52698
52731
  tags: operation.tags.length ? operation.tags : ["default"]
52699
52732
  });
52700
- var generateTargetTags = (currentAcc, operation) => {
52701
- return operation.tags.map(kebab).reduce((acc, tag) => {
52702
- const currentOperation = acc[tag];
52703
- if (!currentOperation) {
52704
- acc[tag] = {
52705
- imports: operation.imports,
52706
- importsMock: operation.importsMock,
52707
- mutators: operation.mutator ? [operation.mutator] : [],
52708
- clientMutators: operation.clientMutators ?? [],
52709
- formData: operation.formData ? [operation.formData] : [],
52710
- formUrlEncoded: operation.formUrlEncoded ? [operation.formUrlEncoded] : [],
52711
- paramsSerializer: operation.paramsSerializer ? [operation.paramsSerializer] : [],
52712
- implementation: operation.implementation,
52713
- implementationMock: {
52714
- function: operation.implementationMock.function,
52715
- handler: operation.implementationMock.handler,
52716
- handlerName: " " + operation.implementationMock.handlerName + "()"
52717
- }
52718
- };
52719
- return acc;
52720
- }
52721
- acc[tag] = {
52722
- implementation: currentOperation.implementation + operation.implementation,
52723
- imports: [...currentOperation.imports, ...operation.imports],
52724
- importsMock: [...currentOperation.importsMock, ...operation.importsMock],
52733
+ var generateTargetTags = (currentAcc, operation, options) => {
52734
+ const tag = kebab(operation.tags[0]);
52735
+ const currentOperation = currentAcc[tag];
52736
+ if (!currentOperation) {
52737
+ currentAcc[tag] = {
52738
+ imports: operation.imports,
52739
+ importsMock: operation.importsMock,
52740
+ mutators: operation.mutator ? [operation.mutator] : [],
52741
+ clientMutators: operation.clientMutators ?? [],
52742
+ formData: operation.formData ? [operation.formData] : [],
52743
+ formUrlEncoded: operation.formUrlEncoded ? [operation.formUrlEncoded] : [],
52744
+ paramsSerializer: operation.paramsSerializer ? [operation.paramsSerializer] : [],
52745
+ implementation: operation.implementation,
52725
52746
  implementationMock: {
52726
- function: currentOperation.implementationMock.function + operation.implementationMock.function,
52727
- handler: currentOperation.implementationMock.handler + operation.implementationMock.handler,
52728
- handlerName: currentOperation.implementationMock.handlerName + ",\n " + operation.implementationMock.handlerName + "()"
52729
- },
52730
- mutators: operation.mutator ? [...currentOperation.mutators ?? [], operation.mutator] : currentOperation.mutators,
52731
- clientMutators: operation.clientMutators ? [
52732
- ...currentOperation.clientMutators ?? [],
52733
- ...operation.clientMutators
52734
- ] : currentOperation.clientMutators,
52735
- formData: operation.formData ? [...currentOperation.formData ?? [], operation.formData] : currentOperation.formData,
52736
- formUrlEncoded: operation.formUrlEncoded ? [...currentOperation.formUrlEncoded ?? [], operation.formUrlEncoded] : currentOperation.formUrlEncoded,
52737
- paramsSerializer: operation.paramsSerializer ? [
52738
- ...currentOperation.paramsSerializer ?? [],
52739
- operation.paramsSerializer
52740
- ] : currentOperation.paramsSerializer
52747
+ function: operation.implementationMock.function,
52748
+ handler: operation.implementationMock.handler,
52749
+ handlerName: " " + operation.implementationMock.handlerName + "()"
52750
+ }
52741
52751
  };
52742
- return acc;
52743
- }, currentAcc);
52752
+ return currentAcc;
52753
+ }
52754
+ currentAcc[tag] = {
52755
+ implementation: currentOperation.implementation + operation.implementation,
52756
+ imports: [...currentOperation.imports, ...operation.imports],
52757
+ importsMock: [...currentOperation.importsMock, ...operation.importsMock],
52758
+ implementationMock: {
52759
+ function: currentOperation.implementationMock.function + operation.implementationMock.function,
52760
+ handler: currentOperation.implementationMock.handler + operation.implementationMock.handler,
52761
+ handlerName: currentOperation.implementationMock.handlerName + ",\n " + operation.implementationMock.handlerName + "()"
52762
+ },
52763
+ mutators: operation.mutator ? [...currentOperation.mutators ?? [], operation.mutator] : currentOperation.mutators,
52764
+ clientMutators: operation.clientMutators ? [
52765
+ ...currentOperation.clientMutators ?? [],
52766
+ ...operation.clientMutators
52767
+ ] : currentOperation.clientMutators,
52768
+ formData: operation.formData ? [...currentOperation.formData ?? [], operation.formData] : currentOperation.formData,
52769
+ formUrlEncoded: operation.formUrlEncoded ? [...currentOperation.formUrlEncoded ?? [], operation.formUrlEncoded] : currentOperation.formUrlEncoded,
52770
+ paramsSerializer: operation.paramsSerializer ? [
52771
+ ...currentOperation.paramsSerializer ?? [],
52772
+ operation.paramsSerializer
52773
+ ] : currentOperation.paramsSerializer
52774
+ };
52775
+ return currentAcc;
52744
52776
  };
52745
52777
  var generateTargetForTags = (builder, options) => {
52746
52778
  const isAngularClient = options.client === OutputClient.ANGULAR;
52747
52779
  const allTargetTags = Object.values(builder.operations).map(addDefaultTagIfEmpty).reduce(
52748
52780
  (acc, operation, index3, arr) => {
52749
- const targetTags = generateTargetTags(acc, operation);
52781
+ const targetTags = generateTargetTags(acc, operation, options);
52750
52782
  if (index3 === arr.length - 1) {
52751
52783
  return Object.entries(targetTags).reduce((acc2, [tag, target]) => {
52752
52784
  const isMutator = !!target.mutators?.some(
@@ -52832,6 +52864,13 @@ var writeSplitTagsMode = async ({
52832
52864
  const isAllowSyntheticDefaultImports = isSyntheticDefaultImportsAllow(
52833
52865
  output.tsconfig
52834
52866
  );
52867
+ const indexFilePath = output.mock && !isFunction2(output.mock) && output.mock.indexMockFiles ? path_exports.join(
52868
+ dirname3,
52869
+ "index." + getMockFileExtensionByTypeName(output.mock) + extension
52870
+ ) : void 0;
52871
+ if (indexFilePath) {
52872
+ await import_fs_extra5.default.outputFile(indexFilePath, "");
52873
+ }
52835
52874
  const generatedFilePathsArray = await Promise.all(
52836
52875
  Object.entries(target).map(async ([tag, target2]) => {
52837
52876
  try {
@@ -52943,6 +52982,15 @@ ${implementationMock}`;
52943
52982
  ) : void 0;
52944
52983
  if (mockPath) {
52945
52984
  await import_fs_extra5.default.outputFile(mockPath, mockData);
52985
+ if (indexFilePath) {
52986
+ const localMockPath = path_exports.joinSafe(
52987
+ "./",
52988
+ tag,
52989
+ tag + "." + getMockFileExtensionByTypeName(output.mock)
52990
+ );
52991
+ import_fs_extra5.default.appendFile(indexFilePath, `export * from '${localMockPath}'
52992
+ `);
52993
+ }
52946
52994
  }
52947
52995
  return [
52948
52996
  implementationPath,