@orval/hono 7.4.1 → 7.6.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.js CHANGED
@@ -2171,7 +2171,7 @@ var getRoutePath = (path) => {
2171
2171
  const matches = path.match(/([^{]*){?([\w*_-]*)}?(.*)/);
2172
2172
  if (!(matches == null ? void 0 : matches.length)) return path;
2173
2173
  const prev = matches[1];
2174
- const param = (0, import_core.sanitize)((0, import_core.camel)(matches[2]), {
2174
+ const param = (0, import_core.sanitize)(matches[2], {
2175
2175
  es5keyword: true,
2176
2176
  underscore: true,
2177
2177
  dash: true,
@@ -2224,11 +2224,12 @@ var getHonoHeader = ({
2224
2224
  }) => {
2225
2225
  const targetInfo = (0, import_core2.getFileInfo)(output.target);
2226
2226
  let handlers = "";
2227
+ const importHandlers = Object.values(verbOptions).filter(
2228
+ (verbOption) => clientImplementation.includes(`${verbOption.operationName}Handlers`)
2229
+ );
2227
2230
  if (output.override.hono.handlers) {
2228
2231
  const handlerFileInfo = (0, import_core2.getFileInfo)(output.override.hono.handlers);
2229
- handlers = Object.values(verbOptions).filter(
2230
- (verbOption) => clientImplementation.includes(`${verbOption.operationName}Handlers`)
2231
- ).map((verbOption) => {
2232
+ handlers = importHandlers.map((verbOption) => {
2232
2233
  var _a, _b, _c;
2233
2234
  const isTagMode = output.mode === "tags" || output.mode === "tags-split";
2234
2235
  const tag2 = (0, import_core2.kebab)((_a = verbOption.tags[0]) != null ? _a : "default");
@@ -2242,9 +2243,10 @@ var getHonoHeader = ({
2242
2243
  return `import { ${verbOption.operationName}Handlers } from '${handlersPath}';`;
2243
2244
  }).join("\n");
2244
2245
  } else {
2246
+ const importHandlerNames = importHandlers.map((verbOption) => ` ${verbOption.operationName}Handlers`).join(`,
2247
+ `);
2245
2248
  handlers = `import {
2246
- ${Object.values(verbOptions).map((verbOption) => ` ${verbOption.operationName}Handlers`).join(`,
2247
- `)}
2249
+ ${importHandlerNames}
2248
2250
  } from './${tag != null ? tag : targetInfo.filename}.handlers';`;
2249
2251
  }
2250
2252
  return `${handlers}
@@ -2255,13 +2257,19 @@ const app = new Hono()
2255
2257
  `;
2256
2258
  };
2257
2259
  var getHonoFooter = () => "export default app";
2258
- var generateHonoRoute = ({ operationName, verb }, { pathRoute }) => {
2260
+ var generateHonoRoute = ({ operationName, verb }, pathRoute) => {
2259
2261
  const path = getRoute(pathRoute);
2260
2262
  return `
2261
2263
  app.${verb.toLowerCase()}('${path}',...${operationName}Handlers)`;
2262
2264
  };
2263
2265
  var generateHono = async (verbOptions, options) => {
2264
- const routeImplementation = generateHonoRoute(verbOptions, options);
2266
+ if (options.override.hono.compositeRoute) {
2267
+ return {
2268
+ implementation: "",
2269
+ imports: []
2270
+ };
2271
+ }
2272
+ const routeImplementation = generateHonoRoute(verbOptions, options.pathRoute);
2265
2273
  return {
2266
2274
  implementation: routeImplementation ? `${routeImplementation}
2267
2275
 
@@ -2314,25 +2322,34 @@ ${currentValidator}async (c: ${contextTypeName}) => {
2314
2322
  },
2315
2323
  );`;
2316
2324
  };
2317
- var getZvalidatorImports = (verbOption, isHonoValidator) => {
2318
- var _a, _b, _c;
2319
- const imports = [];
2320
- if (verbOption.headers) {
2321
- imports.push(`${verbOption.operationName}Header`);
2322
- }
2323
- if (verbOption.params.length) {
2324
- imports.push(`${verbOption.operationName}Params`);
2325
- }
2326
- if (verbOption.queryParams) {
2327
- imports.push(`${verbOption.operationName}QueryParams`);
2328
- }
2329
- if (verbOption.body.definition) {
2330
- imports.push(`${verbOption.operationName}Body`);
2331
- }
2332
- if (!isHonoValidator && !!((_c = (_b = (_a = verbOption.response.originalSchema) == null ? void 0 : _a["200"]) == null ? void 0 : _b.content) == null ? void 0 : _c["application/json"])) {
2333
- imports.push(`${verbOption.operationName}Response`);
2334
- }
2335
- return imports.join(",\n");
2325
+ var getValidatorOutputRelativePath = (validatorOutputPath, handlerPath) => {
2326
+ const { pathWithoutExtension } = (0, import_core2.getFileInfo)(validatorOutputPath);
2327
+ return import_core2.upath.relativeSafe(import_core2.upath.dirname(handlerPath), pathWithoutExtension);
2328
+ };
2329
+ var getZvalidatorImports = (verbOptions, importPath, isHonoValidator) => {
2330
+ const importImplementation = verbOptions.flatMap((verbOption) => {
2331
+ var _a, _b, _c;
2332
+ const imports = [];
2333
+ if (verbOption.headers) {
2334
+ imports.push(`${verbOption.operationName}Header`);
2335
+ }
2336
+ if (verbOption.params.length) {
2337
+ imports.push(`${verbOption.operationName}Params`);
2338
+ }
2339
+ if (verbOption.queryParams) {
2340
+ imports.push(`${verbOption.operationName}QueryParams`);
2341
+ }
2342
+ if (verbOption.body.definition) {
2343
+ imports.push(`${verbOption.operationName}Body`);
2344
+ }
2345
+ if (!isHonoValidator && !!((_c = (_b = (_a = verbOption.response.originalSchema) == null ? void 0 : _a["200"]) == null ? void 0 : _b.content) == null ? void 0 : _c["application/json"])) {
2346
+ imports.push(`${verbOption.operationName}Response`);
2347
+ }
2348
+ return imports.join(",\n");
2349
+ }).join(",\n");
2350
+ return importImplementation ? `import {
2351
+ ${importImplementation}
2352
+ } from '${importPath}'` : "";
2336
2353
  };
2337
2354
  var getVerbOptionGroupByTag = (verbOptions) => {
2338
2355
  return Object.values(verbOptions).reduce(
@@ -2365,7 +2382,7 @@ var generateHandlers = async (verbOptions, output) => {
2365
2382
  (_c = output.override.hono.handlers) != null ? _c : "",
2366
2383
  `./${verbOption.operationName}` + extension
2367
2384
  );
2368
- const hasZValidator2 = !!verbOption.headers || !!verbOption.params.length || !!verbOption.queryParams || !!verbOption.body;
2385
+ const hasZValidator2 = !!verbOption.headers || !!verbOption.params.length || !!verbOption.queryParams || !!verbOption.body.definition;
2369
2386
  const isExist2 = import_fs_extra.default.existsSync(handlerPath2);
2370
2387
  const handlerName = `${verbOption.operationName}Handlers`;
2371
2388
  const contextTypeName = `${(0, import_core2.pascal)(verbOption.operationName)}Context`;
@@ -2388,17 +2405,22 @@ var generateHandlers = async (verbOptions, output) => {
2388
2405
  let validatorImport2 = "";
2389
2406
  if (hasZValidator2) {
2390
2407
  if (output.override.hono.validator === true) {
2408
+ const validatorPath = output.override.hono.validatorOutputPath ? getValidatorOutputRelativePath(
2409
+ output.override.hono.validatorOutputPath,
2410
+ handlerPath2
2411
+ ) : `${outputPath}.validator`;
2391
2412
  validatorImport2 = `
2392
- import { zValidator } from '${outputPath}.validator';`;
2413
+ import { zValidator } from '${validatorPath}';`;
2393
2414
  } else if (output.override.hono.validator === "hono") {
2394
2415
  validatorImport2 = `
2395
2416
  import { zValidator } from '@hono/zod-validator';`;
2396
2417
  }
2397
2418
  }
2398
- const zodImports2 = output.override.hono.validator ? `import { ${getZvalidatorImports(
2399
- verbOption,
2419
+ const zodImports2 = output.override.hono.validator ? getZvalidatorImports(
2420
+ [verbOption],
2421
+ `${outputPath}.zod`,
2400
2422
  output.override.hono.validator === "hono"
2401
- )} } from '${outputPath}.zod';` : "";
2423
+ ) : "";
2402
2424
  const content2 = `import { createFactory } from 'hono/factory';${validatorImport2}
2403
2425
  import { ${contextTypeName} } from '${outputPath}.context';
2404
2426
  ${zodImports2}
@@ -2425,7 +2447,7 @@ ${getHonoHandlers({
2425
2447
  Object.entries(groupByTags).map(async ([tag, verbs]) => {
2426
2448
  const handlerPath2 = output.mode === "tags" ? import_core2.upath.join(dirname, `${(0, import_core2.kebab)(tag)}.handlers${extension}`) : import_core2.upath.join(dirname, tag, tag + ".handlers" + extension);
2427
2449
  const hasZValidator2 = verbs.some(
2428
- (verb) => !!verb.headers || !!verb.params.length || !!verb.queryParams || !!verb.body
2450
+ (verb) => !!verb.headers || !!verb.params.length || !!verb.queryParams || !!verb.body.definition
2429
2451
  );
2430
2452
  const isExist2 = import_fs_extra.default.existsSync(handlerPath2);
2431
2453
  if (isExist2) {
@@ -2451,26 +2473,30 @@ ${getHonoHandlers({
2451
2473
  path: handlerPath2
2452
2474
  };
2453
2475
  }
2454
- const outputRelativePath2 = `./${(0, import_core2.kebab)(tag)}`;
2455
2476
  let validatorImport2 = "";
2456
2477
  if (hasZValidator2) {
2457
2478
  if (output.override.hono.validator === true) {
2479
+ const validatorOutputPath = output.override.hono.validatorOutputPath || `${dirname}/${filename}.validator${extension}`;
2480
+ const validatorPath = getValidatorOutputRelativePath(
2481
+ validatorOutputPath,
2482
+ handlerPath2
2483
+ );
2458
2484
  validatorImport2 = `
2459
- import { zValidator } from '${outputRelativePath2}.validator';`;
2485
+ import { zValidator } from '${validatorPath}';`;
2460
2486
  } else if (output.override.hono.validator === "hono") {
2461
2487
  validatorImport2 = `
2462
2488
  import { zValidator } from '@hono/zod-validator';`;
2463
2489
  }
2464
2490
  }
2465
- const zodImports2 = output.override.hono.validator ? `import { ${Object.values(verbs).map(
2466
- (verb) => getZvalidatorImports(
2467
- verb,
2468
- output.override.hono.validator === "hono"
2469
- )
2470
- ).join(",\n")} } from '${outputRelativePath2}.zod'` : "";
2491
+ const outputRelativePath2 = `./${(0, import_core2.kebab)(tag)}`;
2492
+ const zodImports2 = output.override.hono.validator ? getZvalidatorImports(
2493
+ Object.values(verbs),
2494
+ `${outputRelativePath2}.zod`,
2495
+ output.override.hono.validator === "hono"
2496
+ ) : "";
2471
2497
  let content2 = `import { createFactory } from 'hono/factory';${validatorImport2}
2472
2498
  import { ${Object.values(verbs).map((verb) => `${(0, import_core2.pascal)(verb.operationName)}Context`).join(",\n")} } from '${outputRelativePath2}.context';
2473
- ${zodImports2};
2499
+ ${zodImports2}
2474
2500
 
2475
2501
  const factory = createFactory();`;
2476
2502
  content2 += Object.values(verbs).reduce((acc, verbOption) => {
@@ -2492,7 +2518,7 @@ const factory = createFactory();`;
2492
2518
  );
2493
2519
  }
2494
2520
  const hasZValidator = Object.values(verbOptions).some(
2495
- (verb) => !!verb.headers || !!verb.params.length || !!verb.queryParams || !!verb.body || verb.response.contentTypes.length === 1 && verb.response.contentTypes[0] === "application/json"
2521
+ (verb) => !!verb.headers || !!verb.params.length || !!verb.queryParams || !!verb.body.definition || verb.response.contentTypes.length === 1 && verb.response.contentTypes[0] === "application/json"
2496
2522
  );
2497
2523
  const handlerPath = import_core2.upath.join(dirname, `${filename}.handlers${extension}`);
2498
2524
  const isExist = import_fs_extra.default.existsSync(handlerPath);
@@ -2523,16 +2549,22 @@ const factory = createFactory();`;
2523
2549
  let validatorImport = "";
2524
2550
  if (hasZValidator) {
2525
2551
  if (output.override.hono.validator === true) {
2552
+ const validatorPath = output.override.hono.validatorOutputPath ? getValidatorOutputRelativePath(
2553
+ output.override.hono.validatorOutputPath,
2554
+ handlerPath
2555
+ ) : `${outputRelativePath}.validator`;
2526
2556
  validatorImport = `
2527
- import { zValidator } from '${outputRelativePath}.validator';`;
2557
+ import { zValidator } from '${validatorPath}';`;
2528
2558
  } else if (output.override.hono.validator === "hono") {
2529
2559
  validatorImport = `
2530
2560
  import { zValidator } from '@hono/zod-validator';`;
2531
2561
  }
2532
2562
  }
2533
- const zodImports = output.override.hono.validator ? `import { ${Object.values(verbOptions).map(
2534
- (verb) => getZvalidatorImports(verb, output.override.hono.validator === "hono")
2535
- ).join(",\n")} } from '${outputRelativePath}.zod';` : "";
2563
+ const zodImports = output.override.hono.validator ? getZvalidatorImports(
2564
+ Object.values(verbOptions),
2565
+ `${outputRelativePath}.zod`,
2566
+ output.override.hono.validator === "hono"
2567
+ ) : "";
2536
2568
  let content = `import { createFactory } from 'hono/factory';${validatorImport}
2537
2569
  import { ${Object.values(verbOptions).map((verb) => `${(0, import_core2.pascal)(verb.operationName)}Context`).join(",\n")} } from '${outputRelativePath}.context';
2538
2570
  ${zodImports}
@@ -2558,9 +2590,23 @@ const factory = createFactory();`;
2558
2590
  };
2559
2591
  var getContext = (verbOption) => {
2560
2592
  var _a;
2561
- const paramType = verbOption.params.length ? `param: {
2562
- ${verbOption.params.map((property) => property.definition).join(",\n ")},
2563
- },` : "";
2593
+ let paramType = "";
2594
+ if (verbOption.params.length) {
2595
+ const params = (0, import_core2.getParamsInPath)(verbOption.pathRoute).map((name) => {
2596
+ var _a2;
2597
+ const param = verbOption.params.find(
2598
+ (p) => p.name === (0, import_core2.sanitize)((0, import_core2.camel)(name), { es5keyword: true })
2599
+ );
2600
+ const definition = param == null ? void 0 : param.definition.split(":")[1];
2601
+ const required = (_a2 = param == null ? void 0 : param.required) != null ? _a2 : false;
2602
+ return {
2603
+ definition: `${name}${!required ? "?" : ""}:${definition}`
2604
+ };
2605
+ });
2606
+ paramType = `param: {
2607
+ ${params.map((property) => property.definition).join(",\n ")},
2608
+ },`;
2609
+ }
2564
2610
  const queryType = verbOption.queryParams ? `query: ${(_a = verbOption.queryParams) == null ? void 0 : _a.schema.name},` : "";
2565
2611
  const bodyType = verbOption.body.definition ? `json: ${verbOption.body.definition},` : "";
2566
2612
  const hasIn = !!paramType || !!queryType || !!bodyType;
@@ -2607,14 +2653,21 @@ var generateContext = async (verbOptions, output, context) => {
2607
2653
  imports.push(...verb.body.imports);
2608
2654
  }
2609
2655
  return imports;
2610
- }).filter((imp) => contexts2.includes(imp.name));
2656
+ }).filter((imp) => contexts2.includes(imp.name)).filter(
2657
+ (imp, i, arr) => arr.findIndex((v) => v.name === imp.name) === i
2658
+ );
2611
2659
  if (contexts2.includes("NonReadonly<")) {
2612
2660
  content2 += (0, import_core2.getOrvalGeneratedTypes)();
2613
2661
  content2 += "\n";
2614
2662
  }
2615
- content2 += `import { ${imps2.map((imp) => imp.name).join(",\n")} } from '${relativeSchemasPath2}';
2663
+ if (imps2.length > 0) {
2664
+ const importSchemas = imps2.map((imp) => imp.name).join(",\n ");
2665
+ content2 += `import {
2666
+ ${importSchemas}
2667
+ } from '${relativeSchemasPath2}';
2616
2668
 
2617
2669
  `;
2670
+ }
2618
2671
  content2 += contexts2;
2619
2672
  const contextPath2 = output.mode === "tags" ? import_core2.upath.join(dirname, `${(0, import_core2.kebab)(tag)}.context${extension}`) : import_core2.upath.join(dirname, tag, tag + ".context" + extension);
2620
2673
  return {
@@ -2643,7 +2696,7 @@ var generateContext = async (verbOptions, output, context) => {
2643
2696
  imports.push(...verb.body.imports);
2644
2697
  }
2645
2698
  return imports;
2646
- }).filter((imp) => contexts.includes(imp.name));
2699
+ }).filter((imp) => contexts.includes(imp.name)).filter((imp, i, arr) => arr.findIndex((v) => v.name === imp.name) === i);
2647
2700
  if (contexts.includes("NonReadonly<")) {
2648
2701
  content += (0, import_core2.getOrvalGeneratedTypes)();
2649
2702
  content += "\n";
@@ -2668,7 +2721,7 @@ var generateZodFiles = async (verbOptions, output, context) => {
2668
2721
  );
2669
2722
  if (output.mode === "tags" || output.mode === "tags-split") {
2670
2723
  const groupByTags = getVerbOptionGroupByTag(verbOptions);
2671
- return Promise.all(
2724
+ const builderContexts = await Promise.all(
2672
2725
  Object.entries(groupByTags).map(async ([tag, verbs]) => {
2673
2726
  const zods2 = await Promise.all(
2674
2727
  verbs.map(
@@ -2686,6 +2739,12 @@ var generateZodFiles = async (verbOptions, output, context) => {
2686
2739
  )
2687
2740
  )
2688
2741
  );
2742
+ if (zods2.every((z) => z.implementation === "")) {
2743
+ return {
2744
+ content: "",
2745
+ path: ""
2746
+ };
2747
+ }
2689
2748
  const allMutators2 = zods2.reduce(
2690
2749
  (acc, z) => {
2691
2750
  var _a;
@@ -2710,6 +2769,9 @@ ${mutatorsImports2}
2710
2769
  };
2711
2770
  })
2712
2771
  );
2772
+ return Promise.all(
2773
+ builderContexts.filter((context2) => context2.content !== "")
2774
+ );
2713
2775
  }
2714
2776
  const zods = await Promise.all(
2715
2777
  Object.values(verbOptions).map(
@@ -2757,7 +2819,6 @@ var generateZvalidator = (output, context) => {
2757
2819
  output.override.header,
2758
2820
  context.specs[context.specKey].info
2759
2821
  );
2760
- const { extension, dirname, filename } = (0, import_core2.getFileInfo)(output.target);
2761
2822
  const content = `
2762
2823
  // based on https://github.com/honojs/middleware/blob/main/packages/zod-validator/src/index.ts
2763
2824
  import type { z, ZodSchema, ZodError } from 'zod';
@@ -2895,29 +2956,99 @@ export const zValidator =
2895
2956
  c.res = new Response(JSON.stringify(result.data), c.res);
2896
2957
  }
2897
2958
  }
2959
+
2960
+ return;
2898
2961
  };
2899
2962
  `;
2900
- const validatorPath = import_core2.upath.join(
2901
- dirname,
2902
- `${filename}.validator${extension}`
2903
- );
2963
+ let validatorPath = output.override.hono.validatorOutputPath;
2964
+ if (!output.override.hono.validatorOutputPath) {
2965
+ const { extension, dirname, filename } = (0, import_core2.getFileInfo)(output.target);
2966
+ validatorPath = import_core2.upath.join(dirname, `${filename}.validator${extension}`);
2967
+ }
2904
2968
  return {
2905
2969
  content: `${header}${content}`,
2906
2970
  path: validatorPath
2907
2971
  };
2908
2972
  };
2973
+ var generateCompositeRoutes = async (verbOptions, output, context) => {
2974
+ const targetInfo = (0, import_core2.getFileInfo)(output.target);
2975
+ const compositeRouteInfo = (0, import_core2.getFileInfo)(output.override.hono.compositeRoute);
2976
+ const header = getHeader(
2977
+ output.override.header,
2978
+ context.specs[context.specKey].info
2979
+ );
2980
+ const routes = Object.values(verbOptions).map((verbOption) => {
2981
+ return generateHonoRoute(verbOption, verbOption.pathRoute);
2982
+ }).join(";");
2983
+ const importHandlers = Object.values(verbOptions);
2984
+ let ImportHandlersImplementation = "";
2985
+ if (output.override.hono.handlers) {
2986
+ const handlerFileInfo = (0, import_core2.getFileInfo)(output.override.hono.handlers);
2987
+ const operationNames = importHandlers.map(
2988
+ (verbOption) => verbOption.operationName
2989
+ );
2990
+ ImportHandlersImplementation = operationNames.map((operationName) => {
2991
+ var _a;
2992
+ const importHandlerName = `${operationName}Handlers`;
2993
+ const handlersPath = import_core2.upath.relativeSafe(
2994
+ compositeRouteInfo.dirname,
2995
+ import_core2.upath.join((_a = handlerFileInfo.dirname) != null ? _a : "", `./${operationName}`)
2996
+ );
2997
+ return `import { ${importHandlerName} } from '${handlersPath}';`;
2998
+ }).join("\n");
2999
+ } else {
3000
+ const tags = importHandlers.map(
3001
+ (verbOption) => {
3002
+ var _a;
3003
+ return (0, import_core2.kebab)((_a = verbOption.tags[0]) != null ? _a : "default");
3004
+ }
3005
+ );
3006
+ const uniqueTags = tags.filter((t, i) => tags.indexOf(t) === i);
3007
+ ImportHandlersImplementation = uniqueTags.map((tag) => {
3008
+ var _a;
3009
+ const importHandlerNames = importHandlers.filter((verbOption) => verbOption.tags[0] === tag).map((verbOption) => ` ${verbOption.operationName}Handlers`).join(`,
3010
+ `);
3011
+ const handlersPath = import_core2.upath.relativeSafe(
3012
+ compositeRouteInfo.dirname,
3013
+ import_core2.upath.join((_a = targetInfo.dirname) != null ? _a : "", tag)
3014
+ );
3015
+ return `import {
3016
+ ${importHandlerNames}
3017
+ } from '${handlersPath}/${tag}.handlers';`;
3018
+ }).join("\n");
3019
+ }
3020
+ const honoImport = `import { Hono } from 'hono';`;
3021
+ const honoInitialization = `
3022
+ const app = new Hono()`;
3023
+ const honoAppExport = `
3024
+ export default app`;
3025
+ const content = `${header}${honoImport}
3026
+ ${ImportHandlersImplementation}
3027
+ ${honoInitialization}
3028
+ ${routes}
3029
+ ${honoAppExport}
3030
+ `;
3031
+ return [
3032
+ {
3033
+ content,
3034
+ path: output.override.hono.compositeRoute || ""
3035
+ }
3036
+ ];
3037
+ };
2909
3038
  var generateExtraFiles = async (verbOptions, output, context) => {
2910
- const [handlers, contexts, zods, validator] = await Promise.all([
3039
+ const [handlers, contexts, zods, validator, compositeRoutes] = await Promise.all([
2911
3040
  generateHandlers(verbOptions, output),
2912
3041
  generateContext(verbOptions, output, context),
2913
3042
  generateZodFiles(verbOptions, output, context),
2914
- generateZvalidator(output, context)
3043
+ generateZvalidator(output, context),
3044
+ output.override.hono.compositeRoute ? generateCompositeRoutes(verbOptions, output, context) : []
2915
3045
  ]);
2916
3046
  return [
2917
3047
  ...handlers,
2918
3048
  ...contexts,
2919
3049
  ...zods,
2920
- ...output.override.hono.validator && output.override.hono.validator !== "hono" ? [validator] : []
3050
+ ...output.override.hono.validator && output.override.hono.validator !== "hono" ? [validator] : [],
3051
+ ...compositeRoutes
2921
3052
  ];
2922
3053
  };
2923
3054
  var honoClientBuilder = {