@rcmade/hono-docs 1.0.5 → 1.0.25

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,86 +1,31 @@
1
- "use strict";
2
- var __create = Object.create;
3
- var __defProp = Object.defineProperty;
4
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
- var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getProtoOf = Object.getPrototypeOf;
7
- var __hasOwnProp = Object.prototype.hasOwnProperty;
8
- var __export = (target, all) => {
9
- for (var name in all)
10
- __defProp(target, name, { get: all[name], enumerable: true });
11
- };
12
- var __copyProps = (to, from, except, desc) => {
13
- if (from && typeof from === "object" || typeof from === "function") {
14
- for (let key of __getOwnPropNames(from))
15
- if (!__hasOwnProp.call(to, key) && key !== except)
16
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
- }
18
- return to;
19
- };
20
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
- // If the importer is in node compatibility mode or this is not an ESM
22
- // file that has been converted to a CommonJS file using a Babel-
23
- // compatible transform (i.e. "__esModule" has not been set), then set
24
- // "default" to the CommonJS "module.exports" for node compatibility.
25
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
- mod
27
- ));
28
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
-
30
- // src/index.ts
31
- var index_exports = {};
32
- __export(index_exports, {
33
- defineConfig: () => defineConfig,
34
- runGenerate: () => runGenerate
35
- });
36
- module.exports = __toCommonJS(index_exports);
37
-
38
1
  // src/config/index.ts
39
2
  function defineConfig(config) {
40
3
  return config;
41
4
  }
42
5
 
43
6
  // src/core/runGenerate.ts
44
- var import_node_fs3 = __toESM(require("fs"));
45
- var import_node_path4 = __toESM(require("path"));
46
- var import_ts_morph3 = require("ts-morph");
7
+ import fs3 from "fs";
8
+ import path3, { resolve as resolve3 } from "path";
9
+ import { Project } from "ts-morph";
47
10
 
48
11
  // src/config/loadConfig.ts
49
- var import_path = require("path");
50
- var import_fs = require("fs");
51
- var import_url = require("url");
52
- var import_node = require("esbuild-register/dist/node");
12
+ import { resolve } from "path";
13
+ import { existsSync } from "fs";
14
+ import { tsImport } from "tsx/esm/api";
53
15
  async function loadConfig(configFile) {
54
- const fullPath = (0, import_path.resolve)(process.cwd(), configFile);
55
- if (!(0, import_fs.existsSync)(fullPath)) {
16
+ const fullPath = resolve(process.cwd(), configFile);
17
+ if (!existsSync(fullPath)) {
56
18
  throw new Error(`[hono-docs] Config file not found: ${fullPath}`);
57
19
  }
58
- const ext = (0, import_path.extname)(fullPath);
59
- let unregister = () => {
60
- };
61
- if (ext === ".ts" || ext === ".tsx" || ext === ".mts") {
62
- const reg = (0, import_node.register)({
63
- target: "es2020",
64
- jsx: "automatic"
65
- });
66
- unregister = reg.unregister;
67
- }
68
20
  let configModule;
69
21
  try {
70
- if (ext === ".mjs" || ext === ".mts") {
71
- configModule = await import((0, import_url.pathToFileURL)(fullPath).href);
72
- } else {
73
- configModule = require(fullPath);
74
- }
22
+ configModule = await tsImport(fullPath, import.meta.url);
75
23
  } catch (err) {
76
- unregister();
77
24
  throw new Error(
78
- `[hono-docs] Failed to load config: ${err instanceof Error ? err.message : String(err)}`
25
+ `[hono-docs] Failed to load config: ${err.message ?? String(err)}`
79
26
  );
80
- } finally {
81
- unregister();
82
27
  }
83
- const config = configModule && typeof configModule === "object" && "default" in configModule ? (
28
+ const config = typeof configModule === "object" && configModule !== null && "default" in configModule ? (
84
29
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
85
30
  configModule.default
86
31
  ) : configModule;
@@ -93,8 +38,8 @@ async function loadConfig(configFile) {
93
38
  }
94
39
 
95
40
  // src/core/generateTypes.ts
96
- var import_node_fs = __toESM(require("fs"));
97
- var import_node_path = __toESM(require("path"));
41
+ import fs from "fs";
42
+ import path from "path";
98
43
 
99
44
  // src/utils/format.ts
100
45
  function sanitizeApiPrefix(prefix) {
@@ -144,9 +89,9 @@ async function generateTypes({
144
89
  fileName,
145
90
  outputRoot
146
91
  }) {
147
- import_node_fs.default.mkdirSync(outputRoot, { recursive: true });
148
- const outputPath = import_node_path.default.join(outputRoot, `${fileName}.d.ts`);
149
- const absInput = import_node_path.default.resolve(rootPath, apiGroup.appTypePath);
92
+ fs.mkdirSync(outputRoot, { recursive: true });
93
+ const outputPath = path.join(outputRoot, `${fileName}.d.ts`);
94
+ const absInput = path.resolve(rootPath, apiGroup.appTypePath);
150
95
  const sourceFile = project.addSourceFileAtPath(absInput);
151
96
  const typeAliases = sourceFile.getTypeAliases();
152
97
  const interfaces = sourceFile.getInterfaces();
@@ -164,19 +109,21 @@ async function generateTypes({
164
109
  result += intf.getText() + "\n\n";
165
110
  });
166
111
  const preContent = config.preDefineTypeContent || "";
167
- import_node_fs.default.writeFileSync(outputPath, `${preContent}
112
+ fs.writeFileSync(outputPath, `${preContent}
168
113
  ${result}`, "utf-8");
169
114
  console.log(`\u2705 Wrote: ${outputPath}`);
170
115
  return { appTypePath: outputPath, name: fileName };
171
116
  }
172
117
 
173
118
  // src/core/generateOpenApi.ts
174
- var import_node_fs2 = __toESM(require("fs"));
175
- var import_node_path2 = __toESM(require("path"));
176
- var import_ts_morph2 = require("ts-morph");
119
+ import fs2 from "fs";
120
+ import path2 from "path";
121
+ import {
122
+ SyntaxKind as SyntaxKind2
123
+ } from "ts-morph";
177
124
 
178
125
  // src/utils/buildSchema.ts
179
- var import_ts_morph = require("ts-morph");
126
+ import { SyntaxKind } from "ts-morph";
180
127
  function buildSchema(type) {
181
128
  var _a;
182
129
  if (type.isUnion()) {
@@ -208,13 +155,13 @@ function buildSchema(type) {
208
155
  }
209
156
  const decls = ((_a = type.getSymbol()) == null ? void 0 : _a.getDeclarations()) || [];
210
157
  const isLit = decls.some(
211
- (d) => d.getKind() === import_ts_morph.SyntaxKind.TypeLiteral || d.getKind() === import_ts_morph.SyntaxKind.InterfaceDeclaration
158
+ (d) => d.getKind() === SyntaxKind.TypeLiteral || d.getKind() === SyntaxKind.InterfaceDeclaration
212
159
  );
213
160
  if (!isLit) return {};
214
161
  const props = type.getProperties().filter(
215
162
  (p) => {
216
163
  var _a2;
217
- return ((_a2 = p.getValueDeclaration()) == null ? void 0 : _a2.getKind()) === import_ts_morph.SyntaxKind.PropertySignature;
164
+ return ((_a2 = p.getValueDeclaration()) == null ? void 0 : _a2.getKind()) === SyntaxKind.PropertySignature;
218
165
  }
219
166
  );
220
167
  const propsMap = {};
@@ -284,14 +231,14 @@ async function generateOpenApi({
284
231
  outputRoot
285
232
  }) {
286
233
  const sf = project.addSourceFileAtPath(
287
- import_node_path2.default.resolve(rootPath, snapshotPath.appTypePath)
234
+ path2.resolve(rootPath, snapshotPath.appTypePath)
288
235
  );
289
236
  const aliasDecl = sf.getTypeAliasOrThrow("AppType");
290
237
  const topTypeNode = aliasDecl.getTypeNode();
291
238
  let typeArgs;
292
- if (topTypeNode == null ? void 0 : topTypeNode.isKind(import_ts_morph2.SyntaxKind.TypeReference)) {
239
+ if (topTypeNode == null ? void 0 : topTypeNode.isKind(SyntaxKind2.TypeReference)) {
293
240
  typeArgs = topTypeNode.getTypeArguments();
294
- } else if (topTypeNode == null ? void 0 : topTypeNode.isKind(import_ts_morph2.SyntaxKind.ImportType)) {
241
+ } else if (topTypeNode == null ? void 0 : topTypeNode.isKind(SyntaxKind2.ImportType)) {
295
242
  typeArgs = topTypeNode.getTypeArguments();
296
243
  } else {
297
244
  throw new Error("AppType must be an ImportType or a TypeReference");
@@ -301,12 +248,12 @@ async function generateOpenApi({
301
248
  }
302
249
  const routesNode = typeArgs[1];
303
250
  const literals = [];
304
- if (routesNode.isKind(import_ts_morph2.SyntaxKind.IntersectionType)) {
305
- for (const tn of routesNode.asKind(import_ts_morph2.SyntaxKind.IntersectionType).getTypeNodes()) {
306
- if (tn.isKind(import_ts_morph2.SyntaxKind.TypeLiteral))
251
+ if (routesNode.isKind(SyntaxKind2.IntersectionType)) {
252
+ for (const tn of routesNode.asKind(SyntaxKind2.IntersectionType).getTypeNodes()) {
253
+ if (tn.isKind(SyntaxKind2.TypeLiteral))
307
254
  literals.push(tn);
308
255
  }
309
- } else if (routesNode.isKind(import_ts_morph2.SyntaxKind.TypeLiteral)) {
256
+ } else if (routesNode.isKind(SyntaxKind2.TypeLiteral)) {
310
257
  literals.push(routesNode);
311
258
  } else {
312
259
  throw new Error("Routes type is not a literal or intersection of literals");
@@ -314,17 +261,17 @@ async function generateOpenApi({
314
261
  const paths = {};
315
262
  for (const lit of literals) {
316
263
  for (const member of lit.getMembers()) {
317
- if (!member.isKind(import_ts_morph2.SyntaxKind.PropertySignature)) continue;
318
- const routeProp = member.asKindOrThrow(import_ts_morph2.SyntaxKind.PropertySignature);
264
+ if (!member.isKind(SyntaxKind2.PropertySignature)) continue;
265
+ const routeProp = member.asKindOrThrow(SyntaxKind2.PropertySignature);
319
266
  const raw = routeProp.getNameNode().getText().replace(/"/g, "");
320
267
  const route = raw.replace(/:([^/]+)/g, "{$1}");
321
268
  if (!paths[route]) paths[route] = {};
322
269
  const tn = routeProp.getTypeNode();
323
- if (!tn || !tn.isKind(import_ts_morph2.SyntaxKind.TypeLiteral)) continue;
270
+ if (!tn || !tn.isKind(SyntaxKind2.TypeLiteral)) continue;
324
271
  const rhs = tn;
325
272
  for (const m of rhs.getMembers()) {
326
- if (!m.isKind(import_ts_morph2.SyntaxKind.PropertySignature)) continue;
327
- const methodProp = m.asKindOrThrow(import_ts_morph2.SyntaxKind.PropertySignature);
273
+ if (!m.isKind(SyntaxKind2.PropertySignature)) continue;
274
+ const methodProp = m.asKindOrThrow(SyntaxKind2.PropertySignature);
328
275
  const name = methodProp.getNameNode().getText();
329
276
  const http = name.slice(1).toLowerCase();
330
277
  const variants = unwrapUnion(methodProp.getType());
@@ -360,24 +307,23 @@ async function generateOpenApi({
360
307
  ...config.openApi,
361
308
  paths
362
309
  };
363
- const outputPath = import_node_path2.default.join(outputRoot, `${fileName}.json`);
364
- import_node_fs2.default.mkdirSync(import_node_path2.default.dirname(outputPath), { recursive: true });
365
- import_node_fs2.default.writeFileSync(outputPath, JSON.stringify(spec, null, 2), "utf-8");
310
+ const outputPath = path2.join(outputRoot, `${fileName}.json`);
311
+ fs2.mkdirSync(path2.dirname(outputPath), { recursive: true });
312
+ fs2.writeFileSync(outputPath, JSON.stringify(spec, null, 2), "utf-8");
366
313
  console.log(`\u2705 OpenAPI written to ${outputPath}`);
367
314
  return { openApiPath: outputPath };
368
315
  }
369
316
 
370
317
  // src/utils/libDir.ts
371
- var import_node_path3 = require("path");
372
- var import_node_url = require("url");
373
- var import_meta = {};
318
+ import { dirname, resolve as resolve2 } from "path";
319
+ import { fileURLToPath } from "url";
374
320
  function getLibDir() {
375
321
  if (typeof __dirname !== "undefined") {
376
- return (0, import_node_path3.resolve)(__dirname, "../../");
322
+ return resolve2(__dirname, "../../");
377
323
  }
378
- const __filename = (0, import_node_url.fileURLToPath)(import_meta.url);
379
- const __dirnameEsm = (0, import_node_path3.dirname)(__filename);
380
- return (0, import_node_path3.resolve)(__dirnameEsm, "../../");
324
+ const __filename = fileURLToPath(import.meta.url);
325
+ const __dirnameEsm = dirname(__filename);
326
+ return resolve2(__dirnameEsm, "../../");
381
327
  }
382
328
 
383
329
  // src/core/runGenerate.ts
@@ -385,14 +331,14 @@ async function runGenerate(configPath) {
385
331
  const config = await loadConfig(configPath);
386
332
  const rootPath = process.cwd();
387
333
  console.log("Initializing ts-morph with tsConfig:", config.tsConfigPath);
388
- const project = new import_ts_morph3.Project({
389
- tsConfigFilePath: (0, import_node_path4.resolve)(rootPath, config.tsConfigPath)
334
+ const project = new Project({
335
+ tsConfigFilePath: resolve3(rootPath, config.tsConfigPath)
390
336
  });
391
337
  const libDir = getLibDir();
392
338
  console.log("Library root directory:", libDir);
393
339
  const apis = config.apis;
394
- const snapshotOutputRoot = import_node_path4.default.resolve(libDir, "output/types");
395
- const openAPiOutputRoot = import_node_path4.default.resolve(libDir, "output/openapi");
340
+ const snapshotOutputRoot = path3.resolve(libDir, "output/types");
341
+ const openAPiOutputRoot = path3.resolve(libDir, "output/openapi");
396
342
  const commonParams = {
397
343
  config,
398
344
  libDir,
@@ -422,17 +368,17 @@ async function runGenerate(configPath) {
422
368
  };
423
369
  for (const apiGroup of apis) {
424
370
  const name = sanitizeApiPrefix(apiGroup.apiPrefix);
425
- const openApiFile = import_node_path4.default.join(openAPiOutputRoot, `${name}.json`);
426
- if (!import_node_fs3.default.existsSync(openApiFile)) {
371
+ const openApiFile = path3.join(openAPiOutputRoot, `${name}.json`);
372
+ if (!fs3.existsSync(openApiFile)) {
427
373
  console.warn(`\u26A0\uFE0F Missing OpenAPI file: ${openApiFile}`);
428
374
  continue;
429
375
  }
430
- const json = JSON.parse(import_node_fs3.default.readFileSync(openApiFile, "utf-8"));
376
+ const json = JSON.parse(fs3.readFileSync(openApiFile, "utf-8"));
431
377
  merged.tags.push({ name: apiGroup.name });
432
378
  const customApiMap = /* @__PURE__ */ new Map();
433
379
  if (apiGroup == null ? void 0 : apiGroup.api) {
434
380
  for (const customApi of apiGroup.api) {
435
- const fullPath = import_node_path4.default.posix.join(apiGroup.apiPrefix, customApi.api).replace(/\/+$/, "") || "/";
381
+ const fullPath = path3.posix.join(apiGroup.apiPrefix, customApi.api).replace(/\/+$/, "") || "/";
436
382
  customApiMap.set(
437
383
  `${customApi.method.toLowerCase()} ${fullPath}`,
438
384
  customApi
@@ -440,7 +386,7 @@ async function runGenerate(configPath) {
440
386
  }
441
387
  }
442
388
  for (const [pathKey, operations] of Object.entries(json.paths)) {
443
- const prefixedPath = import_node_path4.default.posix.join(apiGroup.apiPrefix, pathKey).replace(/\/+$/, "") || "/";
389
+ const prefixedPath = path3.posix.join(apiGroup.apiPrefix, pathKey).replace(/\/+$/, "") || "/";
444
390
  if (!merged.paths[prefixedPath]) merged.paths[prefixedPath] = {};
445
391
  for (const [method, operation] of Object.entries(operations)) {
446
392
  const opKey = `${method.toLowerCase()} ${prefixedPath}`;
@@ -460,15 +406,14 @@ async function runGenerate(configPath) {
460
406
  }
461
407
  }
462
408
  }
463
- const outputPath = import_node_path4.default.join(rootPath, config.outputs.openApiJson);
464
- import_node_fs3.default.mkdirSync(import_node_path4.default.dirname(outputPath), { recursive: true });
465
- import_node_fs3.default.writeFileSync(outputPath, `${JSON.stringify(merged, null, 2)}
409
+ const outputPath = path3.join(rootPath, config.outputs.openApiJson);
410
+ fs3.mkdirSync(path3.dirname(outputPath), { recursive: true });
411
+ fs3.writeFileSync(outputPath, `${JSON.stringify(merged, null, 2)}
466
412
  `);
467
413
  console.log(`\u2705 Final merged OpenAPI spec written to: ${outputPath}`);
468
414
  }
469
- // Annotate the CommonJS export names for ESM import in node:
470
- 0 && (module.exports = {
415
+ export {
471
416
  defineConfig,
472
417
  runGenerate
473
- });
418
+ };
474
419
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/config/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","../src/utils/libDir.ts"],"sourcesContent":["export { defineConfig } from \"./config\";\nexport { runGenerate } from \"./core\";\n","// src/config/index.ts\nimport type { HonoDocsConfig } from \"../types\";\n\n/**\n * A no‑op helper to get TS inference and IDE support when\n * writing `export default defineConfig({...})` in userland.\n */\nexport function defineConfig(config: HonoDocsConfig): HonoDocsConfig {\n return config;\n}\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\";\nimport { getLibDir } from \"../utils/libDir\";\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 // path.dirname(fileURLToPath(import.meta.url));\n const libDir = getLibDir();\n console.log(\"Library root directory:\", libDir);\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.summary || 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","// src/utils/libDir.ts\n\nimport { dirname, resolve } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\n/**\n * Returns the root folder of the library, whether running in\n * development (src/) or installed (dist/).\n */\nexport function getLibDir(): string {\n // In CJS (__dirname is injected)\n if (typeof __dirname !== \"undefined\") {\n // When running from dist/core or dist/cli\n return resolve(__dirname, \"../../\");\n }\n // In ESM (import.meta.url)\n const __filename = fileURLToPath(import.meta.url);\n const __dirnameEsm = dirname(__filename);\n return resolve(__dirnameEsm, \"../../\");\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","import_node_path","path","fs"]}
1
+ {"version":3,"sources":["../src/config/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","../src/utils/libDir.ts"],"sourcesContent":["// src/config/index.ts\nimport type { HonoDocsConfig } from \"../types\";\n\n/**\n * A no‑op helper to get TS inference and IDE support when\n * writing `export default defineConfig({...})` in userland.\n */\nexport function defineConfig(config: HonoDocsConfig): HonoDocsConfig {\n return config;\n}\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\";\nimport { getLibDir } from \"../utils/libDir\";\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 // path.dirname(fileURLToPath(import.meta.url));\n const libDir = getLibDir();\n console.log(\"Library root directory:\", libDir);\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.summary || 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","// src/cli/loadConfig.ts\nimport { resolve } from \"path\";\nimport { existsSync } from \"fs\";\n// <-- import tsImport from tsx:\nimport { tsImport } from \"tsx/esm/api\";\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 if (!existsSync(fullPath)) {\n throw new Error(`[hono-docs] Config file not found: ${fullPath}`);\n }\n\n // 2. Dynamically load the config via tsx's tsImport()\n let configModule: unknown;\n try {\n // tsImport(filePath, importMetaUrl) returns the loaded module\n configModule = await tsImport(fullPath, import.meta.url);\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n } catch (err: any) {\n throw new Error(\n `[hono-docs] Failed to load config: ${err.message ?? String(err)}`\n );\n }\n\n // 3. Unwrap default export if present\n const config =\n typeof configModule === \"object\" &&\n configModule !== null &&\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 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","// src/utils/libDir.ts\n\nimport { dirname, resolve } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\n/**\n * Returns the root folder of the library, whether running in\n * development (src/) or installed (dist/).\n */\nexport function getLibDir(): string {\n // In CJS (__dirname is injected)\n if (typeof __dirname !== \"undefined\") {\n // When running from dist/core or dist/cli\n return resolve(__dirname, \"../../\");\n }\n // In ESM (import.meta.url)\n const __filename = fileURLToPath(import.meta.url);\n const __dirnameEsm = dirname(__filename);\n return resolve(__dirnameEsm, \"../../\");\n}\n"],"mappings":"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","names":["fs","path","resolve","fs","path","SyntaxKind","_a","path","SyntaxKind","fs","resolve","resolve","path","fs"]}
package/package.json CHANGED
@@ -1,7 +1,8 @@
1
1
  {
2
2
  "name": "@rcmade/hono-docs",
3
- "version": "1.0.5",
3
+ "version": "1.0.25",
4
4
  "description": "Auto-generate OpenAPI 3.0 spec from Hono route types",
5
+ "type": "module",
5
6
  "repository": {
6
7
  "type": "git",
7
8
  "url": "https://github.com/rcmade/hono-docs.git"
@@ -19,24 +20,14 @@
19
20
  "generator"
20
21
  ],
21
22
  "main": "dist/index.js",
22
- "module": "dist/index.mjs",
23
23
  "types": "dist/index.d.ts",
24
24
  "bin": {
25
25
  "hono-docs": "dist/cli/index.js"
26
26
  },
27
27
  "exports": {
28
- ".": {
29
- "import": "./dist/index.mjs",
30
- "require": "./dist/index.js"
31
- },
32
- "./core": {
33
- "import": "./dist/core/index.mjs",
34
- "require": "./dist/core/index.js"
35
- },
36
- "./cli": {
37
- "import": "./dist/cli/index.mjs",
38
- "require": "./dist/cli/index.js"
39
- },
28
+ ".": "./dist/index.js",
29
+ "./core": "./dist/core/index.js",
30
+ "./cli": "./dist/cli/index.js",
40
31
  "./package.json": "./package.json"
41
32
  },
42
33
  "publishConfig": {
@@ -48,6 +39,7 @@
48
39
  "dependencies": {
49
40
  "esbuild-register": "^3.6.0",
50
41
  "ts-morph": "^26.0.0",
42
+ "tsx": "^4.20.3",
51
43
  "yargs": "^18.0.0"
52
44
  },
53
45
  "devDependencies": {
@@ -56,6 +48,7 @@
56
48
  "@types/yargs": "^17.0.33",
57
49
  "@typescript-eslint/eslint-plugin": "^8.34.1",
58
50
  "@typescript-eslint/parser": "^8.34.1",
51
+ "esbuild": "^0.25.5",
59
52
  "eslint": "^9.29.0",
60
53
  "eslint-config-prettier": "^10.1.5",
61
54
  "eslint-plugin-format": "^1.0.1",
@@ -1 +0,0 @@
1
- #!/usr/bin/env node