@orval/hono 7.13.1 → 7.14.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
@@ -55,6 +55,7 @@ const getRoute = (route) => {
55
55
 
56
56
  //#endregion
57
57
  //#region src/index.ts
58
+ const ZVALIDATOR_SOURCE = fs_extra.default.readFileSync(__orval_core.upath.join(__dirname, "zValidator.ts")).toString("utf8");
58
59
  const HONO_DEPENDENCIES = [{
59
60
  exports: [
60
61
  {
@@ -66,17 +67,41 @@ const HONO_DEPENDENCIES = [{
66
67
  ],
67
68
  dependency: "hono"
68
69
  }];
70
+ /**
71
+ * generateModuleSpecifier generates the specifier that _from_ would use to
72
+ * import _to_. This is syntactical and does not validate the paths.
73
+ *
74
+ * @param from The filesystem path to the importer.
75
+ * @param to If a filesystem path, it and _from_ must be use the same frame of
76
+ * reference, such as process.cwd() or both be absolute. If only one is
77
+ * absolute, the other must be relative to process.cwd().
78
+ *
79
+ * Otherwise, treated as a package name and returned directly.
80
+ *
81
+ * @return A module specifier that can be used at _from_ to import _to_. It is
82
+ * extensionless to conform with the rest of orval.
83
+ */
84
+ const generateModuleSpecifier = (from, to) => {
85
+ if (to.startsWith(".") || __orval_core.upath.isAbsolute(to)) {
86
+ let ret;
87
+ ret = __orval_core.upath.relativeSafe(__orval_core.upath.dirname(from), to);
88
+ ret = ret.replace(/\.ts$/, "");
89
+ ret = ret.replaceAll(__orval_core.upath.separator, "/");
90
+ return ret;
91
+ }
92
+ return to;
93
+ };
69
94
  const getHonoDependencies = () => HONO_DEPENDENCIES;
70
95
  const getHonoHeader = ({ verbOptions, output, tag, clientImplementation }) => {
71
96
  const targetInfo = (0, __orval_core.getFileInfo)(output.target);
72
- let handlers = "";
97
+ let handlers;
73
98
  const importHandlers = Object.values(verbOptions).filter((verbOption) => clientImplementation.includes(`${verbOption.operationName}Handlers`));
74
99
  if (output.override.hono.handlers) {
75
100
  const handlerFileInfo = (0, __orval_core.getFileInfo)(output.override.hono.handlers);
76
101
  handlers = importHandlers.map((verbOption) => {
77
102
  const isTagMode = output.mode === "tags" || output.mode === "tags-split";
78
103
  const tag$1 = (0, __orval_core.kebab)(verbOption.tags[0] ?? "default");
79
- const handlersPath = __orval_core.upath.relativeSafe(__orval_core.upath.join(targetInfo.dirname ?? "", isTagMode ? tag$1 : ""), __orval_core.upath.join(handlerFileInfo.dirname ?? "", `./${verbOption.operationName}`));
104
+ const handlersPath = __orval_core.upath.relativeSafe(__orval_core.upath.join(targetInfo.dirname, isTagMode ? tag$1 : ""), __orval_core.upath.join(handlerFileInfo.dirname, `./${verbOption.operationName}`));
80
105
  return `import { ${verbOption.operationName}Handlers } from '${handlersPath}';`;
81
106
  }).join("\n");
82
107
  } else handlers = `import {\n${importHandlers.map((verbOption) => ` ${verbOption.operationName}Handlers`).join(`, \n`)}\n} from './${tag ?? targetInfo.filename}.handlers';`;
@@ -89,7 +114,7 @@ const generateHonoRoute = ({ operationName, verb }, pathRoute) => {
89
114
  return `
90
115
  app.${verb.toLowerCase()}('${path}',...${operationName}Handlers)`;
91
116
  };
92
- const generateHono = async (verbOptions, options) => {
117
+ const generateHono = (verbOptions, options) => {
93
118
  if (options.override.hono.compositeRoute) return {
94
119
  implementation: "",
95
120
  imports: []
@@ -104,7 +129,12 @@ const generateHono = async (verbOptions, options) => {
104
129
  ]
105
130
  };
106
131
  };
107
- const getHonoHandlers = ({ handlerName, contextTypeName, verbOption, validator }) => {
132
+ /**
133
+ * getHonoHandlers generates TypeScript code for the given verbs and reports
134
+ * whether the code requires zValidator.
135
+ */
136
+ const getHonoHandlers = (...opts) => opts.reduce(([code, hasZValidator], opts$1) => {
137
+ const { handlerName, contextTypeName, verbOption, validator } = opts$1;
108
138
  let currentValidator = "";
109
139
  if (validator) {
110
140
  if (verbOption.headers) currentValidator += `zValidator('header', ${verbOption.operationName}Header),\n`;
@@ -113,28 +143,25 @@ const getHonoHandlers = ({ handlerName, contextTypeName, verbOption, validator }
113
143
  if (verbOption.body.definition) currentValidator += `zValidator('json', ${verbOption.operationName}Body),\n`;
114
144
  if (validator !== "hono" && verbOption.response.originalSchema?.["200"]?.content?.["application/json"]) currentValidator += `zValidator('response', ${verbOption.operationName}Response),\n`;
115
145
  }
116
- return `
146
+ code += `
117
147
  export const ${handlerName} = factory.createHandlers(
118
148
  ${currentValidator}async (c: ${contextTypeName}) => {
119
149
 
120
150
  },
121
151
  );`;
122
- };
123
- const getValidatorOutputRelativePath = (validatorOutputPath, handlerPath) => {
124
- const { pathWithoutExtension } = (0, __orval_core.getFileInfo)(validatorOutputPath);
125
- return __orval_core.upath.relativeSafe(__orval_core.upath.dirname(handlerPath), pathWithoutExtension);
126
- };
152
+ hasZValidator ||= currentValidator !== "";
153
+ return [code, hasZValidator];
154
+ }, ["", false]);
127
155
  const getZvalidatorImports = (verbOptions, importPath, isHonoValidator) => {
128
- const importImplementation = verbOptions.flatMap((verbOption) => {
129
- const imports = [];
130
- if (verbOption.headers) imports.push(`${verbOption.operationName}Header`);
131
- if (verbOption.params.length > 0) imports.push(`${verbOption.operationName}Params`);
132
- if (verbOption.queryParams) imports.push(`${verbOption.operationName}QueryParams`);
133
- if (verbOption.body.definition) imports.push(`${verbOption.operationName}Body`);
134
- if (!isHonoValidator && !!verbOption.response.originalSchema?.["200"]?.content?.["application/json"]) imports.push(`${verbOption.operationName}Response`);
135
- return imports.join(",\n");
136
- }).join(",\n");
137
- return importImplementation ? `import {\n${importImplementation}\n} from '${importPath}'` : "";
156
+ const specifiers = [];
157
+ for (const { operationName, headers, params, queryParams, body, response } of verbOptions) {
158
+ if (headers) specifiers.push(`${operationName}Header`);
159
+ if (params.length > 0) specifiers.push(`${operationName}Params`);
160
+ if (queryParams) specifiers.push(`${operationName}QueryParams`);
161
+ if (body.definition) specifiers.push(`${operationName}Body`);
162
+ if (!isHonoValidator && response.originalSchema?.["200"]?.content?.["application/json"] != null) specifiers.push(`${operationName}Response`);
163
+ }
164
+ return specifiers.length === 0 ? "" : `import {\n${specifiers.join(",\n")}\n} from '${importPath}'`;
138
165
  };
139
166
  const getVerbOptionGroupByTag = (verbOptions) => {
140
167
  return Object.values(verbOptions).reduce((acc, value) => {
@@ -144,155 +171,79 @@ const getVerbOptionGroupByTag = (verbOptions) => {
144
171
  return acc;
145
172
  }, {});
146
173
  };
147
- const generateHandlers = async (verbOptions, output) => {
148
- const { pathWithoutExtension, extension, dirname, filename } = (0, __orval_core.getFileInfo)(output.target);
149
- if (output.override.hono.handlers) return Promise.all(Object.values(verbOptions).map(async (verbOption) => {
150
- const isTagMode = output.mode === "tags" || output.mode === "tags-split";
151
- const tag = (0, __orval_core.kebab)(verbOption.tags[0] ?? "default");
152
- const outputPath = __orval_core.upath.relativeSafe(output.override.hono.handlers ?? "", isTagMode ? `${dirname}/${tag}/${tag}` : pathWithoutExtension);
153
- const handlerPath$1 = __orval_core.upath.join(output.override.hono.handlers ?? "", `./${verbOption.operationName}` + extension);
154
- const hasZValidator$1 = !!verbOption.headers || verbOption.params.length > 0 || !!verbOption.queryParams || !!verbOption.body.definition;
155
- const isExist = fs_extra.default.existsSync(handlerPath$1);
156
- const handlerName = `${verbOption.operationName}Handlers`;
157
- const contextTypeName = `${(0, __orval_core.pascal)(verbOption.operationName)}Context`;
158
- if (isExist) {
159
- const rawFile = await fs_extra.default.readFile(handlerPath$1, "utf8");
160
- let content$1 = rawFile;
161
- if (!rawFile.includes(handlerName)) content$1 += getHonoHandlers({
174
+ const generateHandlerFile = async ({ verbs, path, validatorModule, zodModule, contextModule }) => {
175
+ const validator = validatorModule === "@hono/zod-validator" ? "hono" : validatorModule != null;
176
+ if (fs_extra.default.existsSync(path)) {
177
+ const rawFile = await fs_extra.default.readFile(path, "utf8");
178
+ let content = rawFile;
179
+ content += Object.values(verbs).reduce((acc, verbOption) => {
180
+ const handlerName = `${verbOption.operationName}Handlers`;
181
+ const contextTypeName = `${(0, __orval_core.pascal)(verbOption.operationName)}Context`;
182
+ if (!rawFile.includes(handlerName)) acc += getHonoHandlers({
162
183
  handlerName,
163
184
  contextTypeName,
164
185
  verbOption,
165
- validator: output.override.hono.validator
166
- });
167
- return {
168
- content: content$1,
169
- path: handlerPath$1
170
- };
171
- }
172
- let validatorImport$1 = "";
173
- if (hasZValidator$1) {
174
- if (output.override.hono.validator === true) validatorImport$1 = `\nimport { zValidator } from '${output.override.hono.validatorOutputPath ? getValidatorOutputRelativePath(output.override.hono.validatorOutputPath, handlerPath$1) : `${outputPath}.validator`}';`;
175
- else if (output.override.hono.validator === "hono") validatorImport$1 = `\nimport { zValidator } from '@hono/zod-validator';`;
176
- }
177
- const zodImports$1 = output.override.hono.validator ? getZvalidatorImports([verbOption], `${outputPath}.zod`, output.override.hono.validator === "hono") : "";
178
- return {
179
- content: `import { createFactory } from 'hono/factory';${validatorImport$1}
180
- import { ${contextTypeName} } from '${outputPath}.context';
181
- ${zodImports$1}
182
-
183
- const factory = createFactory();
186
+ validator
187
+ })[0];
188
+ return acc;
189
+ }, "");
190
+ return content;
191
+ }
192
+ const [handlerCode, hasZValidator] = getHonoHandlers(...Object.values(verbs).map((verbOption) => ({
193
+ handlerName: `${verbOption.operationName}Handlers`,
194
+ contextTypeName: `${(0, __orval_core.pascal)(verbOption.operationName)}Context`,
195
+ verbOption,
196
+ validator
197
+ })));
198
+ const imports = ["import { createFactory } from 'hono/factory';"];
199
+ if (hasZValidator && validatorModule != null) imports.push(`import { zValidator } from '${generateModuleSpecifier(path, validatorModule)}';`);
200
+ imports.push(`import { ${Object.values(verbs).map((verb) => `${(0, __orval_core.pascal)(verb.operationName)}Context`).join(",\n")} } from '${generateModuleSpecifier(path, contextModule)}';`);
201
+ if (hasZValidator) imports.push(getZvalidatorImports(Object.values(verbs), generateModuleSpecifier(path, zodModule), validatorModule === "@hono/zod-validator"));
202
+ return `${imports.filter((imp) => imp !== "").join("\n")}
184
203
 
185
- ${getHonoHandlers({
186
- handlerName,
187
- contextTypeName,
188
- verbOption,
189
- validator: output.override.hono.validator
190
- })}
191
- `,
192
- path: handlerPath$1
204
+ const factory = createFactory();${handlerCode}`;
205
+ };
206
+ const generateHandlerFiles = async (verbOptions, output, validatorModule) => {
207
+ const { extension, dirname, filename } = (0, __orval_core.getFileInfo)(output.target);
208
+ if (output.override.hono.handlers) return Promise.all(Object.values(verbOptions).map(async (verbOption) => {
209
+ const tag = (0, __orval_core.kebab)(verbOption.tags[0] ?? "default");
210
+ const path = __orval_core.upath.join(output.override.hono.handlers ?? "", `./${verbOption.operationName}` + extension);
211
+ return {
212
+ content: await generateHandlerFile({
213
+ path,
214
+ verbs: [verbOption],
215
+ validatorModule,
216
+ zodModule: output.mode === "tags" ? __orval_core.upath.join(dirname, `${(0, __orval_core.kebab)(tag)}.zod`) : __orval_core.upath.join(dirname, tag, tag + ".zod"),
217
+ contextModule: output.mode === "tags" ? __orval_core.upath.join(dirname, `${(0, __orval_core.kebab)(tag)}.context`) : __orval_core.upath.join(dirname, tag, tag + ".context")
218
+ }),
219
+ path
193
220
  };
194
221
  }));
195
222
  if (output.mode === "tags" || output.mode === "tags-split") {
196
223
  const groupByTags = getVerbOptionGroupByTag(verbOptions);
197
224
  return Promise.all(Object.entries(groupByTags).map(async ([tag, verbs]) => {
198
225
  const handlerPath$1 = output.mode === "tags" ? __orval_core.upath.join(dirname, `${(0, __orval_core.kebab)(tag)}.handlers${extension}`) : __orval_core.upath.join(dirname, tag, tag + ".handlers" + extension);
199
- const hasZValidator$1 = verbs.some((verb) => !!verb.headers || verb.params.length > 0 || !!verb.queryParams || !!verb.body.definition);
200
- if (fs_extra.default.existsSync(handlerPath$1)) {
201
- const rawFile = await fs_extra.default.readFile(handlerPath$1, "utf8");
202
- let content$2 = rawFile;
203
- content$2 += Object.values(verbs).reduce((acc, verbOption) => {
204
- const handlerName = `${verbOption.operationName}Handlers`;
205
- const contextTypeName = `${(0, __orval_core.pascal)(verbOption.operationName)}Context`;
206
- if (!rawFile.includes(handlerName)) acc += getHonoHandlers({
207
- handlerName,
208
- contextTypeName,
209
- verbOption,
210
- validator: output.override.hono.validator
211
- });
212
- return acc;
213
- }, "");
214
- return {
215
- content: content$2,
216
- path: handlerPath$1
217
- };
218
- }
219
- let validatorImport$1 = "";
220
- if (hasZValidator$1) {
221
- if (output.override.hono.validator === true) {
222
- const validatorOutputPath = output.override.hono.validatorOutputPath || `${dirname}/${filename}.validator${extension}`;
223
- validatorImport$1 = `\nimport { zValidator } from '${getValidatorOutputRelativePath(validatorOutputPath, handlerPath$1)}';`;
224
- } else if (output.override.hono.validator === "hono") validatorImport$1 = `\nimport { zValidator } from '@hono/zod-validator';`;
225
- }
226
- const outputRelativePath$1 = `./${(0, __orval_core.kebab)(tag)}`;
227
- const zodImports$1 = output.override.hono.validator ? getZvalidatorImports(Object.values(verbs), `${outputRelativePath$1}.zod`, output.override.hono.validator === "hono") : "";
228
- let content$1 = `import { createFactory } from 'hono/factory';${validatorImport$1}
229
- import { ${Object.values(verbs).map((verb) => `${(0, __orval_core.pascal)(verb.operationName)}Context`).join(",\n")} } from '${outputRelativePath$1}.context';
230
- ${zodImports$1}
231
-
232
- const factory = createFactory();`;
233
- content$1 += Object.values(verbs).reduce((acc, verbOption) => {
234
- const handlerName = `${verbOption.operationName}Handlers`;
235
- const contextTypeName = `${(0, __orval_core.pascal)(verbOption.operationName)}Context`;
236
- acc += getHonoHandlers({
237
- handlerName,
238
- contextTypeName,
239
- verbOption,
240
- validator: output.override.hono.validator
241
- });
242
- return acc;
243
- }, "");
244
226
  return {
245
- content: content$1,
227
+ content: await generateHandlerFile({
228
+ path: handlerPath$1,
229
+ verbs,
230
+ validatorModule,
231
+ zodModule: output.mode === "tags" ? __orval_core.upath.join(dirname, `${(0, __orval_core.kebab)(tag)}.zod`) : __orval_core.upath.join(dirname, tag, tag + ".zod"),
232
+ contextModule: output.mode === "tags" ? __orval_core.upath.join(dirname, `${(0, __orval_core.kebab)(tag)}.context`) : __orval_core.upath.join(dirname, tag, tag + ".context")
233
+ }),
246
234
  path: handlerPath$1
247
235
  };
248
236
  }));
249
237
  }
250
- const hasZValidator = Object.values(verbOptions).some((verb) => !!verb.headers || verb.params.length > 0 || !!verb.queryParams || !!verb.body.definition || verb.response.contentTypes.length === 1 && verb.response.contentTypes[0] === "application/json");
251
238
  const handlerPath = __orval_core.upath.join(dirname, `${filename}.handlers${extension}`);
252
- if (fs_extra.default.existsSync(handlerPath)) {
253
- const rawFile = await fs_extra.default.readFile(handlerPath, "utf8");
254
- let content$1 = rawFile;
255
- content$1 += Object.values(verbOptions).reduce((acc, verbOption) => {
256
- const handlerName = `${verbOption.operationName}Handlers`;
257
- const contextTypeName = `${(0, __orval_core.pascal)(verbOption.operationName)}Context`;
258
- if (!rawFile.includes(handlerName)) acc += getHonoHandlers({
259
- handlerName,
260
- contextTypeName,
261
- verbOption,
262
- validator: output.override.hono.validator
263
- });
264
- return acc;
265
- }, "");
266
- return [{
267
- content: content$1,
268
- path: handlerPath
269
- }];
270
- }
271
- const outputRelativePath = `./${filename}`;
272
- let validatorImport = "";
273
- if (hasZValidator) {
274
- if (output.override.hono.validator === true) validatorImport = `\nimport { zValidator } from '${output.override.hono.validatorOutputPath ? getValidatorOutputRelativePath(output.override.hono.validatorOutputPath, handlerPath) : `${outputRelativePath}.validator`}';`;
275
- else if (output.override.hono.validator === "hono") validatorImport = `\nimport { zValidator } from '@hono/zod-validator';`;
276
- }
277
- const zodImports = output.override.hono.validator ? getZvalidatorImports(Object.values(verbOptions), `${outputRelativePath}.zod`, output.override.hono.validator === "hono") : "";
278
- let content = `import { createFactory } from 'hono/factory';${validatorImport}
279
- import { ${Object.values(verbOptions).map((verb) => `${(0, __orval_core.pascal)(verb.operationName)}Context`).join(",\n")} } from '${outputRelativePath}.context';
280
- ${zodImports}
281
-
282
- const factory = createFactory();`;
283
- content += Object.values(verbOptions).reduce((acc, verbOption) => {
284
- const handlerName = `${verbOption.operationName}Handlers`;
285
- const contextTypeName = `${(0, __orval_core.pascal)(verbOption.operationName)}Context`;
286
- acc += getHonoHandlers({
287
- handlerName,
288
- contextTypeName,
289
- verbOption,
290
- validator: output.override.hono.validator
291
- });
292
- return acc;
293
- }, "");
294
239
  return [{
295
- content,
240
+ content: await generateHandlerFile({
241
+ path: handlerPath,
242
+ verbs: Object.values(verbOptions),
243
+ validatorModule,
244
+ zodModule: __orval_core.upath.join(dirname, `${filename}.zod`),
245
+ contextModule: __orval_core.upath.join(dirname, `${filename}.context`)
246
+ }),
296
247
  path: handlerPath
297
248
  }];
298
249
  };
@@ -314,59 +265,51 @@ const getHeader = (option, info) => {
314
265
  const header = option(info);
315
266
  return Array.isArray(header) ? (0, __orval_core.jsDoc)({ description: header }) : header;
316
267
  };
317
- const generateContext = async (verbOptions, output, context) => {
318
- const header = getHeader(output.override.header, context.specs[context.specKey].info);
319
- const { extension, dirname, filename } = (0, __orval_core.getFileInfo)(output.target);
320
- if (output.mode === "tags" || output.mode === "tags-split") {
321
- const groupByTags = getVerbOptionGroupByTag(verbOptions);
322
- let relativeSchemasPath$1 = output.mode === "tags-split" ? "../" : "";
323
- relativeSchemasPath$1 += output.schemas ? __orval_core.upath.relativeSafe(dirname, (0, __orval_core.getFileInfo)(output.schemas).dirname) : `${filename}.schemas`;
324
- return Promise.all(Object.entries(groupByTags).map(async ([tag, verbs]) => {
325
- let content$1 = `${header}import type { Context, Env } from 'hono';\n\n`;
326
- const contexts$1 = verbs.map((verb) => getContext(verb)).join("\n");
327
- const imps$1 = verbs.flatMap((verb) => {
328
- const imports = [];
329
- if (verb.params.length > 0) imports.push(...verb.params.flatMap((param) => param.imports));
330
- if (verb.queryParams) imports.push({ name: verb.queryParams.schema.name });
331
- if (verb.body.definition) imports.push(...verb.body.imports);
332
- return imports;
333
- }).filter((imp) => contexts$1.includes(imp.name)).filter((imp, i, arr) => arr.findIndex((v) => v.name === imp.name) === i);
334
- if (contexts$1.includes("NonReadonly<")) {
335
- content$1 += (0, __orval_core.getOrvalGeneratedTypes)();
336
- content$1 += "\n";
337
- }
338
- if (imps$1.length > 0) {
339
- const importSchemas = imps$1.map((imp) => imp.name).join(",\n ");
340
- content$1 += `import {\n ${importSchemas}\n} from '${relativeSchemasPath$1}';\n\n`;
341
- }
342
- content$1 += contexts$1;
343
- const contextPath$1 = output.mode === "tags" ? __orval_core.upath.join(dirname, `${(0, __orval_core.kebab)(tag)}.context${extension}`) : __orval_core.upath.join(dirname, tag, tag + ".context" + extension);
344
- return {
345
- content: content$1,
346
- path: contextPath$1
347
- };
348
- }));
349
- }
350
- let content = `${header}import type { Context, Env } from 'hono';\n\n`;
351
- const contextPath = __orval_core.upath.join(dirname, `${filename}.context${extension}`);
352
- const contexts = Object.values(verbOptions).map((verbOption) => getContext(verbOption)).join("\n");
353
- const imps = Object.values(verbOptions).flatMap((verb) => {
268
+ const generateContextFile = ({ path, verbs, schemaModule }) => {
269
+ let content = `import type { Context, Env } from 'hono';\n\n`;
270
+ const contexts = verbs.map((verb) => getContext(verb));
271
+ const imps = new Set(verbs.flatMap((verb) => {
354
272
  const imports = [];
355
273
  if (verb.params.length > 0) imports.push(...verb.params.flatMap((param) => param.imports));
356
274
  if (verb.queryParams) imports.push({ name: verb.queryParams.schema.name });
357
275
  if (verb.body.definition) imports.push(...verb.body.imports);
358
276
  return imports;
359
- }).filter((imp) => contexts.includes(imp.name)).filter((imp, i, arr) => arr.findIndex((v) => v.name === imp.name) === i);
360
- if (contexts.includes("NonReadonly<")) {
277
+ }).map((imp) => imp.name).filter((imp) => contexts.some((context) => context.includes(imp))));
278
+ if (contexts.some((context) => context.includes("NonReadonly<"))) {
361
279
  content += (0, __orval_core.getOrvalGeneratedTypes)();
362
280
  content += "\n";
363
281
  }
364
- const relativeSchemasPath = output.schemas ? __orval_core.upath.relativeSafe(dirname, (0, __orval_core.getFileInfo)(output.schemas).dirname) : "./" + filename + ".schemas";
365
- content += `import { ${imps.map((imp) => imp.name).join(",\n")} } from '${relativeSchemasPath}';\n\n`;
366
- content += contexts;
282
+ if (imps.size > 0) content += `import type {\n${[...imps].toSorted().join(",\n ")}\n} from '${generateModuleSpecifier(path, schemaModule)}';\n\n`;
283
+ content += contexts.join("\n");
284
+ return content;
285
+ };
286
+ const generateContextFiles = (verbOptions, output, context, schemaModule) => {
287
+ const header = getHeader(output.override.header, context.specs[context.specKey].info);
288
+ const { extension, dirname, filename } = (0, __orval_core.getFileInfo)(output.target);
289
+ if (output.mode === "tags" || output.mode === "tags-split") {
290
+ const groupByTags = getVerbOptionGroupByTag(verbOptions);
291
+ return Object.entries(groupByTags).map(([tag, verbs]) => {
292
+ const path$1 = output.mode === "tags" ? __orval_core.upath.join(dirname, `${(0, __orval_core.kebab)(tag)}.context${extension}`) : __orval_core.upath.join(dirname, tag, tag + ".context" + extension);
293
+ const code$1 = generateContextFile({
294
+ verbs,
295
+ path: path$1,
296
+ schemaModule
297
+ });
298
+ return {
299
+ content: `${header}${code$1}`,
300
+ path: path$1
301
+ };
302
+ });
303
+ }
304
+ const path = __orval_core.upath.join(dirname, `${filename}.context${extension}`);
305
+ const code = generateContextFile({
306
+ verbs: Object.values(verbOptions),
307
+ path,
308
+ schemaModule
309
+ });
367
310
  return [{
368
- content,
369
- path: contextPath
311
+ content: `${header}${code}`,
312
+ path
370
313
  }];
371
314
  };
372
315
  const generateZodFiles = async (verbOptions, output, context) => {
@@ -425,154 +368,13 @@ const generateZodFiles = async (verbOptions, output, context) => {
425
368
  };
426
369
  const generateZvalidator = (output, context) => {
427
370
  const header = getHeader(output.override.header, context.specs[context.specKey].info);
428
- const content = `
429
- // based on https://github.com/honojs/middleware/blob/main/packages/zod-validator/src/index.ts
430
- import type { z, ZodSchema, ZodError } from 'zod';
431
- import {
432
- Context,
433
- Env,
434
- Input,
435
- MiddlewareHandler,
436
- TypedResponse,
437
- ValidationTargets,
438
- } from 'hono';
439
-
440
- type HasUndefined<T> = undefined extends T ? true : false;
441
-
442
- type Hook<T, E extends Env, P extends string, O = {}> = (
443
- result:
444
- | { success: true; data: T }
445
- | { success: false; error: ZodError; data: T },
446
- c: Context<E, P>,
447
- ) =>
448
- | Response
449
- | Promise<Response>
450
- | void
451
- | Promise<Response | void>
452
- | TypedResponse<O>;
453
- import { zValidator as zValidatorBase } from '@hono/zod-validator';
454
-
455
- type ValidationTargetsWithResponse = ValidationTargets & { response: any };
456
-
457
- export const zValidator =
458
- <
459
- T extends ZodSchema,
460
- Target extends keyof ValidationTargetsWithResponse,
461
- E extends Env,
462
- P extends string,
463
- In = z.input<T>,
464
- Out = z.output<T>,
465
- I extends Input = {
466
- in: HasUndefined<In> extends true
467
- ? {
468
- [K in Target]?: K extends 'json'
469
- ? In
470
- : HasUndefined<
471
- keyof ValidationTargetsWithResponse[K]
472
- > extends true
473
- ? { [K2 in keyof In]?: ValidationTargetsWithResponse[K][K2] }
474
- : { [K2 in keyof In]: ValidationTargetsWithResponse[K][K2] };
475
- }
476
- : {
477
- [K in Target]: K extends 'json'
478
- ? In
479
- : HasUndefined<
480
- keyof ValidationTargetsWithResponse[K]
481
- > extends true
482
- ? { [K2 in keyof In]?: ValidationTargetsWithResponse[K][K2] }
483
- : { [K2 in keyof In]: ValidationTargetsWithResponse[K][K2] };
484
- };
485
- out: { [K in Target]: Out };
486
- },
487
- V extends I = I,
488
- >(
489
- target: Target,
490
- schema: T,
491
- hook?: Hook<z.infer<T>, E, P>,
492
- ): MiddlewareHandler<E, P, V> =>
493
- async (c, next) => {
494
- if (target !== 'response') {
495
- const value = await zValidatorBase<
496
- T,
497
- keyof ValidationTargets,
498
- E,
499
- P,
500
- In,
501
- Out,
502
- I,
503
- V
504
- >(
505
- target,
506
- schema,
507
- hook,
508
- )(c, next);
509
-
510
- if (value instanceof Response) {
511
- return value;
512
- }
513
- } else {
514
- await next();
515
-
516
- if (
517
- c.res.status !== 200 ||
518
- !c.res.headers.get('Content-Type')?.includes('application/json')
519
- ) {
520
- return;
521
- }
522
-
523
- let value: unknown;
524
- try {
525
- value = await c.res.json();
526
- } catch {
527
- const message = 'Malformed JSON in response';
528
- c.res = new Response(message, { status: 400 });
529
-
530
- return;
531
- }
532
-
533
- const result = await schema.safeParseAsync(value);
534
-
535
- if (hook) {
536
- const hookResult = hook({ data: value, ...result }, c);
537
- if (hookResult) {
538
- if (hookResult instanceof Response || hookResult instanceof Promise) {
539
- const hookResponse = await hookResult;
540
-
541
- if (hookResponse instanceof Response) {
542
- c.res = new Response(hookResponse.body, hookResponse);
543
- }
544
- }
545
- if (
546
- 'response' in hookResult &&
547
- hookResult.response instanceof Response
548
- ) {
549
- c.res = new Response(hookResult.response.body, hookResult.response);
550
- }
551
- }
552
- }
553
-
554
- if (!result.success) {
555
- c.res = new Response(JSON.stringify(result), {
556
- status: 400,
557
- headers: {
558
- 'Content-Type': 'application/json',
559
- },
560
- });
561
- } else {
562
- c.res = new Response(JSON.stringify(result.data), c.res);
563
- }
564
- }
565
-
566
- return;
567
- };
568
- `;
569
371
  let validatorPath = output.override.hono.validatorOutputPath;
570
372
  if (!output.override.hono.validatorOutputPath) {
571
373
  const { extension, dirname, filename } = (0, __orval_core.getFileInfo)(output.target);
572
374
  validatorPath = __orval_core.upath.join(dirname, `${filename}.validator${extension}`);
573
375
  }
574
376
  return {
575
- content: `${header}${content}`,
377
+ content: `${header}${ZVALIDATOR_SOURCE}`,
576
378
  path: validatorPath
577
379
  };
578
380
  };
@@ -584,19 +386,19 @@ const generateCompositeRoutes = async (verbOptions, output, context) => {
584
386
  return generateHonoRoute(verbOption, verbOption.pathRoute);
585
387
  }).join(";");
586
388
  const importHandlers = Object.values(verbOptions);
587
- let ImportHandlersImplementation = "";
389
+ let ImportHandlersImplementation;
588
390
  if (output.override.hono.handlers) {
589
391
  const handlerFileInfo = (0, __orval_core.getFileInfo)(output.override.hono.handlers);
590
392
  ImportHandlersImplementation = importHandlers.map((verbOption) => verbOption.operationName).map((operationName) => {
591
393
  const importHandlerName = `${operationName}Handlers`;
592
- const handlersPath = __orval_core.upath.relativeSafe(compositeRouteInfo.dirname, __orval_core.upath.join(handlerFileInfo.dirname ?? "", `./${operationName}`));
394
+ const handlersPath = generateModuleSpecifier(compositeRouteInfo.path, __orval_core.upath.join(handlerFileInfo.dirname ?? "", `./${operationName}`));
593
395
  return `import { ${importHandlerName} } from '${handlersPath}';`;
594
396
  }).join("\n");
595
397
  } else {
596
398
  const tags = importHandlers.map((verbOption) => (0, __orval_core.kebab)(verbOption.tags[0] ?? "default"));
597
399
  ImportHandlersImplementation = tags.filter((t, i) => tags.indexOf(t) === i).map((tag) => {
598
400
  const importHandlerNames = importHandlers.filter((verbOption) => verbOption.tags[0] === tag).map((verbOption) => ` ${verbOption.operationName}Handlers`).join(`, \n`);
599
- const handlersPath = __orval_core.upath.relativeSafe(compositeRouteInfo.dirname, __orval_core.upath.join(targetInfo.dirname ?? "", tag));
401
+ const handlersPath = generateModuleSpecifier(compositeRouteInfo.path, __orval_core.upath.join(targetInfo.dirname ?? "", tag));
600
402
  return `import {\n${importHandlerNames}\n} from '${handlersPath}/${tag}.handlers';`;
601
403
  }).join("\n");
602
404
  }
@@ -613,11 +415,16 @@ export default app
613
415
  }];
614
416
  };
615
417
  const generateExtraFiles = async (verbOptions, output, context) => {
616
- const [handlers, contexts, zods, validator, compositeRoutes] = await Promise.all([
617
- generateHandlers(verbOptions, output),
618
- generateContext(verbOptions, output, context),
418
+ const { path, pathWithoutExtension } = (0, __orval_core.getFileInfo)(output.target);
419
+ const validator = generateZvalidator(output, context);
420
+ let schemaModule;
421
+ if (output.schemas != null) schemaModule = (0, __orval_core.getFileInfo)(output.schemas).dirname;
422
+ else if (output.mode === "single") schemaModule = path;
423
+ else schemaModule = `${pathWithoutExtension}.schemas`;
424
+ const [handlers, contexts, zods, compositeRoutes] = await Promise.all([
425
+ generateHandlerFiles(verbOptions, output, validator.path),
426
+ generateContextFiles(verbOptions, output, context, schemaModule),
619
427
  generateZodFiles(verbOptions, output, context),
620
- generateZvalidator(output, context),
621
428
  output.override.hono.compositeRoute ? generateCompositeRoutes(verbOptions, output, context) : []
622
429
  ]);
623
430
  return [
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["HONO_DEPENDENCIES: GeneratorDependency[]","getHonoHeader: ClientHeaderBuilder","tag","upath","getHonoFooter: ClientFooterBuilder","generateHono: ClientBuilder","handlerPath","hasZValidator","fs","content","validatorImport","zodImports","outputRelativePath","relativeSchemasPath","contexts","imps","imports: GeneratorImport[]","contextPath","zods","allMutators","mutatorsImports","zodPath","context","generateExtraFiles: ClientExtraFilesBuilder","honoClientBuilder: ClientGeneratorsBuilder"],"sources":["../src/route.ts","../src/index.ts"],"sourcesContent":["import { sanitize } from '@orval/core';\n\nconst hasParam = (path: string): boolean => /[^{]*{[\\w*_-]*}.*/.test(path);\n\nconst getRoutePath = (path: string): string => {\n const matches = /([^{]*){?([\\w*_-]*)}?(.*)/.exec(path);\n if (!matches?.length) return path; // impossible due to regexp grouping here, but for TS\n\n const prev = matches[1];\n const param = sanitize(matches[2], {\n es5keyword: true,\n underscore: true,\n dash: true,\n dot: true,\n });\n const next = hasParam(matches[3]) ? getRoutePath(matches[3]) : matches[3];\n\n return hasParam(path) ? `${prev}\\:${param}${next}` : `${prev}${param}${next}`;\n};\n\nexport const getRoute = (route: string) => {\n const splittedRoute = route.split('/');\n\n return splittedRoute.reduce((acc, path, i) => {\n if (!path && !i) {\n return acc;\n }\n\n if (!path.includes('{')) {\n return `${acc}/${path}`;\n }\n\n return `${acc}/${getRoutePath(path)}`;\n }, '');\n};\n","import {\n camel,\n ClientBuilder,\n ClientExtraFilesBuilder,\n ClientFooterBuilder,\n ClientGeneratorsBuilder,\n ClientHeaderBuilder,\n ContextSpecs,\n generateMutatorImports,\n GeneratorDependency,\n GeneratorImport,\n GeneratorMutator,\n GeneratorVerbOptions,\n getFileInfo,\n getOrvalGeneratedTypes,\n getParamsInPath,\n jsDoc,\n kebab,\n NormalizedMutator,\n NormalizedOutputOptions,\n pascal,\n sanitize,\n upath,\n} from '@orval/core';\nimport { generateZod } from '@orval/zod';\nimport fs from 'fs-extra';\nimport { InfoObject } from 'openapi3-ts/oas30';\n\nimport { getRoute } from './route';\n\nconst HONO_DEPENDENCIES: GeneratorDependency[] = [\n {\n exports: [\n {\n name: 'Hono',\n values: true,\n },\n {\n name: 'Context',\n },\n {\n name: 'Env',\n },\n ],\n dependency: 'hono',\n },\n];\n\nexport const getHonoDependencies = () => HONO_DEPENDENCIES;\n\nexport const getHonoHeader: ClientHeaderBuilder = ({\n verbOptions,\n output,\n tag,\n clientImplementation,\n}) => {\n const targetInfo = getFileInfo(output.target);\n\n let handlers = '';\n\n const importHandlers = Object.values(verbOptions).filter((verbOption) =>\n clientImplementation.includes(`${verbOption.operationName}Handlers`),\n );\n\n if (output.override.hono.handlers) {\n const handlerFileInfo = getFileInfo(output.override.hono.handlers);\n handlers = importHandlers\n .map((verbOption) => {\n const isTagMode =\n output.mode === 'tags' || output.mode === 'tags-split';\n const tag = kebab(verbOption.tags[0] ?? 'default');\n\n const handlersPath = upath.relativeSafe(\n upath.join(targetInfo.dirname ?? '', isTagMode ? tag : ''),\n upath.join(\n handlerFileInfo.dirname ?? '',\n `./${verbOption.operationName}`,\n ),\n );\n\n return `import { ${verbOption.operationName}Handlers } from '${handlersPath}';`;\n })\n .join('\\n');\n } else {\n const importHandlerNames = importHandlers\n .map((verbOption) => ` ${verbOption.operationName}Handlers`)\n .join(`, \\n`);\n\n handlers = `import {\\n${importHandlerNames}\\n} from './${tag ?? targetInfo.filename}.handlers';`;\n }\n\n return `${handlers}\\n\\n\nconst app = new Hono()\\n\\n`;\n};\n\nexport const getHonoFooter: ClientFooterBuilder = () => 'export default app';\n\nconst generateHonoRoute = (\n { operationName, verb }: GeneratorVerbOptions,\n pathRoute: string,\n) => {\n const path = getRoute(pathRoute);\n\n return `\napp.${verb.toLowerCase()}('${path}',...${operationName}Handlers)`;\n};\n\nexport const generateHono: ClientBuilder = async (verbOptions, options) => {\n if (options.override.hono.compositeRoute) {\n return {\n implementation: '',\n imports: [],\n };\n }\n\n const routeImplementation = generateHonoRoute(verbOptions, options.pathRoute);\n\n return {\n implementation: routeImplementation ? `${routeImplementation}\\n\\n` : '',\n imports: [\n ...verbOptions.params.flatMap((param) => param.imports),\n ...verbOptions.body.imports,\n ...(verbOptions.queryParams\n ? [\n {\n name: verbOptions.queryParams.schema.name,\n },\n ]\n : []),\n ],\n };\n};\n\nconst getHonoHandlers = ({\n handlerName,\n contextTypeName,\n verbOption,\n validator,\n}: {\n handlerName: string;\n contextTypeName: string;\n verbOption: GeneratorVerbOptions;\n validator: boolean | 'hono' | NormalizedMutator;\n}) => {\n let currentValidator = '';\n\n if (validator) {\n if (verbOption.headers) {\n currentValidator += `zValidator('header', ${verbOption.operationName}Header),\\n`;\n }\n if (verbOption.params.length > 0) {\n currentValidator += `zValidator('param', ${verbOption.operationName}Params),\\n`;\n }\n if (verbOption.queryParams) {\n currentValidator += `zValidator('query', ${verbOption.operationName}QueryParams),\\n`;\n }\n if (verbOption.body.definition) {\n currentValidator += `zValidator('json', ${verbOption.operationName}Body),\\n`;\n }\n if (\n validator !== 'hono' &&\n verbOption.response.originalSchema?.['200']?.content?.['application/json']\n ) {\n currentValidator += `zValidator('response', ${verbOption.operationName}Response),\\n`;\n }\n }\n\n return `\nexport const ${handlerName} = factory.createHandlers(\n${currentValidator}async (c: ${contextTypeName}) => {\n\n },\n);`;\n};\n\nconst getValidatorOutputRelativePath = (\n validatorOutputPath: string,\n handlerPath: string,\n) => {\n const { pathWithoutExtension } = getFileInfo(validatorOutputPath);\n\n return upath.relativeSafe(upath.dirname(handlerPath), pathWithoutExtension);\n};\n\nconst getZvalidatorImports = (\n verbOptions: GeneratorVerbOptions[],\n importPath: string,\n isHonoValidator: boolean,\n) => {\n const importImplementation = verbOptions\n .flatMap((verbOption) => {\n const imports = [];\n\n if (verbOption.headers) {\n imports.push(`${verbOption.operationName}Header`);\n }\n\n if (verbOption.params.length > 0) {\n imports.push(`${verbOption.operationName}Params`);\n }\n\n if (verbOption.queryParams) {\n imports.push(`${verbOption.operationName}QueryParams`);\n }\n\n if (verbOption.body.definition) {\n imports.push(`${verbOption.operationName}Body`);\n }\n\n if (\n !isHonoValidator &&\n !!verbOption.response.originalSchema?.['200']?.content?.[\n 'application/json'\n ]\n ) {\n imports.push(`${verbOption.operationName}Response`);\n }\n\n return imports.join(',\\n');\n })\n .join(',\\n');\n\n return importImplementation\n ? `import {\\n${importImplementation}\\n} from '${importPath}'`\n : '';\n};\n\nconst getVerbOptionGroupByTag = (\n verbOptions: Record<string, GeneratorVerbOptions>,\n) => {\n return Object.values(verbOptions).reduce<\n Record<string, GeneratorVerbOptions[]>\n >((acc, value) => {\n const tag = value.tags[0];\n if (!acc[tag]) {\n acc[tag] = [];\n }\n acc[tag].push(value);\n return acc;\n }, {});\n};\n\nconst generateHandlers = async (\n verbOptions: Record<string, GeneratorVerbOptions>,\n output: NormalizedOutputOptions,\n) => {\n const { pathWithoutExtension, extension, dirname, filename } = getFileInfo(\n output.target,\n );\n\n if (output.override.hono.handlers) {\n return Promise.all(\n Object.values(verbOptions).map(async (verbOption) => {\n const isTagMode =\n output.mode === 'tags' || output.mode === 'tags-split';\n const tag = kebab(verbOption.tags[0] ?? 'default');\n const outputPath = upath.relativeSafe(\n output.override.hono.handlers ?? '',\n isTagMode ? `${dirname}/${tag}/${tag}` : pathWithoutExtension,\n );\n\n const handlerPath = upath.join(\n output.override.hono.handlers ?? '',\n `./${verbOption.operationName}` + extension,\n );\n\n const hasZValidator =\n !!verbOption.headers ||\n verbOption.params.length > 0 ||\n !!verbOption.queryParams ||\n !!verbOption.body.definition;\n\n const isExist = fs.existsSync(handlerPath);\n\n const handlerName = `${verbOption.operationName}Handlers`;\n const contextTypeName = `${pascal(verbOption.operationName)}Context`;\n\n if (isExist) {\n const rawFile = await fs.readFile(handlerPath, 'utf8');\n let content = rawFile;\n\n if (!rawFile.includes(handlerName)) {\n content += getHonoHandlers({\n handlerName,\n contextTypeName,\n verbOption,\n validator: output.override.hono.validator,\n });\n }\n\n return {\n content,\n path: handlerPath,\n };\n }\n\n let validatorImport = '';\n\n if (hasZValidator) {\n if (output.override.hono.validator === true) {\n const validatorPath = output.override.hono.validatorOutputPath\n ? getValidatorOutputRelativePath(\n output.override.hono.validatorOutputPath,\n handlerPath,\n )\n : `${outputPath}.validator`;\n\n validatorImport = `\\nimport { zValidator } from '${validatorPath}';`;\n } else if (output.override.hono.validator === 'hono') {\n validatorImport = `\\nimport { zValidator } from '@hono/zod-validator';`;\n }\n }\n\n const zodImports = output.override.hono.validator\n ? getZvalidatorImports(\n [verbOption],\n `${outputPath}.zod`,\n output.override.hono.validator === 'hono',\n )\n : '';\n\n const content = `import { createFactory } from 'hono/factory';${validatorImport}\nimport { ${contextTypeName} } from '${outputPath}.context';\n${zodImports}\n\nconst factory = createFactory();\n\n${getHonoHandlers({\n handlerName,\n contextTypeName,\n verbOption,\n validator: output.override.hono.validator,\n})}\n`;\n\n return {\n content,\n path: handlerPath,\n };\n }),\n );\n }\n\n if (output.mode === 'tags' || output.mode === 'tags-split') {\n const groupByTags = getVerbOptionGroupByTag(verbOptions);\n\n return Promise.all(\n Object.entries(groupByTags).map(async ([tag, verbs]) => {\n const handlerPath =\n output.mode === 'tags'\n ? upath.join(dirname, `${kebab(tag)}.handlers${extension}`)\n : upath.join(dirname, tag, tag + '.handlers' + extension);\n\n const hasZValidator = verbs.some(\n (verb) =>\n !!verb.headers ||\n verb.params.length > 0 ||\n !!verb.queryParams ||\n !!verb.body.definition,\n );\n\n const isExist = fs.existsSync(handlerPath);\n\n if (isExist) {\n const rawFile = await fs.readFile(handlerPath, 'utf8');\n let content = rawFile;\n\n content += Object.values(verbs).reduce((acc, verbOption) => {\n const handlerName = `${verbOption.operationName}Handlers`;\n const contextTypeName = `${pascal(\n verbOption.operationName,\n )}Context`;\n\n if (!rawFile.includes(handlerName)) {\n acc += getHonoHandlers({\n handlerName,\n contextTypeName,\n verbOption,\n validator: output.override.hono.validator,\n });\n }\n\n return acc;\n }, '');\n\n return {\n content,\n path: handlerPath,\n };\n }\n\n let validatorImport = '';\n if (hasZValidator) {\n if (output.override.hono.validator === true) {\n const validatorOutputPath =\n output.override.hono.validatorOutputPath ||\n `${dirname}/${filename}.validator${extension}`;\n const validatorPath = getValidatorOutputRelativePath(\n validatorOutputPath,\n handlerPath,\n );\n\n validatorImport = `\\nimport { zValidator } from '${validatorPath}';`;\n } else if (output.override.hono.validator === 'hono') {\n validatorImport = `\\nimport { zValidator } from '@hono/zod-validator';`;\n }\n }\n\n const outputRelativePath = `./${kebab(tag)}`;\n\n const zodImports = output.override.hono.validator\n ? getZvalidatorImports(\n Object.values(verbs),\n `${outputRelativePath}.zod`,\n output.override.hono.validator === 'hono',\n )\n : '';\n\n let content = `import { createFactory } from 'hono/factory';${validatorImport}\nimport { ${Object.values(verbs)\n .map((verb) => `${pascal(verb.operationName)}Context`)\n .join(',\\n')} } from '${outputRelativePath}.context';\n${zodImports}\n\nconst factory = createFactory();`;\n\n content += Object.values(verbs).reduce((acc, verbOption) => {\n const handlerName = `${verbOption.operationName}Handlers`;\n const contextTypeName = `${pascal(verbOption.operationName)}Context`;\n\n acc += getHonoHandlers({\n handlerName,\n contextTypeName,\n verbOption,\n validator: output.override.hono.validator,\n });\n\n return acc;\n }, '');\n\n return {\n content,\n path: handlerPath,\n };\n }),\n );\n }\n\n const hasZValidator = Object.values(verbOptions).some(\n (verb) =>\n !!verb.headers ||\n verb.params.length > 0 ||\n !!verb.queryParams ||\n !!verb.body.definition ||\n (verb.response.contentTypes.length === 1 &&\n verb.response.contentTypes[0] === 'application/json'),\n );\n\n const handlerPath = upath.join(dirname, `${filename}.handlers${extension}`);\n\n const isExist = fs.existsSync(handlerPath);\n\n if (isExist) {\n const rawFile = await fs.readFile(handlerPath, 'utf8');\n let content = rawFile;\n\n content += Object.values(verbOptions).reduce((acc, verbOption) => {\n const handlerName = `${verbOption.operationName}Handlers`;\n const contextTypeName = `${pascal(verbOption.operationName)}Context`;\n\n if (!rawFile.includes(handlerName)) {\n acc += getHonoHandlers({\n handlerName,\n contextTypeName,\n verbOption,\n validator: output.override.hono.validator,\n });\n }\n\n return acc;\n }, '');\n\n return [\n {\n content,\n path: handlerPath,\n },\n ];\n }\n\n const outputRelativePath = `./${filename}`;\n\n let validatorImport = '';\n\n if (hasZValidator) {\n if (output.override.hono.validator === true) {\n const validatorPath = output.override.hono.validatorOutputPath\n ? getValidatorOutputRelativePath(\n output.override.hono.validatorOutputPath,\n handlerPath,\n )\n : `${outputRelativePath}.validator`;\n\n validatorImport = `\\nimport { zValidator } from '${validatorPath}';`;\n } else if (output.override.hono.validator === 'hono') {\n validatorImport = `\\nimport { zValidator } from '@hono/zod-validator';`;\n }\n }\n\n const zodImports = output.override.hono.validator\n ? getZvalidatorImports(\n Object.values(verbOptions),\n `${outputRelativePath}.zod`,\n output.override.hono.validator === 'hono',\n )\n : '';\n\n let content = `import { createFactory } from 'hono/factory';${validatorImport}\nimport { ${Object.values(verbOptions)\n .map((verb) => `${pascal(verb.operationName)}Context`)\n .join(',\\n')} } from '${outputRelativePath}.context';\n${zodImports}\n\nconst factory = createFactory();`;\n\n content += Object.values(verbOptions).reduce((acc, verbOption) => {\n const handlerName = `${verbOption.operationName}Handlers`;\n const contextTypeName = `${pascal(verbOption.operationName)}Context`;\n\n acc += getHonoHandlers({\n handlerName,\n contextTypeName,\n verbOption,\n validator: output.override.hono.validator,\n });\n\n return acc;\n }, '');\n\n return [\n {\n content,\n path: handlerPath,\n },\n ];\n};\n\nconst getContext = (verbOption: GeneratorVerbOptions) => {\n let paramType = '';\n if (verbOption.params.length > 0) {\n const params = getParamsInPath(verbOption.pathRoute).map((name) => {\n const param = verbOption.params.find(\n (p) => p.name === sanitize(camel(name), { es5keyword: true }),\n );\n const definition = param?.definition.split(':')[1];\n const required = param?.required ?? false;\n return {\n definition: `${name}${required ? '' : '?'}:${definition}`,\n };\n });\n paramType = `param: {\\n ${params\n .map((property) => property.definition)\n .join(',\\n ')},\\n },`;\n }\n\n const queryType = verbOption.queryParams\n ? `query: ${verbOption.queryParams?.schema.name},`\n : '';\n const bodyType = verbOption.body.definition\n ? `json: ${verbOption.body.definition},`\n : '';\n const hasIn = !!paramType || !!queryType || !!bodyType;\n\n return `export type ${pascal(\n verbOption.operationName,\n )}Context<E extends Env = any> = Context<E, '${getRoute(\n verbOption.pathRoute,\n )}'${\n hasIn\n ? `, { in: { ${paramType}${queryType}${bodyType} }, out: { ${paramType}${queryType}${bodyType} } }`\n : ''\n }>`;\n};\n\nconst getHeader = (\n option: false | ((info: InfoObject) => string | string[]),\n info: InfoObject,\n): string => {\n if (!option) {\n return '';\n }\n\n const header = option(info);\n\n return Array.isArray(header) ? jsDoc({ description: header }) : header;\n};\n\nconst generateContext = async (\n verbOptions: Record<string, GeneratorVerbOptions>,\n output: NormalizedOutputOptions,\n context: ContextSpecs,\n) => {\n const header = getHeader(\n output.override.header,\n context.specs[context.specKey].info,\n );\n const { extension, dirname, filename } = getFileInfo(output.target);\n\n if (output.mode === 'tags' || output.mode === 'tags-split') {\n const groupByTags = getVerbOptionGroupByTag(verbOptions);\n\n let relativeSchemasPath = output.mode === 'tags-split' ? '../' : '';\n\n relativeSchemasPath += output.schemas\n ? upath.relativeSafe(dirname, getFileInfo(output.schemas).dirname)\n : `${filename}.schemas`;\n\n return Promise.all(\n Object.entries(groupByTags).map(async ([tag, verbs]) => {\n let content = `${header}import type { Context, Env } from 'hono';\\n\\n`;\n\n const contexts = verbs.map((verb) => getContext(verb)).join('\\n');\n\n const imps = verbs\n .flatMap((verb) => {\n const imports: GeneratorImport[] = [];\n if (verb.params.length > 0) {\n imports.push(...verb.params.flatMap((param) => param.imports));\n }\n\n if (verb.queryParams) {\n imports.push({\n name: verb.queryParams.schema.name,\n });\n }\n\n if (verb.body.definition) {\n imports.push(...verb.body.imports);\n }\n\n return imports;\n })\n .filter((imp) => contexts.includes(imp.name))\n .filter(\n (imp, i, arr) => arr.findIndex((v) => v.name === imp.name) === i,\n );\n\n if (contexts.includes('NonReadonly<')) {\n content += getOrvalGeneratedTypes();\n content += '\\n';\n }\n\n if (imps.length > 0) {\n const importSchemas = imps.map((imp) => imp.name).join(',\\n ');\n\n content += `import {\\n ${importSchemas}\\n} from '${relativeSchemasPath}';\\n\\n`;\n }\n\n content += contexts;\n\n const contextPath =\n output.mode === 'tags'\n ? upath.join(dirname, `${kebab(tag)}.context${extension}`)\n : upath.join(dirname, tag, tag + '.context' + extension);\n\n return {\n content,\n path: contextPath,\n };\n }),\n );\n }\n\n let content = `${header}import type { Context, Env } from 'hono';\\n\\n`;\n\n const contextPath = upath.join(dirname, `${filename}.context${extension}`);\n\n const contexts = Object.values(verbOptions)\n .map((verbOption) => getContext(verbOption))\n .join('\\n');\n\n const imps = Object.values(verbOptions)\n .flatMap((verb) => {\n const imports: GeneratorImport[] = [];\n if (verb.params.length > 0) {\n imports.push(...verb.params.flatMap((param) => param.imports));\n }\n\n if (verb.queryParams) {\n imports.push({\n name: verb.queryParams.schema.name,\n });\n }\n\n if (verb.body.definition) {\n imports.push(...verb.body.imports);\n }\n\n return imports;\n })\n .filter((imp) => contexts.includes(imp.name))\n .filter((imp, i, arr) => arr.findIndex((v) => v.name === imp.name) === i);\n\n if (contexts.includes('NonReadonly<')) {\n content += getOrvalGeneratedTypes();\n content += '\\n';\n }\n\n const relativeSchemasPath = output.schemas\n ? upath.relativeSafe(dirname, getFileInfo(output.schemas).dirname)\n : './' + filename + '.schemas';\n\n content += `import { ${imps\n .map((imp) => imp.name)\n .join(',\\n')} } from '${relativeSchemasPath}';\\n\\n`;\n\n content += contexts;\n\n return [\n {\n content,\n path: contextPath,\n },\n ];\n};\n\nconst generateZodFiles = async (\n verbOptions: Record<string, GeneratorVerbOptions>,\n output: NormalizedOutputOptions,\n context: ContextSpecs,\n) => {\n const { extension, dirname, filename } = getFileInfo(output.target);\n\n const header = getHeader(\n output.override.header,\n context.specs[context.specKey].info,\n );\n\n if (output.mode === 'tags' || output.mode === 'tags-split') {\n const groupByTags = getVerbOptionGroupByTag(verbOptions);\n\n const builderContexts = await Promise.all(\n Object.entries(groupByTags).map(async ([tag, verbs]) => {\n const zods = await Promise.all(\n verbs.map((verbOption) =>\n generateZod(\n verbOption,\n {\n route: verbOption.route,\n pathRoute: verbOption.pathRoute,\n override: output.override,\n context,\n mock: output.mock,\n output: output.target!,\n },\n output.client,\n ),\n ),\n );\n\n if (zods.every((z) => z.implementation === '')) {\n return {\n content: '',\n path: '',\n };\n }\n\n const allMutators = zods.reduce(\n (acc, z) => {\n for (const mutator of z.mutators ?? []) {\n acc[mutator.name] = mutator;\n }\n return acc;\n },\n {} as Record<string, GeneratorMutator>,\n );\n\n const mutatorsImports = generateMutatorImports({\n mutators: Object.values(allMutators),\n });\n\n let content = `${header}import { z as zod } from 'zod';\\n${mutatorsImports}\\n`;\n\n const zodPath =\n output.mode === 'tags'\n ? upath.join(dirname, `${kebab(tag)}.zod${extension}`)\n : upath.join(dirname, tag, tag + '.zod' + extension);\n\n content += zods.map((zod) => zod.implementation).join('\\n');\n\n return {\n content,\n path: zodPath,\n };\n }),\n );\n\n return Promise.all(\n builderContexts.filter((context) => context.content !== ''),\n );\n }\n\n const zods = await Promise.all(\n Object.values(verbOptions).map((verbOption) =>\n generateZod(\n verbOption,\n {\n route: verbOption.route,\n pathRoute: verbOption.pathRoute,\n override: output.override,\n context,\n mock: output.mock,\n output: output.target!,\n },\n output.client,\n ),\n ),\n );\n\n const allMutators = zods.reduce(\n (acc, z) => {\n for (const mutator of z.mutators ?? []) {\n acc[mutator.name] = mutator;\n }\n return acc;\n },\n {} as Record<string, GeneratorMutator>,\n );\n\n const mutatorsImports = generateMutatorImports({\n mutators: Object.values(allMutators),\n });\n\n let content = `${header}import { z as zod } from 'zod';\\n${mutatorsImports}\\n`;\n\n const zodPath = upath.join(dirname, `${filename}.zod${extension}`);\n\n content += zods.map((zod) => zod.implementation).join('\\n');\n\n return [\n {\n content,\n path: zodPath,\n },\n ];\n};\n\nconst generateZvalidator = (\n output: NormalizedOutputOptions,\n context: ContextSpecs,\n) => {\n const header = getHeader(\n output.override.header,\n context.specs[context.specKey].info,\n );\n\n const content = `\n// based on https://github.com/honojs/middleware/blob/main/packages/zod-validator/src/index.ts\nimport type { z, ZodSchema, ZodError } from 'zod';\nimport {\n Context,\n Env,\n Input,\n MiddlewareHandler,\n TypedResponse,\n ValidationTargets,\n} from 'hono';\n\ntype HasUndefined<T> = undefined extends T ? true : false;\n\ntype Hook<T, E extends Env, P extends string, O = {}> = (\n result:\n | { success: true; data: T }\n | { success: false; error: ZodError; data: T },\n c: Context<E, P>,\n) =>\n | Response\n | Promise<Response>\n | void\n | Promise<Response | void>\n | TypedResponse<O>;\nimport { zValidator as zValidatorBase } from '@hono/zod-validator';\n\ntype ValidationTargetsWithResponse = ValidationTargets & { response: any };\n\nexport const zValidator =\n <\n T extends ZodSchema,\n Target extends keyof ValidationTargetsWithResponse,\n E extends Env,\n P extends string,\n In = z.input<T>,\n Out = z.output<T>,\n I extends Input = {\n in: HasUndefined<In> extends true\n ? {\n [K in Target]?: K extends 'json'\n ? In\n : HasUndefined<\n keyof ValidationTargetsWithResponse[K]\n > extends true\n ? { [K2 in keyof In]?: ValidationTargetsWithResponse[K][K2] }\n : { [K2 in keyof In]: ValidationTargetsWithResponse[K][K2] };\n }\n : {\n [K in Target]: K extends 'json'\n ? In\n : HasUndefined<\n keyof ValidationTargetsWithResponse[K]\n > extends true\n ? { [K2 in keyof In]?: ValidationTargetsWithResponse[K][K2] }\n : { [K2 in keyof In]: ValidationTargetsWithResponse[K][K2] };\n };\n out: { [K in Target]: Out };\n },\n V extends I = I,\n >(\n target: Target,\n schema: T,\n hook?: Hook<z.infer<T>, E, P>,\n ): MiddlewareHandler<E, P, V> =>\n async (c, next) => {\n if (target !== 'response') {\n const value = await zValidatorBase<\n T,\n keyof ValidationTargets,\n E,\n P,\n In,\n Out,\n I,\n V\n >(\n target,\n schema,\n hook,\n )(c, next);\n\n if (value instanceof Response) {\n return value;\n }\n } else {\n await next();\n\n if (\n c.res.status !== 200 ||\n !c.res.headers.get('Content-Type')?.includes('application/json')\n ) {\n return;\n }\n\n let value: unknown;\n try {\n value = await c.res.json();\n } catch {\n const message = 'Malformed JSON in response';\n c.res = new Response(message, { status: 400 });\n\n return;\n }\n\n const result = await schema.safeParseAsync(value);\n\n if (hook) {\n const hookResult = hook({ data: value, ...result }, c);\n if (hookResult) {\n if (hookResult instanceof Response || hookResult instanceof Promise) {\n const hookResponse = await hookResult;\n\n if (hookResponse instanceof Response) {\n c.res = new Response(hookResponse.body, hookResponse);\n }\n }\n if (\n 'response' in hookResult &&\n hookResult.response instanceof Response\n ) {\n c.res = new Response(hookResult.response.body, hookResult.response);\n }\n }\n }\n\n if (!result.success) {\n c.res = new Response(JSON.stringify(result), {\n status: 400,\n headers: {\n 'Content-Type': 'application/json',\n },\n });\n } else {\n c.res = new Response(JSON.stringify(result.data), c.res);\n }\n }\n \n return;\n };\n`;\n\n let validatorPath = output.override.hono.validatorOutputPath;\n if (!output.override.hono.validatorOutputPath) {\n const { extension, dirname, filename } = getFileInfo(output.target);\n\n validatorPath = upath.join(dirname, `${filename}.validator${extension}`);\n }\n\n return {\n content: `${header}${content}`,\n path: validatorPath,\n };\n};\n\nconst generateCompositeRoutes = async (\n verbOptions: Record<string, GeneratorVerbOptions>,\n output: NormalizedOutputOptions,\n context: ContextSpecs,\n) => {\n const targetInfo = getFileInfo(output.target);\n const compositeRouteInfo = getFileInfo(output.override.hono.compositeRoute);\n\n const header = getHeader(\n output.override.header,\n context.specs[context.specKey].info,\n );\n\n const routes = Object.values(verbOptions)\n .map((verbOption) => {\n return generateHonoRoute(verbOption, verbOption.pathRoute);\n })\n .join(';');\n\n const importHandlers = Object.values(verbOptions);\n\n let ImportHandlersImplementation = '';\n if (output.override.hono.handlers) {\n const handlerFileInfo = getFileInfo(output.override.hono.handlers);\n const operationNames = importHandlers.map(\n (verbOption) => verbOption.operationName,\n );\n\n ImportHandlersImplementation = operationNames\n .map((operationName) => {\n const importHandlerName = `${operationName}Handlers`;\n\n const handlersPath = upath.relativeSafe(\n compositeRouteInfo.dirname,\n upath.join(handlerFileInfo.dirname ?? '', `./${operationName}`),\n );\n\n return `import { ${importHandlerName} } from '${handlersPath}';`;\n })\n .join('\\n');\n } else {\n const tags = importHandlers.map((verbOption) =>\n kebab(verbOption.tags[0] ?? 'default'),\n );\n const uniqueTags = tags.filter((t, i) => tags.indexOf(t) === i);\n\n ImportHandlersImplementation = uniqueTags\n .map((tag) => {\n const importHandlerNames = importHandlers\n .filter((verbOption) => verbOption.tags[0] === tag)\n .map((verbOption) => ` ${verbOption.operationName}Handlers`)\n .join(`, \\n`);\n\n const handlersPath = upath.relativeSafe(\n compositeRouteInfo.dirname,\n upath.join(targetInfo.dirname ?? '', tag),\n );\n\n return `import {\\n${importHandlerNames}\\n} from '${handlersPath}/${tag}.handlers';`;\n })\n .join('\\n');\n }\n\n const honoImport = `import { Hono } from 'hono';`;\n const honoInitialization = `\\nconst app = new Hono()`;\n const honoAppExport = `\\nexport default app`;\n\n const content = `${header}${honoImport}\n${ImportHandlersImplementation}\n${honoInitialization}\n${routes}\n${honoAppExport}\n`;\n\n return [\n {\n content,\n path: output.override.hono.compositeRoute || '',\n },\n ];\n};\n\nexport const generateExtraFiles: ClientExtraFilesBuilder = async (\n verbOptions,\n output,\n context,\n) => {\n const [handlers, contexts, zods, validator, compositeRoutes] =\n await Promise.all([\n generateHandlers(verbOptions, output),\n generateContext(verbOptions, output, context),\n generateZodFiles(verbOptions, output, context),\n generateZvalidator(output, context),\n output.override.hono.compositeRoute\n ? generateCompositeRoutes(verbOptions, output, context)\n : [],\n ]);\n\n return [\n ...handlers,\n ...contexts,\n ...zods,\n ...(output.override.hono.validator &&\n output.override.hono.validator !== 'hono'\n ? [validator]\n : []),\n ...compositeRoutes,\n ];\n};\n\nconst honoClientBuilder: ClientGeneratorsBuilder = {\n client: generateHono,\n dependencies: getHonoDependencies,\n header: getHonoHeader,\n footer: getHonoFooter,\n extraFiles: generateExtraFiles,\n};\n\nexport const builder = () => () => honoClientBuilder;\n\nexport default builder;\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["fs","upath","HONO_DEPENDENCIES: GeneratorDependency[]","ret: string","getHonoHeader: ClientHeaderBuilder","handlers: string","tag","getHonoFooter: ClientFooterBuilder","generateHono: ClientBuilder","opts","handlerPath","imports: GeneratorImport[]","path","code","zods","allMutators","mutatorsImports","content","zodPath","context","ImportHandlersImplementation: string","generateExtraFiles: ClientExtraFilesBuilder","schemaModule: string","honoClientBuilder: ClientGeneratorsBuilder"],"sources":["../src/route.ts","../src/index.ts"],"sourcesContent":["import { sanitize } from '@orval/core';\n\nconst hasParam = (path: string): boolean => /[^{]*{[\\w*_-]*}.*/.test(path);\n\nconst getRoutePath = (path: string): string => {\n const matches = /([^{]*){?([\\w*_-]*)}?(.*)/.exec(path);\n if (!matches?.length) return path; // impossible due to regexp grouping here, but for TS\n\n const prev = matches[1];\n const param = sanitize(matches[2], {\n es5keyword: true,\n underscore: true,\n dash: true,\n dot: true,\n });\n const next = hasParam(matches[3]) ? getRoutePath(matches[3]) : matches[3];\n\n return hasParam(path) ? `${prev}\\:${param}${next}` : `${prev}${param}${next}`;\n};\n\nexport const getRoute = (route: string) => {\n const splittedRoute = route.split('/');\n\n return splittedRoute.reduce((acc, path, i) => {\n if (!path && !i) {\n return acc;\n }\n\n if (!path.includes('{')) {\n return `${acc}/${path}`;\n }\n\n return `${acc}/${getRoutePath(path)}`;\n }, '');\n};\n","import {\n camel,\n type ClientBuilder,\n type ClientExtraFilesBuilder,\n type ClientFooterBuilder,\n type ClientGeneratorsBuilder,\n type ClientHeaderBuilder,\n type ContextSpecs,\n generateMutatorImports,\n type GeneratorDependency,\n type GeneratorImport,\n type GeneratorMutator,\n type GeneratorVerbOptions,\n getFileInfo,\n getOrvalGeneratedTypes,\n getParamsInPath,\n jsDoc,\n kebab,\n type NormalizedMutator,\n type NormalizedOutputOptions,\n pascal,\n sanitize,\n upath,\n} from '@orval/core';\nimport { generateZod } from '@orval/zod';\nimport fs from 'fs-extra';\nimport { type InfoObject } from 'openapi3-ts/oas30';\n\nimport { getRoute } from './route';\n\nconst ZVALIDATOR_SOURCE = fs\n .readFileSync(upath.join(__dirname, 'zValidator.ts'))\n .toString('utf8');\n\nconst HONO_DEPENDENCIES: GeneratorDependency[] = [\n {\n exports: [\n {\n name: 'Hono',\n values: true,\n },\n {\n name: 'Context',\n },\n {\n name: 'Env',\n },\n ],\n dependency: 'hono',\n },\n];\n\n/**\n * generateModuleSpecifier generates the specifier that _from_ would use to\n * import _to_. This is syntactical and does not validate the paths.\n *\n * @param from The filesystem path to the importer.\n * @param to If a filesystem path, it and _from_ must be use the same frame of\n * reference, such as process.cwd() or both be absolute. If only one is\n * absolute, the other must be relative to process.cwd().\n *\n * Otherwise, treated as a package name and returned directly.\n *\n * @return A module specifier that can be used at _from_ to import _to_. It is\n * extensionless to conform with the rest of orval.\n */\nconst generateModuleSpecifier = (from: string, to: string) => {\n if (to.startsWith('.') || upath.isAbsolute(to)) {\n // One of \"/foo/bar\", \"./foo/bar\", \"../foo/bar\", etc.\n let ret: string;\n ret = upath.relativeSafe(upath.dirname(from), to);\n ret = ret.replace(/\\.ts$/, '');\n ret = ret.replaceAll(upath.separator, '/');\n return ret;\n }\n\n // Not a relative or absolute file path. Import as-is.\n return to;\n};\n\nexport const getHonoDependencies = () => HONO_DEPENDENCIES;\n\nexport const getHonoHeader: ClientHeaderBuilder = ({\n verbOptions,\n output,\n tag,\n clientImplementation,\n}) => {\n const targetInfo = getFileInfo(output.target);\n\n let handlers: string;\n\n const importHandlers = Object.values(verbOptions).filter((verbOption) =>\n clientImplementation.includes(`${verbOption.operationName}Handlers`),\n );\n\n if (output.override.hono.handlers) {\n const handlerFileInfo = getFileInfo(output.override.hono.handlers);\n handlers = importHandlers\n .map((verbOption) => {\n const isTagMode =\n output.mode === 'tags' || output.mode === 'tags-split';\n const tag = kebab(verbOption.tags[0] ?? 'default');\n\n const handlersPath = upath.relativeSafe(\n upath.join(targetInfo.dirname, isTagMode ? tag : ''),\n upath.join(handlerFileInfo.dirname, `./${verbOption.operationName}`),\n );\n\n return `import { ${verbOption.operationName}Handlers } from '${handlersPath}';`;\n })\n .join('\\n');\n } else {\n const importHandlerNames = importHandlers\n .map((verbOption) => ` ${verbOption.operationName}Handlers`)\n .join(`, \\n`);\n\n handlers = `import {\\n${importHandlerNames}\\n} from './${tag ?? targetInfo.filename}.handlers';`;\n }\n\n return `${handlers}\\n\\n\nconst app = new Hono()\\n\\n`;\n};\n\nexport const getHonoFooter: ClientFooterBuilder = () => 'export default app';\n\nconst generateHonoRoute = (\n { operationName, verb }: GeneratorVerbOptions,\n pathRoute: string,\n) => {\n const path = getRoute(pathRoute);\n\n return `\napp.${verb.toLowerCase()}('${path}',...${operationName}Handlers)`;\n};\n\nexport const generateHono: ClientBuilder = (verbOptions, options) => {\n if (options.override.hono.compositeRoute) {\n return {\n implementation: '',\n imports: [],\n };\n }\n\n const routeImplementation = generateHonoRoute(verbOptions, options.pathRoute);\n\n return {\n implementation: routeImplementation ? `${routeImplementation}\\n\\n` : '',\n imports: [\n ...verbOptions.params.flatMap((param) => param.imports),\n ...verbOptions.body.imports,\n ...(verbOptions.queryParams\n ? [\n {\n name: verbOptions.queryParams.schema.name,\n },\n ]\n : []),\n ],\n };\n};\n\n/**\n * getHonoHandlers generates TypeScript code for the given verbs and reports\n * whether the code requires zValidator.\n */\nconst getHonoHandlers = (\n ...opts: Array<{\n handlerName: string;\n contextTypeName: string;\n verbOption: GeneratorVerbOptions;\n validator: boolean | 'hono' | NormalizedMutator;\n }>\n): [\n /** The combined TypeScript handler code snippets. */\n handlerCode: string,\n /** Whether any of the handler code snippets requires importing zValidator. */\n hasZValidator: boolean,\n] =>\n opts.reduce<[string, boolean]>(\n ([code, hasZValidator], opts) => {\n const { handlerName, contextTypeName, verbOption, validator } = opts;\n\n let currentValidator = '';\n\n if (validator) {\n if (verbOption.headers) {\n currentValidator += `zValidator('header', ${verbOption.operationName}Header),\\n`;\n }\n if (verbOption.params.length > 0) {\n currentValidator += `zValidator('param', ${verbOption.operationName}Params),\\n`;\n }\n if (verbOption.queryParams) {\n currentValidator += `zValidator('query', ${verbOption.operationName}QueryParams),\\n`;\n }\n if (verbOption.body.definition) {\n currentValidator += `zValidator('json', ${verbOption.operationName}Body),\\n`;\n }\n if (\n validator !== 'hono' &&\n verbOption.response.originalSchema?.['200']?.content?.[\n 'application/json'\n ]\n ) {\n currentValidator += `zValidator('response', ${verbOption.operationName}Response),\\n`;\n }\n }\n\n code += `\nexport const ${handlerName} = factory.createHandlers(\n${currentValidator}async (c: ${contextTypeName}) => {\n\n },\n);`;\n hasZValidator ||= currentValidator !== '';\n\n return [code, hasZValidator];\n },\n ['', false],\n );\n\nconst getZvalidatorImports = (\n verbOptions: GeneratorVerbOptions[],\n importPath: string,\n isHonoValidator: boolean,\n) => {\n const specifiers = [];\n\n for (const {\n operationName,\n headers,\n params,\n queryParams,\n body,\n response,\n } of verbOptions) {\n if (headers) {\n specifiers.push(`${operationName}Header`);\n }\n\n if (params.length > 0) {\n specifiers.push(`${operationName}Params`);\n }\n\n if (queryParams) {\n specifiers.push(`${operationName}QueryParams`);\n }\n\n if (body.definition) {\n specifiers.push(`${operationName}Body`);\n }\n\n if (\n !isHonoValidator &&\n response.originalSchema?.['200']?.content?.['application/json'] != null\n ) {\n specifiers.push(`${operationName}Response`);\n }\n }\n\n return specifiers.length === 0\n ? ''\n : `import {\\n${specifiers.join(',\\n')}\\n} from '${importPath}'`;\n};\n\nconst getVerbOptionGroupByTag = (\n verbOptions: Record<string, GeneratorVerbOptions>,\n) => {\n return Object.values(verbOptions).reduce<\n Record<string, GeneratorVerbOptions[]>\n >((acc, value) => {\n const tag = value.tags[0];\n if (!acc[tag]) {\n acc[tag] = [];\n }\n acc[tag].push(value);\n return acc;\n }, {});\n};\n\nconst generateHandlerFile = async ({\n verbs,\n path,\n validatorModule,\n zodModule,\n contextModule,\n}: {\n verbs: GeneratorVerbOptions[];\n path: string;\n validatorModule?: string;\n zodModule: string;\n contextModule: string;\n}) => {\n const validator =\n validatorModule === '@hono/zod-validator'\n ? ('hono' as const)\n : validatorModule != null;\n\n const isExist = fs.existsSync(path);\n\n if (isExist) {\n const rawFile = await fs.readFile(path, 'utf8');\n let content = rawFile;\n\n content += Object.values(verbs).reduce((acc, verbOption) => {\n const handlerName = `${verbOption.operationName}Handlers`;\n const contextTypeName = `${pascal(verbOption.operationName)}Context`;\n\n if (!rawFile.includes(handlerName)) {\n acc += getHonoHandlers({\n handlerName,\n contextTypeName,\n verbOption,\n validator,\n })[0];\n }\n\n return acc;\n }, '');\n\n return content;\n }\n\n const [handlerCode, hasZValidator] = getHonoHandlers(\n ...Object.values(verbs).map((verbOption) => ({\n handlerName: `${verbOption.operationName}Handlers`,\n contextTypeName: `${pascal(verbOption.operationName)}Context`,\n verbOption,\n validator,\n })),\n );\n\n const imports = [\"import { createFactory } from 'hono/factory';\"];\n\n if (hasZValidator && validatorModule != null) {\n imports.push(\n `import { zValidator } from '${generateModuleSpecifier(path, validatorModule)}';`,\n );\n }\n\n imports.push(\n `import { ${Object.values(verbs)\n .map((verb) => `${pascal(verb.operationName)}Context`)\n .join(',\\n')} } from '${generateModuleSpecifier(path, contextModule)}';`,\n );\n\n if (hasZValidator) {\n imports.push(\n getZvalidatorImports(\n Object.values(verbs),\n generateModuleSpecifier(path, zodModule),\n validatorModule === '@hono/zod-validator',\n ),\n );\n }\n\n return `${imports.filter((imp) => imp !== '').join('\\n')}\n\nconst factory = createFactory();${handlerCode}`;\n};\n\nconst generateHandlerFiles = async (\n verbOptions: Record<string, GeneratorVerbOptions>,\n output: NormalizedOutputOptions,\n validatorModule: string,\n) => {\n const { extension, dirname, filename } = getFileInfo(output.target);\n\n // This function _does not control_ where the .zod and .context modules land.\n // That determination is made elsewhere and this function must implement the\n // same conventions.\n\n if (output.override.hono.handlers) {\n // One file per operation in the user-provided directory.\n return Promise.all(\n Object.values(verbOptions).map(async (verbOption) => {\n const tag = kebab(verbOption.tags[0] ?? 'default');\n\n const path = upath.join(\n output.override.hono.handlers ?? '',\n `./${verbOption.operationName}` + extension,\n );\n\n return {\n content: await generateHandlerFile({\n path,\n verbs: [verbOption],\n validatorModule,\n zodModule:\n output.mode === 'tags'\n ? upath.join(dirname, `${kebab(tag)}.zod`)\n : upath.join(dirname, tag, tag + '.zod'),\n contextModule:\n output.mode === 'tags'\n ? upath.join(dirname, `${kebab(tag)}.context`)\n : upath.join(dirname, tag, tag + '.context'),\n }),\n path,\n };\n }),\n );\n }\n\n if (output.mode === 'tags' || output.mode === 'tags-split') {\n // One file per operation _tag_ under dirname.\n const groupByTags = getVerbOptionGroupByTag(verbOptions);\n\n return Promise.all(\n Object.entries(groupByTags).map(async ([tag, verbs]) => {\n const handlerPath =\n output.mode === 'tags'\n ? upath.join(dirname, `${kebab(tag)}.handlers${extension}`)\n : upath.join(dirname, tag, tag + '.handlers' + extension);\n\n return {\n content: await generateHandlerFile({\n path: handlerPath,\n verbs,\n validatorModule,\n zodModule:\n output.mode === 'tags'\n ? upath.join(dirname, `${kebab(tag)}.zod`)\n : upath.join(dirname, tag, tag + '.zod'),\n contextModule:\n output.mode === 'tags'\n ? upath.join(dirname, `${kebab(tag)}.context`)\n : upath.join(dirname, tag, tag + '.context'),\n }),\n path: handlerPath,\n };\n }),\n );\n }\n\n // One file with all operations.\n const handlerPath = upath.join(dirname, `${filename}.handlers${extension}`);\n\n return [\n {\n content: await generateHandlerFile({\n path: handlerPath,\n verbs: Object.values(verbOptions),\n validatorModule,\n zodModule: upath.join(dirname, `${filename}.zod`),\n contextModule: upath.join(dirname, `${filename}.context`),\n }),\n path: handlerPath,\n },\n ];\n};\n\nconst getContext = (verbOption: GeneratorVerbOptions) => {\n let paramType = '';\n if (verbOption.params.length > 0) {\n const params = getParamsInPath(verbOption.pathRoute).map((name) => {\n const param = verbOption.params.find(\n (p) => p.name === sanitize(camel(name), { es5keyword: true }),\n );\n const definition = param?.definition.split(':')[1];\n const required = param?.required ?? false;\n return {\n definition: `${name}${required ? '' : '?'}:${definition}`,\n };\n });\n paramType = `param: {\\n ${params\n .map((property) => property.definition)\n .join(',\\n ')},\\n },`;\n }\n\n const queryType = verbOption.queryParams\n ? `query: ${verbOption.queryParams?.schema.name},`\n : '';\n const bodyType = verbOption.body.definition\n ? `json: ${verbOption.body.definition},`\n : '';\n const hasIn = !!paramType || !!queryType || !!bodyType;\n\n return `export type ${pascal(\n verbOption.operationName,\n )}Context<E extends Env = any> = Context<E, '${getRoute(\n verbOption.pathRoute,\n )}'${\n hasIn\n ? `, { in: { ${paramType}${queryType}${bodyType} }, out: { ${paramType}${queryType}${bodyType} } }`\n : ''\n }>`;\n};\n\nconst getHeader = (\n option: false | ((info: InfoObject) => string | string[]),\n info: InfoObject,\n): string => {\n if (!option) {\n return '';\n }\n\n const header = option(info);\n\n return Array.isArray(header) ? jsDoc({ description: header }) : header;\n};\n\nconst generateContextFile = ({\n path,\n verbs,\n schemaModule,\n}: {\n path: string;\n verbs: GeneratorVerbOptions[];\n schemaModule: string;\n}) => {\n let content = `import type { Context, Env } from 'hono';\\n\\n`;\n\n const contexts = verbs.map((verb) => getContext(verb));\n\n const imps = new Set(\n verbs\n .flatMap((verb) => {\n const imports: GeneratorImport[] = [];\n if (verb.params.length > 0) {\n imports.push(...verb.params.flatMap((param) => param.imports));\n }\n\n if (verb.queryParams) {\n imports.push({\n name: verb.queryParams.schema.name,\n });\n }\n\n if (verb.body.definition) {\n imports.push(...verb.body.imports);\n }\n\n return imports;\n })\n .map((imp) => imp.name)\n .filter((imp) => contexts.some((context) => context.includes(imp))),\n );\n\n if (contexts.some((context) => context.includes('NonReadonly<'))) {\n content += getOrvalGeneratedTypes();\n content += '\\n';\n }\n\n if (imps.size > 0) {\n content += `import type {\\n${[...imps]\n .toSorted()\n .join(\n ',\\n ',\n )}\\n} from '${generateModuleSpecifier(path, schemaModule)}';\\n\\n`;\n }\n\n content += contexts.join('\\n');\n\n return content;\n};\n\nconst generateContextFiles = (\n verbOptions: Record<string, GeneratorVerbOptions>,\n output: NormalizedOutputOptions,\n context: ContextSpecs,\n schemaModule: string,\n) => {\n const header = getHeader(\n output.override.header,\n context.specs[context.specKey].info,\n );\n const { extension, dirname, filename } = getFileInfo(output.target);\n\n if (output.mode === 'tags' || output.mode === 'tags-split') {\n const groupByTags = getVerbOptionGroupByTag(verbOptions);\n\n return Object.entries(groupByTags).map(([tag, verbs]) => {\n const path =\n output.mode === 'tags'\n ? upath.join(dirname, `${kebab(tag)}.context${extension}`)\n : upath.join(dirname, tag, tag + '.context' + extension);\n const code = generateContextFile({\n verbs,\n path,\n schemaModule: schemaModule,\n });\n return { content: `${header}${code}`, path };\n });\n }\n\n const path = upath.join(dirname, `${filename}.context${extension}`);\n const code = generateContextFile({\n verbs: Object.values(verbOptions),\n path,\n schemaModule: schemaModule,\n });\n\n return [\n {\n content: `${header}${code}`,\n path,\n },\n ];\n};\n\nconst generateZodFiles = async (\n verbOptions: Record<string, GeneratorVerbOptions>,\n output: NormalizedOutputOptions,\n context: ContextSpecs,\n) => {\n const { extension, dirname, filename } = getFileInfo(output.target);\n\n const header = getHeader(\n output.override.header,\n context.specs[context.specKey].info,\n );\n\n if (output.mode === 'tags' || output.mode === 'tags-split') {\n const groupByTags = getVerbOptionGroupByTag(verbOptions);\n\n const builderContexts = await Promise.all(\n Object.entries(groupByTags).map(async ([tag, verbs]) => {\n const zods = await Promise.all(\n verbs.map((verbOption) =>\n generateZod(\n verbOption,\n {\n route: verbOption.route,\n pathRoute: verbOption.pathRoute,\n override: output.override,\n context,\n mock: output.mock,\n output: output.target!,\n },\n output.client,\n ),\n ),\n );\n\n if (zods.every((z) => z.implementation === '')) {\n return {\n content: '',\n path: '',\n };\n }\n\n const allMutators = zods.reduce(\n (acc, z) => {\n for (const mutator of z.mutators ?? []) {\n acc[mutator.name] = mutator;\n }\n return acc;\n },\n {} as Record<string, GeneratorMutator>,\n );\n\n const mutatorsImports = generateMutatorImports({\n mutators: Object.values(allMutators),\n });\n\n let content = `${header}import { z as zod } from 'zod';\\n${mutatorsImports}\\n`;\n\n const zodPath =\n output.mode === 'tags'\n ? upath.join(dirname, `${kebab(tag)}.zod${extension}`)\n : upath.join(dirname, tag, tag + '.zod' + extension);\n\n content += zods.map((zod) => zod.implementation).join('\\n');\n\n return {\n content,\n path: zodPath,\n };\n }),\n );\n\n return Promise.all(\n builderContexts.filter((context) => context.content !== ''),\n );\n }\n\n const zods = await Promise.all(\n Object.values(verbOptions).map((verbOption) =>\n generateZod(\n verbOption,\n {\n route: verbOption.route,\n pathRoute: verbOption.pathRoute,\n override: output.override,\n context,\n mock: output.mock,\n output: output.target!,\n },\n output.client,\n ),\n ),\n );\n\n const allMutators = zods.reduce(\n (acc, z) => {\n for (const mutator of z.mutators ?? []) {\n acc[mutator.name] = mutator;\n }\n return acc;\n },\n {} as Record<string, GeneratorMutator>,\n );\n\n const mutatorsImports = generateMutatorImports({\n mutators: Object.values(allMutators),\n });\n\n let content = `${header}import { z as zod } from 'zod';\\n${mutatorsImports}\\n`;\n\n const zodPath = upath.join(dirname, `${filename}.zod${extension}`);\n\n content += zods.map((zod) => zod.implementation).join('\\n');\n\n return [\n {\n content,\n path: zodPath,\n },\n ];\n};\n\nconst generateZvalidator = (\n output: NormalizedOutputOptions,\n context: ContextSpecs,\n) => {\n const header = getHeader(\n output.override.header,\n context.specs[context.specKey].info,\n );\n\n let validatorPath = output.override.hono.validatorOutputPath;\n if (!output.override.hono.validatorOutputPath) {\n const { extension, dirname, filename } = getFileInfo(output.target);\n\n validatorPath = upath.join(dirname, `${filename}.validator${extension}`);\n }\n\n return {\n content: `${header}${ZVALIDATOR_SOURCE}`,\n path: validatorPath,\n };\n};\n\nconst generateCompositeRoutes = async (\n verbOptions: Record<string, GeneratorVerbOptions>,\n output: NormalizedOutputOptions,\n context: ContextSpecs,\n) => {\n const targetInfo = getFileInfo(output.target);\n const compositeRouteInfo = getFileInfo(output.override.hono.compositeRoute);\n\n const header = getHeader(\n output.override.header,\n context.specs[context.specKey].info,\n );\n\n const routes = Object.values(verbOptions)\n .map((verbOption) => {\n return generateHonoRoute(verbOption, verbOption.pathRoute);\n })\n .join(';');\n\n const importHandlers = Object.values(verbOptions);\n\n let ImportHandlersImplementation: string;\n if (output.override.hono.handlers) {\n const handlerFileInfo = getFileInfo(output.override.hono.handlers);\n const operationNames = importHandlers.map(\n (verbOption) => verbOption.operationName,\n );\n\n ImportHandlersImplementation = operationNames\n .map((operationName) => {\n const importHandlerName = `${operationName}Handlers`;\n\n const handlersPath = generateModuleSpecifier(\n compositeRouteInfo.path,\n upath.join(handlerFileInfo.dirname ?? '', `./${operationName}`),\n );\n\n return `import { ${importHandlerName} } from '${handlersPath}';`;\n })\n .join('\\n');\n } else {\n const tags = importHandlers.map((verbOption) =>\n kebab(verbOption.tags[0] ?? 'default'),\n );\n const uniqueTags = tags.filter((t, i) => tags.indexOf(t) === i);\n\n ImportHandlersImplementation = uniqueTags\n .map((tag) => {\n const importHandlerNames = importHandlers\n .filter((verbOption) => verbOption.tags[0] === tag)\n .map((verbOption) => ` ${verbOption.operationName}Handlers`)\n .join(`, \\n`);\n\n const handlersPath = generateModuleSpecifier(\n compositeRouteInfo.path,\n upath.join(targetInfo.dirname ?? '', tag),\n );\n\n return `import {\\n${importHandlerNames}\\n} from '${handlersPath}/${tag}.handlers';`;\n })\n .join('\\n');\n }\n\n const honoImport = `import { Hono } from 'hono';`;\n const honoInitialization = `\\nconst app = new Hono()`;\n const honoAppExport = `\\nexport default app`;\n\n const content = `${header}${honoImport}\n${ImportHandlersImplementation}\n${honoInitialization}\n${routes}\n${honoAppExport}\n`;\n\n return [\n {\n content,\n path: output.override.hono.compositeRoute || '',\n },\n ];\n};\n\nexport const generateExtraFiles: ClientExtraFilesBuilder = async (\n verbOptions,\n output,\n context,\n) => {\n const { path, pathWithoutExtension } = getFileInfo(output.target);\n const validator = generateZvalidator(output, context);\n let schemaModule: string;\n\n if (output.schemas != null) {\n schemaModule = getFileInfo(output.schemas).dirname;\n } else if (output.mode === 'single') {\n schemaModule = path;\n } else {\n schemaModule = `${pathWithoutExtension}.schemas`;\n }\n\n const [handlers, contexts, zods, compositeRoutes] = await Promise.all([\n generateHandlerFiles(verbOptions, output, validator.path),\n generateContextFiles(verbOptions, output, context, schemaModule),\n generateZodFiles(verbOptions, output, context),\n output.override.hono.compositeRoute\n ? generateCompositeRoutes(verbOptions, output, context)\n : [],\n ]);\n\n return [\n ...handlers,\n ...contexts,\n ...zods,\n ...(output.override.hono.validator &&\n output.override.hono.validator !== 'hono'\n ? [validator]\n : []),\n ...compositeRoutes,\n ];\n};\n\nconst honoClientBuilder: ClientGeneratorsBuilder = {\n client: generateHono,\n dependencies: getHonoDependencies,\n header: getHonoHeader,\n footer: getHonoFooter,\n extraFiles: generateExtraFiles,\n};\n\nexport const builder = () => () => honoClientBuilder;\n\nexport default builder;\n"],"mappings":"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"}
@@ -0,0 +1,139 @@
1
+ // based on https://github.com/honojs/middleware/blob/main/packages/zod-validator/src/index.ts
2
+ import type { z, ZodSchema, ZodError } from 'zod';
3
+ import type {
4
+ Context,
5
+ Env,
6
+ Input,
7
+ MiddlewareHandler,
8
+ TypedResponse,
9
+ ValidationTargets,
10
+ } from 'hono';
11
+
12
+ type HasUndefined<T> = undefined extends T ? true : false;
13
+
14
+ type Hook<T, E extends Env, P extends string, O = {}> = (
15
+ result:
16
+ | { success: true; data: T }
17
+ | { success: false; error: ZodError; data: T },
18
+ c: Context<E, P>,
19
+ ) =>
20
+ | Response
21
+ | Promise<Response>
22
+ | void
23
+ | Promise<Response | void>
24
+ | TypedResponse<O>;
25
+ import { zValidator as zValidatorBase } from '@hono/zod-validator';
26
+
27
+ type ValidationTargetsWithResponse = ValidationTargets & { response: any };
28
+
29
+ export const zValidator =
30
+ <
31
+ T extends ZodSchema,
32
+ Target extends keyof ValidationTargetsWithResponse,
33
+ E extends Env,
34
+ P extends string,
35
+ In = z.input<T>,
36
+ Out = z.output<T>,
37
+ I extends Input = {
38
+ in: HasUndefined<In> extends true
39
+ ? {
40
+ [K in Target]?: K extends 'json'
41
+ ? In
42
+ : HasUndefined<
43
+ keyof ValidationTargetsWithResponse[K]
44
+ > extends true
45
+ ? { [K2 in keyof In]?: ValidationTargetsWithResponse[K][K2] }
46
+ : { [K2 in keyof In]: ValidationTargetsWithResponse[K][K2] };
47
+ }
48
+ : {
49
+ [K in Target]: K extends 'json'
50
+ ? In
51
+ : HasUndefined<
52
+ keyof ValidationTargetsWithResponse[K]
53
+ > extends true
54
+ ? { [K2 in keyof In]?: ValidationTargetsWithResponse[K][K2] }
55
+ : { [K2 in keyof In]: ValidationTargetsWithResponse[K][K2] };
56
+ };
57
+ out: { [K in Target]: Out };
58
+ },
59
+ V extends I = I,
60
+ >(
61
+ target: Target,
62
+ schema: T,
63
+ hook?: Hook<z.infer<T>, E, P>,
64
+ ): MiddlewareHandler<E, P, V> =>
65
+ async (c, next) => {
66
+ if (target !== 'response') {
67
+ const value = await zValidatorBase<
68
+ T,
69
+ keyof ValidationTargets,
70
+ E,
71
+ P,
72
+ In,
73
+ Out,
74
+ I,
75
+ V
76
+ >(
77
+ target,
78
+ schema,
79
+ hook,
80
+ )(c, next);
81
+
82
+ if (value instanceof Response) {
83
+ return value;
84
+ }
85
+ } else {
86
+ await next();
87
+
88
+ if (
89
+ c.res.status !== 200 ||
90
+ !c.res.headers.get('Content-Type')?.includes('application/json')
91
+ ) {
92
+ return;
93
+ }
94
+
95
+ let value: unknown;
96
+ try {
97
+ value = await c.res.json();
98
+ } catch {
99
+ const message = 'Malformed JSON in response';
100
+ c.res = new Response(message, { status: 400 });
101
+
102
+ return;
103
+ }
104
+
105
+ const result = await schema.safeParseAsync(value);
106
+
107
+ if (hook) {
108
+ const hookResult = hook({ data: value, ...result }, c);
109
+ if (hookResult) {
110
+ if (hookResult instanceof Response || hookResult instanceof Promise) {
111
+ const hookResponse = await hookResult;
112
+
113
+ if (hookResponse instanceof Response) {
114
+ c.res = new Response(hookResponse.body, hookResponse);
115
+ }
116
+ }
117
+ if (
118
+ 'response' in hookResult &&
119
+ hookResult.response instanceof Response
120
+ ) {
121
+ c.res = new Response(hookResult.response.body, hookResult.response);
122
+ }
123
+ }
124
+ }
125
+
126
+ if (!result.success) {
127
+ c.res = new Response(JSON.stringify(result), {
128
+ status: 400,
129
+ headers: {
130
+ 'Content-Type': 'application/json',
131
+ },
132
+ });
133
+ } else {
134
+ c.res = new Response(JSON.stringify(result.data), c.res);
135
+ }
136
+ }
137
+
138
+ return;
139
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@orval/hono",
3
- "version": "7.13.1",
3
+ "version": "7.14.0",
4
4
  "license": "MIT",
5
5
  "exports": {
6
6
  ".": {
@@ -20,8 +20,8 @@
20
20
  "nuke": "rimraf .turbo dist node_modules"
21
21
  },
22
22
  "dependencies": {
23
- "@orval/core": "7.13.1",
24
- "@orval/zod": "7.13.1",
23
+ "@orval/core": "7.14.0",
24
+ "@orval/zod": "7.14.0",
25
25
  "fs-extra": "^11.3.1",
26
26
  "lodash.uniq": "^4.5.0",
27
27
  "openapi3-ts": "4.5.0"