@orval/hono 8.9.0 → 8.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +14 -1
- package/dist/index.mjs +220 -30
- package/dist/index.mjs.map +1 -1
- package/dist/zValidator.ts +2 -0
- package/package.json +3 -3
package/dist/index.d.mts
CHANGED
|
@@ -5,8 +5,21 @@ declare const getHonoDependencies: () => GeneratorDependency[];
|
|
|
5
5
|
declare const getHonoHeader: ClientHeaderBuilder;
|
|
6
6
|
declare const getHonoFooter: ClientFooterBuilder;
|
|
7
7
|
declare const generateHono: ClientBuilder;
|
|
8
|
+
/**
|
|
9
|
+
* extractExistingHandlerBodies scans a previously generated handler file and
|
|
10
|
+
* returns the user-authored body of each
|
|
11
|
+
* `async (c: ...) => { /* body *\/ }` block keyed by handler name.
|
|
12
|
+
*
|
|
13
|
+
* We deliberately preserve only the inner body — not the surrounding
|
|
14
|
+
* `factory.createHandlers(...)` call — so the regenerated wrapper always
|
|
15
|
+
* reflects the current validator chain and imports. The scanner is
|
|
16
|
+
* lex-aware: it skips strings, template literals, regex literals, and
|
|
17
|
+
* comments while counting parentheses/braces, so user code containing
|
|
18
|
+
* `)` or `}` characters in those contexts does not confuse the matcher.
|
|
19
|
+
*/
|
|
20
|
+
declare const extractExistingHandlerBodies: (source: string) => Map<string, string>;
|
|
8
21
|
declare const generateExtraFiles: ClientExtraFilesBuilder;
|
|
9
22
|
declare const builder: () => () => ClientGeneratorsBuilder;
|
|
10
23
|
//#endregion
|
|
11
|
-
export { builder, builder as default, generateExtraFiles, generateHono, getHonoDependencies, getHonoFooter, getHonoHeader };
|
|
24
|
+
export { builder, builder as default, extractExistingHandlerBodies, generateExtraFiles, generateHono, getHonoDependencies, getHonoFooter, getHonoHeader };
|
|
12
25
|
//# sourceMappingURL=index.d.mts.map
|
package/dist/index.mjs
CHANGED
|
@@ -66,9 +66,9 @@ const getHonoHeader = ({ verbOptions, output, tag, clientImplementation }) => {
|
|
|
66
66
|
if (output.override.hono.handlers) {
|
|
67
67
|
const handlerFileInfo = getFileInfo(output.override.hono.handlers);
|
|
68
68
|
handlers = importHandlers.map((verbOption) => {
|
|
69
|
-
const
|
|
69
|
+
const isSplitDir = output.mode === "tags-split";
|
|
70
70
|
const tag = kebab(verbOption.tags[0] ?? "default");
|
|
71
|
-
const handlersPath = upath.relativeSafe(nodePath.join(targetInfo.dirname,
|
|
71
|
+
const handlersPath = upath.relativeSafe(nodePath.join(targetInfo.dirname, isSplitDir ? tag : ""), nodePath.join(handlerFileInfo.dirname, `./${verbOption.operationName}`));
|
|
72
72
|
return `import { ${verbOption.operationName}Handlers } from '${handlersPath}';`;
|
|
73
73
|
}).join("\n");
|
|
74
74
|
} else handlers = `import {\n${importHandlers.map((verbOption) => ` ${verbOption.operationName}Handlers`).join(`, \n`)}\n} from './${tag ?? targetInfo.filename}.handlers';`;
|
|
@@ -97,10 +97,11 @@ const generateHono = (verbOptions, options) => {
|
|
|
97
97
|
* getHonoHandlers generates TypeScript code for the given verbs and reports
|
|
98
98
|
* whether the code requires zValidator.
|
|
99
99
|
*/
|
|
100
|
+
const DEFAULT_HANDLER_BODY = "\n\n ";
|
|
100
101
|
const getHonoHandlers = (...opts) => {
|
|
101
102
|
let code = "";
|
|
102
103
|
let hasZValidator = false;
|
|
103
|
-
for (const { handlerName, contextTypeName, verbOption, validator } of opts) {
|
|
104
|
+
for (const { handlerName, contextTypeName, verbOption, validator, bodyOverride } of opts) {
|
|
104
105
|
let currentValidator = "";
|
|
105
106
|
if (validator) {
|
|
106
107
|
const pascalOperationName = pascal(verbOption.operationName);
|
|
@@ -112,9 +113,7 @@ const getHonoHandlers = (...opts) => {
|
|
|
112
113
|
}
|
|
113
114
|
code += `
|
|
114
115
|
export const ${handlerName} = factory.createHandlers(
|
|
115
|
-
${currentValidator}async (c: ${contextTypeName}) => {
|
|
116
|
-
|
|
117
|
-
},
|
|
116
|
+
${currentValidator}async (c: ${contextTypeName}) => {${bodyOverride ?? DEFAULT_HANDLER_BODY}},
|
|
118
117
|
);`;
|
|
119
118
|
hasZValidator ||= currentValidator !== "";
|
|
120
119
|
}
|
|
@@ -143,22 +142,8 @@ const getVerbOptionGroupByTag = (verbOptions) => {
|
|
|
143
142
|
};
|
|
144
143
|
const generateHandlerFile = async ({ verbs, path, header, validatorModule, zodModule, contextModule }) => {
|
|
145
144
|
const validator = validatorModule === "@hono/zod-validator" ? "hono" : validatorModule != void 0;
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
let content = rawFile;
|
|
149
|
-
for (const verbOption of Object.values(verbs)) {
|
|
150
|
-
const handlerName = `${verbOption.operationName}Handlers`;
|
|
151
|
-
const contextTypeName = `${pascal(verbOption.operationName)}Context`;
|
|
152
|
-
if (!rawFile.includes(handlerName)) content += getHonoHandlers({
|
|
153
|
-
handlerName,
|
|
154
|
-
contextTypeName,
|
|
155
|
-
verbOption,
|
|
156
|
-
validator
|
|
157
|
-
})[0];
|
|
158
|
-
}
|
|
159
|
-
return content;
|
|
160
|
-
}
|
|
161
|
-
const [handlerCode, hasZValidator] = getHonoHandlers(...Object.values(verbs).map((verbOption) => ({
|
|
145
|
+
const verbList = Object.values(verbs);
|
|
146
|
+
const [, hasZValidator] = getHonoHandlers(...verbList.map((verbOption) => ({
|
|
162
147
|
handlerName: `${verbOption.operationName}Handlers`,
|
|
163
148
|
contextTypeName: `${pascal(verbOption.operationName)}Context`,
|
|
164
149
|
verbOption,
|
|
@@ -166,11 +151,204 @@ const generateHandlerFile = async ({ verbs, path, header, validatorModule, zodMo
|
|
|
166
151
|
})));
|
|
167
152
|
const imports = ["import { createFactory } from 'hono/factory';"];
|
|
168
153
|
if (hasZValidator && validatorModule != void 0) imports.push(`import { zValidator } from '${generateModuleSpecifier(path, validatorModule)}';`);
|
|
169
|
-
imports.push(`import { ${
|
|
170
|
-
if (hasZValidator) imports.push(getZvalidatorImports(
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
const
|
|
154
|
+
imports.push(`import { ${verbList.map((verb) => `${pascal(verb.operationName)}Context`).join(",\n")} } from '${generateModuleSpecifier(path, contextModule)}';`);
|
|
155
|
+
if (hasZValidator) imports.push(getZvalidatorImports(verbList, generateModuleSpecifier(path, zodModule), validatorModule === "@hono/zod-validator"));
|
|
156
|
+
const preamble = `${header}${imports.filter((imp) => imp !== "").join("\n")}\n\nconst factory = createFactory();`;
|
|
157
|
+
const existingBodies = fs.existsSync(path) ? extractExistingHandlerBodies(await fs.readFile(path, "utf8")) : /* @__PURE__ */ new Map();
|
|
158
|
+
const [handlerCode] = getHonoHandlers(...verbList.map((verbOption) => ({
|
|
159
|
+
handlerName: `${verbOption.operationName}Handlers`,
|
|
160
|
+
contextTypeName: `${pascal(verbOption.operationName)}Context`,
|
|
161
|
+
verbOption,
|
|
162
|
+
validator,
|
|
163
|
+
bodyOverride: existingBodies.get(`${verbOption.operationName}Handlers`)
|
|
164
|
+
})));
|
|
165
|
+
return `${preamble}${handlerCode}`;
|
|
166
|
+
};
|
|
167
|
+
/**
|
|
168
|
+
* extractExistingHandlerBodies scans a previously generated handler file and
|
|
169
|
+
* returns the user-authored body of each
|
|
170
|
+
* `async (c: ...) => { /* body *\/ }` block keyed by handler name.
|
|
171
|
+
*
|
|
172
|
+
* We deliberately preserve only the inner body — not the surrounding
|
|
173
|
+
* `factory.createHandlers(...)` call — so the regenerated wrapper always
|
|
174
|
+
* reflects the current validator chain and imports. The scanner is
|
|
175
|
+
* lex-aware: it skips strings, template literals, regex literals, and
|
|
176
|
+
* comments while counting parentheses/braces, so user code containing
|
|
177
|
+
* `)` or `}` characters in those contexts does not confuse the matcher.
|
|
178
|
+
*/
|
|
179
|
+
const extractExistingHandlerBodies = (source) => {
|
|
180
|
+
const bodies = /* @__PURE__ */ new Map();
|
|
181
|
+
const exportRegex = /export\s+const\s+(\w+Handlers)\s*=\s*factory\.createHandlers\s*\(/g;
|
|
182
|
+
let match;
|
|
183
|
+
while ((match = exportRegex.exec(source)) !== null) {
|
|
184
|
+
const handlerName = match[1];
|
|
185
|
+
const callOpenIdx = match.index + match[0].length - 1;
|
|
186
|
+
const callCloseIdx = findMatchingClose(source, callOpenIdx, "(", ")");
|
|
187
|
+
if (callCloseIdx === -1) continue;
|
|
188
|
+
const body = extractAsyncArrowBody(source.slice(callOpenIdx + 1, callCloseIdx));
|
|
189
|
+
if (body !== void 0) bodies.set(handlerName, body);
|
|
190
|
+
}
|
|
191
|
+
return bodies;
|
|
192
|
+
};
|
|
193
|
+
/**
|
|
194
|
+
* findMatchingClose returns the index of the closing bracket that pairs with
|
|
195
|
+
* the opening bracket at `openIdx`, or -1 if unbalanced. The scan skips
|
|
196
|
+
* strings, template literals, regex literals, and comments so brackets in
|
|
197
|
+
* those contexts do not affect depth.
|
|
198
|
+
*/
|
|
199
|
+
const findMatchingClose = (source, openIdx, open, close) => {
|
|
200
|
+
let depth = 0;
|
|
201
|
+
let i = openIdx;
|
|
202
|
+
while (i < source.length) {
|
|
203
|
+
const ch = source[i];
|
|
204
|
+
const next = source[i + 1];
|
|
205
|
+
if (ch === "/" && next === "/") {
|
|
206
|
+
const nl = source.indexOf("\n", i + 2);
|
|
207
|
+
i = nl === -1 ? source.length : nl + 1;
|
|
208
|
+
continue;
|
|
209
|
+
}
|
|
210
|
+
if (ch === "/" && next === "*") {
|
|
211
|
+
const end = source.indexOf("*/", i + 2);
|
|
212
|
+
i = end === -1 ? source.length : end + 2;
|
|
213
|
+
continue;
|
|
214
|
+
}
|
|
215
|
+
if (ch === "'" || ch === "\"" || ch === "`") {
|
|
216
|
+
i = skipString(source, i, ch);
|
|
217
|
+
continue;
|
|
218
|
+
}
|
|
219
|
+
if (ch === "/" && isRegexContext(source, i)) {
|
|
220
|
+
i = skipRegex(source, i);
|
|
221
|
+
continue;
|
|
222
|
+
}
|
|
223
|
+
if (ch === open) depth++;
|
|
224
|
+
else if (ch === close) {
|
|
225
|
+
depth--;
|
|
226
|
+
if (depth === 0) return i;
|
|
227
|
+
}
|
|
228
|
+
i++;
|
|
229
|
+
}
|
|
230
|
+
return -1;
|
|
231
|
+
};
|
|
232
|
+
const skipString = (source, start, quote) => {
|
|
233
|
+
let i = start + 1;
|
|
234
|
+
while (i < source.length) {
|
|
235
|
+
const ch = source[i];
|
|
236
|
+
if (ch === "\\") {
|
|
237
|
+
i += 2;
|
|
238
|
+
continue;
|
|
239
|
+
}
|
|
240
|
+
if (quote === "`" && ch === "$" && source[i + 1] === "{") {
|
|
241
|
+
const end = findMatchingClose(source, i + 1, "{", "}");
|
|
242
|
+
i = end === -1 ? source.length : end + 1;
|
|
243
|
+
continue;
|
|
244
|
+
}
|
|
245
|
+
if (ch === quote) return i + 1;
|
|
246
|
+
i++;
|
|
247
|
+
}
|
|
248
|
+
return source.length;
|
|
249
|
+
};
|
|
250
|
+
const skipRegex = (source, start) => {
|
|
251
|
+
let i = start + 1;
|
|
252
|
+
let inClass = false;
|
|
253
|
+
while (i < source.length) {
|
|
254
|
+
const ch = source[i];
|
|
255
|
+
if (ch === "\\") {
|
|
256
|
+
i += 2;
|
|
257
|
+
continue;
|
|
258
|
+
}
|
|
259
|
+
if (ch === "[") inClass = true;
|
|
260
|
+
else if (ch === "]") inClass = false;
|
|
261
|
+
else if (ch === "/" && !inClass) {
|
|
262
|
+
i++;
|
|
263
|
+
while (i < source.length && /[gimsuy]/.test(source[i])) i++;
|
|
264
|
+
return i;
|
|
265
|
+
}
|
|
266
|
+
if (ch === "\n") return start + 1;
|
|
267
|
+
i++;
|
|
268
|
+
}
|
|
269
|
+
return source.length;
|
|
270
|
+
};
|
|
271
|
+
const REGEX_PRECEDING_KEYWORDS = new Set([
|
|
272
|
+
"return",
|
|
273
|
+
"throw",
|
|
274
|
+
"yield",
|
|
275
|
+
"await",
|
|
276
|
+
"case",
|
|
277
|
+
"new",
|
|
278
|
+
"typeof",
|
|
279
|
+
"void",
|
|
280
|
+
"delete",
|
|
281
|
+
"in",
|
|
282
|
+
"of",
|
|
283
|
+
"instanceof"
|
|
284
|
+
]);
|
|
285
|
+
const isRegexContext = (source, slashIdx) => {
|
|
286
|
+
let j = slashIdx - 1;
|
|
287
|
+
while (j >= 0 && (source[j] === " " || source[j] === " " || source[j] === "\n")) j--;
|
|
288
|
+
if (j < 0) return true;
|
|
289
|
+
const c = source[j];
|
|
290
|
+
if (c === ".") {
|
|
291
|
+
if (j >= 2 && source[j - 1] === "." && source[j - 2] === ".") return true;
|
|
292
|
+
return false;
|
|
293
|
+
}
|
|
294
|
+
if (/[A-Za-z0-9_$]/.test(c)) {
|
|
295
|
+
let k = j;
|
|
296
|
+
while (k >= 0 && /[A-Za-z0-9_$]/.test(source[k])) k--;
|
|
297
|
+
const token = source.slice(k + 1, j + 1);
|
|
298
|
+
return REGEX_PRECEDING_KEYWORDS.has(token);
|
|
299
|
+
}
|
|
300
|
+
if (c === ")" || c === "]") return false;
|
|
301
|
+
return true;
|
|
302
|
+
};
|
|
303
|
+
/**
|
|
304
|
+
* extractAsyncArrowBody finds the trailing `async (c: ...) => { ... }`
|
|
305
|
+
* argument inside `factory.createHandlers(...)` and returns the inner body
|
|
306
|
+
* (without the surrounding braces). Returns undefined when the call does not
|
|
307
|
+
* end with the expected arrow function shape.
|
|
308
|
+
*/
|
|
309
|
+
const extractAsyncArrowBody = (callBody) => {
|
|
310
|
+
let i = 0;
|
|
311
|
+
let lastTopLevelArrow = -1;
|
|
312
|
+
while (i < callBody.length) {
|
|
313
|
+
const ch = callBody[i];
|
|
314
|
+
const next = callBody[i + 1];
|
|
315
|
+
if (ch === "/" && next === "/") {
|
|
316
|
+
const nl = callBody.indexOf("\n", i + 2);
|
|
317
|
+
i = nl === -1 ? callBody.length : nl + 1;
|
|
318
|
+
continue;
|
|
319
|
+
}
|
|
320
|
+
if (ch === "/" && next === "*") {
|
|
321
|
+
const end = callBody.indexOf("*/", i + 2);
|
|
322
|
+
i = end === -1 ? callBody.length : end + 2;
|
|
323
|
+
continue;
|
|
324
|
+
}
|
|
325
|
+
if (ch === "'" || ch === "\"" || ch === "`") {
|
|
326
|
+
i = skipString(callBody, i, ch);
|
|
327
|
+
continue;
|
|
328
|
+
}
|
|
329
|
+
if (ch === "/" && isRegexContext(callBody, i)) {
|
|
330
|
+
i = skipRegex(callBody, i);
|
|
331
|
+
continue;
|
|
332
|
+
}
|
|
333
|
+
if (ch === "(" || ch === "{") {
|
|
334
|
+
const end = findMatchingClose(callBody, i, ch, ch === "(" ? ")" : "}");
|
|
335
|
+
i = end === -1 ? callBody.length : end + 1;
|
|
336
|
+
continue;
|
|
337
|
+
}
|
|
338
|
+
if (ch === "=" && next === ">") {
|
|
339
|
+
lastTopLevelArrow = i;
|
|
340
|
+
i += 2;
|
|
341
|
+
continue;
|
|
342
|
+
}
|
|
343
|
+
i++;
|
|
344
|
+
}
|
|
345
|
+
if (lastTopLevelArrow === -1) return void 0;
|
|
346
|
+
let j = lastTopLevelArrow + 2;
|
|
347
|
+
while (j < callBody.length && /\s/.test(callBody[j])) j++;
|
|
348
|
+
if (callBody[j] !== "{") return void 0;
|
|
349
|
+
const closeIdx = findMatchingClose(callBody, j, "{", "}");
|
|
350
|
+
if (closeIdx === -1) return void 0;
|
|
351
|
+
return callBody.slice(j + 1, closeIdx);
|
|
174
352
|
};
|
|
175
353
|
const generateHandlerFiles = async (verbOptions, output, context, validatorModule) => {
|
|
176
354
|
const header = getHeader(output.override.header, getSpecInfo(context));
|
|
@@ -178,14 +356,26 @@ const generateHandlerFiles = async (verbOptions, output, context, validatorModul
|
|
|
178
356
|
if (output.override.hono.handlers) return Promise.all(Object.values(verbOptions).map(async (verbOption) => {
|
|
179
357
|
const tag = kebab(verbOption.tags[0] ?? "default");
|
|
180
358
|
const path = nodePath.join(output.override.hono.handlers ?? "", `./${verbOption.operationName}` + extension);
|
|
359
|
+
let zodModule;
|
|
360
|
+
let contextModule;
|
|
361
|
+
if (output.mode === "tags") {
|
|
362
|
+
zodModule = nodePath.join(dirname, `${kebab(tag)}.zod`);
|
|
363
|
+
contextModule = nodePath.join(dirname, `${kebab(tag)}.context`);
|
|
364
|
+
} else if (output.mode === "tags-split") {
|
|
365
|
+
zodModule = nodePath.join(dirname, tag, tag + ".zod");
|
|
366
|
+
contextModule = nodePath.join(dirname, tag, tag + ".context");
|
|
367
|
+
} else {
|
|
368
|
+
zodModule = nodePath.join(dirname, `${filename}.zod`);
|
|
369
|
+
contextModule = nodePath.join(dirname, `${filename}.context`);
|
|
370
|
+
}
|
|
181
371
|
return {
|
|
182
372
|
content: await generateHandlerFile({
|
|
183
373
|
path,
|
|
184
374
|
header,
|
|
185
375
|
verbs: [verbOption],
|
|
186
376
|
validatorModule,
|
|
187
|
-
zodModule
|
|
188
|
-
contextModule
|
|
377
|
+
zodModule,
|
|
378
|
+
contextModule
|
|
189
379
|
}),
|
|
190
380
|
path
|
|
191
381
|
};
|
|
@@ -399,6 +589,6 @@ const honoClientBuilder = {
|
|
|
399
589
|
};
|
|
400
590
|
const builder = () => () => honoClientBuilder;
|
|
401
591
|
//#endregion
|
|
402
|
-
export { builder, builder as default, generateExtraFiles, generateHono, getHonoDependencies, getHonoFooter, getHonoHeader };
|
|
592
|
+
export { builder, builder as default, extractExistingHandlerBodies, generateExtraFiles, generateHono, getHonoDependencies, getHonoFooter, getHonoHeader };
|
|
403
593
|
|
|
404
594
|
//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":[],"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 let acc = '';\n for (const [i, path] of splittedRoute.entries()) {\n if (!path && i === 0) continue;\n\n acc += path.includes('{') ? `/${getRoutePath(path)}` : `/${path}`;\n }\n\n return acc;\n};\n","import nodePath from 'node:path';\n\nimport {\n camel,\n type ClientBuilder,\n type ClientExtraFilesBuilder,\n type ClientFooterBuilder,\n type ClientGeneratorsBuilder,\n type ClientHeaderBuilder,\n type ContextSpec,\n generateMutatorImports,\n type GeneratorDependency,\n type GeneratorImport,\n type GeneratorVerbOptions,\n getFileInfo,\n getOrvalGeneratedTypes,\n getParamsInPath,\n isObject,\n jsDoc,\n kebab,\n type NormalizedMutator,\n type NormalizedOutputOptions,\n type OpenApiInfoObject,\n pascal,\n sanitize,\n upath,\n} from '@orval/core';\nimport { generateZod } from '@orval/zod';\nimport fs from 'fs-extra';\n\nimport { getRoute } from './route';\n\nconst ZVALIDATOR_SOURCE = fs\n .readFileSync(nodePath.join(import.meta.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('.') || nodePath.isAbsolute(to)) {\n return upath\n .getRelativeImportPath(nodePath.resolve(from), nodePath.resolve(to), true)\n .replace(/\\.ts$/, '');\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 nodePath.join(targetInfo.dirname, isTagMode ? tag : ''),\n nodePath.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\\nconst app = new Hono()\\n`;\n};\n\nexport const getHonoFooter: ClientFooterBuilder = () =>\n ';\\n\\nexport default app;\\n';\n\nconst generateHonoRoute = (\n { operationName, verb }: GeneratorVerbOptions,\n pathRoute: string,\n) => {\n const path = getRoute(pathRoute);\n\n return `\\n .${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}\\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: {\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 let code = '';\n let hasZValidator = false;\n\n for (const { handlerName, contextTypeName, verbOption, validator } of opts) {\n let currentValidator = '';\n\n if (validator) {\n const pascalOperationName = pascal(verbOption.operationName);\n\n if (verbOption.headers) {\n currentValidator += `zValidator('header', ${pascalOperationName}Header),\\n`;\n }\n if (verbOption.params.length > 0) {\n currentValidator += `zValidator('param', ${pascalOperationName}Params),\\n`;\n }\n if (verbOption.queryParams) {\n currentValidator += `zValidator('query', ${pascalOperationName}QueryParams),\\n`;\n }\n if (verbOption.body.definition) {\n currentValidator += `zValidator('json', ${pascalOperationName}Body),\\n`;\n }\n if (\n validator !== 'hono' &&\n verbOption.response.originalSchema?.['200']?.content?.[\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n 'application/json'\n ]\n ) {\n currentValidator += `zValidator('response', ${pascalOperationName}Response),\\n`;\n }\n }\n\n code += `\nexport const ${handlerName} = factory.createHandlers(\n${currentValidator}async (c: ${contextTypeName}) => {\n\n },\n);`;\n\n hasZValidator ||= currentValidator !== '';\n }\n\n return [code, hasZValidator];\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 const pascalOperationName = pascal(operationName);\n\n if (headers) {\n specifiers.push(`${pascalOperationName}Header`);\n }\n\n if (params.length > 0) {\n specifiers.push(`${pascalOperationName}Params`);\n }\n\n if (queryParams) {\n specifiers.push(`${pascalOperationName}QueryParams`);\n }\n\n if (body.definition) {\n specifiers.push(`${pascalOperationName}Body`);\n }\n\n if (\n !isHonoValidator &&\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n response.originalSchema?.['200']?.content?.['application/json'] !=\n undefined\n ) {\n specifiers.push(`${pascalOperationName}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 const grouped: Record<string, GeneratorVerbOptions[]> = {};\n\n for (const value of Object.values(verbOptions)) {\n const tag = value.tags[0];\n // this is not always false\n // TODO look into types\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n if (!grouped[tag]) {\n grouped[tag] = [];\n }\n grouped[tag].push(value);\n }\n\n return grouped;\n};\n\nconst generateHandlerFile = async ({\n verbs,\n path,\n header,\n validatorModule,\n zodModule,\n contextModule,\n}: {\n verbs: GeneratorVerbOptions[];\n path: string;\n header: 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 != undefined;\n\n const isExist = fs.existsSync(path);\n\n if (isExist) {\n // Preserve the existing file (which may contain user edits) and only\n // append handlers that have not been generated yet. The file header is\n // intentionally left untouched so any previously customised header stays\n // in place.\n const rawFile = await fs.readFile(path, 'utf8');\n let content = rawFile;\n\n for (const verbOption of Object.values(verbs)) {\n const handlerName = `${verbOption.operationName}Handlers`;\n const contextTypeName = `${pascal(verbOption.operationName)}Context`;\n\n if (!rawFile.includes(handlerName)) {\n content += getHonoHandlers({\n handlerName,\n contextTypeName,\n verbOption,\n validator,\n })[0];\n }\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 != undefined) {\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 `${header}${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 context: ContextSpec,\n validatorModule: string,\n) => {\n const header = getHeader(output.override.header, getSpecInfo(context));\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 = nodePath.join(\n output.override.hono.handlers ?? '',\n `./${verbOption.operationName}` + extension,\n );\n\n return {\n content: await generateHandlerFile({\n path,\n header,\n verbs: [verbOption],\n validatorModule,\n zodModule:\n output.mode === 'tags'\n ? nodePath.join(dirname, `${kebab(tag)}.zod`)\n : nodePath.join(dirname, tag, tag + '.zod'),\n contextModule:\n output.mode === 'tags'\n ? nodePath.join(dirname, `${kebab(tag)}.context`)\n : nodePath.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 ? nodePath.join(dirname, `${kebab(tag)}.handlers${extension}`)\n : nodePath.join(dirname, tag, tag + '.handlers' + extension);\n\n return {\n content: await generateHandlerFile({\n path: handlerPath,\n header,\n verbs,\n validatorModule,\n zodModule:\n output.mode === 'tags'\n ? nodePath.join(dirname, `${kebab(tag)}.zod`)\n : nodePath.join(dirname, tag, tag + '.zod'),\n contextModule:\n output.mode === 'tags'\n ? nodePath.join(dirname, `${kebab(tag)}.context`)\n : nodePath.join(dirname, tag, tag + '.context'),\n }),\n path: handlerPath,\n };\n }),\n );\n }\n\n // One file with all operations.\n const handlerPath = nodePath.join(\n dirname,\n `${filename}.handlers${extension}`,\n );\n\n return [\n {\n content: await generateHandlerFile({\n path: handlerPath,\n header,\n verbs: Object.values(verbOptions),\n validatorModule,\n zodModule: nodePath.join(dirname, `${filename}.zod`),\n contextModule: nodePath.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: OpenApiInfoObject) => string | string[]),\n info: OpenApiInfoObject,\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 getSpecInfo = (context: ContextSpec): OpenApiInfoObject =>\n context.spec.info ?? {\n title: 'API',\n version: '1.0.0',\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: ContextSpec,\n schemaModule: string,\n) => {\n const header = getHeader(output.override.header, getSpecInfo(context));\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 ? nodePath.join(dirname, `${kebab(tag)}.context${extension}`)\n : nodePath.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 = nodePath.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: ContextSpec,\n) => {\n const { extension, dirname, filename } = getFileInfo(output.target);\n\n const header = getHeader(output.override.header, getSpecInfo(context));\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(async (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 = new Map(\n zods.flatMap((z) => z.mutators ?? []).map((m) => [m.name, m]),\n )\n .values()\n .toArray();\n\n const mutatorsImports = generateMutatorImports({\n mutators: 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 ? nodePath.join(dirname, `${kebab(tag)}.zod${extension}`)\n : nodePath.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 builderContexts.filter((context) => context.content !== '');\n }\n\n const zods = await Promise.all(\n Object.values(verbOptions).map(async (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 = new Map(\n zods.flatMap((z) => z.mutators ?? []).map((m) => [m.name, m]),\n )\n .values()\n .toArray();\n\n const mutatorsImports = generateMutatorImports({\n mutators: allMutators,\n });\n\n let content = `${header}import { z as zod } from 'zod';\\n${mutatorsImports}\\n`;\n\n const zodPath = nodePath.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: ContextSpec,\n) => {\n const header = getHeader(output.override.header, getSpecInfo(context));\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 = nodePath.join(dirname, `${filename}.validator${extension}`);\n }\n\n return {\n content: `${header}${ZVALIDATOR_SOURCE}`,\n path: validatorPath,\n };\n};\n\nconst generateCompositeRoutes = (\n verbOptions: Record<string, GeneratorVerbOptions>,\n output: NormalizedOutputOptions,\n context: ContextSpec,\n) => {\n const targetInfo = getFileInfo(output.target);\n const compositeRouteInfo = getFileInfo(output.override.hono.compositeRoute);\n\n const header = getHeader(output.override.header, getSpecInfo(context));\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 nodePath.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 nodePath.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}${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 != undefined) {\n const schemasPath = (\n isObject(output.schemas) ? output.schemas.path : output.schemas\n ) as string;\n const basePath = getFileInfo(schemasPath).dirname;\n schemaModule = basePath;\n } else if (output.mode === 'single') {\n schemaModule = path;\n } else {\n schemaModule = `${pathWithoutExtension}.schemas`;\n }\n\n const contexts = generateContextFiles(\n verbOptions,\n output,\n context,\n schemaModule,\n );\n const compositeRoutes = output.override.hono.compositeRoute\n ? generateCompositeRoutes(verbOptions, output, context)\n : [];\n const [handlers, zods] = await Promise.all([\n generateHandlerFiles(verbOptions, output, context, validator.path),\n generateZodFiles(verbOptions, output, context),\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.mjs","names":[],"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 let acc = '';\n for (const [i, path] of splittedRoute.entries()) {\n if (!path && i === 0) continue;\n\n acc += path.includes('{') ? `/${getRoutePath(path)}` : `/${path}`;\n }\n\n return acc;\n};\n","import nodePath from 'node:path';\n\nimport {\n camel,\n type ClientBuilder,\n type ClientExtraFilesBuilder,\n type ClientFooterBuilder,\n type ClientGeneratorsBuilder,\n type ClientHeaderBuilder,\n type ContextSpec,\n generateMutatorImports,\n type GeneratorDependency,\n type GeneratorImport,\n type GeneratorVerbOptions,\n getFileInfo,\n getOrvalGeneratedTypes,\n getParamsInPath,\n isObject,\n jsDoc,\n kebab,\n type NormalizedMutator,\n type NormalizedOutputOptions,\n type OpenApiInfoObject,\n pascal,\n sanitize,\n upath,\n} from '@orval/core';\nimport { generateZod } from '@orval/zod';\nimport fs from 'fs-extra';\n\nimport { getRoute } from './route';\n\nconst ZVALIDATOR_SOURCE = fs\n .readFileSync(nodePath.join(import.meta.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('.') || nodePath.isAbsolute(to)) {\n return upath\n .getRelativeImportPath(nodePath.resolve(from), nodePath.resolve(to), true)\n .replace(/\\.ts$/, '');\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 // Only `tags-split` puts each tag's client file inside its own\n // sub-directory. `tags` mode flattens them next to `target`, so the\n // import must be resolved from `targetInfo.dirname` directly.\n const isSplitDir = output.mode === 'tags-split';\n const tag = kebab(verbOption.tags[0] ?? 'default');\n\n const handlersPath = upath.relativeSafe(\n nodePath.join(targetInfo.dirname, isSplitDir ? tag : ''),\n nodePath.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\\nconst app = new Hono()\\n`;\n};\n\nexport const getHonoFooter: ClientFooterBuilder = () =>\n ';\\n\\nexport default app;\\n';\n\nconst generateHonoRoute = (\n { operationName, verb }: GeneratorVerbOptions,\n pathRoute: string,\n) => {\n const path = getRoute(pathRoute);\n\n return `\\n .${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}\\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 DEFAULT_HANDLER_BODY = '\\n\\n ';\n\nconst getHonoHandlers = (\n ...opts: {\n handlerName: string;\n contextTypeName: string;\n verbOption: GeneratorVerbOptions;\n validator: boolean | 'hono' | NormalizedMutator;\n /**\n * Optional async-handler body to splice into the generated wrapper. When\n * supplied the validator chain is still rebuilt from the current verb\n * options, but the body inside `async (c) => { ... }` is taken verbatim\n * from the existing file so user logic survives regeneration.\n */\n bodyOverride?: string;\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 let code = '';\n let hasZValidator = false;\n\n for (const {\n handlerName,\n contextTypeName,\n verbOption,\n validator,\n bodyOverride,\n } of opts) {\n let currentValidator = '';\n\n if (validator) {\n const pascalOperationName = pascal(verbOption.operationName);\n\n if (verbOption.headers) {\n currentValidator += `zValidator('header', ${pascalOperationName}Header),\\n`;\n }\n if (verbOption.params.length > 0) {\n currentValidator += `zValidator('param', ${pascalOperationName}Params),\\n`;\n }\n if (verbOption.queryParams) {\n currentValidator += `zValidator('query', ${pascalOperationName}QueryParams),\\n`;\n }\n if (verbOption.body.definition) {\n currentValidator += `zValidator('json', ${pascalOperationName}Body),\\n`;\n }\n if (\n validator !== 'hono' &&\n verbOption.response.originalSchema?.['200']?.content?.[\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n 'application/json'\n ]\n ) {\n currentValidator += `zValidator('response', ${pascalOperationName}Response),\\n`;\n }\n }\n\n const body = bodyOverride ?? DEFAULT_HANDLER_BODY;\n\n code += `\nexport const ${handlerName} = factory.createHandlers(\n${currentValidator}async (c: ${contextTypeName}) => {${body}},\n);`;\n\n hasZValidator ||= currentValidator !== '';\n }\n\n return [code, hasZValidator];\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 const pascalOperationName = pascal(operationName);\n\n if (headers) {\n specifiers.push(`${pascalOperationName}Header`);\n }\n\n if (params.length > 0) {\n specifiers.push(`${pascalOperationName}Params`);\n }\n\n if (queryParams) {\n specifiers.push(`${pascalOperationName}QueryParams`);\n }\n\n if (body.definition) {\n specifiers.push(`${pascalOperationName}Body`);\n }\n\n if (\n !isHonoValidator &&\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n response.originalSchema?.['200']?.content?.['application/json'] !=\n undefined\n ) {\n specifiers.push(`${pascalOperationName}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 const grouped: Record<string, GeneratorVerbOptions[]> = {};\n\n for (const value of Object.values(verbOptions)) {\n const tag = value.tags[0];\n // this is not always false\n // TODO look into types\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n if (!grouped[tag]) {\n grouped[tag] = [];\n }\n grouped[tag].push(value);\n }\n\n return grouped;\n};\n\nconst generateHandlerFile = async ({\n verbs,\n path,\n header,\n validatorModule,\n zodModule,\n contextModule,\n}: {\n verbs: GeneratorVerbOptions[];\n path: string;\n header: 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 != undefined;\n\n const verbList = Object.values(verbs);\n\n const [, hasZValidator] = getHonoHandlers(\n ...verbList.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 != undefined) {\n imports.push(\n `import { zValidator } from '${generateModuleSpecifier(path, validatorModule)}';`,\n );\n }\n\n imports.push(\n `import { ${verbList\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 verbList,\n generateModuleSpecifier(path, zodModule),\n validatorModule === '@hono/zod-validator',\n ),\n );\n }\n\n const preamble = `${header}${imports.filter((imp) => imp !== '').join('\\n')}\\n\\nconst factory = createFactory();`;\n\n const existingBodies = fs.existsSync(path)\n ? extractExistingHandlerBodies(await fs.readFile(path, 'utf8'))\n : new Map<string, string>();\n\n // Always rebuild the preamble (header + imports + factory) and the validator\n // chain from current metadata so import paths, casing, and middleware match\n // the latest configuration. We only splice the user-authored async body\n // back in — preserving the wrapper would risk keeping stale `zValidator`\n // calls whose imports we just rewrote.\n const [handlerCode] = getHonoHandlers(\n ...verbList.map((verbOption) => ({\n handlerName: `${verbOption.operationName}Handlers`,\n contextTypeName: `${pascal(verbOption.operationName)}Context`,\n verbOption,\n validator,\n bodyOverride: existingBodies.get(`${verbOption.operationName}Handlers`),\n })),\n );\n\n return `${preamble}${handlerCode}`;\n};\n\n/**\n * extractExistingHandlerBodies scans a previously generated handler file and\n * returns the user-authored body of each\n * `async (c: ...) => { /* body *\\/ }` block keyed by handler name.\n *\n * We deliberately preserve only the inner body — not the surrounding\n * `factory.createHandlers(...)` call — so the regenerated wrapper always\n * reflects the current validator chain and imports. The scanner is\n * lex-aware: it skips strings, template literals, regex literals, and\n * comments while counting parentheses/braces, so user code containing\n * `)` or `}` characters in those contexts does not confuse the matcher.\n */\nexport const extractExistingHandlerBodies = (\n source: string,\n): Map<string, string> => {\n const bodies = new Map<string, string>();\n const exportRegex =\n /export\\s+const\\s+(\\w+Handlers)\\s*=\\s*factory\\.createHandlers\\s*\\(/g;\n\n let match: RegExpExecArray | null;\n while ((match = exportRegex.exec(source)) !== null) {\n const handlerName = match[1];\n const callOpenIdx = match.index + match[0].length - 1; // points at '('\n const callCloseIdx = findMatchingClose(source, callOpenIdx, '(', ')');\n if (callCloseIdx === -1) continue;\n\n const callBody = source.slice(callOpenIdx + 1, callCloseIdx);\n const body = extractAsyncArrowBody(callBody);\n if (body !== undefined) {\n bodies.set(handlerName, body);\n }\n }\n\n return bodies;\n};\n\n/**\n * findMatchingClose returns the index of the closing bracket that pairs with\n * the opening bracket at `openIdx`, or -1 if unbalanced. The scan skips\n * strings, template literals, regex literals, and comments so brackets in\n * those contexts do not affect depth.\n */\nconst findMatchingClose = (\n source: string,\n openIdx: number,\n open: '(' | '{',\n close: ')' | '}',\n): number => {\n let depth = 0;\n let i = openIdx;\n while (i < source.length) {\n const ch = source[i];\n const next = source[i + 1];\n\n // Line comment\n if (ch === '/' && next === '/') {\n const nl = source.indexOf('\\n', i + 2);\n i = nl === -1 ? source.length : nl + 1;\n continue;\n }\n // Block comment\n if (ch === '/' && next === '*') {\n const end = source.indexOf('*/', i + 2);\n i = end === -1 ? source.length : end + 2;\n continue;\n }\n // String / template literal\n if (ch === \"'\" || ch === '\"' || ch === '`') {\n i = skipString(source, i, ch);\n continue;\n }\n // Regex literal — only when a regex is syntactically possible. A `/`\n // following an identifier or closing bracket is division, not a regex.\n if (ch === '/' && isRegexContext(source, i)) {\n i = skipRegex(source, i);\n continue;\n }\n\n if (ch === open) depth++;\n else if (ch === close) {\n depth--;\n if (depth === 0) return i;\n }\n i++;\n }\n return -1;\n};\n\nconst skipString = (\n source: string,\n start: number,\n quote: \"'\" | '\"' | '`',\n): number => {\n let i = start + 1;\n while (i < source.length) {\n const ch = source[i];\n if (ch === '\\\\') {\n i += 2;\n continue;\n }\n if (quote === '`' && ch === '$' && source[i + 1] === '{') {\n const end = findMatchingClose(source, i + 1, '{', '}');\n i = end === -1 ? source.length : end + 1;\n continue;\n }\n if (ch === quote) return i + 1;\n i++;\n }\n return source.length;\n};\n\nconst skipRegex = (source: string, start: number): number => {\n let i = start + 1;\n let inClass = false;\n while (i < source.length) {\n const ch = source[i];\n if (ch === '\\\\') {\n i += 2;\n continue;\n }\n if (ch === '[') inClass = true;\n else if (ch === ']') inClass = false;\n else if (ch === '/' && !inClass) {\n i++;\n while (i < source.length && /[gimsuy]/.test(source[i])) i++;\n return i;\n }\n if (ch === '\\n') return start + 1; // not a regex after all; bail\n i++;\n }\n return source.length;\n};\n\nconst REGEX_PRECEDING_KEYWORDS = new Set([\n 'return',\n 'throw',\n 'yield',\n 'await',\n 'case',\n 'new',\n 'typeof',\n 'void',\n 'delete',\n 'in',\n 'of',\n 'instanceof',\n]);\n\nconst isRegexContext = (source: string, slashIdx: number): boolean => {\n let j = slashIdx - 1;\n while (\n j >= 0 &&\n (source[j] === ' ' || source[j] === '\\t' || source[j] === '\\n')\n ) {\n j--;\n }\n if (j < 0) return true;\n\n const c = source[j];\n\n // Spread `...` allows a regex literal as the spread target.\n if (c === '.') {\n if (j >= 2 && source[j - 1] === '.' && source[j - 2] === '.') return true;\n return false;\n }\n\n // Identifier char: scan backward to extract token, check keyword set.\n if (/[A-Za-z0-9_$]/.test(c)) {\n let k = j;\n while (k >= 0 && /[A-Za-z0-9_$]/.test(source[k])) k--;\n const token = source.slice(k + 1, j + 1);\n return REGEX_PRECEDING_KEYWORDS.has(token);\n }\n\n // Closing brackets imply a value precedes — division.\n if (c === ')' || c === ']') return false;\n\n return true;\n};\n\n/**\n * extractAsyncArrowBody finds the trailing `async (c: ...) => { ... }`\n * argument inside `factory.createHandlers(...)` and returns the inner body\n * (without the surrounding braces). Returns undefined when the call does not\n * end with the expected arrow function shape.\n */\nconst extractAsyncArrowBody = (callBody: string): string | undefined => {\n // Walk the argument list at depth 0 only, skipping strings, templates,\n // regex literals, comments, and nested parens/braces, so arrows inside\n // user-authored callbacks (e.g. `pets.map(p => p.id)`) are ignored.\n let i = 0;\n let lastTopLevelArrow = -1;\n while (i < callBody.length) {\n const ch = callBody[i];\n const next = callBody[i + 1];\n\n if (ch === '/' && next === '/') {\n const nl = callBody.indexOf('\\n', i + 2);\n i = nl === -1 ? callBody.length : nl + 1;\n continue;\n }\n if (ch === '/' && next === '*') {\n const end = callBody.indexOf('*/', i + 2);\n i = end === -1 ? callBody.length : end + 2;\n continue;\n }\n if (ch === \"'\" || ch === '\"' || ch === '`') {\n i = skipString(callBody, i, ch);\n continue;\n }\n if (ch === '/' && isRegexContext(callBody, i)) {\n i = skipRegex(callBody, i);\n continue;\n }\n if (ch === '(' || ch === '{') {\n const open = ch;\n const close = ch === '(' ? ')' : '}';\n const end = findMatchingClose(callBody, i, open, close);\n i = end === -1 ? callBody.length : end + 1;\n continue;\n }\n if (ch === '=' && next === '>') {\n lastTopLevelArrow = i;\n i += 2;\n continue;\n }\n i++;\n }\n\n if (lastTopLevelArrow === -1) return undefined;\n\n let j = lastTopLevelArrow + 2;\n while (j < callBody.length && /\\s/.test(callBody[j])) j++;\n if (callBody[j] !== '{') return undefined;\n\n const closeIdx = findMatchingClose(callBody, j, '{', '}');\n if (closeIdx === -1) return undefined;\n\n return callBody.slice(j + 1, closeIdx);\n};\n\nconst generateHandlerFiles = async (\n verbOptions: Record<string, GeneratorVerbOptions>,\n output: NormalizedOutputOptions,\n context: ContextSpec,\n validatorModule: string,\n) => {\n const header = getHeader(output.override.header, getSpecInfo(context));\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 = nodePath.join(\n output.override.hono.handlers ?? '',\n `./${verbOption.operationName}` + extension,\n );\n\n // Mirror the layout used by generateZodFiles/generateContextFiles so\n // imports resolve to the actual emitted modules.\n let zodModule: string;\n let contextModule: string;\n if (output.mode === 'tags') {\n zodModule = nodePath.join(dirname, `${kebab(tag)}.zod`);\n contextModule = nodePath.join(dirname, `${kebab(tag)}.context`);\n } else if (output.mode === 'tags-split') {\n zodModule = nodePath.join(dirname, tag, tag + '.zod');\n contextModule = nodePath.join(dirname, tag, tag + '.context');\n } else {\n zodModule = nodePath.join(dirname, `${filename}.zod`);\n contextModule = nodePath.join(dirname, `${filename}.context`);\n }\n\n return {\n content: await generateHandlerFile({\n path,\n header,\n verbs: [verbOption],\n validatorModule,\n zodModule,\n contextModule,\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 ? nodePath.join(dirname, `${kebab(tag)}.handlers${extension}`)\n : nodePath.join(dirname, tag, tag + '.handlers' + extension);\n\n return {\n content: await generateHandlerFile({\n path: handlerPath,\n header,\n verbs,\n validatorModule,\n zodModule:\n output.mode === 'tags'\n ? nodePath.join(dirname, `${kebab(tag)}.zod`)\n : nodePath.join(dirname, tag, tag + '.zod'),\n contextModule:\n output.mode === 'tags'\n ? nodePath.join(dirname, `${kebab(tag)}.context`)\n : nodePath.join(dirname, tag, tag + '.context'),\n }),\n path: handlerPath,\n };\n }),\n );\n }\n\n // One file with all operations.\n const handlerPath = nodePath.join(\n dirname,\n `${filename}.handlers${extension}`,\n );\n\n return [\n {\n content: await generateHandlerFile({\n path: handlerPath,\n header,\n verbs: Object.values(verbOptions),\n validatorModule,\n zodModule: nodePath.join(dirname, `${filename}.zod`),\n contextModule: nodePath.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: OpenApiInfoObject) => string | string[]),\n info: OpenApiInfoObject,\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 getSpecInfo = (context: ContextSpec): OpenApiInfoObject =>\n context.spec.info ?? {\n title: 'API',\n version: '1.0.0',\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: ContextSpec,\n schemaModule: string,\n) => {\n const header = getHeader(output.override.header, getSpecInfo(context));\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 ? nodePath.join(dirname, `${kebab(tag)}.context${extension}`)\n : nodePath.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 = nodePath.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: ContextSpec,\n) => {\n const { extension, dirname, filename } = getFileInfo(output.target);\n\n const header = getHeader(output.override.header, getSpecInfo(context));\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(async (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 = new Map(\n zods.flatMap((z) => z.mutators ?? []).map((m) => [m.name, m]),\n )\n .values()\n .toArray();\n\n const mutatorsImports = generateMutatorImports({\n mutators: 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 ? nodePath.join(dirname, `${kebab(tag)}.zod${extension}`)\n : nodePath.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 builderContexts.filter((context) => context.content !== '');\n }\n\n const zods = await Promise.all(\n Object.values(verbOptions).map(async (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 = new Map(\n zods.flatMap((z) => z.mutators ?? []).map((m) => [m.name, m]),\n )\n .values()\n .toArray();\n\n const mutatorsImports = generateMutatorImports({\n mutators: allMutators,\n });\n\n let content = `${header}import { z as zod } from 'zod';\\n${mutatorsImports}\\n`;\n\n const zodPath = nodePath.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: ContextSpec,\n) => {\n const header = getHeader(output.override.header, getSpecInfo(context));\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 = nodePath.join(dirname, `${filename}.validator${extension}`);\n }\n\n return {\n content: `${header}${ZVALIDATOR_SOURCE}`,\n path: validatorPath,\n };\n};\n\nconst generateCompositeRoutes = (\n verbOptions: Record<string, GeneratorVerbOptions>,\n output: NormalizedOutputOptions,\n context: ContextSpec,\n) => {\n const targetInfo = getFileInfo(output.target);\n const compositeRouteInfo = getFileInfo(output.override.hono.compositeRoute);\n\n const header = getHeader(output.override.header, getSpecInfo(context));\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 nodePath.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 nodePath.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}${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 != undefined) {\n const schemasPath = (\n isObject(output.schemas) ? output.schemas.path : output.schemas\n ) as string;\n const basePath = getFileInfo(schemasPath).dirname;\n schemaModule = basePath;\n } else if (output.mode === 'single') {\n schemaModule = path;\n } else {\n schemaModule = `${pathWithoutExtension}.schemas`;\n }\n\n const contexts = generateContextFiles(\n verbOptions,\n output,\n context,\n schemaModule,\n );\n const compositeRoutes = output.override.hono.compositeRoute\n ? generateCompositeRoutes(verbOptions, output, context)\n : [];\n const [handlers, zods] = await Promise.all([\n generateHandlerFiles(verbOptions, output, context, validator.path),\n generateZodFiles(verbOptions, output, context),\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":";;;;;AAEA,MAAM,YAAY,SAA0B,oBAAoB,KAAK,KAAK;AAE1E,MAAM,gBAAgB,SAAyB;CAC7C,MAAM,UAAU,4BAA4B,KAAK,KAAK;AACtD,KAAI,CAAC,SAAS,OAAQ,QAAO;CAE7B,MAAM,OAAO,QAAQ;CACrB,MAAM,QAAQ,SAAS,QAAQ,IAAI;EACjC,YAAY;EACZ,YAAY;EACZ,MAAM;EACN,KAAK;EACN,CAAC;CACF,MAAM,OAAO,SAAS,QAAQ,GAAG,GAAG,aAAa,QAAQ,GAAG,GAAG,QAAQ;AAEvE,QAAO,SAAS,KAAK,GAAG,GAAG,KAAK,GAAG,QAAQ,SAAS,GAAG,OAAO,QAAQ;;AAGxE,MAAa,YAAY,UAAkB;CACzC,MAAM,gBAAgB,MAAM,MAAM,IAAI;CAEtC,IAAI,MAAM;AACV,MAAK,MAAM,CAAC,GAAG,SAAS,cAAc,SAAS,EAAE;AAC/C,MAAI,CAAC,QAAQ,MAAM,EAAG;AAEtB,SAAO,KAAK,SAAS,IAAI,GAAG,IAAI,aAAa,KAAK,KAAK,IAAI;;AAG7D,QAAO;;;;ACET,MAAM,oBAAoB,GACvB,aAAa,SAAS,KAAK,OAAO,KAAK,SAAS,gBAAgB,CAAC,CACjE,SAAS,OAAO;AAEnB,MAAM,oBAA2C,CAC/C;CACE,SAAS;EACP;GACE,MAAM;GACN,QAAQ;GACT;EACD,EACE,MAAM,WACP;EACD,EACE,MAAM,OACP;EACF;CACD,YAAY;CACb,CACF;;;;;;;;;;;;;;;AAgBD,MAAM,2BAA2B,MAAc,OAAe;AAC5D,KAAI,GAAG,WAAW,IAAI,IAAI,SAAS,WAAW,GAAG,CAC/C,QAAO,MACJ,sBAAsB,SAAS,QAAQ,KAAK,EAAE,SAAS,QAAQ,GAAG,EAAE,KAAK,CACzE,QAAQ,SAAS,GAAG;AAIzB,QAAO;;AAGT,MAAa,4BAA4B;AAEzC,MAAa,iBAAsC,EACjD,aACA,QACA,KACA,2BACI;CACJ,MAAM,aAAa,YAAY,OAAO,OAAO;CAE7C,IAAI;CAEJ,MAAM,iBAAiB,OAAO,OAAO,YAAY,CAAC,QAAQ,eACxD,qBAAqB,SAAS,GAAG,WAAW,cAAc,UAAU,CACrE;AAED,KAAI,OAAO,SAAS,KAAK,UAAU;EACjC,MAAM,kBAAkB,YAAY,OAAO,SAAS,KAAK,SAAS;AAClE,aAAW,eACR,KAAK,eAAe;GAInB,MAAM,aAAa,OAAO,SAAS;GACnC,MAAM,MAAM,MAAM,WAAW,KAAK,MAAM,UAAU;GAElD,MAAM,eAAe,MAAM,aACzB,SAAS,KAAK,WAAW,SAAS,aAAa,MAAM,GAAG,EACxD,SAAS,KACP,gBAAgB,SAChB,KAAK,WAAW,gBACjB,CACF;AAED,UAAO,YAAY,WAAW,cAAc,mBAAmB,aAAa;IAC5E,CACD,KAAK,KAAK;OAMb,YAAW,aAJgB,eACxB,KAAK,eAAe,IAAI,WAAW,cAAc,UAAU,CAC3D,KAAK,OAAO,CAE4B,cAAc,OAAO,WAAW,SAAS;AAGtF,QAAO,GAAG,SAAS;;AAGrB,MAAa,sBACX;AAEF,MAAM,qBACJ,EAAE,eAAe,QACjB,cACG;CACH,MAAM,OAAO,SAAS,UAAU;AAEhC,QAAO,QAAQ,KAAK,aAAa,CAAC,IAAI,KAAK,QAAQ,cAAc;;AAGnE,MAAa,gBAA+B,aAAa,YAAY;AACnE,KAAI,QAAQ,SAAS,KAAK,eACxB,QAAO;EACL,gBAAgB;EAChB,SAAS,EAAE;EACZ;AAKH,QAAO;EACL,gBAAgB,GAHU,kBAAkB,aAAa,QAAQ,UAAU,CAGpC;EACvC,SAAS;GACP,GAAG,YAAY,OAAO,SAAS,UAAU,MAAM,QAAQ;GACvD,GAAG,YAAY,KAAK;GACpB,GAAI,YAAY,cACZ,CACE,EACE,MAAM,YAAY,YAAY,OAAO,MACtC,CACF,GACD,EAAE;GACP;EACF;;;;;;AAOH,MAAM,uBAAuB;AAE7B,MAAM,mBACJ,GAAG,SAkBA;CACH,IAAI,OAAO;CACX,IAAI,gBAAgB;AAEpB,MAAK,MAAM,EACT,aACA,iBACA,YACA,WACA,kBACG,MAAM;EACT,IAAI,mBAAmB;AAEvB,MAAI,WAAW;GACb,MAAM,sBAAsB,OAAO,WAAW,cAAc;AAE5D,OAAI,WAAW,QACb,qBAAoB,wBAAwB,oBAAoB;AAElE,OAAI,WAAW,OAAO,SAAS,EAC7B,qBAAoB,uBAAuB,oBAAoB;AAEjE,OAAI,WAAW,YACb,qBAAoB,uBAAuB,oBAAoB;AAEjE,OAAI,WAAW,KAAK,WAClB,qBAAoB,sBAAsB,oBAAoB;AAEhE,OACE,cAAc,UACd,WAAW,SAAS,iBAAiB,QAAQ,UAE3C,oBAGF,qBAAoB,0BAA0B,oBAAoB;;AAMtE,UAAQ;eACG,YAAY;EACzB,iBAAiB,YAAY,gBAAgB,QAJ9B,gBAAgB,qBAI2B;;AAGxD,oBAAkB,qBAAqB;;AAGzC,QAAO,CAAC,MAAM,cAAc;;AAG9B,MAAM,wBACJ,aACA,YACA,oBACG;CACH,MAAM,aAAa,EAAE;AAErB,MAAK,MAAM,EACT,eACA,SACA,QACA,aACA,MACA,cACG,aAAa;EAChB,MAAM,sBAAsB,OAAO,cAAc;AAEjD,MAAI,QACF,YAAW,KAAK,GAAG,oBAAoB,QAAQ;AAGjD,MAAI,OAAO,SAAS,EAClB,YAAW,KAAK,GAAG,oBAAoB,QAAQ;AAGjD,MAAI,YACF,YAAW,KAAK,GAAG,oBAAoB,aAAa;AAGtD,MAAI,KAAK,WACP,YAAW,KAAK,GAAG,oBAAoB,MAAM;AAG/C,MACE,CAAC,mBAED,SAAS,iBAAiB,QAAQ,UAAU,uBAC1C,KAAA,EAEF,YAAW,KAAK,GAAG,oBAAoB,UAAU;;AAIrD,QAAO,WAAW,WAAW,IACzB,KACA,aAAa,WAAW,KAAK,MAAM,CAAC,YAAY,WAAW;;AAGjE,MAAM,2BACJ,gBACG;CACH,MAAM,UAAkD,EAAE;AAE1D,MAAK,MAAM,SAAS,OAAO,OAAO,YAAY,EAAE;EAC9C,MAAM,MAAM,MAAM,KAAK;AAIvB,MAAI,CAAC,QAAQ,KACX,SAAQ,OAAO,EAAE;AAEnB,UAAQ,KAAK,KAAK,MAAM;;AAG1B,QAAO;;AAGT,MAAM,sBAAsB,OAAO,EACjC,OACA,MACA,QACA,iBACA,WACA,oBAQI;CACJ,MAAM,YACJ,oBAAoB,wBACf,SACD,mBAAmB,KAAA;CAEzB,MAAM,WAAW,OAAO,OAAO,MAAM;CAErC,MAAM,GAAG,iBAAiB,gBACxB,GAAG,SAAS,KAAK,gBAAgB;EAC/B,aAAa,GAAG,WAAW,cAAc;EACzC,iBAAiB,GAAG,OAAO,WAAW,cAAc,CAAC;EACrD;EACA;EACD,EAAE,CACJ;CAED,MAAM,UAAU,CAAC,gDAAgD;AAEjE,KAAI,iBAAiB,mBAAmB,KAAA,EACtC,SAAQ,KACN,+BAA+B,wBAAwB,MAAM,gBAAgB,CAAC,IAC/E;AAGH,SAAQ,KACN,YAAY,SACT,KAAK,SAAS,GAAG,OAAO,KAAK,cAAc,CAAC,SAAS,CACrD,KAAK,MAAM,CAAC,WAAW,wBAAwB,MAAM,cAAc,CAAC,IACxE;AAED,KAAI,cACF,SAAQ,KACN,qBACE,UACA,wBAAwB,MAAM,UAAU,EACxC,oBAAoB,sBACrB,CACF;CAGH,MAAM,WAAW,GAAG,SAAS,QAAQ,QAAQ,QAAQ,QAAQ,GAAG,CAAC,KAAK,KAAK,CAAC;CAE5E,MAAM,iBAAiB,GAAG,WAAW,KAAK,GACtC,6BAA6B,MAAM,GAAG,SAAS,MAAM,OAAO,CAAC,mBAC7D,IAAI,KAAqB;CAO7B,MAAM,CAAC,eAAe,gBACpB,GAAG,SAAS,KAAK,gBAAgB;EAC/B,aAAa,GAAG,WAAW,cAAc;EACzC,iBAAiB,GAAG,OAAO,WAAW,cAAc,CAAC;EACrD;EACA;EACA,cAAc,eAAe,IAAI,GAAG,WAAW,cAAc,UAAU;EACxE,EAAE,CACJ;AAED,QAAO,GAAG,WAAW;;;;;;;;;;;;;;AAevB,MAAa,gCACX,WACwB;CACxB,MAAM,yBAAS,IAAI,KAAqB;CACxC,MAAM,cACJ;CAEF,IAAI;AACJ,SAAQ,QAAQ,YAAY,KAAK,OAAO,MAAM,MAAM;EAClD,MAAM,cAAc,MAAM;EAC1B,MAAM,cAAc,MAAM,QAAQ,MAAM,GAAG,SAAS;EACpD,MAAM,eAAe,kBAAkB,QAAQ,aAAa,KAAK,IAAI;AACrE,MAAI,iBAAiB,GAAI;EAGzB,MAAM,OAAO,sBADI,OAAO,MAAM,cAAc,GAAG,aAAa,CAChB;AAC5C,MAAI,SAAS,KAAA,EACX,QAAO,IAAI,aAAa,KAAK;;AAIjC,QAAO;;;;;;;;AAST,MAAM,qBACJ,QACA,SACA,MACA,UACW;CACX,IAAI,QAAQ;CACZ,IAAI,IAAI;AACR,QAAO,IAAI,OAAO,QAAQ;EACxB,MAAM,KAAK,OAAO;EAClB,MAAM,OAAO,OAAO,IAAI;AAGxB,MAAI,OAAO,OAAO,SAAS,KAAK;GAC9B,MAAM,KAAK,OAAO,QAAQ,MAAM,IAAI,EAAE;AACtC,OAAI,OAAO,KAAK,OAAO,SAAS,KAAK;AACrC;;AAGF,MAAI,OAAO,OAAO,SAAS,KAAK;GAC9B,MAAM,MAAM,OAAO,QAAQ,MAAM,IAAI,EAAE;AACvC,OAAI,QAAQ,KAAK,OAAO,SAAS,MAAM;AACvC;;AAGF,MAAI,OAAO,OAAO,OAAO,QAAO,OAAO,KAAK;AAC1C,OAAI,WAAW,QAAQ,GAAG,GAAG;AAC7B;;AAIF,MAAI,OAAO,OAAO,eAAe,QAAQ,EAAE,EAAE;AAC3C,OAAI,UAAU,QAAQ,EAAE;AACxB;;AAGF,MAAI,OAAO,KAAM;WACR,OAAO,OAAO;AACrB;AACA,OAAI,UAAU,EAAG,QAAO;;AAE1B;;AAEF,QAAO;;AAGT,MAAM,cACJ,QACA,OACA,UACW;CACX,IAAI,IAAI,QAAQ;AAChB,QAAO,IAAI,OAAO,QAAQ;EACxB,MAAM,KAAK,OAAO;AAClB,MAAI,OAAO,MAAM;AACf,QAAK;AACL;;AAEF,MAAI,UAAU,OAAO,OAAO,OAAO,OAAO,IAAI,OAAO,KAAK;GACxD,MAAM,MAAM,kBAAkB,QAAQ,IAAI,GAAG,KAAK,IAAI;AACtD,OAAI,QAAQ,KAAK,OAAO,SAAS,MAAM;AACvC;;AAEF,MAAI,OAAO,MAAO,QAAO,IAAI;AAC7B;;AAEF,QAAO,OAAO;;AAGhB,MAAM,aAAa,QAAgB,UAA0B;CAC3D,IAAI,IAAI,QAAQ;CAChB,IAAI,UAAU;AACd,QAAO,IAAI,OAAO,QAAQ;EACxB,MAAM,KAAK,OAAO;AAClB,MAAI,OAAO,MAAM;AACf,QAAK;AACL;;AAEF,MAAI,OAAO,IAAK,WAAU;WACjB,OAAO,IAAK,WAAU;WACtB,OAAO,OAAO,CAAC,SAAS;AAC/B;AACA,UAAO,IAAI,OAAO,UAAU,WAAW,KAAK,OAAO,GAAG,CAAE;AACxD,UAAO;;AAET,MAAI,OAAO,KAAM,QAAO,QAAQ;AAChC;;AAEF,QAAO,OAAO;;AAGhB,MAAM,2BAA2B,IAAI,IAAI;CACvC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD,CAAC;AAEF,MAAM,kBAAkB,QAAgB,aAA8B;CACpE,IAAI,IAAI,WAAW;AACnB,QACE,KAAK,MACJ,OAAO,OAAO,OAAO,OAAO,OAAO,OAAQ,OAAO,OAAO,MAE1D;AAEF,KAAI,IAAI,EAAG,QAAO;CAElB,MAAM,IAAI,OAAO;AAGjB,KAAI,MAAM,KAAK;AACb,MAAI,KAAK,KAAK,OAAO,IAAI,OAAO,OAAO,OAAO,IAAI,OAAO,IAAK,QAAO;AACrE,SAAO;;AAIT,KAAI,gBAAgB,KAAK,EAAE,EAAE;EAC3B,IAAI,IAAI;AACR,SAAO,KAAK,KAAK,gBAAgB,KAAK,OAAO,GAAG,CAAE;EAClD,MAAM,QAAQ,OAAO,MAAM,IAAI,GAAG,IAAI,EAAE;AACxC,SAAO,yBAAyB,IAAI,MAAM;;AAI5C,KAAI,MAAM,OAAO,MAAM,IAAK,QAAO;AAEnC,QAAO;;;;;;;;AAST,MAAM,yBAAyB,aAAyC;CAItE,IAAI,IAAI;CACR,IAAI,oBAAoB;AACxB,QAAO,IAAI,SAAS,QAAQ;EAC1B,MAAM,KAAK,SAAS;EACpB,MAAM,OAAO,SAAS,IAAI;AAE1B,MAAI,OAAO,OAAO,SAAS,KAAK;GAC9B,MAAM,KAAK,SAAS,QAAQ,MAAM,IAAI,EAAE;AACxC,OAAI,OAAO,KAAK,SAAS,SAAS,KAAK;AACvC;;AAEF,MAAI,OAAO,OAAO,SAAS,KAAK;GAC9B,MAAM,MAAM,SAAS,QAAQ,MAAM,IAAI,EAAE;AACzC,OAAI,QAAQ,KAAK,SAAS,SAAS,MAAM;AACzC;;AAEF,MAAI,OAAO,OAAO,OAAO,QAAO,OAAO,KAAK;AAC1C,OAAI,WAAW,UAAU,GAAG,GAAG;AAC/B;;AAEF,MAAI,OAAO,OAAO,eAAe,UAAU,EAAE,EAAE;AAC7C,OAAI,UAAU,UAAU,EAAE;AAC1B;;AAEF,MAAI,OAAO,OAAO,OAAO,KAAK;GAG5B,MAAM,MAAM,kBAAkB,UAAU,GAF3B,IACC,OAAO,MAAM,MAAM,IACsB;AACvD,OAAI,QAAQ,KAAK,SAAS,SAAS,MAAM;AACzC;;AAEF,MAAI,OAAO,OAAO,SAAS,KAAK;AAC9B,uBAAoB;AACpB,QAAK;AACL;;AAEF;;AAGF,KAAI,sBAAsB,GAAI,QAAO,KAAA;CAErC,IAAI,IAAI,oBAAoB;AAC5B,QAAO,IAAI,SAAS,UAAU,KAAK,KAAK,SAAS,GAAG,CAAE;AACtD,KAAI,SAAS,OAAO,IAAK,QAAO,KAAA;CAEhC,MAAM,WAAW,kBAAkB,UAAU,GAAG,KAAK,IAAI;AACzD,KAAI,aAAa,GAAI,QAAO,KAAA;AAE5B,QAAO,SAAS,MAAM,IAAI,GAAG,SAAS;;AAGxC,MAAM,uBAAuB,OAC3B,aACA,QACA,SACA,oBACG;CACH,MAAM,SAAS,UAAU,OAAO,SAAS,QAAQ,YAAY,QAAQ,CAAC;CACtE,MAAM,EAAE,WAAW,SAAS,aAAa,YAAY,OAAO,OAAO;AAMnE,KAAI,OAAO,SAAS,KAAK,SAEvB,QAAO,QAAQ,IACb,OAAO,OAAO,YAAY,CAAC,IAAI,OAAO,eAAe;EACnD,MAAM,MAAM,MAAM,WAAW,KAAK,MAAM,UAAU;EAElD,MAAM,OAAO,SAAS,KACpB,OAAO,SAAS,KAAK,YAAY,IACjC,KAAK,WAAW,kBAAkB,UACnC;EAID,IAAI;EACJ,IAAI;AACJ,MAAI,OAAO,SAAS,QAAQ;AAC1B,eAAY,SAAS,KAAK,SAAS,GAAG,MAAM,IAAI,CAAC,MAAM;AACvD,mBAAgB,SAAS,KAAK,SAAS,GAAG,MAAM,IAAI,CAAC,UAAU;aACtD,OAAO,SAAS,cAAc;AACvC,eAAY,SAAS,KAAK,SAAS,KAAK,MAAM,OAAO;AACrD,mBAAgB,SAAS,KAAK,SAAS,KAAK,MAAM,WAAW;SACxD;AACL,eAAY,SAAS,KAAK,SAAS,GAAG,SAAS,MAAM;AACrD,mBAAgB,SAAS,KAAK,SAAS,GAAG,SAAS,UAAU;;AAG/D,SAAO;GACL,SAAS,MAAM,oBAAoB;IACjC;IACA;IACA,OAAO,CAAC,WAAW;IACnB;IACA;IACA;IACD,CAAC;GACF;GACD;GACD,CACH;AAGH,KAAI,OAAO,SAAS,UAAU,OAAO,SAAS,cAAc;EAE1D,MAAM,cAAc,wBAAwB,YAAY;AAExD,SAAO,QAAQ,IACb,OAAO,QAAQ,YAAY,CAAC,IAAI,OAAO,CAAC,KAAK,WAAW;GACtD,MAAM,cACJ,OAAO,SAAS,SACZ,SAAS,KAAK,SAAS,GAAG,MAAM,IAAI,CAAC,WAAW,YAAY,GAC5D,SAAS,KAAK,SAAS,KAAK,MAAM,cAAc,UAAU;AAEhE,UAAO;IACL,SAAS,MAAM,oBAAoB;KACjC,MAAM;KACN;KACA;KACA;KACA,WACE,OAAO,SAAS,SACZ,SAAS,KAAK,SAAS,GAAG,MAAM,IAAI,CAAC,MAAM,GAC3C,SAAS,KAAK,SAAS,KAAK,MAAM,OAAO;KAC/C,eACE,OAAO,SAAS,SACZ,SAAS,KAAK,SAAS,GAAG,MAAM,IAAI,CAAC,UAAU,GAC/C,SAAS,KAAK,SAAS,KAAK,MAAM,WAAW;KACpD,CAAC;IACF,MAAM;IACP;IACD,CACH;;CAIH,MAAM,cAAc,SAAS,KAC3B,SACA,GAAG,SAAS,WAAW,YACxB;AAED,QAAO,CACL;EACE,SAAS,MAAM,oBAAoB;GACjC,MAAM;GACN;GACA,OAAO,OAAO,OAAO,YAAY;GACjC;GACA,WAAW,SAAS,KAAK,SAAS,GAAG,SAAS,MAAM;GACpD,eAAe,SAAS,KAAK,SAAS,GAAG,SAAS,UAAU;GAC7D,CAAC;EACF,MAAM;EACP,CACF;;AAGH,MAAM,cAAc,eAAqC;CACvD,IAAI,YAAY;AAChB,KAAI,WAAW,OAAO,SAAS,EAW7B,aAAY,cAVG,gBAAgB,WAAW,UAAU,CAAC,KAAK,SAAS;EACjE,MAAM,QAAQ,WAAW,OAAO,MAC7B,MAAM,EAAE,SAAS,SAAS,MAAM,KAAK,EAAE,EAAE,YAAY,MAAM,CAAC,CAC9D;EACD,MAAM,aAAa,OAAO,WAAW,MAAM,IAAI,CAAC;AAEhD,SAAO,EACL,YAAY,GAAG,OAFA,OAAO,YAAY,QAED,KAAK,IAAI,GAAG,cAC9C;GACD,CAEC,KAAK,aAAa,SAAS,WAAW,CACtC,KAAK,UAAU,CAAC;CAGrB,MAAM,YAAY,WAAW,cACzB,UAAU,WAAW,YAAY,OAAO,KAAK,KAC7C;CACJ,MAAM,WAAW,WAAW,KAAK,aAC7B,SAAS,WAAW,KAAK,WAAW,KACpC;CACJ,MAAM,QAAQ,CAAC,CAAC,aAAa,CAAC,CAAC,aAAa,CAAC,CAAC;AAE9C,QAAO,eAAe,OACpB,WAAW,cACZ,CAAC,6CAA6C,SAC7C,WAAW,UACZ,CAAC,GACA,QACI,aAAa,YAAY,YAAY,SAAS,aAAa,YAAY,YAAY,SAAS,QAC5F,GACL;;AAGH,MAAM,aACJ,QACA,SACW;AACX,KAAI,CAAC,OACH,QAAO;CAGT,MAAM,SAAS,OAAO,KAAK;AAE3B,QAAO,MAAM,QAAQ,OAAO,GAAG,MAAM,EAAE,aAAa,QAAQ,CAAC,GAAG;;AAGlE,MAAM,eAAe,YACnB,QAAQ,KAAK,QAAQ;CACnB,OAAO;CACP,SAAS;CACV;AAEH,MAAM,uBAAuB,EAC3B,MACA,OACA,mBAKI;CACJ,IAAI,UAAU;CAEd,MAAM,WAAW,MAAM,KAAK,SAAS,WAAW,KAAK,CAAC;CAEtD,MAAM,OAAO,IAAI,IACf,MACG,SAAS,SAAS;EACjB,MAAM,UAA6B,EAAE;AACrC,MAAI,KAAK,OAAO,SAAS,EACvB,SAAQ,KAAK,GAAG,KAAK,OAAO,SAAS,UAAU,MAAM,QAAQ,CAAC;AAGhE,MAAI,KAAK,YACP,SAAQ,KAAK,EACX,MAAM,KAAK,YAAY,OAAO,MAC/B,CAAC;AAGJ,MAAI,KAAK,KAAK,WACZ,SAAQ,KAAK,GAAG,KAAK,KAAK,QAAQ;AAGpC,SAAO;GACP,CACD,KAAK,QAAQ,IAAI,KAAK,CACtB,QAAQ,QAAQ,SAAS,MAAM,YAAY,QAAQ,SAAS,IAAI,CAAC,CAAC,CACtE;AAED,KAAI,SAAS,MAAM,YAAY,QAAQ,SAAS,eAAe,CAAC,EAAE;AAChE,aAAW,wBAAwB;AACnC,aAAW;;AAGb,KAAI,KAAK,OAAO,EACd,YAAW,kBAAkB,CAAC,GAAG,KAAK,CACnC,UAAU,CACV,KACC,QACD,CAAC,YAAY,wBAAwB,MAAM,aAAa,CAAC;AAG9D,YAAW,SAAS,KAAK,KAAK;AAE9B,QAAO;;AAGT,MAAM,wBACJ,aACA,QACA,SACA,iBACG;CACH,MAAM,SAAS,UAAU,OAAO,SAAS,QAAQ,YAAY,QAAQ,CAAC;CACtE,MAAM,EAAE,WAAW,SAAS,aAAa,YAAY,OAAO,OAAO;AAEnE,KAAI,OAAO,SAAS,UAAU,OAAO,SAAS,cAAc;EAC1D,MAAM,cAAc,wBAAwB,YAAY;AAExD,SAAO,OAAO,QAAQ,YAAY,CAAC,KAAK,CAAC,KAAK,WAAW;GACvD,MAAM,OACJ,OAAO,SAAS,SACZ,SAAS,KAAK,SAAS,GAAG,MAAM,IAAI,CAAC,UAAU,YAAY,GAC3D,SAAS,KAAK,SAAS,KAAK,MAAM,aAAa,UAAU;AAM/D,UAAO;IAAE,SAAS,GAAG,SALR,oBAAoB;KAC/B;KACA;KACc;KACf,CAAC;IACoC;IAAM;IAC5C;;CAGJ,MAAM,OAAO,SAAS,KAAK,SAAS,GAAG,SAAS,UAAU,YAAY;AAOtE,QAAO,CACL;EACE,SAAS,GAAG,SARH,oBAAoB;GAC/B,OAAO,OAAO,OAAO,YAAY;GACjC;GACc;GACf,CAAC;EAKE;EACD,CACF;;AAGH,MAAM,mBAAmB,OACvB,aACA,QACA,YACG;CACH,MAAM,EAAE,WAAW,SAAS,aAAa,YAAY,OAAO,OAAO;CAEnE,MAAM,SAAS,UAAU,OAAO,SAAS,QAAQ,YAAY,QAAQ,CAAC;AAEtE,KAAI,OAAO,SAAS,UAAU,OAAO,SAAS,cAAc;EAC1D,MAAM,cAAc,wBAAwB,YAAY;AAsDxD,UApDwB,MAAM,QAAQ,IACpC,OAAO,QAAQ,YAAY,CAAC,IAAI,OAAO,CAAC,KAAK,WAAW;GACtD,MAAM,OAAO,MAAM,QAAQ,IACzB,MAAM,IAAI,OAAO,eACf,YACE,YACA;IACE,OAAO,WAAW;IAClB,WAAW,WAAW;IACtB,UAAU,OAAO;IACjB;IACA,MAAM,OAAO;IACb,QAAQ,OAAO;IAChB,EACD,OAAO,OACR,CACF,CACF;AAED,OAAI,KAAK,OAAO,MAAM,EAAE,mBAAmB,GAAG,CAC5C,QAAO;IACL,SAAS;IACT,MAAM;IACP;GAaH,IAAI,UAAU,GAAG,OAAO,mCAJA,uBAAuB,EAC7C,UAPkB,IAAI,IACtB,KAAK,SAAS,MAAM,EAAE,YAAY,EAAE,CAAC,CAAC,KAAK,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC,CAC9D,CACE,QAAQ,CACR,SAAS,EAIX,CAAC,CAEyE;GAE3E,MAAM,UACJ,OAAO,SAAS,SACZ,SAAS,KAAK,SAAS,GAAG,MAAM,IAAI,CAAC,MAAM,YAAY,GACvD,SAAS,KAAK,SAAS,KAAK,MAAM,SAAS,UAAU;AAE3D,cAAW,KAAK,KAAK,QAAQ,IAAI,eAAe,CAAC,KAAK,KAAK;AAE3D,UAAO;IACL;IACA,MAAM;IACP;IACD,CACH,EAEsB,QAAQ,YAAY,QAAQ,YAAY,GAAG;;CAGpE,MAAM,OAAO,MAAM,QAAQ,IACzB,OAAO,OAAO,YAAY,CAAC,IAAI,OAAO,eACpC,YACE,YACA;EACE,OAAO,WAAW;EAClB,WAAW,WAAW;EACtB,UAAU,OAAO;EACjB;EACA,MAAM,OAAO;EACb,QAAQ,OAAO;EAChB,EACD,OAAO,OACR,CACF,CACF;CAYD,IAAI,UAAU,GAAG,OAAO,mCAJA,uBAAuB,EAC7C,UAPkB,IAAI,IACtB,KAAK,SAAS,MAAM,EAAE,YAAY,EAAE,CAAC,CAAC,KAAK,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC,CAC9D,CACE,QAAQ,CACR,SAAS,EAIX,CAAC,CAEyE;CAE3E,MAAM,UAAU,SAAS,KAAK,SAAS,GAAG,SAAS,MAAM,YAAY;AAErE,YAAW,KAAK,KAAK,QAAQ,IAAI,eAAe,CAAC,KAAK,KAAK;AAE3D,QAAO,CACL;EACE;EACA,MAAM;EACP,CACF;;AAGH,MAAM,sBACJ,QACA,YACG;CACH,MAAM,SAAS,UAAU,OAAO,SAAS,QAAQ,YAAY,QAAQ,CAAC;CAEtE,IAAI,gBAAgB,OAAO,SAAS,KAAK;AACzC,KAAI,CAAC,OAAO,SAAS,KAAK,qBAAqB;EAC7C,MAAM,EAAE,WAAW,SAAS,aAAa,YAAY,OAAO,OAAO;AAEnE,kBAAgB,SAAS,KAAK,SAAS,GAAG,SAAS,YAAY,YAAY;;AAG7E,QAAO;EACL,SAAS,GAAG,SAAS;EACrB,MAAM;EACP;;AAGH,MAAM,2BACJ,aACA,QACA,YACG;CACH,MAAM,aAAa,YAAY,OAAO,OAAO;CAC7C,MAAM,qBAAqB,YAAY,OAAO,SAAS,KAAK,eAAe;CAE3E,MAAM,SAAS,UAAU,OAAO,SAAS,QAAQ,YAAY,QAAQ,CAAC;CAEtE,MAAM,SAAS,OAAO,OAAO,YAAY,CACtC,KAAK,eAAe;AACnB,SAAO,kBAAkB,YAAY,WAAW,UAAU;GAC1D,CACD,KAAK,GAAG;CAEX,MAAM,iBAAiB,OAAO,OAAO,YAAY;CAEjD,IAAI;AACJ,KAAI,OAAO,SAAS,KAAK,UAAU;EACjC,MAAM,kBAAkB,YAAY,OAAO,SAAS,KAAK,SAAS;AAKlE,iCAJuB,eAAe,KACnC,eAAe,WAAW,cAC5B,CAGE,KAAK,kBAAkB;AAQtB,UAAO,YAPmB,GAAG,cAAc,UAON,WALhB,wBACnB,mBAAmB,MACnB,SAAS,KAAK,gBAAgB,SAAS,KAAK,gBAAgB,CAC7D,CAE4D;IAC7D,CACD,KAAK,KAAK;QACR;EACL,MAAM,OAAO,eAAe,KAAK,eAC/B,MAAM,WAAW,KAAK,MAAM,UAAU,CACvC;AAGD,iCAFmB,KAAK,QAAQ,GAAG,MAAM,KAAK,QAAQ,EAAE,KAAK,EAAE,CAG5D,KAAK,QAAQ;AAWZ,UAAO,aAVoB,eACxB,QAAQ,eAAe,WAAW,KAAK,OAAO,IAAI,CAClD,KAAK,eAAe,IAAI,WAAW,cAAc,UAAU,CAC3D,KAAK,OAAO,CAOwB,YALlB,wBACnB,mBAAmB,MACnB,SAAS,KAAK,WAAW,SAAS,IAAI,CACvC,CAE+D,GAAG,IAAI;IACvE,CACD,KAAK,KAAK;;AAaf,QAAO,CACL;EACE,SARY,GAAG,OAAA;EACnB,6BAA6B;;wBACR,OAAO;;;;EAOxB,MAAM,OAAO,SAAS,KAAK,kBAAkB;EAC9C,CACF;;AAGH,MAAa,qBAA8C,OACzD,aACA,QACA,YACG;CACH,MAAM,EAAE,MAAM,yBAAyB,YAAY,OAAO,OAAO;CACjE,MAAM,YAAY,mBAAmB,QAAQ,QAAQ;CACrD,IAAI;AAEJ,KAAI,OAAO,WAAW,KAAA,EAKpB,gBADiB,YAFf,SAAS,OAAO,QAAQ,GAAG,OAAO,QAAQ,OAAO,OAAO,QAEjB,CAAC;UAEjC,OAAO,SAAS,SACzB,gBAAe;KAEf,gBAAe,GAAG,qBAAqB;CAGzC,MAAM,WAAW,qBACf,aACA,QACA,SACA,aACD;CACD,MAAM,kBAAkB,OAAO,SAAS,KAAK,iBACzC,wBAAwB,aAAa,QAAQ,QAAQ,GACrD,EAAE;CACN,MAAM,CAAC,UAAU,QAAQ,MAAM,QAAQ,IAAI,CACzC,qBAAqB,aAAa,QAAQ,SAAS,UAAU,KAAK,EAClE,iBAAiB,aAAa,QAAQ,QAAQ,CAC/C,CAAC;AAEF,QAAO;EACL,GAAG;EACH,GAAG;EACH,GAAG;EACH,GAAI,OAAO,SAAS,KAAK,aACzB,OAAO,SAAS,KAAK,cAAc,SAC/B,CAAC,UAAU,GACX,EAAE;EACN,GAAG;EACJ;;AAGH,MAAM,oBAA6C;CACjD,QAAQ;CACR,cAAc;CACd,QAAQ;CACR,QAAQ;CACR,YAAY;CACb;AAED,MAAa,sBAAsB"}
|
package/dist/zValidator.ts
CHANGED
|
@@ -123,8 +123,10 @@ export const zValidator =
|
|
|
123
123
|
if (typeof hookResult === 'object' && hookResult != null) {
|
|
124
124
|
if (hookResult instanceof Response) {
|
|
125
125
|
c.res = new Response(hookResult.body, hookResult)
|
|
126
|
+
return
|
|
126
127
|
} else if ('response' in hookResult && hookResult.response instanceof Response) {
|
|
127
128
|
c.res = new Response(hookResult.response.body, hookResult.response)
|
|
129
|
+
return
|
|
128
130
|
}
|
|
129
131
|
}
|
|
130
132
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@orval/hono",
|
|
3
|
-
"version": "8.
|
|
3
|
+
"version": "8.10.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -35,8 +35,8 @@
|
|
|
35
35
|
"nuke": "rimraf .turbo dist node_modules"
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@orval/core": "8.
|
|
39
|
-
"@orval/zod": "8.
|
|
38
|
+
"@orval/core": "8.10.0",
|
|
39
|
+
"@orval/zod": "8.10.0",
|
|
40
40
|
"fs-extra": "^11.3.2",
|
|
41
41
|
"remeda": "^2.33.6"
|
|
42
42
|
},
|