@h3ravel/router 0.2.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +32 -0
- package/dist/index.cjs +15 -10
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +11 -84
- package/dist/index.d.ts +11 -84
- package/dist/index.js +12 -7
- package/dist/index.js.map +1 -1
- package/package.json +7 -7
- package/src/Providers/AssetsServiceProvider.ts +8 -8
- package/src/Providers/RouteServiceProvider.ts +2 -2
- package/src/Route.ts +182 -1
- package/src/index.ts +0 -1
- package/tsconfig.json +1 -1
- package/src/Router.ts +0 -180
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,37 @@
|
|
|
1
1
|
# @h3ravel/router
|
|
2
2
|
|
|
3
|
+
## 0.4.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 8ceb2c1: implement the Application class directly since it already implements the IClass contract
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- a27f452: chore: fix all linting issues.
|
|
12
|
+
- c906050: chore: migrate tests suite to jest
|
|
13
|
+
- Updated dependencies [8ceb2c1]
|
|
14
|
+
- Updated dependencies [a27f452]
|
|
15
|
+
- Updated dependencies [c906050]
|
|
16
|
+
- @h3ravel/core@0.4.0
|
|
17
|
+
- @h3ravel/shared@0.4.0
|
|
18
|
+
- @h3ravel/support@0.4.0
|
|
19
|
+
- @h3ravel/http@2.0.0
|
|
20
|
+
|
|
21
|
+
## 0.3.0
|
|
22
|
+
|
|
23
|
+
### Minor Changes
|
|
24
|
+
|
|
25
|
+
- 3ff97bf: refactor: add a shared package to be extended by others to avoid cyclic dependency issues.
|
|
26
|
+
|
|
27
|
+
### Patch Changes
|
|
28
|
+
|
|
29
|
+
- Updated dependencies [3ff97bf]
|
|
30
|
+
- @h3ravel/core@0.3.0
|
|
31
|
+
- @h3ravel/http@1.0.0
|
|
32
|
+
- @h3ravel/shared@0.3.0
|
|
33
|
+
- @h3ravel/support@0.3.0
|
|
34
|
+
|
|
3
35
|
## 0.2.0
|
|
4
36
|
|
|
5
37
|
### Minor Changes
|
package/dist/index.cjs
CHANGED
|
@@ -29,15 +29,16 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
29
29
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
30
30
|
|
|
31
31
|
// src/index.ts
|
|
32
|
-
var
|
|
33
|
-
__export(
|
|
32
|
+
var src_exports = {};
|
|
33
|
+
__export(src_exports, {
|
|
34
34
|
AssetsServiceProvider: () => AssetsServiceProvider,
|
|
35
35
|
RouteServiceProvider: () => RouteServiceProvider,
|
|
36
36
|
Router: () => Router
|
|
37
37
|
});
|
|
38
|
-
module.exports = __toCommonJS(
|
|
38
|
+
module.exports = __toCommonJS(src_exports);
|
|
39
39
|
|
|
40
40
|
// src/Router.ts
|
|
41
|
+
var import_http = require("@h3ravel/http");
|
|
41
42
|
var import_core = require("@h3ravel/core");
|
|
42
43
|
var import_support = require("@h3ravel/support");
|
|
43
44
|
var Router = class {
|
|
@@ -62,7 +63,10 @@ var Router = class {
|
|
|
62
63
|
*/
|
|
63
64
|
resolveHandler(handler, middleware = []) {
|
|
64
65
|
return async (event) => {
|
|
65
|
-
const kernel = new import_core.Kernel(
|
|
66
|
+
const kernel = new import_core.Kernel(() => ({
|
|
67
|
+
request: new import_http.Request(event),
|
|
68
|
+
response: new import_http.Response(event)
|
|
69
|
+
}), middleware);
|
|
66
70
|
return kernel.handle(event, (ctx) => Promise.resolve(handler(ctx)));
|
|
67
71
|
};
|
|
68
72
|
}
|
|
@@ -91,7 +95,7 @@ var Router = class {
|
|
|
91
95
|
const controller = new handler(this.app);
|
|
92
96
|
const action = methodName || "index";
|
|
93
97
|
if (typeof controller[action] !== "function") {
|
|
94
|
-
throw new Error(`Method "${action}" not found on controller ${handler.name}`);
|
|
98
|
+
throw new Error(`Method "${String(action)}" not found on controller ${handler.name}`);
|
|
95
99
|
}
|
|
96
100
|
return controller[action](ctx);
|
|
97
101
|
};
|
|
@@ -137,7 +141,8 @@ var Router = class {
|
|
|
137
141
|
*/
|
|
138
142
|
route(name, params = {}) {
|
|
139
143
|
const found = this.routes.find((r) => r.name === name);
|
|
140
|
-
if (!found)
|
|
144
|
+
if (!found)
|
|
145
|
+
return void 0;
|
|
141
146
|
let url = found.path;
|
|
142
147
|
for (const [key, value] of Object.entries(params)) {
|
|
143
148
|
url = url.replace(`:${key}`, value);
|
|
@@ -187,11 +192,11 @@ var AssetsServiceProvider = class extends import_core2.ServiceProvider {
|
|
|
187
192
|
indexNames: [
|
|
188
193
|
"/index.html"
|
|
189
194
|
],
|
|
190
|
-
getContents:
|
|
195
|
+
getContents: (id) => {
|
|
191
196
|
const newId = id.replace(`/${fsconfig.public_mask}/`, "");
|
|
192
197
|
return (0, import_promises.readFile)((0, import_node_path.join)((0, import_support2.before)(publicPath, newId), newId));
|
|
193
|
-
},
|
|
194
|
-
getMeta:
|
|
198
|
+
},
|
|
199
|
+
getMeta: async (id) => {
|
|
195
200
|
const newId = id.replace(`/${fsconfig.public_mask}/`, "");
|
|
196
201
|
const stats = await (0, import_promises.stat)((0, import_node_path.join)((0, import_support2.before)(publicPath, newId), newId)).catch(() => {
|
|
197
202
|
});
|
|
@@ -201,7 +206,7 @@ var AssetsServiceProvider = class extends import_core2.ServiceProvider {
|
|
|
201
206
|
mtime: stats.mtimeMs
|
|
202
207
|
};
|
|
203
208
|
}
|
|
204
|
-
}
|
|
209
|
+
}
|
|
205
210
|
});
|
|
206
211
|
});
|
|
207
212
|
this.app.singleton("asset", () => {
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/Router.ts","../src/Providers/AssetsServiceProvider.ts","../src/Providers/RouteServiceProvider.ts"],"sourcesContent":["/**\n * @file Automatically generated by barrelsby.\n */\n\nexport * from './Controller';\nexport * from './Route';\nexport * from './Router';\nexport * from './Decorators/ApiResource';\nexport * from './Decorators/Controller';\nexport * from './Decorators/Get';\nexport * from './Decorators/Middleware';\nexport * from './Decorators/Post';\nexport * from './Providers/AssetsServiceProvider';\nexport * from './Providers/RouteServiceProvider';\n","import { H3Event, Middleware, MiddlewareOptions, type H3 } from 'h3'\nimport { Application, Controller, Kernel } from '@h3ravel/core'\nimport { Middleware as HttpMiddleware } from '@h3ravel/http'\nimport { HttpContext } from '@h3ravel/http'\nimport { afterLast } from '@h3ravel/support'\n\ntype EventHandler = (ctx: HttpContext) => unknown\n\ninterface RouteDefinition {\n method: string\n path: string\n name?: string\n handler: EventHandler\n}\n\nexport class Router {\n private routes: RouteDefinition[] = []\n private groupPrefix = ''\n private groupMiddleware: EventHandler[] = []\n\n constructor(private h3App: H3, private app: Application) { }\n\n /**\n * Route Resolver\n * \n * @param handler \n * @param middleware \n * @returns \n */\n private resolveHandler (handler: EventHandler, middleware: HttpMiddleware[] = []) {\n return async (event: H3Event) => {\n const kernel = new Kernel(middleware)\n return kernel.handle(event, (ctx) => Promise.resolve(handler(ctx)))\n }\n }\n\n /**\n * Add a route to the stack\n * \n * @param method \n * @param path \n * @param handler \n * @param name \n * @param middleware \n */\n private addRoute (\n method: string,\n path: string,\n handler: EventHandler,\n name?: string,\n middleware: HttpMiddleware[] = []\n ) {\n const fullPath = `${this.groupPrefix}${path}`.replace(/\\/+/g, '/')\n this.routes.push({ method, path: fullPath, name, handler })\n this.h3App[method as 'get'](fullPath, this.resolveHandler(handler, middleware))\n }\n\n private resolveControllerOrHandler (\n handler: EventHandler | (new (...args: any[]) => Controller),\n methodName?: string\n ): EventHandler {\n if (typeof handler === 'function' && (handler as any).prototype instanceof Controller) {\n return (ctx) => {\n const controller = new (handler as new (...args: any[]) => Controller)(this.app)\n const action = (methodName || 'index') as keyof Controller\n\n if (typeof controller[action] !== 'function') {\n throw new Error(`Method \"${action}\" not found on controller ${handler.name}`)\n }\n\n return controller[action](ctx)\n }\n }\n\n return handler as EventHandler\n }\n\n\n get (\n path: string,\n handler: EventHandler | (new (...args: any[]) => Controller),\n methodName?: string, name?: string, middleware: HttpMiddleware[] = []\n ) {\n this.addRoute('get', path, this.resolveControllerOrHandler(handler, methodName), name, middleware)\n }\n\n post (\n path: string,\n handler: EventHandler | (new (...args: any[]) => Controller),\n methodName?: string, name?: string, middleware: HttpMiddleware[] = []\n ) {\n this.addRoute('post', path, this.resolveControllerOrHandler(handler, methodName), name, middleware)\n }\n\n put (\n path: string,\n handler: EventHandler | (new (...args: any[]) => Controller),\n methodName?: string, name?: string, middleware: HttpMiddleware[] = []\n ) {\n this.addRoute('put', path, this.resolveControllerOrHandler(handler, methodName), name, middleware)\n }\n\n delete (\n path: string,\n handler: EventHandler | (new (...args: any[]) => Controller),\n methodName?: string, name?: string, middleware: HttpMiddleware[] = []\n ) {\n this.addRoute('delete', path, this.resolveControllerOrHandler(handler, methodName), name, middleware)\n }\n\n /**\n * API Resource support \n * \n * @param path \n * @param controller \n */\n apiResource (\n path: string,\n Controller: new (app: Application) => Controller,\n middleware: HttpMiddleware[] = []\n ) {\n path = path.replace(/\\//g, '/')\n\n const name = afterLast(path, '/')\n const basePath = `/${path}`.replace(/\\/+/g, '/')\n\n const controller = new Controller(this.app)\n\n this.addRoute('get', basePath, controller.index.bind(controller), `${name}.index`, middleware)\n this.addRoute('post', basePath, controller.store.bind(controller), `${name}.store`, middleware)\n this.addRoute('get', `${basePath}/:id`, controller.show.bind(controller), `${name}.show`, middleware)\n this.addRoute('put', `${basePath}/:id`, controller.update.bind(controller), `${name}.update`, middleware)\n this.addRoute('patch', `${basePath}/:id`, controller.update.bind(controller), `${name}.update`, middleware)\n this.addRoute('delete', `${basePath}/:id`, controller.destroy.bind(controller), `${name}.destroy`, middleware)\n }\n\n /**\n * Named route URL generator\n * \n * @param name \n * @param params \n * @returns \n */\n route (name: string, params: Record<string, string> = {}): string | undefined {\n const found = this.routes.find(r => r.name === name)\n if (!found) return undefined\n\n let url = found.path\n for (const [key, value] of Object.entries(params)) {\n url = url.replace(`:${key}`, value)\n }\n return url\n }\n\n /**\n * Grouping\n * \n * @param options \n * @param callback \n */\n group (options: { prefix?: string; middleware?: EventHandler[] }, callback: () => void) {\n const prevPrefix = this.groupPrefix\n const prevMiddleware = [...this.groupMiddleware]\n\n this.groupPrefix += options.prefix || ''\n this.groupMiddleware.push(...(options.middleware || []))\n\n callback()\n\n /**\n * Restore state after group\n */\n this.groupPrefix = prevPrefix\n this.groupMiddleware = prevMiddleware\n }\n\n middleware (path: string, handler: Middleware, opts?: MiddlewareOptions) {\n this.h3App.use(path, handler, opts)\n }\n}\n","import { readFile, stat } from \"node:fs/promises\";\n\nimport { ServiceProvider } from '@h3ravel/core'\nimport { before } from \"@h3ravel/support\";\nimport { join } from \"node:path\";\nimport { serveStatic } from 'h3'\nimport { statSync } from \"node:fs\";\n\n/**\n * Handles public assets loading\n * \n * Auto-Registered\n */\nexport class AssetsServiceProvider extends ServiceProvider {\n register () {\n const app = this.app.make('router')\n const config = this.app.make('config')\n const fsconfig = config.get('filesystem')\n const publicPath = this.app.getPath('public')\n\n app.middleware(`/${fsconfig.public_mask}/**`, (event) => {\n return serveStatic(event, {\n indexNames: [\"/index.html\"],\n getContents: (id) => {\n const newId = id.replace(`/${fsconfig.public_mask}/`, '')\n return readFile(join(before(publicPath, newId), newId))\n },\n getMeta: async (id) => {\n const newId = id.replace(`/${fsconfig.public_mask}/`, '')\n const stats = await stat(join(before(publicPath, newId), newId)).catch(() => { });\n if (stats?.isFile()) {\n return {\n size: stats.size,\n mtime: stats.mtimeMs,\n };\n }\n },\n });\n })\n\n this.app.singleton('asset', () => {\n return (key: string, def = '') => {\n try {\n statSync(join(before(publicPath, key), key))\n } catch {\n key = def\n }\n\n return join(fsconfig.public_mask, key)\n }\n })\n }\n}\n","import { Router } from '../Router'\nimport { ServiceProvider } from '@h3ravel/core'\nimport path from 'node:path'\nimport { readdir } from 'node:fs/promises'\n\n/**\n * Handles routing registration\n * \n * Load route files (web.ts, api.ts).\n * Map controllers to routes.\n * Register route-related middleware.\n * \n * Auto-Registered\n */\nexport class RouteServiceProvider extends ServiceProvider {\n register () {\n this.app.singleton('router', () => {\n const h3App = this.app.make('http.app')\n return new Router(h3App, this.app)\n })\n }\n\n /**\n * Load routes from src/routes\n */\n async boot () {\n try {\n const routePath = this.app.getPath('routes')\n\n const files = await readdir(routePath);\n\n for (let i = 0; i < files.length; i++) {\n const routesModule = await import(path.join(routePath, files[i]))\n\n if (typeof routesModule.default === 'function') {\n const router = this.app.make('router')\n routesModule.default(router)\n }\n }\n } catch (e) {\n console.warn('No web routes found or failed to load:', e)\n }\n }\n}\n"],"mappings":"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","names":["Router","routes","groupPrefix","groupMiddleware","h3App","app","resolveHandler","handler","middleware","event","kernel","Kernel","handle","ctx","Promise","resolve","addRoute","method","path","name","fullPath","replace","push","resolveControllerOrHandler","methodName","prototype","Controller","controller","action","Error","get","post","put","delete","apiResource","afterLast","basePath","index","bind","store","show","update","destroy","route","params","found","find","r","undefined","url","key","value","Object","entries","group","options","callback","prevPrefix","prevMiddleware","prefix","opts","use","import_core","import_support","AssetsServiceProvider","ServiceProvider","register","app","make","config","fsconfig","get","publicPath","getPath","middleware","public_mask","event","serveStatic","indexNames","getContents","id","newId","replace","readFile","join","before","getMeta","stats","stat","catch","isFile","size","mtime","mtimeMs","singleton","key","def","statSync","import_core","import_node_path","import_promises","RouteServiceProvider","ServiceProvider","register","app","singleton","h3App","make","Router","boot","routePath","getPath","files","readdir","i","length","routesModule","path","join","default","router","e","console","warn"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/Router.ts","../src/Providers/AssetsServiceProvider.ts","../src/Providers/RouteServiceProvider.ts"],"sourcesContent":["/**\n * @file Automatically generated by barrelsby.\n */\n\nexport * from './Controller';\nexport * from './Route';\nexport * from './Router';\nexport * from './Decorators/ApiResource';\nexport * from './Decorators/Controller';\nexport * from './Decorators/Get';\nexport * from './Decorators/Middleware';\nexport * from './Decorators/Post';\nexport * from './Providers/AssetsServiceProvider';\nexport * from './Providers/RouteServiceProvider';\n","import { H3Event, Middleware, MiddlewareOptions, type H3 } from 'h3'\nimport { Request, Response } from '@h3ravel/http'\nimport { Controller, Kernel } from '@h3ravel/core'\nimport { afterLast } from '@h3ravel/support'\nimport { EventHandler, HttpContext, IApplication, IController, IMiddleware } from '@h3ravel/shared'\n\ninterface RouteDefinition {\n method: string\n path: string\n name?: string\n handler: EventHandler\n}\n\nexport class Router {\n private routes: RouteDefinition[] = []\n private groupPrefix = ''\n private groupMiddleware: EventHandler[] = []\n\n constructor(protected h3App: H3, private app: IApplication) { }\n\n /**\n * Route Resolver\n * \n * @param handler \n * @param middleware \n * @returns \n */\n private resolveHandler (handler: EventHandler, middleware: IMiddleware[] = []) {\n return async (event: H3Event) => {\n const kernel = new Kernel(() => ({\n request: new Request(event),\n response: new Response(event)\n }), middleware)\n\n return kernel.handle(event, (ctx) => Promise.resolve(handler(ctx)))\n }\n }\n\n /**\n * Add a route to the stack\n * \n * @param method \n * @param path \n * @param handler \n * @param name \n * @param middleware \n */\n private addRoute (\n method: string,\n path: string,\n handler: EventHandler,\n name?: string,\n middleware: IMiddleware[] = []\n ) {\n const fullPath = `${this.groupPrefix}${path}`.replace(/\\/+/g, '/')\n this.routes.push({ method, path: fullPath, name, handler })\n this.h3App[method as 'get'](fullPath, this.resolveHandler(handler, middleware))\n }\n\n private resolveControllerOrHandler (\n handler: EventHandler | (new (...args: any[]) => IController),\n methodName?: string\n ): EventHandler {\n if (typeof handler === 'function' && (handler as any).prototype instanceof Controller) {\n return (ctx) => {\n const controller = new (handler as new (...args: any[]) => IController)(this.app)\n const action = (methodName || 'index') as keyof IController\n\n if (typeof controller[action] !== 'function') {\n throw new Error(`Method \"${String(action)}\" not found on controller ${handler.name}`)\n }\n\n return controller[action](ctx)\n }\n }\n\n return handler as EventHandler\n }\n\n\n get (\n path: string,\n handler: EventHandler | (new (...args: any[]) => IController),\n methodName?: string, name?: string, middleware: IMiddleware[] = []\n ) {\n this.addRoute('get', path, this.resolveControllerOrHandler(handler, methodName), name, middleware)\n }\n\n post (\n path: string,\n handler: EventHandler | (new (...args: any[]) => IController),\n methodName?: string, name?: string, middleware: IMiddleware[] = []\n ) {\n this.addRoute('post', path, this.resolveControllerOrHandler(handler, methodName), name, middleware)\n }\n\n put (\n path: string,\n handler: EventHandler | (new (...args: any[]) => IController),\n methodName?: string, name?: string, middleware: IMiddleware[] = []\n ) {\n this.addRoute('put', path, this.resolveControllerOrHandler(handler, methodName), name, middleware)\n }\n\n delete (\n path: string,\n handler: EventHandler | (new (...args: any[]) => IController),\n methodName?: string, name?: string, middleware: IMiddleware[] = []\n ) {\n this.addRoute('delete', path, this.resolveControllerOrHandler(handler, methodName), name, middleware)\n }\n\n /**\n * API Resource support \n * \n * @param path \n * @param controller \n */\n apiResource (\n path: string,\n Controller: new (app: IApplication) => IController,\n middleware: IMiddleware[] = []\n ) {\n path = path.replace(/\\//g, '/')\n\n const name = afterLast(path, '/')\n const basePath = `/${path}`.replace(/\\/+/g, '/')\n\n const controller = new Controller(this.app)\n\n this.addRoute('get', basePath, controller.index.bind(controller), `${name}.index`, middleware)\n this.addRoute('post', basePath, controller.store.bind(controller), `${name}.store`, middleware)\n this.addRoute('get', `${basePath}/:id`, controller.show.bind(controller), `${name}.show`, middleware)\n this.addRoute('put', `${basePath}/:id`, controller.update.bind(controller), `${name}.update`, middleware)\n this.addRoute('patch', `${basePath}/:id`, controller.update.bind(controller), `${name}.update`, middleware)\n this.addRoute('delete', `${basePath}/:id`, controller.destroy.bind(controller), `${name}.destroy`, middleware)\n }\n\n /**\n * Named route URL generator\n * \n * @param name \n * @param params \n * @returns \n */\n route (name: string, params: Record<string, string> = {}): string | undefined {\n const found = this.routes.find(r => r.name === name)\n if (!found) return undefined\n\n let url = found.path\n for (const [key, value] of Object.entries(params)) {\n url = url.replace(`:${key}`, value)\n }\n return url\n }\n\n /**\n * Grouping\n * \n * @param options \n * @param callback \n */\n group (options: { prefix?: string; middleware?: EventHandler[] }, callback: () => void) {\n const prevPrefix = this.groupPrefix\n const prevMiddleware = [...this.groupMiddleware]\n\n this.groupPrefix += options.prefix || ''\n this.groupMiddleware.push(...(options.middleware || []))\n\n callback()\n\n /**\n * Restore state after group\n */\n this.groupPrefix = prevPrefix\n this.groupMiddleware = prevMiddleware\n }\n\n middleware (path: string, handler: Middleware, opts?: MiddlewareOptions) {\n this.h3App.use(path, handler, opts)\n }\n}\n","import { readFile, stat } from \"node:fs/promises\";\n\nimport { ServiceProvider } from '@h3ravel/core'\nimport { before } from \"@h3ravel/support\";\nimport { join } from \"node:path\";\nimport { serveStatic } from 'h3'\nimport { statSync } from \"node:fs\";\n\n/**\n * Handles public assets loading\n * \n * Auto-Registered\n */\nexport class AssetsServiceProvider extends ServiceProvider {\n register () {\n const app = this.app.make('router')\n const config = this.app.make('config')\n const fsconfig = config.get('filesystem')\n const publicPath = this.app.getPath('public')\n\n app.middleware(`/${fsconfig.public_mask}/**`, (event) => {\n return serveStatic(event, {\n indexNames: [\"/index.html\"],\n getContents: (id) => {\n const newId = id.replace(`/${fsconfig.public_mask}/`, '')\n return readFile(join(before(publicPath, newId), newId))\n },\n getMeta: async (id) => {\n const newId = id.replace(`/${fsconfig.public_mask}/`, '')\n const stats = await stat(join(before(publicPath, newId), newId)).catch(() => { });\n if (stats?.isFile()) {\n return {\n size: stats.size,\n mtime: stats.mtimeMs,\n };\n }\n },\n });\n })\n\n this.app.singleton('asset', () => {\n return (key: string, def = '') => {\n try {\n statSync(join(before(publicPath, key), key))\n } catch {\n key = def\n }\n\n return join(fsconfig.public_mask, key)\n }\n })\n }\n}\n","import { Router } from '../Router'\nimport { ServiceProvider } from '@h3ravel/core'\nimport path from 'node:path'\nimport { readdir } from 'node:fs/promises'\n\n/**\n * Handles routing registration\n * \n * Load route files (web.ts, api.ts).\n * Map controllers to routes.\n * Register route-related middleware.\n * \n * Auto-Registered\n */\nexport class RouteServiceProvider extends ServiceProvider {\n register () {\n this.app.singleton('router', () => {\n const h3App = this.app.make('http.app')\n return new Router(h3App, this.app)\n })\n }\n\n /**\n * Load routes from src/routes\n */\n async boot () {\n try {\n const routePath = this.app.getPath('routes')\n\n const files = await readdir(routePath);\n\n for (let i = 0; i < files.length; i++) {\n const routesModule = await import(path.join(routePath, files[i]))\n\n if (typeof routesModule.default === 'function') {\n const router = this.app.make('router')\n routesModule.default(router)\n }\n }\n } catch (e) {\n console.warn('No web routes found or failed to load:', e)\n }\n }\n}\n"],"mappings":"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","names":["Router","routes","groupPrefix","groupMiddleware","h3App","app","resolveHandler","handler","middleware","event","kernel","Kernel","request","Request","response","Response","handle","ctx","Promise","resolve","addRoute","method","path","name","fullPath","replace","push","resolveControllerOrHandler","methodName","prototype","Controller","controller","action","Error","String","get","post","put","delete","apiResource","afterLast","basePath","index","bind","store","show","update","destroy","route","params","found","find","r","undefined","url","key","value","Object","entries","group","options","callback","prevPrefix","prevMiddleware","prefix","opts","use","import_core","import_support","AssetsServiceProvider","ServiceProvider","register","app","make","config","fsconfig","get","publicPath","getPath","middleware","public_mask","event","serveStatic","indexNames","getContents","id","newId","replace","readFile","join","before","getMeta","stats","stat","catch","isFile","size","mtime","mtimeMs","singleton","key","def","statSync","import_core","import_node_path","import_promises","RouteServiceProvider","ServiceProvider","register","app","singleton","h3App","make","Router","boot","routePath","getPath","files","readdir","i","length","routesModule","path","join","default","router","e","console","warn"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -1,87 +1,14 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { H3, Middleware, MiddlewareOptions } from 'h3';
|
|
2
|
+
import { IApplication, EventHandler, IController, IMiddleware } from '@h3ravel/shared';
|
|
3
|
+
import { ServiceProvider } from '@h3ravel/core';
|
|
4
4
|
|
|
5
|
-
declare class Request {
|
|
6
|
-
private readonly event;
|
|
7
|
-
constructor(event: H3Event);
|
|
8
|
-
/**
|
|
9
|
-
* Get all input data (query + body).
|
|
10
|
-
*/
|
|
11
|
-
all<T = Record<string, unknown>>(): Promise<T>;
|
|
12
|
-
/**
|
|
13
|
-
* Get a single input field from query or body.
|
|
14
|
-
*/
|
|
15
|
-
input<T = unknown>(key: string, defaultValue?: T): Promise<T>;
|
|
16
|
-
/**
|
|
17
|
-
* Get route parameters.
|
|
18
|
-
*/
|
|
19
|
-
params<T = Record<string, string>>(): T;
|
|
20
|
-
/**
|
|
21
|
-
* Get query parameters.
|
|
22
|
-
*/
|
|
23
|
-
query<T = Record<string, string>>(): T;
|
|
24
|
-
/**
|
|
25
|
-
* Get the base event
|
|
26
|
-
*/
|
|
27
|
-
getEvent(): H3Event;
|
|
28
|
-
getEvent<K extends DotNestedKeys<H3Event>>(key: K): DotNestedValue<H3Event, K>;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
declare class Response {
|
|
32
|
-
private readonly event;
|
|
33
|
-
private statusCode;
|
|
34
|
-
private headers;
|
|
35
|
-
constructor(event: H3Event);
|
|
36
|
-
/**
|
|
37
|
-
* Set HTTP status code.
|
|
38
|
-
*/
|
|
39
|
-
setStatusCode(code: number): this;
|
|
40
|
-
/**
|
|
41
|
-
* Set a header.
|
|
42
|
-
*/
|
|
43
|
-
setHeader(name: string, value: string): this;
|
|
44
|
-
html(content: string): string;
|
|
45
|
-
/**
|
|
46
|
-
* Send a JSON response.
|
|
47
|
-
*/
|
|
48
|
-
json<T = unknown>(data: T): T;
|
|
49
|
-
/**
|
|
50
|
-
* Send plain text.
|
|
51
|
-
*/
|
|
52
|
-
text(data: string): string;
|
|
53
|
-
/**
|
|
54
|
-
* Redirect to another URL.
|
|
55
|
-
*/
|
|
56
|
-
redirect(url: string, status?: number): string;
|
|
57
|
-
/**
|
|
58
|
-
* Apply headers before sending response.
|
|
59
|
-
*/
|
|
60
|
-
private applyHeaders;
|
|
61
|
-
/**
|
|
62
|
-
* Get the base event
|
|
63
|
-
*/
|
|
64
|
-
getEvent(): H3Event;
|
|
65
|
-
getEvent<K extends DotNestedKeys<H3Event>>(key: K): DotNestedValue<H3Event, K>;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
interface HttpContext {
|
|
69
|
-
request: Request;
|
|
70
|
-
response: Response;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
declare abstract class Middleware {
|
|
74
|
-
abstract handle(context: HttpContext, next: () => Promise<unknown>): Promise<unknown>;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
type EventHandler = (ctx: HttpContext) => unknown;
|
|
78
5
|
declare class Router {
|
|
79
|
-
|
|
6
|
+
protected h3App: H3;
|
|
80
7
|
private app;
|
|
81
8
|
private routes;
|
|
82
9
|
private groupPrefix;
|
|
83
10
|
private groupMiddleware;
|
|
84
|
-
constructor(h3App: H3, app:
|
|
11
|
+
constructor(h3App: H3, app: IApplication);
|
|
85
12
|
/**
|
|
86
13
|
* Route Resolver
|
|
87
14
|
*
|
|
@@ -101,17 +28,17 @@ declare class Router {
|
|
|
101
28
|
*/
|
|
102
29
|
private addRoute;
|
|
103
30
|
private resolveControllerOrHandler;
|
|
104
|
-
get(path: string, handler: EventHandler | (new (...args: any[]) =>
|
|
105
|
-
post(path: string, handler: EventHandler | (new (...args: any[]) =>
|
|
106
|
-
put(path: string, handler: EventHandler | (new (...args: any[]) =>
|
|
107
|
-
delete(path: string, handler: EventHandler | (new (...args: any[]) =>
|
|
31
|
+
get(path: string, handler: EventHandler | (new (...args: any[]) => IController), methodName?: string, name?: string, middleware?: IMiddleware[]): void;
|
|
32
|
+
post(path: string, handler: EventHandler | (new (...args: any[]) => IController), methodName?: string, name?: string, middleware?: IMiddleware[]): void;
|
|
33
|
+
put(path: string, handler: EventHandler | (new (...args: any[]) => IController), methodName?: string, name?: string, middleware?: IMiddleware[]): void;
|
|
34
|
+
delete(path: string, handler: EventHandler | (new (...args: any[]) => IController), methodName?: string, name?: string, middleware?: IMiddleware[]): void;
|
|
108
35
|
/**
|
|
109
36
|
* API Resource support
|
|
110
37
|
*
|
|
111
38
|
* @param path
|
|
112
39
|
* @param controller
|
|
113
40
|
*/
|
|
114
|
-
apiResource(path: string, Controller: new (app:
|
|
41
|
+
apiResource(path: string, Controller: new (app: IApplication) => IController, middleware?: IMiddleware[]): void;
|
|
115
42
|
/**
|
|
116
43
|
* Named route URL generator
|
|
117
44
|
*
|
|
@@ -130,7 +57,7 @@ declare class Router {
|
|
|
130
57
|
prefix?: string;
|
|
131
58
|
middleware?: EventHandler[];
|
|
132
59
|
}, callback: () => void): void;
|
|
133
|
-
middleware(path: string, handler: Middleware
|
|
60
|
+
middleware(path: string, handler: Middleware, opts?: MiddlewareOptions): void;
|
|
134
61
|
}
|
|
135
62
|
|
|
136
63
|
/**
|
package/dist/index.d.ts
CHANGED
|
@@ -1,87 +1,14 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { H3, Middleware, MiddlewareOptions } from 'h3';
|
|
2
|
+
import { IApplication, EventHandler, IController, IMiddleware } from '@h3ravel/shared';
|
|
3
|
+
import { ServiceProvider } from '@h3ravel/core';
|
|
4
4
|
|
|
5
|
-
declare class Request {
|
|
6
|
-
private readonly event;
|
|
7
|
-
constructor(event: H3Event);
|
|
8
|
-
/**
|
|
9
|
-
* Get all input data (query + body).
|
|
10
|
-
*/
|
|
11
|
-
all<T = Record<string, unknown>>(): Promise<T>;
|
|
12
|
-
/**
|
|
13
|
-
* Get a single input field from query or body.
|
|
14
|
-
*/
|
|
15
|
-
input<T = unknown>(key: string, defaultValue?: T): Promise<T>;
|
|
16
|
-
/**
|
|
17
|
-
* Get route parameters.
|
|
18
|
-
*/
|
|
19
|
-
params<T = Record<string, string>>(): T;
|
|
20
|
-
/**
|
|
21
|
-
* Get query parameters.
|
|
22
|
-
*/
|
|
23
|
-
query<T = Record<string, string>>(): T;
|
|
24
|
-
/**
|
|
25
|
-
* Get the base event
|
|
26
|
-
*/
|
|
27
|
-
getEvent(): H3Event;
|
|
28
|
-
getEvent<K extends DotNestedKeys<H3Event>>(key: K): DotNestedValue<H3Event, K>;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
declare class Response {
|
|
32
|
-
private readonly event;
|
|
33
|
-
private statusCode;
|
|
34
|
-
private headers;
|
|
35
|
-
constructor(event: H3Event);
|
|
36
|
-
/**
|
|
37
|
-
* Set HTTP status code.
|
|
38
|
-
*/
|
|
39
|
-
setStatusCode(code: number): this;
|
|
40
|
-
/**
|
|
41
|
-
* Set a header.
|
|
42
|
-
*/
|
|
43
|
-
setHeader(name: string, value: string): this;
|
|
44
|
-
html(content: string): string;
|
|
45
|
-
/**
|
|
46
|
-
* Send a JSON response.
|
|
47
|
-
*/
|
|
48
|
-
json<T = unknown>(data: T): T;
|
|
49
|
-
/**
|
|
50
|
-
* Send plain text.
|
|
51
|
-
*/
|
|
52
|
-
text(data: string): string;
|
|
53
|
-
/**
|
|
54
|
-
* Redirect to another URL.
|
|
55
|
-
*/
|
|
56
|
-
redirect(url: string, status?: number): string;
|
|
57
|
-
/**
|
|
58
|
-
* Apply headers before sending response.
|
|
59
|
-
*/
|
|
60
|
-
private applyHeaders;
|
|
61
|
-
/**
|
|
62
|
-
* Get the base event
|
|
63
|
-
*/
|
|
64
|
-
getEvent(): H3Event;
|
|
65
|
-
getEvent<K extends DotNestedKeys<H3Event>>(key: K): DotNestedValue<H3Event, K>;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
interface HttpContext {
|
|
69
|
-
request: Request;
|
|
70
|
-
response: Response;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
declare abstract class Middleware {
|
|
74
|
-
abstract handle(context: HttpContext, next: () => Promise<unknown>): Promise<unknown>;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
type EventHandler = (ctx: HttpContext) => unknown;
|
|
78
5
|
declare class Router {
|
|
79
|
-
|
|
6
|
+
protected h3App: H3;
|
|
80
7
|
private app;
|
|
81
8
|
private routes;
|
|
82
9
|
private groupPrefix;
|
|
83
10
|
private groupMiddleware;
|
|
84
|
-
constructor(h3App: H3, app:
|
|
11
|
+
constructor(h3App: H3, app: IApplication);
|
|
85
12
|
/**
|
|
86
13
|
* Route Resolver
|
|
87
14
|
*
|
|
@@ -101,17 +28,17 @@ declare class Router {
|
|
|
101
28
|
*/
|
|
102
29
|
private addRoute;
|
|
103
30
|
private resolveControllerOrHandler;
|
|
104
|
-
get(path: string, handler: EventHandler | (new (...args: any[]) =>
|
|
105
|
-
post(path: string, handler: EventHandler | (new (...args: any[]) =>
|
|
106
|
-
put(path: string, handler: EventHandler | (new (...args: any[]) =>
|
|
107
|
-
delete(path: string, handler: EventHandler | (new (...args: any[]) =>
|
|
31
|
+
get(path: string, handler: EventHandler | (new (...args: any[]) => IController), methodName?: string, name?: string, middleware?: IMiddleware[]): void;
|
|
32
|
+
post(path: string, handler: EventHandler | (new (...args: any[]) => IController), methodName?: string, name?: string, middleware?: IMiddleware[]): void;
|
|
33
|
+
put(path: string, handler: EventHandler | (new (...args: any[]) => IController), methodName?: string, name?: string, middleware?: IMiddleware[]): void;
|
|
34
|
+
delete(path: string, handler: EventHandler | (new (...args: any[]) => IController), methodName?: string, name?: string, middleware?: IMiddleware[]): void;
|
|
108
35
|
/**
|
|
109
36
|
* API Resource support
|
|
110
37
|
*
|
|
111
38
|
* @param path
|
|
112
39
|
* @param controller
|
|
113
40
|
*/
|
|
114
|
-
apiResource(path: string, Controller: new (app:
|
|
41
|
+
apiResource(path: string, Controller: new (app: IApplication) => IController, middleware?: IMiddleware[]): void;
|
|
115
42
|
/**
|
|
116
43
|
* Named route URL generator
|
|
117
44
|
*
|
|
@@ -130,7 +57,7 @@ declare class Router {
|
|
|
130
57
|
prefix?: string;
|
|
131
58
|
middleware?: EventHandler[];
|
|
132
59
|
}, callback: () => void): void;
|
|
133
|
-
middleware(path: string, handler: Middleware
|
|
60
|
+
middleware(path: string, handler: Middleware, opts?: MiddlewareOptions): void;
|
|
134
61
|
}
|
|
135
62
|
|
|
136
63
|
/**
|
package/dist/index.js
CHANGED
|
@@ -2,6 +2,7 @@ var __defProp = Object.defineProperty;
|
|
|
2
2
|
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
3
3
|
|
|
4
4
|
// src/Router.ts
|
|
5
|
+
import { Request, Response } from "@h3ravel/http";
|
|
5
6
|
import { Controller, Kernel } from "@h3ravel/core";
|
|
6
7
|
import { afterLast } from "@h3ravel/support";
|
|
7
8
|
var Router = class {
|
|
@@ -26,7 +27,10 @@ var Router = class {
|
|
|
26
27
|
*/
|
|
27
28
|
resolveHandler(handler, middleware = []) {
|
|
28
29
|
return async (event) => {
|
|
29
|
-
const kernel = new Kernel(
|
|
30
|
+
const kernel = new Kernel(() => ({
|
|
31
|
+
request: new Request(event),
|
|
32
|
+
response: new Response(event)
|
|
33
|
+
}), middleware);
|
|
30
34
|
return kernel.handle(event, (ctx) => Promise.resolve(handler(ctx)));
|
|
31
35
|
};
|
|
32
36
|
}
|
|
@@ -55,7 +59,7 @@ var Router = class {
|
|
|
55
59
|
const controller = new handler(this.app);
|
|
56
60
|
const action = methodName || "index";
|
|
57
61
|
if (typeof controller[action] !== "function") {
|
|
58
|
-
throw new Error(`Method "${action}" not found on controller ${handler.name}`);
|
|
62
|
+
throw new Error(`Method "${String(action)}" not found on controller ${handler.name}`);
|
|
59
63
|
}
|
|
60
64
|
return controller[action](ctx);
|
|
61
65
|
};
|
|
@@ -101,7 +105,8 @@ var Router = class {
|
|
|
101
105
|
*/
|
|
102
106
|
route(name, params = {}) {
|
|
103
107
|
const found = this.routes.find((r) => r.name === name);
|
|
104
|
-
if (!found)
|
|
108
|
+
if (!found)
|
|
109
|
+
return void 0;
|
|
105
110
|
let url = found.path;
|
|
106
111
|
for (const [key, value] of Object.entries(params)) {
|
|
107
112
|
url = url.replace(`:${key}`, value);
|
|
@@ -151,11 +156,11 @@ var AssetsServiceProvider = class extends ServiceProvider {
|
|
|
151
156
|
indexNames: [
|
|
152
157
|
"/index.html"
|
|
153
158
|
],
|
|
154
|
-
getContents:
|
|
159
|
+
getContents: (id) => {
|
|
155
160
|
const newId = id.replace(`/${fsconfig.public_mask}/`, "");
|
|
156
161
|
return readFile(join(before(publicPath, newId), newId));
|
|
157
|
-
},
|
|
158
|
-
getMeta:
|
|
162
|
+
},
|
|
163
|
+
getMeta: async (id) => {
|
|
159
164
|
const newId = id.replace(`/${fsconfig.public_mask}/`, "");
|
|
160
165
|
const stats = await stat(join(before(publicPath, newId), newId)).catch(() => {
|
|
161
166
|
});
|
|
@@ -165,7 +170,7 @@ var AssetsServiceProvider = class extends ServiceProvider {
|
|
|
165
170
|
mtime: stats.mtimeMs
|
|
166
171
|
};
|
|
167
172
|
}
|
|
168
|
-
}
|
|
173
|
+
}
|
|
169
174
|
});
|
|
170
175
|
});
|
|
171
176
|
this.app.singleton("asset", () => {
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/Router.ts","../src/Providers/AssetsServiceProvider.ts","../src/Providers/RouteServiceProvider.ts"],"sourcesContent":["import { H3Event, Middleware, MiddlewareOptions, type H3 } from 'h3'\nimport { Application, Controller, Kernel } from '@h3ravel/core'\nimport { Middleware as HttpMiddleware } from '@h3ravel/http'\nimport { HttpContext } from '@h3ravel/http'\nimport { afterLast } from '@h3ravel/support'\n\ntype EventHandler = (ctx: HttpContext) => unknown\n\ninterface RouteDefinition {\n method: string\n path: string\n name?: string\n handler: EventHandler\n}\n\nexport class Router {\n private routes: RouteDefinition[] = []\n private groupPrefix = ''\n private groupMiddleware: EventHandler[] = []\n\n constructor(private h3App: H3, private app: Application) { }\n\n /**\n * Route Resolver\n * \n * @param handler \n * @param middleware \n * @returns \n */\n private resolveHandler (handler: EventHandler, middleware: HttpMiddleware[] = []) {\n return async (event: H3Event) => {\n const kernel = new Kernel(middleware)\n return kernel.handle(event, (ctx) => Promise.resolve(handler(ctx)))\n }\n }\n\n /**\n * Add a route to the stack\n * \n * @param method \n * @param path \n * @param handler \n * @param name \n * @param middleware \n */\n private addRoute (\n method: string,\n path: string,\n handler: EventHandler,\n name?: string,\n middleware: HttpMiddleware[] = []\n ) {\n const fullPath = `${this.groupPrefix}${path}`.replace(/\\/+/g, '/')\n this.routes.push({ method, path: fullPath, name, handler })\n this.h3App[method as 'get'](fullPath, this.resolveHandler(handler, middleware))\n }\n\n private resolveControllerOrHandler (\n handler: EventHandler | (new (...args: any[]) => Controller),\n methodName?: string\n ): EventHandler {\n if (typeof handler === 'function' && (handler as any).prototype instanceof Controller) {\n return (ctx) => {\n const controller = new (handler as new (...args: any[]) => Controller)(this.app)\n const action = (methodName || 'index') as keyof Controller\n\n if (typeof controller[action] !== 'function') {\n throw new Error(`Method \"${action}\" not found on controller ${handler.name}`)\n }\n\n return controller[action](ctx)\n }\n }\n\n return handler as EventHandler\n }\n\n\n get (\n path: string,\n handler: EventHandler | (new (...args: any[]) => Controller),\n methodName?: string, name?: string, middleware: HttpMiddleware[] = []\n ) {\n this.addRoute('get', path, this.resolveControllerOrHandler(handler, methodName), name, middleware)\n }\n\n post (\n path: string,\n handler: EventHandler | (new (...args: any[]) => Controller),\n methodName?: string, name?: string, middleware: HttpMiddleware[] = []\n ) {\n this.addRoute('post', path, this.resolveControllerOrHandler(handler, methodName), name, middleware)\n }\n\n put (\n path: string,\n handler: EventHandler | (new (...args: any[]) => Controller),\n methodName?: string, name?: string, middleware: HttpMiddleware[] = []\n ) {\n this.addRoute('put', path, this.resolveControllerOrHandler(handler, methodName), name, middleware)\n }\n\n delete (\n path: string,\n handler: EventHandler | (new (...args: any[]) => Controller),\n methodName?: string, name?: string, middleware: HttpMiddleware[] = []\n ) {\n this.addRoute('delete', path, this.resolveControllerOrHandler(handler, methodName), name, middleware)\n }\n\n /**\n * API Resource support \n * \n * @param path \n * @param controller \n */\n apiResource (\n path: string,\n Controller: new (app: Application) => Controller,\n middleware: HttpMiddleware[] = []\n ) {\n path = path.replace(/\\//g, '/')\n\n const name = afterLast(path, '/')\n const basePath = `/${path}`.replace(/\\/+/g, '/')\n\n const controller = new Controller(this.app)\n\n this.addRoute('get', basePath, controller.index.bind(controller), `${name}.index`, middleware)\n this.addRoute('post', basePath, controller.store.bind(controller), `${name}.store`, middleware)\n this.addRoute('get', `${basePath}/:id`, controller.show.bind(controller), `${name}.show`, middleware)\n this.addRoute('put', `${basePath}/:id`, controller.update.bind(controller), `${name}.update`, middleware)\n this.addRoute('patch', `${basePath}/:id`, controller.update.bind(controller), `${name}.update`, middleware)\n this.addRoute('delete', `${basePath}/:id`, controller.destroy.bind(controller), `${name}.destroy`, middleware)\n }\n\n /**\n * Named route URL generator\n * \n * @param name \n * @param params \n * @returns \n */\n route (name: string, params: Record<string, string> = {}): string | undefined {\n const found = this.routes.find(r => r.name === name)\n if (!found) return undefined\n\n let url = found.path\n for (const [key, value] of Object.entries(params)) {\n url = url.replace(`:${key}`, value)\n }\n return url\n }\n\n /**\n * Grouping\n * \n * @param options \n * @param callback \n */\n group (options: { prefix?: string; middleware?: EventHandler[] }, callback: () => void) {\n const prevPrefix = this.groupPrefix\n const prevMiddleware = [...this.groupMiddleware]\n\n this.groupPrefix += options.prefix || ''\n this.groupMiddleware.push(...(options.middleware || []))\n\n callback()\n\n /**\n * Restore state after group\n */\n this.groupPrefix = prevPrefix\n this.groupMiddleware = prevMiddleware\n }\n\n middleware (path: string, handler: Middleware, opts?: MiddlewareOptions) {\n this.h3App.use(path, handler, opts)\n }\n}\n","import { readFile, stat } from \"node:fs/promises\";\n\nimport { ServiceProvider } from '@h3ravel/core'\nimport { before } from \"@h3ravel/support\";\nimport { join } from \"node:path\";\nimport { serveStatic } from 'h3'\nimport { statSync } from \"node:fs\";\n\n/**\n * Handles public assets loading\n * \n * Auto-Registered\n */\nexport class AssetsServiceProvider extends ServiceProvider {\n register () {\n const app = this.app.make('router')\n const config = this.app.make('config')\n const fsconfig = config.get('filesystem')\n const publicPath = this.app.getPath('public')\n\n app.middleware(`/${fsconfig.public_mask}/**`, (event) => {\n return serveStatic(event, {\n indexNames: [\"/index.html\"],\n getContents: (id) => {\n const newId = id.replace(`/${fsconfig.public_mask}/`, '')\n return readFile(join(before(publicPath, newId), newId))\n },\n getMeta: async (id) => {\n const newId = id.replace(`/${fsconfig.public_mask}/`, '')\n const stats = await stat(join(before(publicPath, newId), newId)).catch(() => { });\n if (stats?.isFile()) {\n return {\n size: stats.size,\n mtime: stats.mtimeMs,\n };\n }\n },\n });\n })\n\n this.app.singleton('asset', () => {\n return (key: string, def = '') => {\n try {\n statSync(join(before(publicPath, key), key))\n } catch {\n key = def\n }\n\n return join(fsconfig.public_mask, key)\n }\n })\n }\n}\n","import { Router } from '../Router'\nimport { ServiceProvider } from '@h3ravel/core'\nimport path from 'node:path'\nimport { readdir } from 'node:fs/promises'\n\n/**\n * Handles routing registration\n * \n * Load route files (web.ts, api.ts).\n * Map controllers to routes.\n * Register route-related middleware.\n * \n * Auto-Registered\n */\nexport class RouteServiceProvider extends ServiceProvider {\n register () {\n this.app.singleton('router', () => {\n const h3App = this.app.make('http.app')\n return new Router(h3App, this.app)\n })\n }\n\n /**\n * Load routes from src/routes\n */\n async boot () {\n try {\n const routePath = this.app.getPath('routes')\n\n const files = await readdir(routePath);\n\n for (let i = 0; i < files.length; i++) {\n const routesModule = await import(path.join(routePath, files[i]))\n\n if (typeof routesModule.default === 'function') {\n const router = this.app.make('router')\n routesModule.default(router)\n }\n }\n } catch (e) {\n console.warn('No web routes found or failed to load:', e)\n }\n }\n}\n"],"mappings":"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","names":["Controller","Kernel","afterLast","Router","routes","groupPrefix","groupMiddleware","h3App","app","resolveHandler","handler","middleware","event","kernel","Kernel","handle","ctx","Promise","resolve","addRoute","method","path","name","fullPath","replace","push","resolveControllerOrHandler","methodName","prototype","Controller","controller","action","Error","get","post","put","delete","apiResource","afterLast","basePath","index","bind","store","show","update","destroy","route","params","found","find","r","undefined","url","key","value","Object","entries","group","options","callback","prevPrefix","prevMiddleware","prefix","opts","use","readFile","stat","ServiceProvider","before","join","serveStatic","statSync","AssetsServiceProvider","ServiceProvider","register","app","make","config","fsconfig","get","publicPath","getPath","middleware","public_mask","event","serveStatic","indexNames","getContents","id","newId","replace","readFile","join","before","getMeta","stats","stat","catch","isFile","size","mtime","mtimeMs","singleton","key","def","statSync","ServiceProvider","path","readdir","RouteServiceProvider","ServiceProvider","register","app","singleton","h3App","make","Router","boot","routePath","getPath","files","readdir","i","length","routesModule","path","join","default","router","e","console","warn"]}
|
|
1
|
+
{"version":3,"sources":["../src/Router.ts","../src/Providers/AssetsServiceProvider.ts","../src/Providers/RouteServiceProvider.ts"],"sourcesContent":["import { H3Event, Middleware, MiddlewareOptions, type H3 } from 'h3'\nimport { Request, Response } from '@h3ravel/http'\nimport { Controller, Kernel } from '@h3ravel/core'\nimport { afterLast } from '@h3ravel/support'\nimport { EventHandler, HttpContext, IApplication, IController, IMiddleware } from '@h3ravel/shared'\n\ninterface RouteDefinition {\n method: string\n path: string\n name?: string\n handler: EventHandler\n}\n\nexport class Router {\n private routes: RouteDefinition[] = []\n private groupPrefix = ''\n private groupMiddleware: EventHandler[] = []\n\n constructor(protected h3App: H3, private app: IApplication) { }\n\n /**\n * Route Resolver\n * \n * @param handler \n * @param middleware \n * @returns \n */\n private resolveHandler (handler: EventHandler, middleware: IMiddleware[] = []) {\n return async (event: H3Event) => {\n const kernel = new Kernel(() => ({\n request: new Request(event),\n response: new Response(event)\n }), middleware)\n\n return kernel.handle(event, (ctx) => Promise.resolve(handler(ctx)))\n }\n }\n\n /**\n * Add a route to the stack\n * \n * @param method \n * @param path \n * @param handler \n * @param name \n * @param middleware \n */\n private addRoute (\n method: string,\n path: string,\n handler: EventHandler,\n name?: string,\n middleware: IMiddleware[] = []\n ) {\n const fullPath = `${this.groupPrefix}${path}`.replace(/\\/+/g, '/')\n this.routes.push({ method, path: fullPath, name, handler })\n this.h3App[method as 'get'](fullPath, this.resolveHandler(handler, middleware))\n }\n\n private resolveControllerOrHandler (\n handler: EventHandler | (new (...args: any[]) => IController),\n methodName?: string\n ): EventHandler {\n if (typeof handler === 'function' && (handler as any).prototype instanceof Controller) {\n return (ctx) => {\n const controller = new (handler as new (...args: any[]) => IController)(this.app)\n const action = (methodName || 'index') as keyof IController\n\n if (typeof controller[action] !== 'function') {\n throw new Error(`Method \"${String(action)}\" not found on controller ${handler.name}`)\n }\n\n return controller[action](ctx)\n }\n }\n\n return handler as EventHandler\n }\n\n\n get (\n path: string,\n handler: EventHandler | (new (...args: any[]) => IController),\n methodName?: string, name?: string, middleware: IMiddleware[] = []\n ) {\n this.addRoute('get', path, this.resolveControllerOrHandler(handler, methodName), name, middleware)\n }\n\n post (\n path: string,\n handler: EventHandler | (new (...args: any[]) => IController),\n methodName?: string, name?: string, middleware: IMiddleware[] = []\n ) {\n this.addRoute('post', path, this.resolveControllerOrHandler(handler, methodName), name, middleware)\n }\n\n put (\n path: string,\n handler: EventHandler | (new (...args: any[]) => IController),\n methodName?: string, name?: string, middleware: IMiddleware[] = []\n ) {\n this.addRoute('put', path, this.resolveControllerOrHandler(handler, methodName), name, middleware)\n }\n\n delete (\n path: string,\n handler: EventHandler | (new (...args: any[]) => IController),\n methodName?: string, name?: string, middleware: IMiddleware[] = []\n ) {\n this.addRoute('delete', path, this.resolveControllerOrHandler(handler, methodName), name, middleware)\n }\n\n /**\n * API Resource support \n * \n * @param path \n * @param controller \n */\n apiResource (\n path: string,\n Controller: new (app: IApplication) => IController,\n middleware: IMiddleware[] = []\n ) {\n path = path.replace(/\\//g, '/')\n\n const name = afterLast(path, '/')\n const basePath = `/${path}`.replace(/\\/+/g, '/')\n\n const controller = new Controller(this.app)\n\n this.addRoute('get', basePath, controller.index.bind(controller), `${name}.index`, middleware)\n this.addRoute('post', basePath, controller.store.bind(controller), `${name}.store`, middleware)\n this.addRoute('get', `${basePath}/:id`, controller.show.bind(controller), `${name}.show`, middleware)\n this.addRoute('put', `${basePath}/:id`, controller.update.bind(controller), `${name}.update`, middleware)\n this.addRoute('patch', `${basePath}/:id`, controller.update.bind(controller), `${name}.update`, middleware)\n this.addRoute('delete', `${basePath}/:id`, controller.destroy.bind(controller), `${name}.destroy`, middleware)\n }\n\n /**\n * Named route URL generator\n * \n * @param name \n * @param params \n * @returns \n */\n route (name: string, params: Record<string, string> = {}): string | undefined {\n const found = this.routes.find(r => r.name === name)\n if (!found) return undefined\n\n let url = found.path\n for (const [key, value] of Object.entries(params)) {\n url = url.replace(`:${key}`, value)\n }\n return url\n }\n\n /**\n * Grouping\n * \n * @param options \n * @param callback \n */\n group (options: { prefix?: string; middleware?: EventHandler[] }, callback: () => void) {\n const prevPrefix = this.groupPrefix\n const prevMiddleware = [...this.groupMiddleware]\n\n this.groupPrefix += options.prefix || ''\n this.groupMiddleware.push(...(options.middleware || []))\n\n callback()\n\n /**\n * Restore state after group\n */\n this.groupPrefix = prevPrefix\n this.groupMiddleware = prevMiddleware\n }\n\n middleware (path: string, handler: Middleware, opts?: MiddlewareOptions) {\n this.h3App.use(path, handler, opts)\n }\n}\n","import { readFile, stat } from \"node:fs/promises\";\n\nimport { ServiceProvider } from '@h3ravel/core'\nimport { before } from \"@h3ravel/support\";\nimport { join } from \"node:path\";\nimport { serveStatic } from 'h3'\nimport { statSync } from \"node:fs\";\n\n/**\n * Handles public assets loading\n * \n * Auto-Registered\n */\nexport class AssetsServiceProvider extends ServiceProvider {\n register () {\n const app = this.app.make('router')\n const config = this.app.make('config')\n const fsconfig = config.get('filesystem')\n const publicPath = this.app.getPath('public')\n\n app.middleware(`/${fsconfig.public_mask}/**`, (event) => {\n return serveStatic(event, {\n indexNames: [\"/index.html\"],\n getContents: (id) => {\n const newId = id.replace(`/${fsconfig.public_mask}/`, '')\n return readFile(join(before(publicPath, newId), newId))\n },\n getMeta: async (id) => {\n const newId = id.replace(`/${fsconfig.public_mask}/`, '')\n const stats = await stat(join(before(publicPath, newId), newId)).catch(() => { });\n if (stats?.isFile()) {\n return {\n size: stats.size,\n mtime: stats.mtimeMs,\n };\n }\n },\n });\n })\n\n this.app.singleton('asset', () => {\n return (key: string, def = '') => {\n try {\n statSync(join(before(publicPath, key), key))\n } catch {\n key = def\n }\n\n return join(fsconfig.public_mask, key)\n }\n })\n }\n}\n","import { Router } from '../Router'\nimport { ServiceProvider } from '@h3ravel/core'\nimport path from 'node:path'\nimport { readdir } from 'node:fs/promises'\n\n/**\n * Handles routing registration\n * \n * Load route files (web.ts, api.ts).\n * Map controllers to routes.\n * Register route-related middleware.\n * \n * Auto-Registered\n */\nexport class RouteServiceProvider extends ServiceProvider {\n register () {\n this.app.singleton('router', () => {\n const h3App = this.app.make('http.app')\n return new Router(h3App, this.app)\n })\n }\n\n /**\n * Load routes from src/routes\n */\n async boot () {\n try {\n const routePath = this.app.getPath('routes')\n\n const files = await readdir(routePath);\n\n for (let i = 0; i < files.length; i++) {\n const routesModule = await import(path.join(routePath, files[i]))\n\n if (typeof routesModule.default === 'function') {\n const router = this.app.make('router')\n routesModule.default(router)\n }\n }\n } catch (e) {\n console.warn('No web routes found or failed to load:', e)\n }\n }\n}\n"],"mappings":"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","names":["Request","Response","Controller","Kernel","afterLast","Router","routes","groupPrefix","groupMiddleware","h3App","app","resolveHandler","handler","middleware","event","kernel","Kernel","request","Request","response","Response","handle","ctx","Promise","resolve","addRoute","method","path","name","fullPath","replace","push","resolveControllerOrHandler","methodName","prototype","Controller","controller","action","Error","String","get","post","put","delete","apiResource","afterLast","basePath","index","bind","store","show","update","destroy","route","params","found","find","r","undefined","url","key","value","Object","entries","group","options","callback","prevPrefix","prevMiddleware","prefix","opts","use","readFile","stat","ServiceProvider","before","join","serveStatic","statSync","AssetsServiceProvider","ServiceProvider","register","app","make","config","fsconfig","get","publicPath","getPath","middleware","public_mask","event","serveStatic","indexNames","getContents","id","newId","replace","readFile","join","before","getMeta","stats","stat","catch","isFile","size","mtime","mtimeMs","singleton","key","def","statSync","ServiceProvider","path","readdir","RouteServiceProvider","ServiceProvider","register","app","singleton","h3App","make","Router","boot","routePath","getPath","files","readdir","i","length","routesModule","path","join","default","router","e","console","warn"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@h3ravel/router",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Route facade, decorators and controller system for H3ravel.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -9,11 +9,11 @@
|
|
|
9
9
|
"access": "public"
|
|
10
10
|
},
|
|
11
11
|
"dependencies": {
|
|
12
|
-
"
|
|
13
|
-
"@h3ravel/
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
"
|
|
12
|
+
"h3": "^2.0.0-beta.1",
|
|
13
|
+
"@h3ravel/http": "2.0.0",
|
|
14
|
+
"@h3ravel/support": "0.4.0",
|
|
15
|
+
"@h3ravel/core": "0.4.0",
|
|
16
|
+
"@h3ravel/shared": "0.4.0"
|
|
17
17
|
},
|
|
18
18
|
"scripts": {
|
|
19
19
|
"barrel": "barrelsby --directory src --delete --singleQuotes",
|
|
@@ -21,6 +21,6 @@
|
|
|
21
21
|
"dev": "tsx watch src/index.ts",
|
|
22
22
|
"start": "node dist/index.js",
|
|
23
23
|
"lint": "eslint . --ext .ts",
|
|
24
|
-
"test": "
|
|
24
|
+
"test": "jest --passWithNoTests"
|
|
25
25
|
}
|
|
26
26
|
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { readFile, stat } from
|
|
1
|
+
import { readFile, stat } from 'node:fs/promises'
|
|
2
2
|
|
|
3
3
|
import { ServiceProvider } from '@h3ravel/core'
|
|
4
|
-
import { before } from
|
|
5
|
-
import { join } from
|
|
4
|
+
import { before } from '@h3ravel/support'
|
|
5
|
+
import { join } from 'node:path'
|
|
6
6
|
import { serveStatic } from 'h3'
|
|
7
|
-
import { statSync } from
|
|
7
|
+
import { statSync } from 'node:fs'
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* Handles public assets loading
|
|
@@ -20,22 +20,22 @@ export class AssetsServiceProvider extends ServiceProvider {
|
|
|
20
20
|
|
|
21
21
|
app.middleware(`/${fsconfig.public_mask}/**`, (event) => {
|
|
22
22
|
return serveStatic(event, {
|
|
23
|
-
indexNames: [
|
|
23
|
+
indexNames: ['/index.html'],
|
|
24
24
|
getContents: (id) => {
|
|
25
25
|
const newId = id.replace(`/${fsconfig.public_mask}/`, '')
|
|
26
26
|
return readFile(join(before(publicPath, newId), newId))
|
|
27
27
|
},
|
|
28
28
|
getMeta: async (id) => {
|
|
29
29
|
const newId = id.replace(`/${fsconfig.public_mask}/`, '')
|
|
30
|
-
const stats = await stat(join(before(publicPath, newId), newId)).catch(() => { })
|
|
30
|
+
const stats = await stat(join(before(publicPath, newId), newId)).catch(() => { })
|
|
31
31
|
if (stats?.isFile()) {
|
|
32
32
|
return {
|
|
33
33
|
size: stats.size,
|
|
34
34
|
mtime: stats.mtimeMs,
|
|
35
|
-
}
|
|
35
|
+
}
|
|
36
36
|
}
|
|
37
37
|
},
|
|
38
|
-
})
|
|
38
|
+
})
|
|
39
39
|
})
|
|
40
40
|
|
|
41
41
|
this.app.singleton('asset', () => {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Router } from '../
|
|
1
|
+
import { Router } from '../Route'
|
|
2
2
|
import { ServiceProvider } from '@h3ravel/core'
|
|
3
3
|
import path from 'node:path'
|
|
4
4
|
import { readdir } from 'node:fs/promises'
|
|
@@ -27,7 +27,7 @@ export class RouteServiceProvider extends ServiceProvider {
|
|
|
27
27
|
try {
|
|
28
28
|
const routePath = this.app.getPath('routes')
|
|
29
29
|
|
|
30
|
-
const files = await readdir(routePath)
|
|
30
|
+
const files = await readdir(routePath)
|
|
31
31
|
|
|
32
32
|
for (let i = 0; i < files.length; i++) {
|
|
33
33
|
const routesModule = await import(path.join(routePath, files[i]))
|
package/src/Route.ts
CHANGED
|
@@ -1 +1,182 @@
|
|
|
1
|
-
|
|
1
|
+
import { H3Event, Middleware, MiddlewareOptions, type H3 } from 'h3'
|
|
2
|
+
import { Request, Response } from '@h3ravel/http'
|
|
3
|
+
import { Application, Controller, Kernel } from '@h3ravel/core'
|
|
4
|
+
import { afterLast } from '@h3ravel/support'
|
|
5
|
+
import { EventHandler, IController, IMiddleware } from '@h3ravel/shared'
|
|
6
|
+
|
|
7
|
+
interface RouteDefinition {
|
|
8
|
+
method: string
|
|
9
|
+
path: string
|
|
10
|
+
name?: string
|
|
11
|
+
handler: EventHandler
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export class Router {
|
|
15
|
+
private routes: RouteDefinition[] = []
|
|
16
|
+
private groupPrefix = ''
|
|
17
|
+
private groupMiddleware: EventHandler[] = []
|
|
18
|
+
|
|
19
|
+
constructor(protected h3App: H3, private app: Application) { }
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Route Resolver
|
|
23
|
+
*
|
|
24
|
+
* @param handler
|
|
25
|
+
* @param middleware
|
|
26
|
+
* @returns
|
|
27
|
+
*/
|
|
28
|
+
private resolveHandler (handler: EventHandler, middleware: IMiddleware[] = []) {
|
|
29
|
+
return async (event: H3Event) => {
|
|
30
|
+
const kernel = new Kernel(() => ({
|
|
31
|
+
request: new Request(event),
|
|
32
|
+
response: new Response(event)
|
|
33
|
+
}), middleware)
|
|
34
|
+
|
|
35
|
+
return kernel.handle(event, (ctx) => Promise.resolve(handler(ctx)))
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Add a route to the stack
|
|
41
|
+
*
|
|
42
|
+
* @param method
|
|
43
|
+
* @param path
|
|
44
|
+
* @param handler
|
|
45
|
+
* @param name
|
|
46
|
+
* @param middleware
|
|
47
|
+
*/
|
|
48
|
+
private addRoute (
|
|
49
|
+
method: string,
|
|
50
|
+
path: string,
|
|
51
|
+
handler: EventHandler,
|
|
52
|
+
name?: string,
|
|
53
|
+
middleware: IMiddleware[] = []
|
|
54
|
+
) {
|
|
55
|
+
const fullPath = `${this.groupPrefix}${path}`.replace(/\/+/g, '/')
|
|
56
|
+
this.routes.push({ method, path: fullPath, name, handler })
|
|
57
|
+
this.h3App[method as 'get'](fullPath, this.resolveHandler(handler, middleware))
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
private resolveControllerOrHandler (
|
|
61
|
+
handler: EventHandler | (new (...args: any[]) => IController),
|
|
62
|
+
methodName?: string
|
|
63
|
+
): EventHandler {
|
|
64
|
+
if (typeof handler === 'function' && (handler as any).prototype instanceof Controller) {
|
|
65
|
+
return (ctx) => {
|
|
66
|
+
const controller = new (handler as new (...args: any[]) => IController)(this.app)
|
|
67
|
+
const action = (methodName || 'index') as keyof IController
|
|
68
|
+
|
|
69
|
+
if (typeof controller[action] !== 'function') {
|
|
70
|
+
throw new Error(`Method "${String(action)}" not found on controller ${handler.name}`)
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
return controller[action](ctx)
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return handler as EventHandler
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
get (
|
|
82
|
+
path: string,
|
|
83
|
+
handler: EventHandler | (new (...args: any[]) => IController),
|
|
84
|
+
methodName?: string, name?: string, middleware: IMiddleware[] = []
|
|
85
|
+
) {
|
|
86
|
+
this.addRoute('get', path, this.resolveControllerOrHandler(handler, methodName), name, middleware)
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
post (
|
|
90
|
+
path: string,
|
|
91
|
+
handler: EventHandler | (new (...args: any[]) => IController),
|
|
92
|
+
methodName?: string, name?: string, middleware: IMiddleware[] = []
|
|
93
|
+
) {
|
|
94
|
+
this.addRoute('post', path, this.resolveControllerOrHandler(handler, methodName), name, middleware)
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
put (
|
|
98
|
+
path: string,
|
|
99
|
+
handler: EventHandler | (new (...args: any[]) => IController),
|
|
100
|
+
methodName?: string, name?: string, middleware: IMiddleware[] = []
|
|
101
|
+
) {
|
|
102
|
+
this.addRoute('put', path, this.resolveControllerOrHandler(handler, methodName), name, middleware)
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
delete (
|
|
106
|
+
path: string,
|
|
107
|
+
handler: EventHandler | (new (...args: any[]) => IController),
|
|
108
|
+
methodName?: string, name?: string, middleware: IMiddleware[] = []
|
|
109
|
+
) {
|
|
110
|
+
this.addRoute('delete', path, this.resolveControllerOrHandler(handler, methodName), name, middleware)
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* API Resource support
|
|
115
|
+
*
|
|
116
|
+
* @param path
|
|
117
|
+
* @param controller
|
|
118
|
+
*/
|
|
119
|
+
apiResource (
|
|
120
|
+
path: string,
|
|
121
|
+
Controller: new (app: Application) => IController,
|
|
122
|
+
middleware: IMiddleware[] = []
|
|
123
|
+
) {
|
|
124
|
+
path = path.replace(/\//g, '/')
|
|
125
|
+
|
|
126
|
+
const name = afterLast(path, '/')
|
|
127
|
+
const basePath = `/${path}`.replace(/\/+/g, '/')
|
|
128
|
+
|
|
129
|
+
const controller = new Controller(this.app)
|
|
130
|
+
|
|
131
|
+
this.addRoute('get', basePath, controller.index.bind(controller), `${name}.index`, middleware)
|
|
132
|
+
this.addRoute('post', basePath, controller.store.bind(controller), `${name}.store`, middleware)
|
|
133
|
+
this.addRoute('get', `${basePath}/:id`, controller.show.bind(controller), `${name}.show`, middleware)
|
|
134
|
+
this.addRoute('put', `${basePath}/:id`, controller.update.bind(controller), `${name}.update`, middleware)
|
|
135
|
+
this.addRoute('patch', `${basePath}/:id`, controller.update.bind(controller), `${name}.update`, middleware)
|
|
136
|
+
this.addRoute('delete', `${basePath}/:id`, controller.destroy.bind(controller), `${name}.destroy`, middleware)
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Named route URL generator
|
|
141
|
+
*
|
|
142
|
+
* @param name
|
|
143
|
+
* @param params
|
|
144
|
+
* @returns
|
|
145
|
+
*/
|
|
146
|
+
route (name: string, params: Record<string, string> = {}): string | undefined {
|
|
147
|
+
const found = this.routes.find(r => r.name === name)
|
|
148
|
+
if (!found) return undefined
|
|
149
|
+
|
|
150
|
+
let url = found.path
|
|
151
|
+
for (const [key, value] of Object.entries(params)) {
|
|
152
|
+
url = url.replace(`:${key}`, value)
|
|
153
|
+
}
|
|
154
|
+
return url
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Grouping
|
|
159
|
+
*
|
|
160
|
+
* @param options
|
|
161
|
+
* @param callback
|
|
162
|
+
*/
|
|
163
|
+
group (options: { prefix?: string; middleware?: EventHandler[] }, callback: () => void) {
|
|
164
|
+
const prevPrefix = this.groupPrefix
|
|
165
|
+
const prevMiddleware = [...this.groupMiddleware]
|
|
166
|
+
|
|
167
|
+
this.groupPrefix += options.prefix || ''
|
|
168
|
+
this.groupMiddleware.push(...(options.middleware || []))
|
|
169
|
+
|
|
170
|
+
callback()
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Restore state after group
|
|
174
|
+
*/
|
|
175
|
+
this.groupPrefix = prevPrefix
|
|
176
|
+
this.groupMiddleware = prevMiddleware
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
middleware (path: string, handler: Middleware, opts?: MiddlewareOptions) {
|
|
180
|
+
this.h3App.use(path, handler, opts)
|
|
181
|
+
}
|
|
182
|
+
}
|
package/src/index.ts
CHANGED
package/tsconfig.json
CHANGED
package/src/Router.ts
DELETED
|
@@ -1,180 +0,0 @@
|
|
|
1
|
-
import { H3Event, Middleware, MiddlewareOptions, type H3 } from 'h3'
|
|
2
|
-
import { Application, Controller, Kernel } from '@h3ravel/core'
|
|
3
|
-
import { Middleware as HttpMiddleware } from '@h3ravel/http'
|
|
4
|
-
import { HttpContext } from '@h3ravel/http'
|
|
5
|
-
import { afterLast } from '@h3ravel/support'
|
|
6
|
-
|
|
7
|
-
type EventHandler = (ctx: HttpContext) => unknown
|
|
8
|
-
|
|
9
|
-
interface RouteDefinition {
|
|
10
|
-
method: string
|
|
11
|
-
path: string
|
|
12
|
-
name?: string
|
|
13
|
-
handler: EventHandler
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export class Router {
|
|
17
|
-
private routes: RouteDefinition[] = []
|
|
18
|
-
private groupPrefix = ''
|
|
19
|
-
private groupMiddleware: EventHandler[] = []
|
|
20
|
-
|
|
21
|
-
constructor(protected h3App: H3, private app: Application) { }
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* Route Resolver
|
|
25
|
-
*
|
|
26
|
-
* @param handler
|
|
27
|
-
* @param middleware
|
|
28
|
-
* @returns
|
|
29
|
-
*/
|
|
30
|
-
private resolveHandler (handler: EventHandler, middleware: HttpMiddleware[] = []) {
|
|
31
|
-
return async (event: H3Event) => {
|
|
32
|
-
const kernel = new Kernel(middleware)
|
|
33
|
-
return kernel.handle(event, (ctx) => Promise.resolve(handler(ctx)))
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* Add a route to the stack
|
|
39
|
-
*
|
|
40
|
-
* @param method
|
|
41
|
-
* @param path
|
|
42
|
-
* @param handler
|
|
43
|
-
* @param name
|
|
44
|
-
* @param middleware
|
|
45
|
-
*/
|
|
46
|
-
private addRoute (
|
|
47
|
-
method: string,
|
|
48
|
-
path: string,
|
|
49
|
-
handler: EventHandler,
|
|
50
|
-
name?: string,
|
|
51
|
-
middleware: HttpMiddleware[] = []
|
|
52
|
-
) {
|
|
53
|
-
const fullPath = `${this.groupPrefix}${path}`.replace(/\/+/g, '/')
|
|
54
|
-
this.routes.push({ method, path: fullPath, name, handler })
|
|
55
|
-
this.h3App[method as 'get'](fullPath, this.resolveHandler(handler, middleware))
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
private resolveControllerOrHandler (
|
|
59
|
-
handler: EventHandler | (new (...args: any[]) => Controller),
|
|
60
|
-
methodName?: string
|
|
61
|
-
): EventHandler {
|
|
62
|
-
if (typeof handler === 'function' && (handler as any).prototype instanceof Controller) {
|
|
63
|
-
return (ctx) => {
|
|
64
|
-
const controller = new (handler as new (...args: any[]) => Controller)(this.app)
|
|
65
|
-
const action = (methodName || 'index') as keyof Controller
|
|
66
|
-
|
|
67
|
-
if (typeof controller[action] !== 'function') {
|
|
68
|
-
throw new Error(`Method "${action}" not found on controller ${handler.name}`)
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
return controller[action](ctx)
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
return handler as EventHandler
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
get (
|
|
80
|
-
path: string,
|
|
81
|
-
handler: EventHandler | (new (...args: any[]) => Controller),
|
|
82
|
-
methodName?: string, name?: string, middleware: HttpMiddleware[] = []
|
|
83
|
-
) {
|
|
84
|
-
this.addRoute('get', path, this.resolveControllerOrHandler(handler, methodName), name, middleware)
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
post (
|
|
88
|
-
path: string,
|
|
89
|
-
handler: EventHandler | (new (...args: any[]) => Controller),
|
|
90
|
-
methodName?: string, name?: string, middleware: HttpMiddleware[] = []
|
|
91
|
-
) {
|
|
92
|
-
this.addRoute('post', path, this.resolveControllerOrHandler(handler, methodName), name, middleware)
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
put (
|
|
96
|
-
path: string,
|
|
97
|
-
handler: EventHandler | (new (...args: any[]) => Controller),
|
|
98
|
-
methodName?: string, name?: string, middleware: HttpMiddleware[] = []
|
|
99
|
-
) {
|
|
100
|
-
this.addRoute('put', path, this.resolveControllerOrHandler(handler, methodName), name, middleware)
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
delete (
|
|
104
|
-
path: string,
|
|
105
|
-
handler: EventHandler | (new (...args: any[]) => Controller),
|
|
106
|
-
methodName?: string, name?: string, middleware: HttpMiddleware[] = []
|
|
107
|
-
) {
|
|
108
|
-
this.addRoute('delete', path, this.resolveControllerOrHandler(handler, methodName), name, middleware)
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
/**
|
|
112
|
-
* API Resource support
|
|
113
|
-
*
|
|
114
|
-
* @param path
|
|
115
|
-
* @param controller
|
|
116
|
-
*/
|
|
117
|
-
apiResource (
|
|
118
|
-
path: string,
|
|
119
|
-
Controller: new (app: Application) => Controller,
|
|
120
|
-
middleware: HttpMiddleware[] = []
|
|
121
|
-
) {
|
|
122
|
-
path = path.replace(/\//g, '/')
|
|
123
|
-
|
|
124
|
-
const name = afterLast(path, '/')
|
|
125
|
-
const basePath = `/${path}`.replace(/\/+/g, '/')
|
|
126
|
-
|
|
127
|
-
const controller = new Controller(this.app)
|
|
128
|
-
|
|
129
|
-
this.addRoute('get', basePath, controller.index.bind(controller), `${name}.index`, middleware)
|
|
130
|
-
this.addRoute('post', basePath, controller.store.bind(controller), `${name}.store`, middleware)
|
|
131
|
-
this.addRoute('get', `${basePath}/:id`, controller.show.bind(controller), `${name}.show`, middleware)
|
|
132
|
-
this.addRoute('put', `${basePath}/:id`, controller.update.bind(controller), `${name}.update`, middleware)
|
|
133
|
-
this.addRoute('patch', `${basePath}/:id`, controller.update.bind(controller), `${name}.update`, middleware)
|
|
134
|
-
this.addRoute('delete', `${basePath}/:id`, controller.destroy.bind(controller), `${name}.destroy`, middleware)
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
/**
|
|
138
|
-
* Named route URL generator
|
|
139
|
-
*
|
|
140
|
-
* @param name
|
|
141
|
-
* @param params
|
|
142
|
-
* @returns
|
|
143
|
-
*/
|
|
144
|
-
route (name: string, params: Record<string, string> = {}): string | undefined {
|
|
145
|
-
const found = this.routes.find(r => r.name === name)
|
|
146
|
-
if (!found) return undefined
|
|
147
|
-
|
|
148
|
-
let url = found.path
|
|
149
|
-
for (const [key, value] of Object.entries(params)) {
|
|
150
|
-
url = url.replace(`:${key}`, value)
|
|
151
|
-
}
|
|
152
|
-
return url
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
/**
|
|
156
|
-
* Grouping
|
|
157
|
-
*
|
|
158
|
-
* @param options
|
|
159
|
-
* @param callback
|
|
160
|
-
*/
|
|
161
|
-
group (options: { prefix?: string; middleware?: EventHandler[] }, callback: () => void) {
|
|
162
|
-
const prevPrefix = this.groupPrefix
|
|
163
|
-
const prevMiddleware = [...this.groupMiddleware]
|
|
164
|
-
|
|
165
|
-
this.groupPrefix += options.prefix || ''
|
|
166
|
-
this.groupMiddleware.push(...(options.middleware || []))
|
|
167
|
-
|
|
168
|
-
callback()
|
|
169
|
-
|
|
170
|
-
/**
|
|
171
|
-
* Restore state after group
|
|
172
|
-
*/
|
|
173
|
-
this.groupPrefix = prevPrefix
|
|
174
|
-
this.groupMiddleware = prevMiddleware
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
middleware (path: string, handler: Middleware, opts?: MiddlewareOptions) {
|
|
178
|
-
this.h3App.use(path, handler, opts)
|
|
179
|
-
}
|
|
180
|
-
}
|