@rcmade/hono-docs 1.0.1

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.
@@ -0,0 +1,464 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ var __create = Object.create;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __getProtoOf = Object.getPrototypeOf;
8
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") {
11
+ for (let key of __getOwnPropNames(from))
12
+ if (!__hasOwnProp.call(to, key) && key !== except)
13
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
+ }
15
+ return to;
16
+ };
17
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
18
+ // If the importer is in node compatibility mode or this is not an ESM
19
+ // file that has been converted to a CommonJS file using a Babel-
20
+ // compatible transform (i.e. "__esModule" has not been set), then set
21
+ // "default" to the CommonJS "module.exports" for node compatibility.
22
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
23
+ mod
24
+ ));
25
+
26
+ // src/cli/index.ts
27
+ var import_yargs = __toESM(require("yargs"));
28
+ var import_helpers = require("yargs/helpers");
29
+
30
+ // src/core/runGenerate.ts
31
+ var import_node_fs3 = __toESM(require("fs"));
32
+ var import_node_path3 = __toESM(require("path"));
33
+ var import_ts_morph3 = require("ts-morph");
34
+
35
+ // src/config/loadConfig.ts
36
+ var import_path = require("path");
37
+ var import_fs = require("fs");
38
+ var import_url = require("url");
39
+ var import_node = require("esbuild-register/dist/node");
40
+ async function loadConfig(configFile) {
41
+ const fullPath = (0, import_path.resolve)(process.cwd(), configFile);
42
+ if (!(0, import_fs.existsSync)(fullPath)) {
43
+ throw new Error(`[hono-docs] Config file not found: ${fullPath}`);
44
+ }
45
+ const ext = (0, import_path.extname)(fullPath);
46
+ let unregister = () => {
47
+ };
48
+ if (ext === ".ts" || ext === ".tsx" || ext === ".mts") {
49
+ const reg = (0, import_node.register)({
50
+ target: "es2020",
51
+ jsx: "automatic"
52
+ });
53
+ unregister = reg.unregister;
54
+ }
55
+ let configModule;
56
+ try {
57
+ if (ext === ".mjs" || ext === ".mts") {
58
+ configModule = await import((0, import_url.pathToFileURL)(fullPath).href);
59
+ } else {
60
+ configModule = require(fullPath);
61
+ }
62
+ } catch (err) {
63
+ unregister();
64
+ throw new Error(
65
+ `[hono-docs] Failed to load config: ${err instanceof Error ? err.message : String(err)}`
66
+ );
67
+ } finally {
68
+ unregister();
69
+ }
70
+ const config = configModule && typeof configModule === "object" && "default" in configModule ? (
71
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
72
+ configModule.default
73
+ ) : configModule;
74
+ if (!config || typeof config !== "object") {
75
+ throw new Error(
76
+ `[hono-docs] Invalid config file. Expected an object, got: ${typeof config}`
77
+ );
78
+ }
79
+ return config;
80
+ }
81
+
82
+ // src/core/generateTypes.ts
83
+ var import_node_fs = __toESM(require("fs"));
84
+ var import_node_path = __toESM(require("path"));
85
+
86
+ // src/utils/format.ts
87
+ function sanitizeApiPrefix(prefix) {
88
+ return prefix.replace(/^\//, "").split(/[^a-z0-9]+/i).filter(Boolean).map(
89
+ (seg, i) => i === 0 ? seg.toLowerCase() : seg[0].toUpperCase() + seg.slice(1).toLowerCase()
90
+ ).join("");
91
+ }
92
+ function unwrapUnion(type) {
93
+ return type.isUnion() ? type.getUnionTypes() : [type];
94
+ }
95
+ function normalizeImportPaths(typeText) {
96
+ return typeText.replace(/from ["'].*node_modules\/(.*)["']/g, `from "$1"`);
97
+ }
98
+ function cleanDefaultResponse(operation, pathKey, method) {
99
+ var _a;
100
+ const defaultResponse = (_a = operation.responses) == null ? void 0 : _a.default;
101
+ if (!defaultResponse) return;
102
+ const desc = defaultResponse.description ?? "";
103
+ if (desc.includes("import(")) {
104
+ const content = defaultResponse.content;
105
+ if (content && Object.keys(content).length > 0) {
106
+ defaultResponse.description = "Default fallback response";
107
+ console.log(
108
+ `\u2139\uFE0F Cleaned 'default' description in ${method.toUpperCase()} ${pathKey}`
109
+ );
110
+ } else {
111
+ delete operation.responses.default;
112
+ console.log(
113
+ `\u{1F5D1}\uFE0F Removed empty 'default' in ${method.toUpperCase()} ${pathKey}`
114
+ );
115
+ }
116
+ }
117
+ }
118
+ function groupBy(arr, fn) {
119
+ return arr.reduce((acc, x) => {
120
+ (acc[fn(x)] ||= []).push(x);
121
+ return acc;
122
+ }, {});
123
+ }
124
+
125
+ // src/core/generateTypes.ts
126
+ async function generateTypes({
127
+ config,
128
+ project,
129
+ rootPath,
130
+ apiGroup,
131
+ fileName,
132
+ outputRoot
133
+ }) {
134
+ import_node_fs.default.mkdirSync(outputRoot, { recursive: true });
135
+ const outputPath = import_node_path.default.join(outputRoot, `${fileName}.d.ts`);
136
+ const absInput = import_node_path.default.resolve(rootPath, apiGroup.appTypePath);
137
+ const sourceFile = project.addSourceFileAtPath(absInput);
138
+ const typeAliases = sourceFile.getTypeAliases();
139
+ const interfaces = sourceFile.getInterfaces();
140
+ let result = `// AUTO-GENERATED from ${apiGroup.appTypePath}
141
+
142
+ `;
143
+ typeAliases.forEach((alias) => {
144
+ const raw = alias.getType().getText(alias);
145
+ const clean = normalizeImportPaths(raw);
146
+ result += `export type ${alias.getName()} = ${clean};
147
+
148
+ `;
149
+ });
150
+ interfaces.forEach((intf) => {
151
+ result += intf.getText() + "\n\n";
152
+ });
153
+ const preContent = config.preDefineTypeContent || "";
154
+ import_node_fs.default.writeFileSync(outputPath, `${preContent}
155
+ ${result}`, "utf-8");
156
+ console.log(`\u2705 Wrote: ${outputPath}`);
157
+ return { appTypePath: outputPath, name: fileName };
158
+ }
159
+
160
+ // src/core/generateOpenApi.ts
161
+ var import_node_fs2 = __toESM(require("fs"));
162
+ var import_node_path2 = __toESM(require("path"));
163
+ var import_ts_morph2 = require("ts-morph");
164
+
165
+ // src/utils/buildSchema.ts
166
+ var import_ts_morph = require("ts-morph");
167
+ function buildSchema(type) {
168
+ var _a;
169
+ if (type.isUnion()) {
170
+ const members = type.getUnionTypes();
171
+ const lits = members.filter((u) => u.isStringLiteral());
172
+ const onlyNull = members.every(
173
+ (u) => u.isStringLiteral() || u.isNull() || u.isUndefined()
174
+ );
175
+ if (lits.length && onlyNull) {
176
+ const schema = {
177
+ type: "string",
178
+ enum: lits.map((u) => u.getLiteralValue())
179
+ };
180
+ if (members.some((u) => u.isNull() || u.isUndefined()))
181
+ schema.nullable = true;
182
+ return schema;
183
+ }
184
+ const nonNull = members.filter((u) => !u.isNull() && !u.isUndefined());
185
+ return { oneOf: nonNull.map(buildSchema) };
186
+ }
187
+ if (type.isString()) return { type: "string" };
188
+ if (type.isNumber()) return { type: "number" };
189
+ if (type.isBoolean()) return { type: "boolean" };
190
+ if (type.isArray()) {
191
+ return {
192
+ type: "array",
193
+ items: buildSchema(type.getArrayElementTypeOrThrow())
194
+ };
195
+ }
196
+ const decls = ((_a = type.getSymbol()) == null ? void 0 : _a.getDeclarations()) || [];
197
+ const isLit = decls.some(
198
+ (d) => d.getKind() === import_ts_morph.SyntaxKind.TypeLiteral || d.getKind() === import_ts_morph.SyntaxKind.InterfaceDeclaration
199
+ );
200
+ if (!isLit) return {};
201
+ const props = type.getProperties().filter(
202
+ (p) => {
203
+ var _a2;
204
+ return ((_a2 = p.getValueDeclaration()) == null ? void 0 : _a2.getKind()) === import_ts_morph.SyntaxKind.PropertySignature;
205
+ }
206
+ );
207
+ const propsMap = {};
208
+ const req = [];
209
+ for (const p of props) {
210
+ const decl = p.getValueDeclarationOrThrow();
211
+ propsMap[p.getName()] = buildSchema(decl.getType());
212
+ if (!p.isOptional()) req.push(p.getName());
213
+ }
214
+ const res = { type: "object", properties: propsMap };
215
+ if (req.length) res.required = req;
216
+ return res;
217
+ }
218
+
219
+ // src/utils/parameters.ts
220
+ function genParameters(type) {
221
+ var _a;
222
+ const input = (_a = type.getProperty("input")) == null ? void 0 : _a.getValueDeclarationOrThrow().getType();
223
+ if (!input) return [];
224
+ const sources = ["query", "param", "header", "cookie"];
225
+ const params = [];
226
+ for (const src of sources) {
227
+ const p = input.getProperty(src);
228
+ if (!p) continue;
229
+ const srcType = p.getValueDeclarationOrThrow().getType();
230
+ for (const f of srcType.getProperties()) {
231
+ const ft = f.getValueDeclarationOrThrow().getType();
232
+ params.push({
233
+ name: f.getName(),
234
+ in: src === "param" ? "path" : src,
235
+ required: !f.isOptional(),
236
+ schema: buildSchema(ft)
237
+ });
238
+ }
239
+ }
240
+ return params;
241
+ }
242
+
243
+ // src/utils/requestBody.ts
244
+ function genRequestBody(type) {
245
+ var _a;
246
+ const inp = (_a = type.getProperty("input")) == null ? void 0 : _a.getValueDeclarationOrThrow().getType();
247
+ if (!inp) return null;
248
+ const content = {};
249
+ const j = inp.getProperty("json");
250
+ if (j) {
251
+ content["application/json"] = {
252
+ schema: buildSchema(j.getValueDeclarationOrThrow().getType())
253
+ };
254
+ }
255
+ const f = inp.getProperty("form");
256
+ if (f) {
257
+ content["multipart/form-data"] = {
258
+ schema: buildSchema(f.getValueDeclarationOrThrow().getType())
259
+ };
260
+ }
261
+ return Object.keys(content).length ? { required: true, content } : null;
262
+ }
263
+
264
+ // src/core/generateOpenApi.ts
265
+ async function generateOpenApi({
266
+ config,
267
+ snapshotPath,
268
+ fileName,
269
+ project,
270
+ rootPath,
271
+ outputRoot
272
+ }) {
273
+ const sf = project.addSourceFileAtPath(
274
+ import_node_path2.default.resolve(rootPath, snapshotPath.appTypePath)
275
+ );
276
+ const aliasDecl = sf.getTypeAliasOrThrow("AppType");
277
+ const topTypeNode = aliasDecl.getTypeNode();
278
+ let typeArgs;
279
+ if (topTypeNode == null ? void 0 : topTypeNode.isKind(import_ts_morph2.SyntaxKind.TypeReference)) {
280
+ typeArgs = topTypeNode.getTypeArguments();
281
+ } else if (topTypeNode == null ? void 0 : topTypeNode.isKind(import_ts_morph2.SyntaxKind.ImportType)) {
282
+ typeArgs = topTypeNode.getTypeArguments();
283
+ } else {
284
+ throw new Error("AppType must be an ImportType or a TypeReference");
285
+ }
286
+ if (typeArgs.length < 2) {
287
+ throw new Error("Expected two type arguments on HonoBase");
288
+ }
289
+ const routesNode = typeArgs[1];
290
+ const literals = [];
291
+ if (routesNode.isKind(import_ts_morph2.SyntaxKind.IntersectionType)) {
292
+ for (const tn of routesNode.asKind(import_ts_morph2.SyntaxKind.IntersectionType).getTypeNodes()) {
293
+ if (tn.isKind(import_ts_morph2.SyntaxKind.TypeLiteral))
294
+ literals.push(tn);
295
+ }
296
+ } else if (routesNode.isKind(import_ts_morph2.SyntaxKind.TypeLiteral)) {
297
+ literals.push(routesNode);
298
+ } else {
299
+ throw new Error("Routes type is not a literal or intersection of literals");
300
+ }
301
+ const paths = {};
302
+ for (const lit of literals) {
303
+ for (const member of lit.getMembers()) {
304
+ if (!member.isKind(import_ts_morph2.SyntaxKind.PropertySignature)) continue;
305
+ const routeProp = member.asKindOrThrow(import_ts_morph2.SyntaxKind.PropertySignature);
306
+ const raw = routeProp.getNameNode().getText().replace(/"/g, "");
307
+ const route = raw.replace(/:([^/]+)/g, "{$1}");
308
+ if (!paths[route]) paths[route] = {};
309
+ const tn = routeProp.getTypeNode();
310
+ if (!tn || !tn.isKind(import_ts_morph2.SyntaxKind.TypeLiteral)) continue;
311
+ const rhs = tn;
312
+ for (const m of rhs.getMembers()) {
313
+ if (!m.isKind(import_ts_morph2.SyntaxKind.PropertySignature)) continue;
314
+ const methodProp = m.asKindOrThrow(import_ts_morph2.SyntaxKind.PropertySignature);
315
+ const name = methodProp.getNameNode().getText();
316
+ const http = name.slice(1).toLowerCase();
317
+ const variants = unwrapUnion(methodProp.getType());
318
+ const op = {
319
+ summary: `Auto-generated ${http.toUpperCase()} ${route}`
320
+ };
321
+ const params = genParameters(variants[0]);
322
+ if (params.length) op.parameters = params;
323
+ const rb = genRequestBody(variants[0]);
324
+ if (rb) op.requestBody = rb;
325
+ op.responses = {};
326
+ const byStatus = groupBy(variants, (v) => {
327
+ const s = v.getProperty("status").getValueDeclarationOrThrow().getType().getText();
328
+ return /^\d+$/.test(s) ? s : "default";
329
+ });
330
+ for (const [code, vs] of Object.entries(byStatus)) {
331
+ const schemas = vs.map(
332
+ (v) => buildSchema(
333
+ v.getProperty("output").getValueDeclarationOrThrow().getType()
334
+ )
335
+ );
336
+ const schema = schemas.length > 1 ? { oneOf: schemas } : schemas[0];
337
+ op.responses[code] = {
338
+ description: code === "default" ? `Generic status from ${vs[0].getProperty("status").getValueDeclarationOrThrow().getType().getText()}` : `Status ${code}`,
339
+ content: { "application/json": { schema } }
340
+ };
341
+ }
342
+ paths[route][http] = op;
343
+ }
344
+ }
345
+ }
346
+ const spec = {
347
+ ...config.openApi,
348
+ paths
349
+ };
350
+ const outputPath = import_node_path2.default.join(outputRoot, `${fileName}.json`);
351
+ import_node_fs2.default.mkdirSync(import_node_path2.default.dirname(outputPath), { recursive: true });
352
+ import_node_fs2.default.writeFileSync(outputPath, JSON.stringify(spec, null, 2), "utf-8");
353
+ console.log(`\u2705 OpenAPI written to ${outputPath}`);
354
+ return { openApiPath: outputPath };
355
+ }
356
+
357
+ // src/core/runGenerate.ts
358
+ async function runGenerate(configPath) {
359
+ const config = await loadConfig(configPath);
360
+ const rootPath = process.cwd();
361
+ console.log("Initializing ts-morph with tsConfig:", config.tsConfigPath);
362
+ const project = new import_ts_morph3.Project({
363
+ tsConfigFilePath: (0, import_node_path3.resolve)(rootPath, config.tsConfigPath)
364
+ });
365
+ const isDevMode = __dirname.includes("/src/") || __dirname.includes("\\src\\");
366
+ const libDir = isDevMode ? import_node_path3.default.resolve(__dirname, "../../") : import_node_path3.default.dirname(require.resolve("@rcmade/hono-docs/package.json"));
367
+ const apis = config.apis;
368
+ const snapshotOutputRoot = import_node_path3.default.resolve(libDir, "output/types");
369
+ const openAPiOutputRoot = import_node_path3.default.resolve(libDir, "output/openapi");
370
+ const commonParams = {
371
+ config,
372
+ libDir,
373
+ project,
374
+ rootPath
375
+ };
376
+ for (const apiGroup of apis) {
377
+ const sanitizedName = sanitizeApiPrefix(apiGroup.apiPrefix);
378
+ const snapshotPath = await generateTypes({
379
+ ...commonParams,
380
+ apiGroup,
381
+ fileName: sanitizedName,
382
+ outputRoot: snapshotOutputRoot
383
+ });
384
+ await generateOpenApi({
385
+ snapshotPath,
386
+ ...commonParams,
387
+ fileName: sanitizedName,
388
+ outputRoot: openAPiOutputRoot
389
+ });
390
+ }
391
+ const merged = {
392
+ ...config.openApi,
393
+ tags: [],
394
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
395
+ paths: {}
396
+ };
397
+ for (const apiGroup of apis) {
398
+ const name = sanitizeApiPrefix(apiGroup.apiPrefix);
399
+ const openApiFile = import_node_path3.default.join(openAPiOutputRoot, `${name}.json`);
400
+ if (!import_node_fs3.default.existsSync(openApiFile)) {
401
+ console.warn(`\u26A0\uFE0F Missing OpenAPI file: ${openApiFile}`);
402
+ continue;
403
+ }
404
+ const json = JSON.parse(import_node_fs3.default.readFileSync(openApiFile, "utf-8"));
405
+ merged.tags.push({ name: apiGroup.name });
406
+ const customApiMap = /* @__PURE__ */ new Map();
407
+ if (apiGroup == null ? void 0 : apiGroup.api) {
408
+ for (const customApi of apiGroup.api) {
409
+ const fullPath = import_node_path3.default.posix.join(apiGroup.apiPrefix, customApi.api).replace(/\/+$/, "") || "/";
410
+ customApiMap.set(
411
+ `${customApi.method.toLowerCase()} ${fullPath}`,
412
+ customApi
413
+ );
414
+ }
415
+ }
416
+ for (const [pathKey, operations] of Object.entries(json.paths)) {
417
+ const prefixedPath = import_node_path3.default.posix.join(apiGroup.apiPrefix, pathKey).replace(/\/+$/, "") || "/";
418
+ if (!merged.paths[prefixedPath]) merged.paths[prefixedPath] = {};
419
+ for (const [method, operation] of Object.entries(operations)) {
420
+ const opKey = `${method.toLowerCase()} ${prefixedPath}`;
421
+ const customApi = customApiMap.get(opKey);
422
+ if (customApi) {
423
+ operation.summary = customApi.summery || operation.summary;
424
+ operation.description = customApi.description || operation.description;
425
+ operation.tags = customApi.tag && customApi.tag.length > 0 ? customApi.tag : [apiGroup.name];
426
+ } else {
427
+ operation.tags = operation.tags || [];
428
+ if (!operation.tags.includes(apiGroup.name)) {
429
+ operation.tags.push(apiGroup.name);
430
+ }
431
+ }
432
+ cleanDefaultResponse(operation, prefixedPath, method);
433
+ merged.paths[prefixedPath][method] = operation;
434
+ }
435
+ }
436
+ }
437
+ const outputPath = import_node_path3.default.join(rootPath, config.outputs.openApiJson);
438
+ import_node_fs3.default.mkdirSync(import_node_path3.default.dirname(outputPath), { recursive: true });
439
+ import_node_fs3.default.writeFileSync(outputPath, `${JSON.stringify(merged, null, 2)}
440
+ `);
441
+ console.log(`\u2705 Final merged OpenAPI spec written to: ${outputPath}`);
442
+ }
443
+
444
+ // src/cli/index.ts
445
+ (0, import_yargs.default)((0, import_helpers.hideBin)(process.argv)).scriptName("hono-docs").command(
446
+ "generate",
447
+ "Generate OpenAPI JSON",
448
+ (y) => y.option("config", {
449
+ alias: "c",
450
+ type: "string",
451
+ describe: "Path to config file",
452
+ demandOption: true,
453
+ default: "./hono-docs.ts"
454
+ }),
455
+ async (argv) => {
456
+ try {
457
+ await runGenerate(argv.config);
458
+ } catch (e) {
459
+ console.error("\u274C", e);
460
+ process.exit(1);
461
+ }
462
+ }
463
+ ).demandCommand(1).help().parse();
464
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/cli/index.ts","../../src/core/runGenerate.ts","../../src/config/loadConfig.ts","../../src/core/generateTypes.ts","../../src/utils/format.ts","../../src/core/generateOpenApi.ts","../../src/utils/buildSchema.ts","../../src/utils/parameters.ts","../../src/utils/requestBody.ts"],"sourcesContent":["#!/usr/bin/env node\nimport yargs from \"yargs\";\nimport { hideBin } from \"yargs/helpers\";\nimport { runGenerate } from \"../core\";\n\nyargs(hideBin(process.argv))\n .scriptName(\"hono-docs\")\n .command(\n \"generate\",\n \"Generate OpenAPI JSON\",\n (y) =>\n y.option(\"config\", {\n alias: \"c\",\n type: \"string\",\n describe: \"Path to config file\",\n demandOption: true,\n default: \"./hono-docs.ts\",\n }),\n async (argv) => {\n try {\n await runGenerate(argv.config);\n } catch (e) {\n console.error(\"❌\", e);\n process.exit(1);\n }\n }\n )\n .demandCommand(1)\n .help()\n .parse();\n","import fs from \"node:fs\";\nimport path, { resolve } from \"node:path\";\nimport { Project } from \"ts-morph\";\nimport { loadConfig } from \"../config/loadConfig\";\nimport { generateTypes } from \"./generateTypes\";\nimport { generateOpenApi } from \"./generateOpenApi\";\nimport { Api } from \"../types\";\nimport { cleanDefaultResponse, sanitizeApiPrefix } from \"../utils/format\";\n\nexport async function runGenerate(configPath: string) {\n const config = await loadConfig(configPath);\n\n const rootPath = process.cwd();\n console.log(\"Initializing ts-morph with tsConfig:\", config.tsConfigPath);\n const project = new Project({\n tsConfigFilePath: resolve(rootPath, config.tsConfigPath),\n });\n\n const isDevMode =\n __dirname.includes(\"/src/\") || __dirname.includes(\"\\\\src\\\\\");\n\n const libDir = isDevMode\n ? path.resolve(__dirname, \"../../\")\n : path.dirname(require.resolve(\"@rcmade/hono-docs/package.json\"));\n\n const apis = config.apis;\n\n const snapshotOutputRoot = path.resolve(libDir, \"output/types\");\n const openAPiOutputRoot = path.resolve(libDir, \"output/openapi\");\n\n const commonParams = {\n config,\n libDir,\n project,\n rootPath,\n };\n for (const apiGroup of apis) {\n const sanitizedName = sanitizeApiPrefix(apiGroup.apiPrefix);\n\n const snapshotPath = await generateTypes({\n ...commonParams,\n apiGroup: apiGroup,\n fileName: sanitizedName,\n outputRoot: snapshotOutputRoot,\n });\n\n await generateOpenApi({\n snapshotPath,\n ...commonParams,\n fileName: sanitizedName,\n outputRoot: openAPiOutputRoot,\n });\n }\n\n const merged = {\n ...config.openApi,\n tags: [] as { name: string }[],\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n paths: {} as Record<string, any>,\n };\n\n for (const apiGroup of apis) {\n const name = sanitizeApiPrefix(apiGroup.apiPrefix);\n const openApiFile = path.join(openAPiOutputRoot, `${name}.json`);\n\n if (!fs.existsSync(openApiFile)) {\n console.warn(`⚠️ Missing OpenAPI file: ${openApiFile}`);\n continue;\n }\n\n const json = JSON.parse(fs.readFileSync(openApiFile, \"utf-8\"));\n merged.tags.push({ name: apiGroup.name });\n\n const customApiMap = new Map<string, Api>();\n\n if (apiGroup?.api) {\n for (const customApi of apiGroup.api) {\n const fullPath =\n path.posix\n .join(apiGroup.apiPrefix, customApi.api)\n .replace(/\\/+$/, \"\") || \"/\";\n customApiMap.set(\n `${customApi.method.toLowerCase()} ${fullPath}`,\n customApi\n );\n }\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n for (const [pathKey, operations] of Object.entries<any>(json.paths)) {\n const prefixedPath =\n path.posix.join(apiGroup.apiPrefix, pathKey).replace(/\\/+$/, \"\") || \"/\";\n if (!merged.paths[prefixedPath]) merged.paths[prefixedPath] = {};\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n for (const [method, operation] of Object.entries<any>(operations)) {\n const opKey = `${method.toLowerCase()} ${prefixedPath}`;\n const customApi = customApiMap.get(opKey);\n\n // Override or enrich metadata if defined\n if (customApi) {\n operation.summary = customApi.summery || operation.summary;\n operation.description =\n customApi.description || operation.description;\n operation.tags =\n customApi.tag && customApi.tag.length > 0\n ? customApi.tag\n : [apiGroup.name];\n } else {\n operation.tags = operation.tags || [];\n if (!operation.tags.includes(apiGroup.name)) {\n operation.tags.push(apiGroup.name);\n }\n }\n\n cleanDefaultResponse(operation, prefixedPath, method);\n merged.paths[prefixedPath][method] = operation;\n }\n }\n }\n\n const outputPath = path.join(rootPath, config.outputs.openApiJson);\n fs.mkdirSync(path.dirname(outputPath), { recursive: true });\n\n fs.writeFileSync(outputPath, `${JSON.stringify(merged, null, 2)}\\n`);\n\n console.log(`✅ Final merged OpenAPI spec written to: ${outputPath}`);\n}\n","import { resolve, extname } from \"path\";\nimport { existsSync } from \"fs\";\nimport { pathToFileURL } from \"url\";\nimport { register } from \"esbuild-register/dist/node\";\nimport type { HonoDocsConfig } from \"../types\";\n\nexport async function loadConfig(configFile: string): Promise<HonoDocsConfig> {\n // 1. Resolve absolute path\n const fullPath = resolve(process.cwd(), configFile);\n\n if (!existsSync(fullPath)) {\n throw new Error(`[hono-docs] Config file not found: ${fullPath}`);\n }\n\n // 2. Detect file extension\n const ext = extname(fullPath);\n let unregister = () => {};\n\n // 3. Register TS transpiler if needed\n if (ext === \".ts\" || ext === \".tsx\" || ext === \".mts\") {\n const reg = register({\n target: \"es2020\",\n jsx: \"automatic\",\n });\n unregister = reg.unregister;\n }\n\n // 4. Dynamically load the config\n let configModule: unknown;\n\n try {\n if (ext === \".mjs\" || ext === \".mts\") {\n // ESM config\n configModule = await import(pathToFileURL(fullPath).href);\n } else {\n // Use require with esbuild-register hook for .ts/.js\n configModule = require(fullPath);\n }\n } catch (err) {\n unregister();\n throw new Error(\n `[hono-docs] Failed to load config: ${\n err instanceof Error ? err.message : String(err)\n }`\n );\n } finally {\n unregister();\n }\n\n // 5. Handle default or named export\n const config =\n configModule &&\n typeof configModule === \"object\" &&\n \"default\" in configModule\n ? // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (configModule as any).default\n : configModule;\n\n if (!config || typeof config !== \"object\") {\n throw new Error(\n `[hono-docs] Invalid config file. Expected an object, got: ${typeof config}`\n );\n }\n\n return config as HonoDocsConfig;\n}\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport type { ApiGroup, GenerateParams } from \"../types\";\nimport { normalizeImportPaths } from \"../utils/format\";\n\nexport async function generateTypes({\n config,\n project,\n rootPath,\n apiGroup,\n fileName,\n outputRoot,\n}: GenerateParams & { apiGroup: ApiGroup }) {\n fs.mkdirSync(outputRoot, { recursive: true });\n\n const outputPath = path.join(outputRoot, `${fileName}.d.ts`);\n const absInput = path.resolve(rootPath, apiGroup.appTypePath);\n\n const sourceFile = project.addSourceFileAtPath(absInput);\n const typeAliases = sourceFile.getTypeAliases();\n const interfaces = sourceFile.getInterfaces();\n\n let result = `// AUTO-GENERATED from ${apiGroup.appTypePath}\\n\\n`;\n\n typeAliases.forEach((alias) => {\n const raw = alias.getType().getText(alias);\n const clean = normalizeImportPaths(raw);\n result += `export type ${alias.getName()} = ${clean};\\n\\n`;\n });\n\n interfaces.forEach((intf) => {\n result += intf.getText() + \"\\n\\n\";\n });\n\n const preContent = config.preDefineTypeContent || \"\";\n\n fs.writeFileSync(outputPath, `${preContent}\\n${result}`, \"utf-8\");\n console.log(`✅ Wrote: ${outputPath}`);\n return { appTypePath: outputPath, name: fileName };\n}\n","export function sanitizeApiPrefix(prefix: string): string {\n return prefix\n .replace(/^\\//, \"\")\n .split(/[^a-z0-9]+/i)\n .filter(Boolean)\n .map((seg, i) =>\n i === 0\n ? seg.toLowerCase()\n : seg[0].toUpperCase() + seg.slice(1).toLowerCase()\n )\n .join(\"\");\n}\n\nexport function unwrapUnion(\n type: import(\"ts-morph\").Type\n): import(\"ts-morph\").Type[] {\n return type.isUnion() ? type.getUnionTypes() : [type];\n}\n\nexport function normalizeImportPaths(typeText: string): string {\n return typeText.replace(/from [\"'].*node_modules\\/(.*)[\"']/g, `from \"$1\"`);\n}\n\nexport function cleanDefaultResponse(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n operation: any,\n pathKey: string,\n method: string\n) {\n const defaultResponse = operation.responses?.default;\n if (!defaultResponse) return;\n\n const desc = defaultResponse.description ?? \"\";\n\n if (desc.includes(\"import(\")) {\n const content = defaultResponse.content;\n\n if (content && Object.keys(content).length > 0) {\n defaultResponse.description = \"Default fallback response\";\n console.log(\n `ℹ️ Cleaned 'default' description in ${method.toUpperCase()} ${pathKey}`\n );\n } else {\n delete operation.responses.default;\n console.log(\n `🗑️ Removed empty 'default' in ${method.toUpperCase()} ${pathKey}`\n );\n }\n }\n}\n\n\nexport function groupBy<T>(\n arr: T[],\n fn: (x: T) => string\n): Record<string, T[]> {\n return arr.reduce((acc, x) => {\n (acc[fn(x)] ||= []).push(x);\n return acc;\n }, {} as Record<string, T[]>);\n}\n","// src/core/generateOpenApi.ts\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport {\n SyntaxKind,\n TypeLiteralNode,\n ImportTypeNode,\n TypeReferenceNode,\n TypeNode,\n ts,\n} from \"ts-morph\";\nimport type {\n AppTypeSnapshotPath,\n GenerateParams,\n OpenApiPath,\n} from \"../types\";\nimport { genParameters } from \"../utils/parameters\";\nimport { genRequestBody } from \"../utils/requestBody\";\nimport { buildSchema } from \"../utils/buildSchema\";\nimport { groupBy, unwrapUnion } from \"../utils/format\";\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype OpenAPI = Record<string, any>;\n\nexport async function generateOpenApi({\n config,\n snapshotPath,\n fileName,\n project,\n rootPath,\n outputRoot,\n}: // {\n// config: HonoDocsConfig;\n// snapshotPath: AppTypeSnapshotPath;\n// }\nGenerateParams & {\n snapshotPath: AppTypeSnapshotPath;\n}): Promise<OpenApiPath> {\n const sf = project.addSourceFileAtPath(\n path.resolve(rootPath, snapshotPath.appTypePath)\n );\n const aliasDecl = sf.getTypeAliasOrThrow(\"AppType\");\n\n const topTypeNode = aliasDecl.getTypeNode();\n\n let typeArgs: readonly TypeNode<ts.TypeNode>[];\n\n if (topTypeNode?.isKind(SyntaxKind.TypeReference)) {\n typeArgs = (topTypeNode as TypeReferenceNode).getTypeArguments();\n } else if (topTypeNode?.isKind(SyntaxKind.ImportType)) {\n typeArgs = (topTypeNode as ImportTypeNode).getTypeArguments();\n } else {\n throw new Error(\"AppType must be an ImportType or a TypeReference\");\n }\n\n if (typeArgs.length < 2) {\n throw new Error(\"Expected two type arguments on HonoBase\");\n }\n\n const routesNode = typeArgs[1];\n\n // Gather all TypeLiteralNodes (handle intersections)\n const literals: TypeLiteralNode[] = [];\n if (routesNode.isKind(SyntaxKind.IntersectionType)) {\n for (const tn of routesNode\n .asKind(SyntaxKind.IntersectionType)!\n .getTypeNodes()) {\n if (tn.isKind(SyntaxKind.TypeLiteral))\n literals.push(tn as TypeLiteralNode);\n }\n } else if (routesNode.isKind(SyntaxKind.TypeLiteral)) {\n literals.push(routesNode as TypeLiteralNode);\n } else {\n throw new Error(\"Routes type is not a literal or intersection of literals\");\n }\n\n const paths: OpenAPI = {};\n\n for (const lit of literals) {\n for (const member of lit.getMembers()) {\n if (!member.isKind(SyntaxKind.PropertySignature)) continue;\n const routeProp = member.asKindOrThrow(SyntaxKind.PropertySignature);\n // Extract route string and normalize to OpenAPI path syntax\n const raw = routeProp.getNameNode().getText().replace(/\"/g, \"\");\n const route = raw.replace(/:([^/]+)/g, \"{$1}\");\n if (!paths[route]) paths[route] = {};\n\n // === NEW: get the RHS TypeLiteralNode properly ===\n const tn = routeProp.getTypeNode();\n if (!tn || !tn.isKind(SyntaxKind.TypeLiteral)) continue;\n const rhs = tn as TypeLiteralNode;\n\n for (const m of rhs.getMembers()) {\n if (!m.isKind(SyntaxKind.PropertySignature)) continue;\n const methodProp = m.asKindOrThrow(SyntaxKind.PropertySignature);\n const name = methodProp.getNameNode().getText(); // e.g. \"$get\"\n const http = name.slice(1).toLowerCase(); // \"get\", \"post\", etc.\n const variants = unwrapUnion(methodProp.getType());\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const op: any = {\n summary: `Auto-generated ${http.toUpperCase()} ${route}`,\n };\n\n // parameters\n const params = genParameters(variants[0]);\n if (params.length) op.parameters = params;\n\n // requestBody\n const rb = genRequestBody(variants[0]);\n if (rb) op.requestBody = rb;\n\n // responses\n op.responses = {};\n const byStatus = groupBy(variants, (v) => {\n const s = v\n .getProperty(\"status\")!\n .getValueDeclarationOrThrow()\n .getType()\n .getText();\n return /^\\d+$/.test(s) ? s : \"default\";\n });\n for (const [code, vs] of Object.entries(byStatus)) {\n const schemas = vs.map((v) =>\n buildSchema(\n v.getProperty(\"output\")!.getValueDeclarationOrThrow().getType()\n )\n );\n const schema = schemas.length > 1 ? { oneOf: schemas } : schemas[0];\n op.responses[code] = {\n description:\n code === \"default\"\n ? `Generic status from ${vs[0]\n .getProperty(\"status\")!\n .getValueDeclarationOrThrow()\n .getType()\n .getText()}`\n : `Status ${code}`,\n content: { \"application/json\": { schema } },\n };\n }\n\n paths[route][http] = op;\n }\n }\n }\n\n const spec = {\n ...config.openApi,\n paths,\n };\n\n // write to disk\n const outputPath = path.join(outputRoot, `${fileName}.json`);\n\n fs.mkdirSync(path.dirname(outputPath), { recursive: true });\n fs.writeFileSync(outputPath, JSON.stringify(spec, null, 2), \"utf-8\");\n console.log(`✅ OpenAPI written to ${outputPath}`);\n return { openApiPath: outputPath };\n}\n","import { SyntaxKind } from \"ts-morph\";\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function buildSchema(type: import(\"ts-morph\").Type): any {\n if (type.isUnion()) {\n const members = type.getUnionTypes();\n const lits = members.filter((u) => u.isStringLiteral());\n const onlyNull = members.every(\n (u) => u.isStringLiteral() || u.isNull() || u.isUndefined()\n );\n if (lits.length && onlyNull) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const schema: any = {\n type: \"string\",\n enum: lits.map((u) => u.getLiteralValue()),\n };\n if (members.some((u) => u.isNull() || u.isUndefined()))\n schema.nullable = true;\n return schema;\n }\n const nonNull = members.filter((u) => !u.isNull() && !u.isUndefined());\n return { oneOf: nonNull.map(buildSchema) };\n }\n if (type.isString()) return { type: \"string\" };\n if (type.isNumber()) return { type: \"number\" };\n if (type.isBoolean()) return { type: \"boolean\" };\n if (type.isArray()) {\n return {\n type: \"array\",\n items: buildSchema(type.getArrayElementTypeOrThrow()),\n };\n }\n\n const decls = type.getSymbol()?.getDeclarations() || [];\n const isLit = decls.some(\n (d) =>\n d.getKind() === SyntaxKind.TypeLiteral ||\n d.getKind() === SyntaxKind.InterfaceDeclaration\n );\n if (!isLit) return {};\n\n const props = type\n .getProperties()\n .filter(\n (p) => p.getValueDeclaration()?.getKind() === SyntaxKind.PropertySignature\n );\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const propsMap: Record<string, any> = {};\n const req: string[] = [];\n for (const p of props) {\n const decl = p.getValueDeclarationOrThrow();\n propsMap[p.getName()] = buildSchema(decl.getType());\n if (!p.isOptional()) req.push(p.getName());\n }\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const res: any = { type: \"object\", properties: propsMap };\n if (req.length) res.required = req;\n return res;\n}\n","import { buildSchema } from \"./buildSchema\";\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function genParameters(type: import(\"ts-morph\").Type): any[] {\n const input = type\n .getProperty(\"input\")\n ?.getValueDeclarationOrThrow()\n .getType();\n if (!input) return [];\n const sources = [\"query\", \"param\", \"header\", \"cookie\"];\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const params: any[] = [];\n for (const src of sources) {\n const p = input.getProperty(src);\n if (!p) continue;\n const srcType = p.getValueDeclarationOrThrow().getType();\n for (const f of srcType.getProperties()) {\n const ft = f.getValueDeclarationOrThrow().getType();\n params.push({\n name: f.getName(),\n in: src === \"param\" ? \"path\" : src,\n required: !f.isOptional(),\n schema: buildSchema(ft),\n });\n }\n }\n return params;\n}\n","import { buildSchema } from \"./buildSchema\";\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function genRequestBody(type: import(\"ts-morph\").Type): any | null {\n const inp = type.getProperty(\"input\")?.getValueDeclarationOrThrow().getType();\n if (!inp) return null;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const content: Record<string, any> = {};\n const j = inp.getProperty(\"json\");\n if (j) {\n content[\"application/json\"] = {\n schema: buildSchema(j.getValueDeclarationOrThrow().getType()),\n };\n }\n const f = inp.getProperty(\"form\");\n if (f) {\n content[\"multipart/form-data\"] = {\n schema: buildSchema(f.getValueDeclarationOrThrow().getType()),\n };\n }\n return Object.keys(content).length ? { required: true, content } : null;\n}\n"],"mappings":"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","names":["import_node_fs","import_node_path","import_ts_morph","fs","path","import_node_fs","import_node_path","import_ts_morph","_a","path","fs","path","fs","yargs"]}