@weconjs/core 0.1.1 → 1.1.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/README.md +460 -41
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +1 -0
- package/dist/config.js.map +1 -1
- package/dist/context.d.ts +6 -8
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +30 -21
- package/dist/context.js.map +1 -1
- package/dist/database/index.d.ts +108 -5
- package/dist/database/index.d.ts.map +1 -1
- package/dist/database/index.js +148 -12
- package/dist/database/index.js.map +1 -1
- package/dist/devtools/controllers/config.controller.d.ts +28 -0
- package/dist/devtools/controllers/config.controller.d.ts.map +1 -0
- package/dist/devtools/controllers/config.controller.js +100 -0
- package/dist/devtools/controllers/config.controller.js.map +1 -0
- package/dist/devtools/controllers/i18n.controller.d.ts +22 -0
- package/dist/devtools/controllers/i18n.controller.d.ts.map +1 -0
- package/dist/devtools/controllers/i18n.controller.js +93 -0
- package/dist/devtools/controllers/i18n.controller.js.map +1 -0
- package/dist/devtools/controllers/modules.controller.d.ts +16 -0
- package/dist/devtools/controllers/modules.controller.d.ts.map +1 -0
- package/dist/devtools/controllers/modules.controller.js +73 -0
- package/dist/devtools/controllers/modules.controller.js.map +1 -0
- package/dist/devtools/controllers/routes.controller.d.ts +13 -0
- package/dist/devtools/controllers/routes.controller.d.ts.map +1 -0
- package/dist/devtools/controllers/routes.controller.js +32 -0
- package/dist/devtools/controllers/routes.controller.js.map +1 -0
- package/dist/devtools/index.d.ts +28 -0
- package/dist/devtools/index.d.ts.map +1 -0
- package/dist/devtools/index.js +66 -0
- package/dist/devtools/index.js.map +1 -0
- package/dist/devtools/middleware.d.ts +11 -0
- package/dist/devtools/middleware.d.ts.map +1 -0
- package/dist/devtools/middleware.js +30 -0
- package/dist/devtools/middleware.js.map +1 -0
- package/dist/devtools/types.d.ts +59 -0
- package/dist/devtools/types.d.ts.map +1 -0
- package/dist/devtools/types.js +5 -0
- package/dist/devtools/types.js.map +1 -0
- package/dist/errors/ConfigError.d.ts +6 -0
- package/dist/errors/ConfigError.d.ts.map +1 -0
- package/dist/errors/ConfigError.js +16 -0
- package/dist/errors/ConfigError.js.map +1 -0
- package/dist/errors/RequestError.d.ts +6 -0
- package/dist/errors/RequestError.d.ts.map +1 -0
- package/dist/errors/RequestError.js +16 -0
- package/dist/errors/RequestError.js.map +1 -0
- package/dist/errors/index.d.ts +9 -0
- package/dist/errors/index.d.ts.map +1 -0
- package/dist/errors/index.js +5 -0
- package/dist/errors/index.js.map +1 -0
- package/dist/index.d.ts +15 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +13 -3
- package/dist/index.js.map +1 -1
- package/dist/logger/index.d.ts +102 -0
- package/dist/logger/index.d.ts.map +1 -0
- package/dist/logger/index.js +147 -0
- package/dist/logger/index.js.map +1 -0
- package/dist/module/index.d.ts +6 -0
- package/dist/module/index.d.ts.map +1 -0
- package/dist/module/index.js +5 -0
- package/dist/module/index.js.map +1 -0
- package/dist/module/module-loader.d.ts +60 -0
- package/dist/module/module-loader.d.ts.map +1 -0
- package/dist/module/module-loader.js +119 -0
- package/dist/module/module-loader.js.map +1 -0
- package/dist/routing/ErrorCatcher.d.ts +18 -0
- package/dist/routing/ErrorCatcher.d.ts.map +1 -0
- package/dist/routing/ErrorCatcher.js +50 -0
- package/dist/routing/ErrorCatcher.js.map +1 -0
- package/dist/routing/RaiMatcher.d.ts +27 -0
- package/dist/routing/RaiMatcher.d.ts.map +1 -0
- package/dist/routing/RaiMatcher.js +127 -0
- package/dist/routing/RaiMatcher.js.map +1 -0
- package/dist/routing/Route.d.ts +28 -0
- package/dist/routing/Route.d.ts.map +1 -0
- package/dist/routing/Route.js +125 -0
- package/dist/routing/Route.js.map +1 -0
- package/dist/routing/Routes.d.ts +31 -0
- package/dist/routing/Routes.d.ts.map +1 -0
- package/dist/routing/Routes.js +151 -0
- package/dist/routing/Routes.js.map +1 -0
- package/dist/routing/RoutesParam.d.ts +29 -0
- package/dist/routing/RoutesParam.d.ts.map +1 -0
- package/dist/routing/RoutesParam.js +113 -0
- package/dist/routing/RoutesParam.js.map +1 -0
- package/dist/routing/Wecon.d.ts +66 -0
- package/dist/routing/Wecon.d.ts.map +1 -0
- package/dist/routing/Wecon.js +248 -0
- package/dist/routing/Wecon.js.map +1 -0
- package/dist/routing/index.d.ts +9 -0
- package/dist/routing/index.d.ts.map +1 -0
- package/dist/routing/index.js +7 -0
- package/dist/routing/index.js.map +1 -0
- package/dist/server/index.d.ts +162 -10
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +339 -25
- package/dist/server/index.js.map +1 -1
- package/dist/types.d.ts +75 -3
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +1 -1
- package/package.json +21 -4
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RoutesParam.js","sourceRoot":"","sources":["../../src/routing/RoutesParam.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wecon - Express.js routing with built-in RBAC
|
|
3
|
+
*
|
|
4
|
+
* Two-layer request processing:
|
|
5
|
+
* 1. Intelligence Layer: RaiMatcher validates and authorizes requests
|
|
6
|
+
* 2. Execution Layer: Single master Express Router handles the request
|
|
7
|
+
*/
|
|
8
|
+
import type { RequestHandler } from "express";
|
|
9
|
+
import type { RAI, DefaultRole } from "../types.js";
|
|
10
|
+
import Routes from "./Routes.js";
|
|
11
|
+
import Route from "./Route.js";
|
|
12
|
+
/** Development mode configuration */
|
|
13
|
+
export interface WeconDevConfig {
|
|
14
|
+
/** Enable debug mode with verbose logging */
|
|
15
|
+
debugMode?: boolean;
|
|
16
|
+
/** Provide helpful error suggestions */
|
|
17
|
+
helpfulErrors?: boolean;
|
|
18
|
+
/** Log registered routes on startup */
|
|
19
|
+
logRoutes?: boolean;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Main Wecon class with fluent API.
|
|
23
|
+
* Compiles routes into a single master router with RBAC enforcement.
|
|
24
|
+
*/
|
|
25
|
+
declare class Wecon<TRole extends string = DefaultRole> {
|
|
26
|
+
private _routes?;
|
|
27
|
+
private _roles;
|
|
28
|
+
private _guestRole;
|
|
29
|
+
private _onRoutesPrepared?;
|
|
30
|
+
private _dev?;
|
|
31
|
+
private _raiMatcher?;
|
|
32
|
+
private _masterRouter?;
|
|
33
|
+
private _built;
|
|
34
|
+
private _raisMap?;
|
|
35
|
+
private _middleware?;
|
|
36
|
+
constructor();
|
|
37
|
+
/** Set the root routes */
|
|
38
|
+
routes(routes: Routes<TRole>): this;
|
|
39
|
+
/** Define available roles */
|
|
40
|
+
roles<T extends string>(roles: readonly T[]): Wecon<T>;
|
|
41
|
+
/** Set guest role for unauthenticated users */
|
|
42
|
+
guestRole(guestRole: string): this;
|
|
43
|
+
/** Set callback for when routes are compiled */
|
|
44
|
+
onRoutesPrepared(callback: (routes: Route[]) => void | Promise<void>): this;
|
|
45
|
+
/** Configure development mode options */
|
|
46
|
+
dev(config: WeconDevConfig): this;
|
|
47
|
+
/**
|
|
48
|
+
* Compile all routes into the middleware.
|
|
49
|
+
* Must be called before using the Wecon instance.
|
|
50
|
+
*/
|
|
51
|
+
build(): this;
|
|
52
|
+
/** Sort routes: static segments before dynamic */
|
|
53
|
+
private compareRoutes;
|
|
54
|
+
/** Create the main Express middleware (intelligence + execution layers) */
|
|
55
|
+
private createMiddleware;
|
|
56
|
+
private createHelpfulNotFoundError;
|
|
57
|
+
private createHelpfulUnauthorizedError;
|
|
58
|
+
/** Get all registered routes (must call build() first) */
|
|
59
|
+
getRoutes(): Route[];
|
|
60
|
+
/** Get a route by RAI */
|
|
61
|
+
getRoute(rai: RAI): Route | undefined;
|
|
62
|
+
/** Get the Express middleware function */
|
|
63
|
+
handler(): RequestHandler;
|
|
64
|
+
}
|
|
65
|
+
export default Wecon;
|
|
66
|
+
//# sourceMappingURL=Wecon.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Wecon.d.ts","sourceRoot":"","sources":["../../src/routing/Wecon.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAGV,cAAc,EAGf,MAAM,SAAS,CAAC;AACjB,OAAO,KAAK,EAAE,GAAG,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,MAAM,MAAM,aAAa,CAAC;AACjC,OAAO,KAAK,MAAM,YAAY,CAAC;AAI/B,qCAAqC;AACrC,MAAM,WAAW,cAAc;IAC7B,6CAA6C;IAC7C,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,wCAAwC;IACxC,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,uCAAuC;IACvC,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED;;;GAGG;AACH,cAAM,KAAK,CAAC,KAAK,SAAS,MAAM,GAAG,WAAW;IAC5C,OAAO,CAAC,OAAO,CAAC,CAAgB;IAChC,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,UAAU,CAAmB;IACrC,OAAO,CAAC,iBAAiB,CAAC,CAAmD;IAC7E,OAAO,CAAC,IAAI,CAAC,CAAiB;IAE9B,OAAO,CAAC,WAAW,CAAC,CAAa;IACjC,OAAO,CAAC,aAAa,CAAC,CAAS;IAE/B,OAAO,CAAC,MAAM,CAAkB;IAChC,OAAO,CAAC,QAAQ,CAAC,CAAyB;IAC1C,OAAO,CAAC,WAAW,CAAC,CAAiB;;IAIrC,0BAA0B;IACnB,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI;IAW1C,6BAA6B;IACtB,KAAK,CAAC,CAAC,SAAS,MAAM,EAAE,KAAK,EAAE,SAAS,CAAC,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC;IAW7D,+CAA+C;IACxC,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAWzC,gDAAgD;IACzC,gBAAgB,CACrB,QAAQ,EAAE,CAAC,MAAM,EAAE,KAAK,EAAE,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,GAClD,IAAI;IAWP,yCAAyC;IAClC,GAAG,CAAC,MAAM,EAAE,cAAc,GAAG,IAAI;IAQxC;;;OAGG;IACI,KAAK,IAAI,IAAI;IA+EpB,kDAAkD;IAClD,OAAO,CAAC,aAAa;IAsBrB,2EAA2E;IAC3E,OAAO,CAAC,gBAAgB;IAiDxB,OAAO,CAAC,0BAA0B;IAelC,OAAO,CAAC,8BAA8B;IAatC,0DAA0D;IACnD,SAAS,IAAI,KAAK,EAAE;IAO3B,yBAAyB;IAClB,QAAQ,CAAC,GAAG,EAAE,GAAG,GAAG,KAAK,GAAG,SAAS;IAO5C,0CAA0C;IACnC,OAAO,IAAI,cAAc;CAMjC;AAED,eAAe,KAAK,CAAC"}
|
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wecon - Express.js routing with built-in RBAC
|
|
3
|
+
*
|
|
4
|
+
* Two-layer request processing:
|
|
5
|
+
* 1. Intelligence Layer: RaiMatcher validates and authorizes requests
|
|
6
|
+
* 2. Execution Layer: Single master Express Router handles the request
|
|
7
|
+
*/
|
|
8
|
+
import Routes from "./Routes.js";
|
|
9
|
+
import errors from "../errors/index.js";
|
|
10
|
+
import RaiMatcher from "./RaiMatcher.js";
|
|
11
|
+
/**
|
|
12
|
+
* Main Wecon class with fluent API.
|
|
13
|
+
* Compiles routes into a single master router with RBAC enforcement.
|
|
14
|
+
*/
|
|
15
|
+
class Wecon {
|
|
16
|
+
_routes;
|
|
17
|
+
_roles = [];
|
|
18
|
+
_guestRole = "guest";
|
|
19
|
+
_onRoutesPrepared;
|
|
20
|
+
_dev;
|
|
21
|
+
_raiMatcher;
|
|
22
|
+
_masterRouter;
|
|
23
|
+
_built = false;
|
|
24
|
+
_raisMap;
|
|
25
|
+
_middleware;
|
|
26
|
+
constructor() { }
|
|
27
|
+
/** Set the root routes */
|
|
28
|
+
routes(routes) {
|
|
29
|
+
if (this._built) {
|
|
30
|
+
throw new Error("Cannot modify Wecon after build() has been called");
|
|
31
|
+
}
|
|
32
|
+
if (!(routes instanceof Routes)) {
|
|
33
|
+
throw new Error("routes() must receive an instance of the Routes class");
|
|
34
|
+
}
|
|
35
|
+
this._routes = routes;
|
|
36
|
+
return this;
|
|
37
|
+
}
|
|
38
|
+
/** Define available roles */
|
|
39
|
+
roles(roles) {
|
|
40
|
+
if (this._built) {
|
|
41
|
+
throw new Error("Cannot modify Wecon after build() has been called");
|
|
42
|
+
}
|
|
43
|
+
if (!Array.isArray(roles)) {
|
|
44
|
+
throw new Error("roles() must receive an array of strings");
|
|
45
|
+
}
|
|
46
|
+
this._roles = [...roles];
|
|
47
|
+
return this;
|
|
48
|
+
}
|
|
49
|
+
/** Set guest role for unauthenticated users */
|
|
50
|
+
guestRole(guestRole) {
|
|
51
|
+
if (this._built) {
|
|
52
|
+
throw new Error("Cannot modify Wecon after build() has been called");
|
|
53
|
+
}
|
|
54
|
+
if (typeof guestRole !== "string") {
|
|
55
|
+
throw new Error("guestRole() must receive a string");
|
|
56
|
+
}
|
|
57
|
+
this._guestRole = guestRole;
|
|
58
|
+
return this;
|
|
59
|
+
}
|
|
60
|
+
/** Set callback for when routes are compiled */
|
|
61
|
+
onRoutesPrepared(callback) {
|
|
62
|
+
if (this._built) {
|
|
63
|
+
throw new Error("Cannot modify Wecon after build() has been called");
|
|
64
|
+
}
|
|
65
|
+
if (typeof callback !== "function") {
|
|
66
|
+
throw new Error("onRoutesPrepared() must receive a function");
|
|
67
|
+
}
|
|
68
|
+
this._onRoutesPrepared = callback;
|
|
69
|
+
return this;
|
|
70
|
+
}
|
|
71
|
+
/** Configure development mode options */
|
|
72
|
+
dev(config) {
|
|
73
|
+
if (this._built) {
|
|
74
|
+
throw new Error("Cannot modify Wecon after build() has been called");
|
|
75
|
+
}
|
|
76
|
+
this._dev = config;
|
|
77
|
+
return this;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Compile all routes into the middleware.
|
|
81
|
+
* Must be called before using the Wecon instance.
|
|
82
|
+
*/
|
|
83
|
+
build() {
|
|
84
|
+
if (this._built)
|
|
85
|
+
throw new Error("build() can only be called once");
|
|
86
|
+
if (!this._routes)
|
|
87
|
+
throw new Error("routes() must be called before build()");
|
|
88
|
+
if (this._roles.length === 0)
|
|
89
|
+
throw new Error("roles() missing");
|
|
90
|
+
this._built = true;
|
|
91
|
+
this._raisMap = this._routes.groupRoutesByRai();
|
|
92
|
+
// 1. Initialize RAI Matcher
|
|
93
|
+
const routesList = Array.from(this._raisMap.values()).map((r) => ({
|
|
94
|
+
path: r.path,
|
|
95
|
+
method: r.method,
|
|
96
|
+
rai: r.rai,
|
|
97
|
+
}));
|
|
98
|
+
this._raiMatcher = new RaiMatcher(routesList);
|
|
99
|
+
// 2. Create master router (dynamic import would be async, so we use require-style)
|
|
100
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
101
|
+
const { Router: ExpressRouter } = require("express");
|
|
102
|
+
this._masterRouter = ExpressRouter({ mergeParams: true });
|
|
103
|
+
// 3. Sort routes by specificity (static before dynamic)
|
|
104
|
+
const sortedRoutes = Array.from(this._raisMap.values()).sort(this.compareRoutes);
|
|
105
|
+
// 4. Register all routes on the master router
|
|
106
|
+
sortedRoutes.forEach((route) => {
|
|
107
|
+
// Register param handlers
|
|
108
|
+
route.params?.forEach((param) => {
|
|
109
|
+
this._masterRouter.param(param.path, param.middleware);
|
|
110
|
+
if (param.validate) {
|
|
111
|
+
this._masterRouter.param(param.path, (_req, _res, next, val) => {
|
|
112
|
+
if (!param.validateValue(val)) {
|
|
113
|
+
return next(new errors.RequestError("Invalid Parameter", {
|
|
114
|
+
code: "INVALID_PARAM",
|
|
115
|
+
}));
|
|
116
|
+
}
|
|
117
|
+
next();
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
// Register route by method
|
|
122
|
+
switch (route.method) {
|
|
123
|
+
case "GET":
|
|
124
|
+
this._masterRouter.get(route.path, ...route.middlewares);
|
|
125
|
+
break;
|
|
126
|
+
case "POST":
|
|
127
|
+
this._masterRouter.post(route.path, ...route.middlewares);
|
|
128
|
+
break;
|
|
129
|
+
case "PUT":
|
|
130
|
+
this._masterRouter.put(route.path, ...route.middlewares);
|
|
131
|
+
break;
|
|
132
|
+
case "DELETE":
|
|
133
|
+
this._masterRouter.delete(route.path, ...route.middlewares);
|
|
134
|
+
break;
|
|
135
|
+
}
|
|
136
|
+
});
|
|
137
|
+
// 5. Create the intelligence layer middleware
|
|
138
|
+
this._middleware = this.createMiddleware();
|
|
139
|
+
// 6. Notify callback
|
|
140
|
+
if (this._onRoutesPrepared) {
|
|
141
|
+
const result = this._onRoutesPrepared(sortedRoutes);
|
|
142
|
+
if (result instanceof Promise) {
|
|
143
|
+
result.catch((err) => {
|
|
144
|
+
console.error("Error in onRoutesPrepared callback:", err);
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
return this;
|
|
149
|
+
}
|
|
150
|
+
/** Sort routes: static segments before dynamic */
|
|
151
|
+
compareRoutes(a, b) {
|
|
152
|
+
const aSegments = a.path.split("/").filter(Boolean);
|
|
153
|
+
const bSegments = b.path.split("/").filter(Boolean);
|
|
154
|
+
const len = Math.max(aSegments.length, bSegments.length);
|
|
155
|
+
for (let i = 0; i < len; i++) {
|
|
156
|
+
const segA = aSegments[i];
|
|
157
|
+
const segB = bSegments[i];
|
|
158
|
+
if (segA === undefined)
|
|
159
|
+
return 1;
|
|
160
|
+
if (segB === undefined)
|
|
161
|
+
return -1;
|
|
162
|
+
const aIsDynamic = segA.startsWith(":");
|
|
163
|
+
const bIsDynamic = segB.startsWith(":");
|
|
164
|
+
if (aIsDynamic && !bIsDynamic)
|
|
165
|
+
return 1;
|
|
166
|
+
if (!aIsDynamic && bIsDynamic)
|
|
167
|
+
return -1;
|
|
168
|
+
}
|
|
169
|
+
return b.path.length - a.path.length;
|
|
170
|
+
}
|
|
171
|
+
/** Create the main Express middleware (intelligence + execution layers) */
|
|
172
|
+
createMiddleware() {
|
|
173
|
+
return async (req, res, next) => {
|
|
174
|
+
try {
|
|
175
|
+
// Intelligence Layer: match RAI and check authorization
|
|
176
|
+
const path = req.path;
|
|
177
|
+
const reqRai = this._raiMatcher.findRai(path, req.method);
|
|
178
|
+
if (!reqRai) {
|
|
179
|
+
const errorPath = req.originalUrl.split("?")[0];
|
|
180
|
+
res.status(404);
|
|
181
|
+
return next(new errors.RequestError(this._dev?.helpfulErrors
|
|
182
|
+
? this.createHelpfulNotFoundError(errorPath, req.method)
|
|
183
|
+
: `Route not found`, { code: "RAI_NOT_FOUND" }));
|
|
184
|
+
}
|
|
185
|
+
const route = this._raisMap.get(reqRai);
|
|
186
|
+
req.rai = reqRai;
|
|
187
|
+
req.route_instance = route;
|
|
188
|
+
const user = req.user;
|
|
189
|
+
const userRoles = user?.roles || [this._guestRole];
|
|
190
|
+
if (!route.isAuthorized(userRoles)) {
|
|
191
|
+
const isGuest = userRoles.includes(this._guestRole) && userRoles.length === 1;
|
|
192
|
+
res.status(isGuest ? 401 : 403);
|
|
193
|
+
return next(new errors.RequestError(this._dev?.helpfulErrors
|
|
194
|
+
? this.createHelpfulUnauthorizedError(route, userRoles)
|
|
195
|
+
: `Unauthorized`, { code: "UNAUTHORIZED" }));
|
|
196
|
+
}
|
|
197
|
+
// Execution Layer: delegate to master router
|
|
198
|
+
return this._masterRouter(req, res, next);
|
|
199
|
+
}
|
|
200
|
+
catch (error) {
|
|
201
|
+
return next(error);
|
|
202
|
+
}
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
createHelpfulNotFoundError(path, method) {
|
|
206
|
+
const availableRoutes = Array.from(this._raisMap.values())
|
|
207
|
+
.filter((r) => r.method === method)
|
|
208
|
+
.map((r) => r.path);
|
|
209
|
+
let message = `No route found for ${method} ${path}`;
|
|
210
|
+
if (availableRoutes.length > 0) {
|
|
211
|
+
message += `\n\nAvailable ${method} routes:\n`;
|
|
212
|
+
availableRoutes.forEach((route) => {
|
|
213
|
+
message += ` - ${route}\n`;
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
return message;
|
|
217
|
+
}
|
|
218
|
+
createHelpfulUnauthorizedError(route, userRoles) {
|
|
219
|
+
const isGuest = userRoles.length === 1 && userRoles[0] === this._guestRole;
|
|
220
|
+
if (isGuest) {
|
|
221
|
+
return `Authentication required to access ${route.method} ${route.path}\n\nThis route requires one of the following roles: ${route.roles.join(", ")}`;
|
|
222
|
+
}
|
|
223
|
+
return `Insufficient permissions to access ${route.method} ${route.path}\n\nRequired roles: ${route.roles.join(", ")}\nYour roles: ${userRoles.join(", ")}`;
|
|
224
|
+
}
|
|
225
|
+
/** Get all registered routes (must call build() first) */
|
|
226
|
+
getRoutes() {
|
|
227
|
+
if (!this._built) {
|
|
228
|
+
throw new Error("Cannot get routes before build() is called");
|
|
229
|
+
}
|
|
230
|
+
return Array.from(this._raisMap.values());
|
|
231
|
+
}
|
|
232
|
+
/** Get a route by RAI */
|
|
233
|
+
getRoute(rai) {
|
|
234
|
+
if (!this._built) {
|
|
235
|
+
throw new Error("Cannot get route before build() is called");
|
|
236
|
+
}
|
|
237
|
+
return this._raisMap.get(rai);
|
|
238
|
+
}
|
|
239
|
+
/** Get the Express middleware function */
|
|
240
|
+
handler() {
|
|
241
|
+
if (!this._built) {
|
|
242
|
+
throw new Error("Cannot get handler before build() is called. Make sure to call build() first.");
|
|
243
|
+
}
|
|
244
|
+
return this._middleware;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
export default Wecon;
|
|
248
|
+
//# sourceMappingURL=Wecon.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Wecon.js","sourceRoot":"","sources":["../../src/routing/Wecon.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAUH,OAAO,MAAM,MAAM,aAAa,CAAC;AAEjC,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,UAAU,MAAM,iBAAiB,CAAC;AAYzC;;;GAGG;AACH,MAAM,KAAK;IACD,OAAO,CAAiB;IACxB,MAAM,GAAY,EAAE,CAAC;IACrB,UAAU,GAAW,OAAO,CAAC;IAC7B,iBAAiB,CAAoD;IACrE,IAAI,CAAkB;IAEtB,WAAW,CAAc;IACzB,aAAa,CAAU;IAEvB,MAAM,GAAY,KAAK,CAAC;IACxB,QAAQ,CAA0B;IAClC,WAAW,CAAkB;IAErC,gBAAe,CAAC;IAEhB,0BAA0B;IACnB,MAAM,CAAC,MAAqB;QACjC,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAC;QACvE,CAAC;QACD,IAAI,CAAC,CAAC,MAAM,YAAY,MAAM,CAAC,EAAE,CAAC;YAChC,MAAM,IAAI,KAAK,CAAC,uDAAuD,CAAC,CAAC;QAC3E,CAAC;QACD,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC;QACtB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,6BAA6B;IACtB,KAAK,CAAmB,KAAmB;QAChD,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAC;QACvE,CAAC;QACD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YAC1B,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC;QAC9D,CAAC;QACA,IAA4B,CAAC,MAAM,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC;QAClD,OAAO,IAA2B,CAAC;IACrC,CAAC;IAED,+CAA+C;IACxC,SAAS,CAAC,SAAiB;QAChC,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAC;QACvE,CAAC;QACD,IAAI,OAAO,SAAS,KAAK,QAAQ,EAAE,CAAC;YAClC,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC;QACvD,CAAC;QACD,IAAI,CAAC,UAAU,GAAG,SAAS,CAAC;QAC5B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,gDAAgD;IACzC,gBAAgB,CACrB,QAAmD;QAEnD,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAC;QACvE,CAAC;QACD,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE,CAAC;YACnC,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAC;QAChE,CAAC;QACD,IAAI,CAAC,iBAAiB,GAAG,QAAQ,CAAC;QAClC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,yCAAyC;IAClC,GAAG,CAAC,MAAsB;QAC/B,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAC;QACvE,CAAC;QACD,IAAI,CAAC,IAAI,GAAG,MAAM,CAAC;QACnB,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;OAGG;IACI,KAAK;QACV,IAAI,IAAI,CAAC,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC;QACpE,IAAI,CAAC,IAAI,CAAC,OAAO;YAAE,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAC;QAC7E,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAC;QAEjE,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;QACnB,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,gBAAgB,EAAE,CAAC;QAEhD,4BAA4B;QAC5B,MAAM,UAAU,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YAChE,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,MAAM,EAAE,CAAC,CAAC,MAAM;YAChB,GAAG,EAAE,CAAC,CAAC,GAAG;SACX,CAAC,CAAC,CAAC;QACJ,IAAI,CAAC,WAAW,GAAG,IAAI,UAAU,CAAC,UAAU,CAAC,CAAC;QAE9C,mFAAmF;QACnF,iEAAiE;QACjE,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;QACrD,IAAI,CAAC,aAAa,GAAG,aAAa,CAAC,EAAE,WAAW,EAAE,IAAI,EAAE,CAAW,CAAC;QAEpE,wDAAwD;QACxD,MAAM,YAAY,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAC1D,IAAI,CAAC,aAAa,CACnB,CAAC;QAEF,8CAA8C;QAC9C,YAAY,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;YAC7B,0BAA0B;YAC1B,KAAK,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;gBAC9B,IAAI,CAAC,aAAc,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC;gBAExD,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;oBACnB,IAAI,CAAC,aAAc,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE;wBAC9D,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,GAAG,CAAC,EAAE,CAAC;4BAC9B,OAAO,IAAI,CACT,IAAI,MAAM,CAAC,YAAY,CAAC,mBAAmB,EAAE;gCAC3C,IAAI,EAAE,eAAe;6BACtB,CAAC,CACH,CAAC;wBACJ,CAAC;wBACD,IAAI,EAAE,CAAC;oBACT,CAAC,CAAC,CAAC;gBACL,CAAC;YACH,CAAC,CAAC,CAAC;YAEH,2BAA2B;YAC3B,QAAQ,KAAK,CAAC,MAAM,EAAE,CAAC;gBACrB,KAAK,KAAK;oBACR,IAAI,CAAC,aAAc,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,GAAG,KAAK,CAAC,WAAW,CAAC,CAAC;oBAC1D,MAAM;gBACR,KAAK,MAAM;oBACT,IAAI,CAAC,aAAc,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,GAAG,KAAK,CAAC,WAAW,CAAC,CAAC;oBAC3D,MAAM;gBACR,KAAK,KAAK;oBACR,IAAI,CAAC,aAAc,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,GAAG,KAAK,CAAC,WAAW,CAAC,CAAC;oBAC1D,MAAM;gBACR,KAAK,QAAQ;oBACX,IAAI,CAAC,aAAc,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,GAAG,KAAK,CAAC,WAAW,CAAC,CAAC;oBAC7D,MAAM;YACV,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,8CAA8C;QAC9C,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,gBAAgB,EAAE,CAAC;QAE3C,qBAAqB;QACrB,IAAI,IAAI,CAAC,iBAAiB,EAAE,CAAC;YAC3B,MAAM,MAAM,GAAG,IAAI,CAAC,iBAAiB,CAAC,YAAY,CAAC,CAAC;YACpD,IAAI,MAAM,YAAY,OAAO,EAAE,CAAC;gBAC9B,MAAM,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;oBACnB,OAAO,CAAC,KAAK,CAAC,qCAAqC,EAAE,GAAG,CAAC,CAAC;gBAC5D,CAAC,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;IAED,kDAAkD;IAC1C,aAAa,CAAC,CAAQ,EAAE,CAAQ;QACtC,MAAM,SAAS,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACpD,MAAM,SAAS,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACpD,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,MAAM,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC;QAEzD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;YAC7B,MAAM,IAAI,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;YAC1B,MAAM,IAAI,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;YAE1B,IAAI,IAAI,KAAK,SAAS;gBAAE,OAAO,CAAC,CAAC;YACjC,IAAI,IAAI,KAAK,SAAS;gBAAE,OAAO,CAAC,CAAC,CAAC;YAElC,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;YACxC,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;YAExC,IAAI,UAAU,IAAI,CAAC,UAAU;gBAAE,OAAO,CAAC,CAAC;YACxC,IAAI,CAAC,UAAU,IAAI,UAAU;gBAAE,OAAO,CAAC,CAAC,CAAC;QAC3C,CAAC;QAED,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC;IACvC,CAAC;IAED,2EAA2E;IACnE,gBAAgB;QACtB,OAAO,KAAK,EAAE,GAAY,EAAE,GAAa,EAAE,IAAkB,EAAE,EAAE;YAC/D,IAAI,CAAC;gBACH,wDAAwD;gBACxD,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC;gBACtB,MAAM,MAAM,GAAG,IAAI,CAAC,WAAY,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;gBAE3D,IAAI,CAAC,MAAM,EAAE,CAAC;oBACZ,MAAM,SAAS,GAAG,GAAG,CAAC,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;oBAChD,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;oBAChB,OAAO,IAAI,CACT,IAAI,MAAM,CAAC,YAAY,CACrB,IAAI,CAAC,IAAI,EAAE,aAAa;wBACtB,CAAC,CAAC,IAAI,CAAC,0BAA0B,CAAC,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC;wBACxD,CAAC,CAAC,iBAAiB,EACrB,EAAE,IAAI,EAAE,eAAe,EAAE,CAC1B,CACF,CAAC;gBACJ,CAAC;gBAED,MAAM,KAAK,GAAG,IAAI,CAAC,QAAS,CAAC,GAAG,CAAC,MAAM,CAAE,CAAC;gBAC1C,GAAG,CAAC,GAAG,GAAG,MAAM,CAAC;gBACjB,GAAG,CAAC,cAAc,GAAG,KAAK,CAAC;gBAE3B,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC;gBACtB,MAAM,SAAS,GAAa,IAAI,EAAE,KAAK,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;gBAE7D,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,SAAS,CAAC,EAAE,CAAC;oBACnC,MAAM,OAAO,GACX,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,CAAC;oBAChE,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;oBAChC,OAAO,IAAI,CACT,IAAI,MAAM,CAAC,YAAY,CACrB,IAAI,CAAC,IAAI,EAAE,aAAa;wBACtB,CAAC,CAAC,IAAI,CAAC,8BAA8B,CAAC,KAAK,EAAE,SAAS,CAAC;wBACvD,CAAC,CAAC,cAAc,EAClB,EAAE,IAAI,EAAE,cAAc,EAAE,CACzB,CACF,CAAC;gBACJ,CAAC;gBAED,6CAA6C;gBAC7C,OAAO,IAAI,CAAC,aAAc,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;YAC7C,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC;YACrB,CAAC;QACH,CAAC,CAAC;IACJ,CAAC;IAEO,0BAA0B,CAAC,IAAY,EAAE,MAAc;QAC7D,MAAM,eAAe,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,QAAS,CAAC,MAAM,EAAE,CAAC;aACxD,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC;aAClC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAEtB,IAAI,OAAO,GAAG,sBAAsB,MAAM,IAAI,IAAI,EAAE,CAAC;QACrD,IAAI,eAAe,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC/B,OAAO,IAAI,iBAAiB,MAAM,YAAY,CAAC;YAC/C,eAAe,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;gBAChC,OAAO,IAAI,OAAO,KAAK,IAAI,CAAC;YAC9B,CAAC,CAAC,CAAC;QACL,CAAC;QACD,OAAO,OAAO,CAAC;IACjB,CAAC;IAEO,8BAA8B,CACpC,KAAY,EACZ,SAAmB;QAEnB,MAAM,OAAO,GAAG,SAAS,CAAC,MAAM,KAAK,CAAC,IAAI,SAAS,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,UAAU,CAAC;QAE3E,IAAI,OAAO,EAAE,CAAC;YACZ,OAAO,qCAAqC,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,IAAI,uDAAuD,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QACxJ,CAAC;QAED,OAAO,sCAAsC,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,IAAI,uBAAuB,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,iBAAiB,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;IAC9J,CAAC;IAED,0DAA0D;IACnD,SAAS;QACd,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAC;QAChE,CAAC;QACD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,QAAS,CAAC,MAAM,EAAE,CAAC,CAAC;IAC7C,CAAC;IAED,yBAAyB;IAClB,QAAQ,CAAC,GAAQ;QACtB,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAC;QAC/D,CAAC;QACD,OAAO,IAAI,CAAC,QAAS,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACjC,CAAC;IAED,0CAA0C;IACnC,OAAO;QACZ,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CAAC,+EAA+E,CAAC,CAAC;QACnG,CAAC;QACD,OAAO,IAAI,CAAC,WAAY,CAAC;IAC3B,CAAC;CACF;AAED,eAAe,KAAK,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export { default as Wecon } from "./Wecon.js";
|
|
2
|
+
export type { WeconDevConfig } from "./Wecon.js";
|
|
3
|
+
export { default as Route } from "./Route.js";
|
|
4
|
+
export { default as Routes } from "./Routes.js";
|
|
5
|
+
export { default as RoutesParam } from "./RoutesParam.js";
|
|
6
|
+
export { default as RaiMatcher } from "./RaiMatcher.js";
|
|
7
|
+
export type { RaiRoutesList } from "./RaiMatcher.js";
|
|
8
|
+
export { ErrorCatcher } from "./ErrorCatcher.js";
|
|
9
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/routing/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,YAAY,CAAC;AAC9C,YAAY,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AACjD,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,iBAAiB,CAAC;AACxD,YAAY,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { default as Wecon } from "./Wecon.js";
|
|
2
|
+
export { default as Route } from "./Route.js";
|
|
3
|
+
export { default as Routes } from "./Routes.js";
|
|
4
|
+
export { default as RoutesParam } from "./RoutesParam.js";
|
|
5
|
+
export { default as RaiMatcher } from "./RaiMatcher.js";
|
|
6
|
+
export { ErrorCatcher } from "./ErrorCatcher.js";
|
|
7
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/routing/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,YAAY,CAAC;AAE9C,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAExD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC"}
|
package/dist/server/index.d.ts
CHANGED
|
@@ -3,9 +3,56 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Creates and configures the Express application with all framework features.
|
|
5
5
|
* This is the main entry point for the Wecon framework.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* import { createWecon, loadConfig } from '@weconjs/core';
|
|
10
|
+
*
|
|
11
|
+
* const config = await loadConfig('./wecon.config.ts');
|
|
12
|
+
*
|
|
13
|
+
* const app = await createWecon({
|
|
14
|
+
* config,
|
|
15
|
+
* modules: [authModule, usersModule],
|
|
16
|
+
* database: { enabled: true },
|
|
17
|
+
* plugins: { fieldShield: true },
|
|
18
|
+
* });
|
|
19
|
+
*
|
|
20
|
+
* await app.start();
|
|
21
|
+
* ```
|
|
6
22
|
*/
|
|
7
|
-
import
|
|
8
|
-
import
|
|
23
|
+
import http from "http";
|
|
24
|
+
import https from "https";
|
|
25
|
+
import type { Application, RequestHandler } from "express";
|
|
26
|
+
import type { ResolvedConfig, WeconModule, WeconContext } from "../types.js";
|
|
27
|
+
import type Wecon from "../routing/Wecon.js";
|
|
28
|
+
import { type DatabaseConnection } from "../database/index.js";
|
|
29
|
+
import { type DevToolsOptions } from "../devtools/index.js";
|
|
30
|
+
/**
|
|
31
|
+
* API Error format
|
|
32
|
+
*/
|
|
33
|
+
export interface ApiError {
|
|
34
|
+
code: string;
|
|
35
|
+
message: string;
|
|
36
|
+
field?: string;
|
|
37
|
+
params?: Record<string, unknown>;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Standard API Response format
|
|
41
|
+
*/
|
|
42
|
+
export interface ApiResponse<T = unknown> {
|
|
43
|
+
success: boolean;
|
|
44
|
+
data: T | null;
|
|
45
|
+
errors: ApiError[] | null;
|
|
46
|
+
meta: Record<string, unknown> | null;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Response options for res.respond()
|
|
50
|
+
*/
|
|
51
|
+
export interface RespondOptions<T = unknown> {
|
|
52
|
+
data?: T;
|
|
53
|
+
errors?: ApiError[];
|
|
54
|
+
meta?: Record<string, unknown>;
|
|
55
|
+
}
|
|
9
56
|
/**
|
|
10
57
|
* Options for creating a Wecon application
|
|
11
58
|
*/
|
|
@@ -19,25 +66,120 @@ export interface CreateWeconOptions {
|
|
|
19
66
|
*/
|
|
20
67
|
modules: WeconModule[];
|
|
21
68
|
/**
|
|
22
|
-
*
|
|
69
|
+
* The Wecon routing instance (for route handling).
|
|
70
|
+
* If provided, wecon.handler() is mounted automatically.
|
|
71
|
+
*/
|
|
72
|
+
wecon?: Wecon;
|
|
73
|
+
/**
|
|
74
|
+
* Custom middleware to apply before routes
|
|
75
|
+
*/
|
|
76
|
+
middleware?: RequestHandler[];
|
|
77
|
+
/**
|
|
78
|
+
* Database options
|
|
79
|
+
*/
|
|
80
|
+
database?: {
|
|
81
|
+
/**
|
|
82
|
+
* Enable database connection
|
|
83
|
+
*/
|
|
84
|
+
enabled?: boolean;
|
|
85
|
+
/**
|
|
86
|
+
* Direct MongoDB URI (overrides config)
|
|
87
|
+
*/
|
|
88
|
+
uri?: string;
|
|
89
|
+
/**
|
|
90
|
+
* Mongoose plugins to register
|
|
91
|
+
*/
|
|
92
|
+
plugins?: Array<{
|
|
93
|
+
plugin: (schema: unknown, options?: unknown) => void;
|
|
94
|
+
options?: unknown;
|
|
95
|
+
}>;
|
|
96
|
+
};
|
|
97
|
+
/**
|
|
98
|
+
* Plugin options
|
|
99
|
+
*/
|
|
100
|
+
plugins?: {
|
|
101
|
+
/**
|
|
102
|
+
* Enable FieldShield integration
|
|
103
|
+
*/
|
|
104
|
+
fieldShield?: boolean | {
|
|
105
|
+
strict?: boolean;
|
|
106
|
+
debug?: boolean;
|
|
107
|
+
};
|
|
108
|
+
};
|
|
109
|
+
/**
|
|
110
|
+
* i18n options
|
|
111
|
+
*/
|
|
112
|
+
i18n?: {
|
|
113
|
+
/**
|
|
114
|
+
* Enable i18n middleware
|
|
115
|
+
* @default true if config.features.i18n.enabled
|
|
116
|
+
*/
|
|
117
|
+
enabled?: boolean;
|
|
118
|
+
/**
|
|
119
|
+
* Path to modules directory for translation discovery
|
|
120
|
+
*/
|
|
121
|
+
modulesDir?: string;
|
|
122
|
+
};
|
|
123
|
+
/**
|
|
124
|
+
* Logger options
|
|
125
|
+
*/
|
|
126
|
+
logger?: {
|
|
127
|
+
/**
|
|
128
|
+
* Use Winston logger (requires winston package)
|
|
129
|
+
* @default true
|
|
130
|
+
*/
|
|
131
|
+
useWinston?: boolean;
|
|
132
|
+
/**
|
|
133
|
+
* Enable file logging
|
|
134
|
+
* @default false
|
|
135
|
+
*/
|
|
136
|
+
enableFile?: boolean;
|
|
137
|
+
/**
|
|
138
|
+
* Log directory
|
|
139
|
+
* @default 'logs'
|
|
140
|
+
*/
|
|
141
|
+
logDir?: string;
|
|
142
|
+
};
|
|
143
|
+
/**
|
|
144
|
+
* Module dependency options
|
|
23
145
|
*/
|
|
24
|
-
|
|
146
|
+
moduleDeps?: {
|
|
147
|
+
/**
|
|
148
|
+
* Auto-install missing module dependencies
|
|
149
|
+
* @default true in development, false in production
|
|
150
|
+
*/
|
|
151
|
+
autoInstall?: boolean;
|
|
152
|
+
/**
|
|
153
|
+
* Root directory for resolving module paths and node_modules
|
|
154
|
+
* @default process.cwd()
|
|
155
|
+
*/
|
|
156
|
+
rootDir?: string;
|
|
157
|
+
/**
|
|
158
|
+
* Module paths (keyed by module name) for dependency checking.
|
|
159
|
+
* If not provided, dependency checking is skipped.
|
|
160
|
+
*/
|
|
161
|
+
paths?: Record<string, string>;
|
|
162
|
+
};
|
|
163
|
+
/**
|
|
164
|
+
* DevTools REST API options
|
|
165
|
+
*/
|
|
166
|
+
devtools?: DevToolsOptions;
|
|
25
167
|
/**
|
|
26
168
|
* Lifecycle hooks
|
|
27
169
|
*/
|
|
28
170
|
hooks?: {
|
|
29
171
|
/**
|
|
30
|
-
* Called before server starts
|
|
172
|
+
* Called before server starts (after middleware setup)
|
|
31
173
|
*/
|
|
32
|
-
onBoot?: () => Promise<void> | void;
|
|
174
|
+
onBoot?: (ctx: WeconContext) => Promise<void> | void;
|
|
33
175
|
/**
|
|
34
176
|
* Called when server is shutting down
|
|
35
177
|
*/
|
|
36
|
-
onShutdown?: () => Promise<void> | void;
|
|
178
|
+
onShutdown?: (ctx: WeconContext) => Promise<void> | void;
|
|
37
179
|
/**
|
|
38
180
|
* Called after each module is initialized
|
|
39
181
|
*/
|
|
40
|
-
onModuleInit?: (module: WeconModule) => Promise<void> | void;
|
|
182
|
+
onModuleInit?: (module: WeconModule, ctx: WeconContext) => Promise<void> | void;
|
|
41
183
|
};
|
|
42
184
|
}
|
|
43
185
|
/**
|
|
@@ -48,10 +190,18 @@ export interface WeconApp {
|
|
|
48
190
|
* The underlying Express application
|
|
49
191
|
*/
|
|
50
192
|
app: Application;
|
|
193
|
+
/**
|
|
194
|
+
* The application context
|
|
195
|
+
*/
|
|
196
|
+
ctx: WeconContext;
|
|
197
|
+
/**
|
|
198
|
+
* Database connection (if enabled)
|
|
199
|
+
*/
|
|
200
|
+
db?: DatabaseConnection;
|
|
51
201
|
/**
|
|
52
202
|
* Start the server
|
|
53
203
|
*/
|
|
54
|
-
start: (port?: number) => Promise<
|
|
204
|
+
start: (port?: number) => Promise<http.Server | https.Server>;
|
|
55
205
|
/**
|
|
56
206
|
* Gracefully shutdown the server
|
|
57
207
|
*/
|
|
@@ -64,7 +214,9 @@ export interface WeconApp {
|
|
|
64
214
|
* - Database connection
|
|
65
215
|
* - i18n initialization
|
|
66
216
|
* - Module loading
|
|
67
|
-
* -
|
|
217
|
+
* - Logging
|
|
218
|
+
* - HTTPS support
|
|
219
|
+
* - Graceful shutdown
|
|
68
220
|
*
|
|
69
221
|
* @param options - Configuration options
|
|
70
222
|
* @returns Wecon application instance
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"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"}
|