@rexeus/typeweaver-hono 0.5.1 → 0.6.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.
package/README.md CHANGED
@@ -54,7 +54,7 @@ import { HttpStatusCode } from "@rexeus/typeweaver-core";
54
54
  import type { IGetUserRequest, GetUserResponse, UserNotFoundErrorResponse } from "./generated";
55
55
  import { GetUserSuccessResponse } from "./generated";
56
56
 
57
- export class UserHandlers implements UserApiHandler {
57
+ export class UserHandlers implements HonoUserApiHandler {
58
58
  async handleGetUserRequest(request: IGetUserRequest, context: Context): Promise<GetUserResponse> {
59
59
  // Symbolic database fetch
60
60
  const databaseResult = {} as any;
@@ -108,7 +108,7 @@ serve({ fetch: app.fetch, port: 3000 }, () => {
108
108
 
109
109
  `TypeweaverHonoOptions<RequestHandlers>`
110
110
 
111
- - `requestHandlers`: object implementing the generated `<ResourceName>ApiHandler` type
111
+ - `requestHandlers`: object implementing the generated `Hono<ResourceName>ApiHandler` type
112
112
  - `validateRequests` (default: `true`): enable/disable request validation
113
113
  - `handleValidationErrors`: `true` | `false` | `(err, c) => IHttpResponse | Promise<IHttpResponse>`,
114
114
  - If `true` (default), returns `400 Bad Request` with validation issues in the body
package/dist/index.cjs CHANGED
@@ -1,102 +1,106 @@
1
- 'use strict';
2
-
3
- var path = require('node:path');
4
- var node_url = require('node:url');
5
- var typeweaverGen = require('@rexeus/typeweaver-gen');
6
- var typeweaverCore = require('@rexeus/typeweaver-core');
7
- var Case = require('case');
8
-
9
- function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
1
+ //#region \0rolldown/runtime.js
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 __copyProps = (to, from, except, desc) => {
9
+ if (from && typeof from === "object" || typeof from === "function") {
10
+ for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
11
+ key = keys[i];
12
+ if (!__hasOwnProp.call(to, key) && key !== except) {
13
+ __defProp(to, key, {
14
+ get: ((k) => from[k]).bind(null, key),
15
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
16
+ });
17
+ }
18
+ }
19
+ }
20
+ return to;
21
+ };
22
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
23
+ value: mod,
24
+ enumerable: true
25
+ }) : target, mod));
10
26
 
11
- var path__default = /*#__PURE__*/_interopDefault(path);
12
- var Case__default = /*#__PURE__*/_interopDefault(Case);
27
+ //#endregion
28
+ let node_path = require("node:path");
29
+ node_path = __toESM(node_path);
30
+ let node_url = require("node:url");
31
+ let _rexeus_typeweaver_gen = require("@rexeus/typeweaver-gen");
32
+ let _rexeus_typeweaver_core = require("@rexeus/typeweaver-core");
33
+ let case$1 = require("case");
34
+ case$1 = __toESM(case$1);
13
35
 
14
- // ../../node_modules/.pnpm/tsup@8.5.1_jiti@2.6.1_postcss@8.5.6_tsx@4.21.0_typescript@5.9.3/node_modules/tsup/assets/cjs_shims.js
15
- var getImportMetaUrl = () => typeof document === "undefined" ? new URL(`file:${__filename}`).href : document.currentScript && document.currentScript.tagName.toUpperCase() === "SCRIPT" ? document.currentScript.src : new URL("main.js", document.baseURI).href;
16
- var importMetaUrl = /* @__PURE__ */ getImportMetaUrl();
36
+ //#region src/HonoRouterGenerator.ts
17
37
  var HonoRouterGenerator = class {
18
- static generate(context) {
19
- const moduleDir2 = path__default.default.dirname(node_url.fileURLToPath(importMetaUrl));
20
- const templateFile = path__default.default.join(moduleDir2, "templates", "HonoRouter.ejs");
21
- for (const [entityName, entityResource] of Object.entries(
22
- context.resources.entityResources
23
- )) {
24
- this.writeHonoRouter(
25
- entityName,
26
- templateFile,
27
- entityResource.operations,
28
- context
29
- );
30
- }
31
- }
32
- static writeHonoRouter(entityName, templateFile, operationResources, context) {
33
- const pascalCaseEntityName = Case__default.default.pascal(entityName);
34
- const outputDir = path__default.default.join(context.outputDir, entityName);
35
- const outputPath = path__default.default.join(outputDir, `${pascalCaseEntityName}Hono.ts`);
36
- const operations = operationResources.filter((resource) => resource.definition.method !== typeweaverCore.HttpMethod.HEAD).map((resource) => this.createOperationData(resource)).sort((a, b) => this.compareRoutes(a, b));
37
- const content = context.renderTemplate(templateFile, {
38
- coreDir: path__default.default.relative(outputDir, context.outputDir),
39
- entityName,
40
- pascalCaseEntityName,
41
- operations
42
- });
43
- const relativePath = path__default.default.relative(context.outputDir, outputPath);
44
- context.writeFile(relativePath, content);
45
- }
46
- static createOperationData(resource) {
47
- const operationId = resource.definition.operationId;
48
- const className = Case__default.default.pascal(operationId);
49
- const handlerName = `handle${className}Request`;
50
- return {
51
- className,
52
- handlerName,
53
- method: resource.definition.method,
54
- path: resource.definition.path
55
- };
56
- }
57
- static compareRoutes(a, b) {
58
- const aSegments = a.path.split("/").filter((s) => s);
59
- const bSegments = b.path.split("/").filter((s) => s);
60
- if (aSegments.length !== bSegments.length) {
61
- return aSegments.length - bSegments.length;
62
- }
63
- for (let i = 0; i < aSegments.length; i++) {
64
- const aSegment = aSegments[i];
65
- const bSegment = bSegments[i];
66
- const aIsParam = aSegment.startsWith(":");
67
- const bIsParam = bSegment.startsWith(":");
68
- if (aIsParam !== bIsParam) {
69
- return aIsParam ? 1 : -1;
70
- }
71
- if (aSegment !== bSegment) {
72
- return aSegment.localeCompare(bSegment);
73
- }
74
- }
75
- return this.getMethodPriority(a.method) - this.getMethodPriority(b.method);
76
- }
77
- static getMethodPriority(method) {
78
- const priorities = {
79
- GET: 1,
80
- POST: 2,
81
- PUT: 3,
82
- PATCH: 4,
83
- DELETE: 5,
84
- OPTIONS: 6,
85
- HEAD: 7
86
- };
87
- return priorities[method] ?? 999;
88
- }
38
+ static generate(context) {
39
+ const moduleDir = node_path.default.dirname((0, node_url.fileURLToPath)(require("url").pathToFileURL(__filename).href));
40
+ const templateFile = node_path.default.join(moduleDir, "templates", "HonoRouter.ejs");
41
+ for (const [entityName, entityResource] of Object.entries(context.resources.entityResources)) this.writeHonoRouter(entityName, templateFile, entityResource.operations, context);
42
+ }
43
+ static writeHonoRouter(entityName, templateFile, operationResources, context) {
44
+ const pascalCaseEntityName = case$1.default.pascal(entityName);
45
+ const outputDir = node_path.default.join(context.outputDir, entityName);
46
+ const outputPath = node_path.default.join(outputDir, `${pascalCaseEntityName}Hono.ts`);
47
+ const operations = operationResources.filter((resource) => resource.definition.method !== _rexeus_typeweaver_core.HttpMethod.HEAD).map((resource) => this.createOperationData(resource)).sort((a, b) => this.compareRoutes(a, b));
48
+ const content = context.renderTemplate(templateFile, {
49
+ coreDir: node_path.default.relative(outputDir, context.outputDir),
50
+ entityName,
51
+ pascalCaseEntityName,
52
+ operations
53
+ });
54
+ const relativePath = node_path.default.relative(context.outputDir, outputPath);
55
+ context.writeFile(relativePath, content);
56
+ }
57
+ static createOperationData(resource) {
58
+ const operationId = resource.definition.operationId;
59
+ const className = case$1.default.pascal(operationId);
60
+ return {
61
+ className,
62
+ handlerName: `handle${className}Request`,
63
+ method: resource.definition.method,
64
+ path: resource.definition.path
65
+ };
66
+ }
67
+ static compareRoutes(a, b) {
68
+ const aSegments = a.path.split("/").filter((s) => s);
69
+ const bSegments = b.path.split("/").filter((s) => s);
70
+ if (aSegments.length !== bSegments.length) return aSegments.length - bSegments.length;
71
+ for (let i = 0; i < aSegments.length; i++) {
72
+ const aSegment = aSegments[i];
73
+ const bSegment = bSegments[i];
74
+ const aIsParam = aSegment.startsWith(":");
75
+ if (aIsParam !== bSegment.startsWith(":")) return aIsParam ? 1 : -1;
76
+ if (aSegment !== bSegment) return aSegment.localeCompare(bSegment);
77
+ }
78
+ return this.getMethodPriority(a.method) - this.getMethodPriority(b.method);
79
+ }
80
+ static getMethodPriority(method) {
81
+ return {
82
+ GET: 1,
83
+ POST: 2,
84
+ PUT: 3,
85
+ PATCH: 4,
86
+ DELETE: 5,
87
+ OPTIONS: 6,
88
+ HEAD: 7
89
+ }[method] ?? 999;
90
+ }
89
91
  };
90
92
 
91
- // src/index.ts
92
- var moduleDir = path__default.default.dirname(node_url.fileURLToPath(importMetaUrl));
93
- var HonoPlugin = class extends typeweaverGen.BasePlugin {
94
- name = "hono";
95
- generate(context) {
96
- const libSourceDir = path__default.default.join(moduleDir, "lib");
97
- this.copyLibFiles(context, libSourceDir, this.name);
98
- HonoRouterGenerator.generate(context);
99
- }
93
+ //#endregion
94
+ //#region src/index.ts
95
+ const moduleDir = node_path.default.dirname((0, node_url.fileURLToPath)(require("url").pathToFileURL(__filename).href));
96
+ var HonoPlugin = class extends _rexeus_typeweaver_gen.BasePlugin {
97
+ name = "hono";
98
+ generate(context) {
99
+ const libSourceDir = node_path.default.join(moduleDir, "lib");
100
+ this.copyLibFiles(context, libSourceDir, this.name);
101
+ HonoRouterGenerator.generate(context);
102
+ }
100
103
  };
101
104
 
102
- module.exports = HonoPlugin;
105
+ //#endregion
106
+ module.exports = HonoPlugin;
package/dist/index.d.cts CHANGED
@@ -1,8 +1,9 @@
1
- import { BasePlugin, GeneratorContext } from '@rexeus/typeweaver-gen';
1
+ import { BasePlugin, GeneratorContext } from "@rexeus/typeweaver-gen";
2
2
 
3
+ //#region src/index.d.ts
3
4
  declare class HonoPlugin extends BasePlugin {
4
- name: string;
5
- generate(context: GeneratorContext): void;
5
+ name: string;
6
+ generate(context: GeneratorContext): void;
6
7
  }
7
-
8
- export { HonoPlugin as default };
8
+ export = HonoPlugin;
9
+ //# sourceMappingURL=index.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.cts","names":[],"sources":["../src/index.ts"],"mappings":";;;cAQqB,UAAA,SAAmB,UAAA;EAC/B,IAAA;EAES,QAAA,CAAS,OAAA,EAAS,gBAAA;AAAA;AAAA"}
@@ -0,0 +1,10 @@
1
+ import { BasePlugin, GeneratorContext } from "@rexeus/typeweaver-gen";
2
+
3
+ //#region src/index.d.ts
4
+ declare class HonoPlugin extends BasePlugin {
5
+ name: string;
6
+ generate(context: GeneratorContext): void;
7
+ }
8
+ //#endregion
9
+ export { HonoPlugin as default };
10
+ //# sourceMappingURL=index.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/index.ts"],"mappings":";;;cAQqB,UAAA,SAAmB,UAAA;EAC/B,IAAA;EAES,QAAA,CAAS,OAAA,EAAS,gBAAA;AAAA"}
package/dist/index.mjs ADDED
@@ -0,0 +1,78 @@
1
+ import path from "node:path";
2
+ import { fileURLToPath } from "node:url";
3
+ import { BasePlugin } from "@rexeus/typeweaver-gen";
4
+ import { HttpMethod } from "@rexeus/typeweaver-core";
5
+ import Case from "case";
6
+
7
+ //#region src/HonoRouterGenerator.ts
8
+ var HonoRouterGenerator = class {
9
+ static generate(context) {
10
+ const moduleDir = path.dirname(fileURLToPath(import.meta.url));
11
+ const templateFile = path.join(moduleDir, "templates", "HonoRouter.ejs");
12
+ for (const [entityName, entityResource] of Object.entries(context.resources.entityResources)) this.writeHonoRouter(entityName, templateFile, entityResource.operations, context);
13
+ }
14
+ static writeHonoRouter(entityName, templateFile, operationResources, context) {
15
+ const pascalCaseEntityName = Case.pascal(entityName);
16
+ const outputDir = path.join(context.outputDir, entityName);
17
+ const outputPath = path.join(outputDir, `${pascalCaseEntityName}Hono.ts`);
18
+ const operations = operationResources.filter((resource) => resource.definition.method !== HttpMethod.HEAD).map((resource) => this.createOperationData(resource)).sort((a, b) => this.compareRoutes(a, b));
19
+ const content = context.renderTemplate(templateFile, {
20
+ coreDir: path.relative(outputDir, context.outputDir),
21
+ entityName,
22
+ pascalCaseEntityName,
23
+ operations
24
+ });
25
+ const relativePath = path.relative(context.outputDir, outputPath);
26
+ context.writeFile(relativePath, content);
27
+ }
28
+ static createOperationData(resource) {
29
+ const operationId = resource.definition.operationId;
30
+ const className = Case.pascal(operationId);
31
+ return {
32
+ className,
33
+ handlerName: `handle${className}Request`,
34
+ method: resource.definition.method,
35
+ path: resource.definition.path
36
+ };
37
+ }
38
+ static compareRoutes(a, b) {
39
+ const aSegments = a.path.split("/").filter((s) => s);
40
+ const bSegments = b.path.split("/").filter((s) => s);
41
+ if (aSegments.length !== bSegments.length) return aSegments.length - bSegments.length;
42
+ for (let i = 0; i < aSegments.length; i++) {
43
+ const aSegment = aSegments[i];
44
+ const bSegment = bSegments[i];
45
+ const aIsParam = aSegment.startsWith(":");
46
+ if (aIsParam !== bSegment.startsWith(":")) return aIsParam ? 1 : -1;
47
+ if (aSegment !== bSegment) return aSegment.localeCompare(bSegment);
48
+ }
49
+ return this.getMethodPriority(a.method) - this.getMethodPriority(b.method);
50
+ }
51
+ static getMethodPriority(method) {
52
+ return {
53
+ GET: 1,
54
+ POST: 2,
55
+ PUT: 3,
56
+ PATCH: 4,
57
+ DELETE: 5,
58
+ OPTIONS: 6,
59
+ HEAD: 7
60
+ }[method] ?? 999;
61
+ }
62
+ };
63
+
64
+ //#endregion
65
+ //#region src/index.ts
66
+ const moduleDir = path.dirname(fileURLToPath(import.meta.url));
67
+ var HonoPlugin = class extends BasePlugin {
68
+ name = "hono";
69
+ generate(context) {
70
+ const libSourceDir = path.join(moduleDir, "lib");
71
+ this.copyLibFiles(context, libSourceDir, this.name);
72
+ HonoRouterGenerator.generate(context);
73
+ }
74
+ };
75
+
76
+ //#endregion
77
+ export { HonoPlugin as default };
78
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../src/HonoRouterGenerator.ts","../src/index.ts"],"sourcesContent":["import path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { HttpMethod } from \"@rexeus/typeweaver-core\";\nimport type {\n GeneratorContext,\n OperationResource,\n} from \"@rexeus/typeweaver-gen\";\nimport Case from \"case\";\n\nexport class HonoRouterGenerator {\n public static generate(context: GeneratorContext): void {\n const moduleDir = path.dirname(fileURLToPath(import.meta.url));\n const templateFile = path.join(moduleDir, \"templates\", \"HonoRouter.ejs\");\n\n for (const [entityName, entityResource] of Object.entries(\n context.resources.entityResources\n )) {\n this.writeHonoRouter(\n entityName,\n templateFile,\n entityResource.operations,\n context\n );\n }\n }\n\n private static writeHonoRouter(\n entityName: string,\n templateFile: string,\n operationResources: OperationResource[],\n context: GeneratorContext\n ): void {\n const pascalCaseEntityName = Case.pascal(entityName);\n const outputDir = path.join(context.outputDir, entityName);\n const outputPath = path.join(outputDir, `${pascalCaseEntityName}Hono.ts`);\n\n const operations = operationResources\n // Hono handles HEAD requests automatically, so we skip them\n .filter(resource => resource.definition.method !== HttpMethod.HEAD)\n .map(resource => this.createOperationData(resource))\n .sort((a, b) => this.compareRoutes(a, b));\n\n const content = context.renderTemplate(templateFile, {\n coreDir: path.relative(outputDir, context.outputDir),\n entityName,\n pascalCaseEntityName,\n operations,\n });\n\n const relativePath = path.relative(context.outputDir, outputPath);\n context.writeFile(relativePath, content);\n }\n\n private static createOperationData(resource: OperationResource) {\n const operationId = resource.definition.operationId;\n const className = Case.pascal(operationId);\n const handlerName = `handle${className}Request`;\n\n return {\n className,\n handlerName,\n method: resource.definition.method,\n path: resource.definition.path,\n };\n }\n\n private static compareRoutes(\n a: ReturnType<typeof HonoRouterGenerator.createOperationData>,\n b: ReturnType<typeof HonoRouterGenerator.createOperationData>\n ): number {\n const aSegments = a.path.split(\"/\").filter(s => s);\n const bSegments = b.path.split(\"/\").filter(s => s);\n\n // 1. Compare by depth first (shallow to deep)\n if (aSegments.length !== bSegments.length) {\n return aSegments.length - bSegments.length;\n }\n\n // 2. Compare segment by segment\n for (let i = 0; i < aSegments.length; i++) {\n const aSegment = aSegments[i]!;\n const bSegment = bSegments[i]!;\n\n const aIsParam = aSegment.startsWith(\":\");\n const bIsParam = bSegment.startsWith(\":\");\n\n // Static segments before parameters\n if (aIsParam !== bIsParam) {\n return aIsParam ? 1 : -1;\n }\n\n // Within same type, alphabetical order\n if (aSegment !== bSegment) {\n return aSegment.localeCompare(bSegment);\n }\n }\n\n // 3. Same path = sort by HTTP method priority\n return this.getMethodPriority(a.method) - this.getMethodPriority(b.method);\n }\n\n private static getMethodPriority(method: string): number {\n const priorities: Record<string, number> = {\n GET: 1,\n POST: 2,\n PUT: 3,\n PATCH: 4,\n DELETE: 5,\n OPTIONS: 6,\n HEAD: 7,\n };\n return priorities[method] ?? 999;\n }\n}\n","import path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { BasePlugin } from \"@rexeus/typeweaver-gen\";\nimport type { GeneratorContext } from \"@rexeus/typeweaver-gen\";\nimport { HonoRouterGenerator } from \"./HonoRouterGenerator\";\n\nconst moduleDir = path.dirname(fileURLToPath(import.meta.url));\n\nexport default class HonoPlugin extends BasePlugin {\n public name = \"hono\";\n\n public override generate(context: GeneratorContext): void {\n const libSourceDir = path.join(moduleDir, \"lib\");\n this.copyLibFiles(context, libSourceDir, this.name);\n\n HonoRouterGenerator.generate(context);\n }\n}\n"],"mappings":";;;;;;;AASA,IAAa,sBAAb,MAAiC;CAC/B,OAAc,SAAS,SAAiC;EACtD,MAAM,YAAY,KAAK,QAAQ,cAAc,OAAO,KAAK,IAAI,CAAC;EAC9D,MAAM,eAAe,KAAK,KAAK,WAAW,aAAa,iBAAiB;AAExE,OAAK,MAAM,CAAC,YAAY,mBAAmB,OAAO,QAChD,QAAQ,UAAU,gBACnB,CACC,MAAK,gBACH,YACA,cACA,eAAe,YACf,QACD;;CAIL,OAAe,gBACb,YACA,cACA,oBACA,SACM;EACN,MAAM,uBAAuB,KAAK,OAAO,WAAW;EACpD,MAAM,YAAY,KAAK,KAAK,QAAQ,WAAW,WAAW;EAC1D,MAAM,aAAa,KAAK,KAAK,WAAW,GAAG,qBAAqB,SAAS;EAEzE,MAAM,aAAa,mBAEhB,QAAO,aAAY,SAAS,WAAW,WAAW,WAAW,KAAK,CAClE,KAAI,aAAY,KAAK,oBAAoB,SAAS,CAAC,CACnD,MAAM,GAAG,MAAM,KAAK,cAAc,GAAG,EAAE,CAAC;EAE3C,MAAM,UAAU,QAAQ,eAAe,cAAc;GACnD,SAAS,KAAK,SAAS,WAAW,QAAQ,UAAU;GACpD;GACA;GACA;GACD,CAAC;EAEF,MAAM,eAAe,KAAK,SAAS,QAAQ,WAAW,WAAW;AACjE,UAAQ,UAAU,cAAc,QAAQ;;CAG1C,OAAe,oBAAoB,UAA6B;EAC9D,MAAM,cAAc,SAAS,WAAW;EACxC,MAAM,YAAY,KAAK,OAAO,YAAY;AAG1C,SAAO;GACL;GACA,aAJkB,SAAS,UAAU;GAKrC,QAAQ,SAAS,WAAW;GAC5B,MAAM,SAAS,WAAW;GAC3B;;CAGH,OAAe,cACb,GACA,GACQ;EACR,MAAM,YAAY,EAAE,KAAK,MAAM,IAAI,CAAC,QAAO,MAAK,EAAE;EAClD,MAAM,YAAY,EAAE,KAAK,MAAM,IAAI,CAAC,QAAO,MAAK,EAAE;AAGlD,MAAI,UAAU,WAAW,UAAU,OACjC,QAAO,UAAU,SAAS,UAAU;AAItC,OAAK,IAAI,IAAI,GAAG,IAAI,UAAU,QAAQ,KAAK;GACzC,MAAM,WAAW,UAAU;GAC3B,MAAM,WAAW,UAAU;GAE3B,MAAM,WAAW,SAAS,WAAW,IAAI;AAIzC,OAAI,aAHa,SAAS,WAAW,IAAI,CAIvC,QAAO,WAAW,IAAI;AAIxB,OAAI,aAAa,SACf,QAAO,SAAS,cAAc,SAAS;;AAK3C,SAAO,KAAK,kBAAkB,EAAE,OAAO,GAAG,KAAK,kBAAkB,EAAE,OAAO;;CAG5E,OAAe,kBAAkB,QAAwB;AAUvD,SAT2C;GACzC,KAAK;GACL,MAAM;GACN,KAAK;GACL,OAAO;GACP,QAAQ;GACR,SAAS;GACT,MAAM;GACP,CACiB,WAAW;;;;;;ACzGjC,MAAM,YAAY,KAAK,QAAQ,cAAc,OAAO,KAAK,IAAI,CAAC;AAE9D,IAAqB,aAArB,cAAwC,WAAW;CACjD,AAAO,OAAO;CAEd,AAAgB,SAAS,SAAiC;EACxD,MAAM,eAAe,KAAK,KAAK,WAAW,MAAM;AAChD,OAAK,aAAa,SAAS,cAAc,KAAK,KAAK;AAEnD,sBAAoB,SAAS,QAAQ"}
@@ -6,12 +6,12 @@
6
6
  */
7
7
 
8
8
  import { HttpResponse, RequestValidationError } from "@rexeus/typeweaver-core";
9
- import { Hono } from "hono";
10
9
  import type {
11
10
  IHttpRequest,
12
11
  IHttpResponse,
13
12
  IRequestValidator,
14
13
  } from "@rexeus/typeweaver-core";
14
+ import { Hono } from "hono";
15
15
  import { HonoAdapter } from "./HonoAdapter";
16
16
  import type { HonoRequestHandler } from "./HonoRequestHandler";
17
17
  import type { Context } from "hono";
package/package.json CHANGED
@@ -1,17 +1,17 @@
1
1
  {
2
2
  "name": "@rexeus/typeweaver-hono",
3
- "version": "0.5.1",
3
+ "version": "0.6.1",
4
4
  "description": "Generates Hono routers and handlers straight from your API definitions. Powered by Typeweaver 🧵✨",
5
5
  "type": "module",
6
6
  "sideEffects": false,
7
7
  "main": "dist/index.cjs",
8
- "module": "dist/index.js",
9
- "types": "dist/index.d.ts",
8
+ "module": "dist/index.mjs",
9
+ "types": "dist/index.d.mts",
10
10
  "exports": {
11
11
  ".": {
12
12
  "import": {
13
- "types": "./dist/index.d.ts",
14
- "default": "./dist/index.js"
13
+ "types": "./dist/index.d.mts",
14
+ "default": "./dist/index.mjs"
15
15
  },
16
16
  "require": {
17
17
  "types": "./dist/index.d.cts",
@@ -47,22 +47,22 @@
47
47
  "homepage": "https://github.com/rexeus/typeweaver#readme",
48
48
  "peerDependencies": {
49
49
  "hono": "^4.11.0",
50
- "@rexeus/typeweaver-core": "^0.5.1",
51
- "@rexeus/typeweaver-gen": "^0.5.1"
50
+ "@rexeus/typeweaver-core": "^0.6.1",
51
+ "@rexeus/typeweaver-gen": "^0.6.1"
52
52
  },
53
53
  "devDependencies": {
54
54
  "hono": "^4.11.3",
55
55
  "test-utils": "file:../test-utils",
56
- "@rexeus/typeweaver-gen": "^0.5.1",
57
- "@rexeus/typeweaver-core": "^0.5.1"
56
+ "@rexeus/typeweaver-core": "^0.6.1",
57
+ "@rexeus/typeweaver-gen": "^0.6.1"
58
58
  },
59
59
  "dependencies": {
60
60
  "case": "^1.6.3"
61
61
  },
62
62
  "scripts": {
63
63
  "typecheck": "tsc --noEmit",
64
- "format": "prettier --write .",
65
- "build": "tsup && mkdir -p ./dist/templates ./dist/lib && cp -r ./src/templates/* ./dist/templates/ && cp -r ./src/lib/* ./dist/lib/ && cp ../../LICENSE ../../NOTICE ./dist/",
64
+ "format": "oxfmt",
65
+ "build": "tsdown && mkdir -p ./dist/templates ./dist/lib && cp -r ./src/templates/* ./dist/templates/ && cp -r ./src/lib/* ./dist/lib/ && cp ../../LICENSE ../../NOTICE ./dist/",
66
66
  "test": "vitest --run",
67
67
  "preversion": "npm run build"
68
68
  }
package/dist/index.d.ts DELETED
@@ -1,8 +0,0 @@
1
- import { BasePlugin, GeneratorContext } from '@rexeus/typeweaver-gen';
2
-
3
- declare class HonoPlugin extends BasePlugin {
4
- name: string;
5
- generate(context: GeneratorContext): void;
6
- }
7
-
8
- export { HonoPlugin as default };
package/dist/index.js DELETED
@@ -1,93 +0,0 @@
1
- import path from 'node:path';
2
- import { fileURLToPath } from 'node:url';
3
- import { BasePlugin } from '@rexeus/typeweaver-gen';
4
- import { HttpMethod } from '@rexeus/typeweaver-core';
5
- import Case from 'case';
6
-
7
- // src/index.ts
8
- var HonoRouterGenerator = class {
9
- static generate(context) {
10
- const moduleDir2 = path.dirname(fileURLToPath(import.meta.url));
11
- const templateFile = path.join(moduleDir2, "templates", "HonoRouter.ejs");
12
- for (const [entityName, entityResource] of Object.entries(
13
- context.resources.entityResources
14
- )) {
15
- this.writeHonoRouter(
16
- entityName,
17
- templateFile,
18
- entityResource.operations,
19
- context
20
- );
21
- }
22
- }
23
- static writeHonoRouter(entityName, templateFile, operationResources, context) {
24
- const pascalCaseEntityName = Case.pascal(entityName);
25
- const outputDir = path.join(context.outputDir, entityName);
26
- const outputPath = path.join(outputDir, `${pascalCaseEntityName}Hono.ts`);
27
- const operations = operationResources.filter((resource) => resource.definition.method !== HttpMethod.HEAD).map((resource) => this.createOperationData(resource)).sort((a, b) => this.compareRoutes(a, b));
28
- const content = context.renderTemplate(templateFile, {
29
- coreDir: path.relative(outputDir, context.outputDir),
30
- entityName,
31
- pascalCaseEntityName,
32
- operations
33
- });
34
- const relativePath = path.relative(context.outputDir, outputPath);
35
- context.writeFile(relativePath, content);
36
- }
37
- static createOperationData(resource) {
38
- const operationId = resource.definition.operationId;
39
- const className = Case.pascal(operationId);
40
- const handlerName = `handle${className}Request`;
41
- return {
42
- className,
43
- handlerName,
44
- method: resource.definition.method,
45
- path: resource.definition.path
46
- };
47
- }
48
- static compareRoutes(a, b) {
49
- const aSegments = a.path.split("/").filter((s) => s);
50
- const bSegments = b.path.split("/").filter((s) => s);
51
- if (aSegments.length !== bSegments.length) {
52
- return aSegments.length - bSegments.length;
53
- }
54
- for (let i = 0; i < aSegments.length; i++) {
55
- const aSegment = aSegments[i];
56
- const bSegment = bSegments[i];
57
- const aIsParam = aSegment.startsWith(":");
58
- const bIsParam = bSegment.startsWith(":");
59
- if (aIsParam !== bIsParam) {
60
- return aIsParam ? 1 : -1;
61
- }
62
- if (aSegment !== bSegment) {
63
- return aSegment.localeCompare(bSegment);
64
- }
65
- }
66
- return this.getMethodPriority(a.method) - this.getMethodPriority(b.method);
67
- }
68
- static getMethodPriority(method) {
69
- const priorities = {
70
- GET: 1,
71
- POST: 2,
72
- PUT: 3,
73
- PATCH: 4,
74
- DELETE: 5,
75
- OPTIONS: 6,
76
- HEAD: 7
77
- };
78
- return priorities[method] ?? 999;
79
- }
80
- };
81
-
82
- // src/index.ts
83
- var moduleDir = path.dirname(fileURLToPath(import.meta.url));
84
- var HonoPlugin = class extends BasePlugin {
85
- name = "hono";
86
- generate(context) {
87
- const libSourceDir = path.join(moduleDir, "lib");
88
- this.copyLibFiles(context, libSourceDir, this.name);
89
- HonoRouterGenerator.generate(context);
90
- }
91
- };
92
-
93
- export { HonoPlugin as default };
@@ -1 +0,0 @@
1
- {"inputs":{"../../node_modules/.pnpm/tsup@8.5.1_jiti@2.6.1_postcss@8.5.6_tsx@4.21.0_typescript@5.9.3/node_modules/tsup/assets/cjs_shims.js":{"bytes":569,"imports":[],"format":"esm"},"src/HonoRouterGenerator.ts":{"bytes":3465,"imports":[{"path":"node:path","kind":"import-statement","external":true},{"path":"node:url","kind":"import-statement","external":true},{"path":"@rexeus/typeweaver-core","kind":"import-statement","external":true},{"path":"case","kind":"import-statement","external":true},{"path":"/home/runner/work/typeweaver/typeweaver/node_modules/.pnpm/tsup@8.5.1_jiti@2.6.1_postcss@8.5.6_tsx@4.21.0_typescript@5.9.3/node_modules/tsup/assets/cjs_shims.js","kind":"import-statement","external":true}],"format":"esm"},"src/index.ts":{"bytes":617,"imports":[{"path":"node:path","kind":"import-statement","external":true},{"path":"node:url","kind":"import-statement","external":true},{"path":"@rexeus/typeweaver-gen","kind":"import-statement","external":true},{"path":"src/HonoRouterGenerator.ts","kind":"import-statement","original":"./HonoRouterGenerator"},{"path":"/home/runner/work/typeweaver/typeweaver/node_modules/.pnpm/tsup@8.5.1_jiti@2.6.1_postcss@8.5.6_tsx@4.21.0_typescript@5.9.3/node_modules/tsup/assets/cjs_shims.js","kind":"import-statement","external":true}],"format":"esm"}},"outputs":{"dist/index.cjs":{"imports":[{"path":"node:path","kind":"import-statement","external":true},{"path":"node:url","kind":"import-statement","external":true},{"path":"@rexeus/typeweaver-gen","kind":"import-statement","external":true},{"path":"node:path","kind":"import-statement","external":true},{"path":"node:url","kind":"import-statement","external":true},{"path":"@rexeus/typeweaver-core","kind":"import-statement","external":true},{"path":"case","kind":"import-statement","external":true}],"exports":["default"],"entryPoint":"src/index.ts","inputs":{"../../node_modules/.pnpm/tsup@8.5.1_jiti@2.6.1_postcss@8.5.6_tsx@4.21.0_typescript@5.9.3/node_modules/tsup/assets/cjs_shims.js":{"bytesInOutput":314},"src/index.ts":{"bytesInOutput":451},"src/HonoRouterGenerator.ts":{"bytesInOutput":2705}},"bytes":3701}}}
@@ -1 +0,0 @@
1
- {"inputs":{"../../node_modules/.pnpm/tsup@8.5.1_jiti@2.6.1_postcss@8.5.6_tsx@4.21.0_typescript@5.9.3/node_modules/tsup/assets/esm_shims.js":{"bytes":322,"imports":[{"path":"node:path","kind":"import-statement","external":true},{"path":"node:url","kind":"import-statement","external":true}],"format":"esm"},"src/HonoRouterGenerator.ts":{"bytes":3465,"imports":[{"path":"node:path","kind":"import-statement","external":true},{"path":"node:url","kind":"import-statement","external":true},{"path":"@rexeus/typeweaver-core","kind":"import-statement","external":true},{"path":"case","kind":"import-statement","external":true},{"path":"/home/runner/work/typeweaver/typeweaver/node_modules/.pnpm/tsup@8.5.1_jiti@2.6.1_postcss@8.5.6_tsx@4.21.0_typescript@5.9.3/node_modules/tsup/assets/esm_shims.js","kind":"import-statement","external":true}],"format":"esm"},"src/index.ts":{"bytes":617,"imports":[{"path":"node:path","kind":"import-statement","external":true},{"path":"node:url","kind":"import-statement","external":true},{"path":"@rexeus/typeweaver-gen","kind":"import-statement","external":true},{"path":"src/HonoRouterGenerator.ts","kind":"import-statement","original":"./HonoRouterGenerator"},{"path":"/home/runner/work/typeweaver/typeweaver/node_modules/.pnpm/tsup@8.5.1_jiti@2.6.1_postcss@8.5.6_tsx@4.21.0_typescript@5.9.3/node_modules/tsup/assets/esm_shims.js","kind":"import-statement","external":true}],"format":"esm"}},"outputs":{"dist/index.js":{"imports":[{"path":"node:path","kind":"import-statement","external":true},{"path":"node:url","kind":"import-statement","external":true},{"path":"@rexeus/typeweaver-gen","kind":"import-statement","external":true},{"path":"node:path","kind":"import-statement","external":true},{"path":"node:url","kind":"import-statement","external":true},{"path":"@rexeus/typeweaver-core","kind":"import-statement","external":true},{"path":"case","kind":"import-statement","external":true}],"exports":["default"],"entryPoint":"src/index.ts","inputs":{"src/index.ts":{"bytesInOutput":453},"src/HonoRouterGenerator.ts":{"bytesInOutput":2707}},"bytes":3260}}}