@kurdel/runtime 0.1.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +44 -0
- package/lib/app/errors/controller-action-missing-result-error.d.ts +9 -0
- package/lib/app/errors/controller-action-missing-result-error.js +14 -0
- package/lib/app/errors/controller-action-missing-result-error.js.map +1 -0
- package/lib/app/errors/module-validation-error.d.ts +25 -0
- package/lib/app/errors/module-validation-error.js +29 -0
- package/lib/app/errors/module-validation-error.js.map +1 -0
- package/lib/app/errors/provider-configuration-error.d.ts +24 -0
- package/lib/app/errors/provider-configuration-error.js +28 -0
- package/lib/app/errors/provider-configuration-error.js.map +1 -0
- package/lib/app/index.d.ts +1 -0
- package/lib/app/index.js +2 -0
- package/lib/app/index.js.map +1 -0
- package/lib/app/lifecycle-manager.d.ts +26 -0
- package/lib/app/lifecycle-manager.js +40 -0
- package/lib/app/lifecycle-manager.js.map +1 -0
- package/lib/app/module-loader.d.ts +29 -0
- package/lib/app/module-loader.js +61 -0
- package/lib/app/module-loader.js.map +1 -0
- package/lib/app/provider-registrar.d.ts +29 -0
- package/lib/app/provider-registrar.js +67 -0
- package/lib/app/provider-registrar.js.map +1 -0
- package/lib/app/runtime-application.d.ts +75 -0
- package/lib/app/runtime-application.js +97 -0
- package/lib/app/runtime-application.js.map +1 -0
- package/lib/app/runtime-composer.d.ts +25 -0
- package/lib/app/runtime-composer.js +100 -0
- package/lib/app/runtime-composer.js.map +1 -0
- package/lib/app/server-runner.d.ts +36 -0
- package/lib/app/server-runner.js +65 -0
- package/lib/app/server-runner.js.map +1 -0
- package/lib/http/index.d.ts +6 -0
- package/lib/http/index.js +7 -0
- package/lib/http/index.js.map +1 -0
- package/lib/http/is-http-error.d.ts +2 -0
- package/lib/http/is-http-error.js +7 -0
- package/lib/http/is-http-error.js.map +1 -0
- package/lib/http/noop-response-renderer.d.ts +7 -0
- package/lib/http/noop-response-renderer.js +10 -0
- package/lib/http/noop-response-renderer.js.map +1 -0
- package/lib/http/render-action-result.d.ts +4 -0
- package/lib/http/render-action-result.js +24 -0
- package/lib/http/render-action-result.js.map +1 -0
- package/lib/http/runtime-controller-pipe.d.ts +16 -0
- package/lib/http/runtime-controller-pipe.js +26 -0
- package/lib/http/runtime-controller-pipe.js.map +1 -0
- package/lib/http/runtime-controller-resolver.d.ts +12 -0
- package/lib/http/runtime-controller-resolver.js +29 -0
- package/lib/http/runtime-controller-resolver.js.map +1 -0
- package/lib/http/runtime-http-context-factory.d.ts +29 -0
- package/lib/http/runtime-http-context-factory.js +91 -0
- package/lib/http/runtime-http-context-factory.js.map +1 -0
- package/lib/http/runtime-middleware-pipe.d.ts +15 -0
- package/lib/http/runtime-middleware-pipe.js +31 -0
- package/lib/http/runtime-middleware-pipe.js.map +1 -0
- package/lib/http/runtime-middleware-registry.d.ts +18 -0
- package/lib/http/runtime-middleware-registry.js +39 -0
- package/lib/http/runtime-middleware-registry.js.map +1 -0
- package/lib/http/runtime-request-orchestrator.d.ts +21 -0
- package/lib/http/runtime-request-orchestrator.js +114 -0
- package/lib/http/runtime-request-orchestrator.js.map +1 -0
- package/lib/http/runtime-response-renderer.d.ts +12 -0
- package/lib/http/runtime-response-renderer.js +37 -0
- package/lib/http/runtime-response-renderer.js.map +1 -0
- package/lib/http/runtime-router.d.ts +37 -0
- package/lib/http/runtime-router.js +135 -0
- package/lib/http/runtime-router.js.map +1 -0
- package/lib/index.d.ts +3 -0
- package/lib/index.js +4 -0
- package/lib/index.js.map +1 -0
- package/lib/middlewares/create-validator.d.ts +7 -0
- package/lib/middlewares/create-validator.js +21 -0
- package/lib/middlewares/create-validator.js.map +1 -0
- package/lib/middlewares/error-handle.d.ts +2 -0
- package/lib/middlewares/error-handle.js +30 -0
- package/lib/middlewares/error-handle.js.map +1 -0
- package/lib/middlewares/index.d.ts +2 -0
- package/lib/middlewares/index.js +3 -0
- package/lib/middlewares/index.js.map +1 -0
- package/lib/middlewares/json-body-parser.d.ts +14 -0
- package/lib/middlewares/json-body-parser.js +23 -0
- package/lib/middlewares/json-body-parser.js.map +1 -0
- package/lib/middlewares/schema-validator.d.ts +13 -0
- package/lib/middlewares/schema-validator.js +44 -0
- package/lib/middlewares/schema-validator.js.map +1 -0
- package/lib/modules/controller-module.d.ts +23 -0
- package/lib/modules/controller-module.js +76 -0
- package/lib/modules/controller-module.js.map +1 -0
- package/lib/modules/database-module.d.ts +25 -0
- package/lib/modules/database-module.js +40 -0
- package/lib/modules/database-module.js.map +1 -0
- package/lib/modules/index.d.ts +1 -0
- package/lib/modules/index.js +2 -0
- package/lib/modules/index.js.map +1 -0
- package/lib/modules/lifecycle-module.d.ts +9 -0
- package/lib/modules/lifecycle-module.js +17 -0
- package/lib/modules/lifecycle-module.js.map +1 -0
- package/lib/modules/middleware-module.d.ts +18 -0
- package/lib/modules/middleware-module.js +45 -0
- package/lib/modules/middleware-module.js.map +1 -0
- package/lib/modules/model-module.d.ts +17 -0
- package/lib/modules/model-module.js +24 -0
- package/lib/modules/model-module.js.map +1 -0
- package/lib/modules/server-module.d.ts +30 -0
- package/lib/modules/server-module.js +65 -0
- package/lib/modules/server-module.js.map +1 -0
- package/lib/template/ensure-template-engine-binding.d.ts +2 -0
- package/lib/template/ensure-template-engine-binding.js +8 -0
- package/lib/template/ensure-template-engine-binding.js.map +1 -0
- package/lib/template/index.d.ts +1 -0
- package/lib/template/index.js +2 -0
- package/lib/template/index.js.map +1 -0
- package/lib/template/noop-template-engine.d.ts +4 -0
- package/lib/template/noop-template-engine.js +6 -0
- package/lib/template/noop-template-engine.js.map +1 -0
- package/package.json +64 -0
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { HttpError } from '@kurdel/core/http';
|
|
2
|
+
import { isHttpError } from '../http/is-http-error.js';
|
|
3
|
+
export const errorHandler = async (ctx, next) => {
|
|
4
|
+
try {
|
|
5
|
+
return await next();
|
|
6
|
+
}
|
|
7
|
+
catch (err) {
|
|
8
|
+
if (err instanceof HttpError) {
|
|
9
|
+
return {
|
|
10
|
+
kind: 'json',
|
|
11
|
+
status: err.status,
|
|
12
|
+
body: {
|
|
13
|
+
error: err.message,
|
|
14
|
+
...(err.details ? { details: err.details } : {}),
|
|
15
|
+
},
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
if (isHttpError(err)) {
|
|
19
|
+
ctx.res.status(err.status).send(err.message ?? 'Error');
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
console.error(err);
|
|
23
|
+
return {
|
|
24
|
+
kind: 'json',
|
|
25
|
+
status: 500,
|
|
26
|
+
body: { error: 'Internal Server Error' },
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
//# sourceMappingURL=error-handle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error-handle.js","sourceRoot":"","sources":["../../src/middlewares/error-handle.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAE9C,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAExD,MAAM,CAAC,MAAM,YAAY,GAAe,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE;IAC1D,IAAI,CAAC;QACH,OAAO,MAAM,IAAI,EAAE,CAAC;IACtB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,GAAG,YAAY,SAAS,EAAE,CAAC;YAC7B,OAAO;gBACL,IAAI,EAAE,MAAM;gBACZ,MAAM,EAAE,GAAG,CAAC,MAAM;gBAClB,IAAI,EAAE;oBACJ,KAAK,EAAE,GAAG,CAAC,OAAO;oBAClB,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,GAAG,CAAC,OAAc,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;iBACxD;aACF,CAAC;QACJ,CAAC;QAED,IAAI,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC;YACrB,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,IAAI,OAAO,CAAC,CAAC;YACxD,OAAO;QACT,CAAC;QAED,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAEnB,OAAO;YACL,IAAI,EAAE,MAAM;YACZ,MAAM,EAAE,GAAG;YACX,IAAI,EAAE,EAAE,KAAK,EAAE,uBAAuB,EAAE;SACzC,CAAC;IACJ,CAAC;AACH,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/middlewares/index.ts"],"names":[],"mappings":"AAAA,cAAc,uBAAuB,CAAC;AACtC,cAAc,uBAAuB,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { Middleware } from '@kurdel/core/http';
|
|
2
|
+
/**
|
|
3
|
+
* Parses JSON request body and assigns it to ctx.body.
|
|
4
|
+
*
|
|
5
|
+
* Usage:
|
|
6
|
+
* appConfig.middlewares = [jsonBodyParser];
|
|
7
|
+
*
|
|
8
|
+
* Then in controller:
|
|
9
|
+
* async create(ctx: HttpContext<Deps, { name: string }>) {
|
|
10
|
+
* if (!ctx.body?.name) throw BadRequest('Name is required');
|
|
11
|
+
* ...
|
|
12
|
+
* }
|
|
13
|
+
*/
|
|
14
|
+
export declare const jsonBodyParser: Middleware;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parses JSON request body and assigns it to ctx.body.
|
|
3
|
+
*
|
|
4
|
+
* Usage:
|
|
5
|
+
* appConfig.middlewares = [jsonBodyParser];
|
|
6
|
+
*
|
|
7
|
+
* Then in controller:
|
|
8
|
+
* async create(ctx: HttpContext<Deps, { name: string }>) {
|
|
9
|
+
* if (!ctx.body?.name) throw BadRequest('Name is required');
|
|
10
|
+
* ...
|
|
11
|
+
* }
|
|
12
|
+
*/
|
|
13
|
+
export const jsonBodyParser = async (ctx, next) => {
|
|
14
|
+
const contentType = ctx.req.headers?.['content-type'] ?? '';
|
|
15
|
+
if (!contentType.includes('application/json')) {
|
|
16
|
+
return next();
|
|
17
|
+
}
|
|
18
|
+
if (ctx.req.body && typeof ctx.req.body === 'object') {
|
|
19
|
+
ctx.body = ctx.req.body;
|
|
20
|
+
}
|
|
21
|
+
return next();
|
|
22
|
+
};
|
|
23
|
+
//# sourceMappingURL=json-body-parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"json-body-parser.js","sourceRoot":"","sources":["../../src/middlewares/json-body-parser.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,cAAc,GAAe,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE;IAC5D,MAAM,WAAW,GAAG,GAAG,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC;IAC5D,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,kBAAkB,CAAC,EAAE,CAAC;QAC9C,OAAO,IAAI,EAAE,CAAC;IAChB,CAAC;IAED,IAAI,GAAG,CAAC,GAAG,CAAC,IAAI,IAAI,OAAO,GAAG,CAAC,GAAG,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QACrD,GAAG,CAAC,IAAI,GAAG,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC;IAC1B,CAAC;IAED,OAAO,IAAI,EAAE,CAAC;AAChB,CAAC,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type Middleware } from '@kurdel/core/http';
|
|
2
|
+
/**
|
|
3
|
+
* ## schemaValidator
|
|
4
|
+
*
|
|
5
|
+
* Global middleware that performs runtime validation of incoming
|
|
6
|
+
* requests based on the {@link RouteSchema} defined in `ctx.route.schema`.
|
|
7
|
+
*
|
|
8
|
+
* No explicit schema injection required — it works automatically
|
|
9
|
+
* for any route that defines `schema` in its metadata.
|
|
10
|
+
*
|
|
11
|
+
* If validation fails, it returns a 400 JSON response.
|
|
12
|
+
*/
|
|
13
|
+
export declare const schemaValidator: Middleware;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { ValidationError, } from '@kurdel/core/http';
|
|
2
|
+
/**
|
|
3
|
+
* ## schemaValidator
|
|
4
|
+
*
|
|
5
|
+
* Global middleware that performs runtime validation of incoming
|
|
6
|
+
* requests based on the {@link RouteSchema} defined in `ctx.route.schema`.
|
|
7
|
+
*
|
|
8
|
+
* No explicit schema injection required — it works automatically
|
|
9
|
+
* for any route that defines `schema` in its metadata.
|
|
10
|
+
*
|
|
11
|
+
* If validation fails, it returns a 400 JSON response.
|
|
12
|
+
*/
|
|
13
|
+
export const schemaValidator = async (ctx, next) => {
|
|
14
|
+
const schema = ctx.route?.schema;
|
|
15
|
+
if (!schema) {
|
|
16
|
+
// No schema — just pass through
|
|
17
|
+
return next();
|
|
18
|
+
}
|
|
19
|
+
try {
|
|
20
|
+
// Validate each part if present in schema
|
|
21
|
+
if (schema.params) {
|
|
22
|
+
ctx.params = await schema.params.validate(ctx.params);
|
|
23
|
+
}
|
|
24
|
+
if (schema.query) {
|
|
25
|
+
ctx.query = await schema.query.validate(ctx.query);
|
|
26
|
+
}
|
|
27
|
+
if (schema.body) {
|
|
28
|
+
ctx.body = await schema.body.validate(ctx.body);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
catch (err) {
|
|
32
|
+
if (err instanceof ValidationError) {
|
|
33
|
+
return ctx.json(400, {
|
|
34
|
+
error: 'Bad Request',
|
|
35
|
+
message: err.message,
|
|
36
|
+
field: err.field,
|
|
37
|
+
details: err.details,
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
throw err;
|
|
41
|
+
}
|
|
42
|
+
return next();
|
|
43
|
+
};
|
|
44
|
+
//# sourceMappingURL=schema-validator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema-validator.js","sourceRoot":"","sources":["../../src/middlewares/schema-validator.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,eAAe,GAChB,MAAM,mBAAmB,CAAC;AAE3B;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,eAAe,GAAe,KAAK,EAAE,GAAgB,EAAE,IAAI,EAAE,EAAE;IAC1E,MAAM,MAAM,GAA4B,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC;IAC1D,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,gCAAgC;QAChC,OAAO,IAAI,EAAE,CAAC;IAChB,CAAC;IAED,IAAI,CAAC;QACH,0CAA0C;QAC1C,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;YACjB,GAAW,CAAC,MAAM,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACjE,CAAC;QACD,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;YAChB,GAAW,CAAC,KAAK,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAC9D,CAAC;QACD,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;YACf,GAAW,CAAC,IAAI,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC3D,CAAC;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,GAAG,YAAY,eAAe,EAAE,CAAC;YACnC,OAAO,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE;gBACnB,KAAK,EAAE,aAAa;gBACpB,OAAO,EAAE,GAAG,CAAC,OAAO;gBACpB,KAAK,EAAE,GAAG,CAAC,KAAK;gBAChB,OAAO,EAAE,GAAG,CAAC,OAAO;aACrB,CAAC,CAAC;QACL,CAAC;QACD,MAAM,GAAG,CAAC;IACZ,CAAC;IAED,OAAO,IAAI,EAAE,CAAC;AAChB,CAAC,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { Container } from '@kurdel/ioc';
|
|
2
|
+
import type { ControllerConfig } from '@kurdel/core/http';
|
|
3
|
+
import type { AppModule, ProviderConfig } from '@kurdel/core/app';
|
|
4
|
+
/**
|
|
5
|
+
* ## ControllerModule
|
|
6
|
+
*
|
|
7
|
+
* Responsible for:
|
|
8
|
+
* - Registering all controller providers in the IoC container.
|
|
9
|
+
* - Instantiating and initializing the `RuntimeRouter`.
|
|
10
|
+
* - Binding declared middlewares to the `MiddlewareRegistry`.
|
|
11
|
+
*/
|
|
12
|
+
export declare class ControllerModule implements AppModule {
|
|
13
|
+
private readonly controllers;
|
|
14
|
+
readonly exports: {
|
|
15
|
+
controllerConfigs: import("@kurdel/ioc").InjectionToken<ControllerConfig[]>;
|
|
16
|
+
};
|
|
17
|
+
readonly providers: ProviderConfig[];
|
|
18
|
+
constructor(controllers: ControllerConfig[]);
|
|
19
|
+
/**
|
|
20
|
+
* Initializes router and middleware registry after IoC bootstrap.
|
|
21
|
+
*/
|
|
22
|
+
register(ioc: Container): Promise<void>;
|
|
23
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { TOKENS } from '@kurdel/core/tokens';
|
|
2
|
+
import { RuntimeControllerResolver } from '../http/runtime-controller-resolver.js';
|
|
3
|
+
import { RuntimeRouter } from '../http/runtime-router.js';
|
|
4
|
+
import { ensureTemplateEngineBinding } from '../template/ensure-template-engine-binding.js';
|
|
5
|
+
/**
|
|
6
|
+
* ## ControllerModule
|
|
7
|
+
*
|
|
8
|
+
* Responsible for:
|
|
9
|
+
* - Registering all controller providers in the IoC container.
|
|
10
|
+
* - Instantiating and initializing the `RuntimeRouter`.
|
|
11
|
+
* - Binding declared middlewares to the `MiddlewareRegistry`.
|
|
12
|
+
*/
|
|
13
|
+
export class ControllerModule {
|
|
14
|
+
constructor(controllers) {
|
|
15
|
+
this.controllers = controllers;
|
|
16
|
+
this.exports = {
|
|
17
|
+
controllerConfigs: TOKENS.ControllerConfigs,
|
|
18
|
+
};
|
|
19
|
+
this.providers = [
|
|
20
|
+
{
|
|
21
|
+
provide: TOKENS.ControllerResolver,
|
|
22
|
+
useFactory: (ioc) => new RuntimeControllerResolver(ioc),
|
|
23
|
+
singleton: true,
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
provide: TOKENS.Router,
|
|
27
|
+
useClass: RuntimeRouter,
|
|
28
|
+
singleton: true,
|
|
29
|
+
},
|
|
30
|
+
...controllers.map(c => ({
|
|
31
|
+
provide: c.use,
|
|
32
|
+
useClass: c.use,
|
|
33
|
+
deps: {
|
|
34
|
+
...c.deps,
|
|
35
|
+
view: TOKENS.TemplateEngineToken,
|
|
36
|
+
},
|
|
37
|
+
})),
|
|
38
|
+
{
|
|
39
|
+
provide: TOKENS.ControllerConfigs,
|
|
40
|
+
useInstance: controllers,
|
|
41
|
+
},
|
|
42
|
+
];
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Initializes router and middleware registry after IoC bootstrap.
|
|
46
|
+
*/
|
|
47
|
+
async register(ioc) {
|
|
48
|
+
// Ensure that a template engine is bound before controller creation.
|
|
49
|
+
ensureTemplateEngineBinding(ioc);
|
|
50
|
+
const resolver = ioc.get(TOKENS.ControllerResolver);
|
|
51
|
+
const router = ioc.get(TOKENS.Router);
|
|
52
|
+
const registry = ioc.get(TOKENS.MiddlewareRegistry);
|
|
53
|
+
const configs = ioc.get(TOKENS.ControllerConfigs);
|
|
54
|
+
// Initialize router (build route table)
|
|
55
|
+
router.init(resolver, configs);
|
|
56
|
+
// Register controller-scoped middlewares
|
|
57
|
+
for (const cfg of this.controllers) {
|
|
58
|
+
for (const entry of cfg.middlewares ?? []) {
|
|
59
|
+
const reg = typeof entry === 'function'
|
|
60
|
+
? { use: entry, zone: 'pre', priority: 0 }
|
|
61
|
+
: {
|
|
62
|
+
use: entry.use,
|
|
63
|
+
zone: entry.zone ?? 'pre',
|
|
64
|
+
priority: entry.priority ?? 0,
|
|
65
|
+
action: entry.action,
|
|
66
|
+
};
|
|
67
|
+
registry.useFor(cfg.use, reg.use, {
|
|
68
|
+
zone: reg.zone,
|
|
69
|
+
priority: reg.priority,
|
|
70
|
+
action: reg.action,
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=controller-module.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"controller-module.js","sourceRoot":"","sources":["../../src/modules/controller-module.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAE7C,OAAO,EAAE,yBAAyB,EAAE,MAAM,yCAAyC,CAAC;AACpF,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,EAAE,2BAA2B,EAAE,MAAM,gDAAgD,CAAC;AAE7F;;;;;;;GAOG;AACH,MAAM,OAAO,gBAAgB;IAO3B,YAA6B,WAA+B;QAA/B,gBAAW,GAAX,WAAW,CAAoB;QANnD,YAAO,GAAG;YACjB,iBAAiB,EAAE,MAAM,CAAC,iBAAiB;SAC5C,CAAC;QAKA,IAAI,CAAC,SAAS,GAAG;YACf;gBACE,OAAO,EAAE,MAAM,CAAC,kBAAkB;gBAClC,UAAU,EAAE,CAAC,GAAc,EAAE,EAAE,CAAC,IAAI,yBAAyB,CAAC,GAAG,CAAC;gBAClE,SAAS,EAAE,IAAI;aAChB;YACD;gBACE,OAAO,EAAE,MAAM,CAAC,MAAM;gBACtB,QAAQ,EAAE,aAAuD;gBACjE,SAAS,EAAE,IAAI;aAChB;YACD,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;gBACvB,OAAO,EAAE,CAAC,CAAC,GAAG;gBACd,QAAQ,EAAE,CAAC,CAAC,GAAG;gBACf,IAAI,EAAE;oBACJ,GAAG,CAAC,CAAC,IAAI;oBACT,IAAI,EAAE,MAAM,CAAC,mBAAmB;iBACjC;aACF,CAAC,CAAC;YACH;gBACE,OAAO,EAAE,MAAM,CAAC,iBAAiB;gBACjC,WAAW,EAAE,WAAW;aACzB;SACF,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,QAAQ,CAAC,GAAc;QAC3B,qEAAqE;QACrE,2BAA2B,CAAC,GAAG,CAAC,CAAC;QAEjC,MAAM,QAAQ,GAAG,GAAG,CAAC,GAAG,CAAqB,MAAM,CAAC,kBAAkB,CAAC,CAAC;QACxE,MAAM,MAAM,GAAG,GAAG,CAAC,GAAG,CAAgB,MAAM,CAAC,MAAM,CAAC,CAAC;QACrD,MAAM,QAAQ,GAAG,GAAG,CAAC,GAAG,CAAqB,MAAM,CAAC,kBAAkB,CAAC,CAAC;QACxE,MAAM,OAAO,GAAG,GAAG,CAAC,GAAG,CAAqB,MAAM,CAAC,iBAAiB,CAAC,CAAC;QAEtE,wCAAwC;QACxC,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAE/B,yCAAyC;QACzC,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;YACnC,KAAK,MAAM,KAAK,IAAI,GAAG,CAAC,WAAW,IAAI,EAAE,EAAE,CAAC;gBAC1C,MAAM,GAAG,GACP,OAAO,KAAK,KAAK,UAAU;oBACzB,CAAC,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,EAAE;oBAC1C,CAAC,CAAC;wBACE,GAAG,EAAE,KAAK,CAAC,GAAG;wBACd,IAAI,EAAE,KAAK,CAAC,IAAI,IAAI,KAAK;wBACzB,QAAQ,EAAE,KAAK,CAAC,QAAQ,IAAI,CAAC;wBAC7B,MAAM,EAAE,KAAK,CAAC,MAAM;qBACrB,CAAC;gBAER,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE;oBAChC,IAAI,EAAE,GAAG,CAAC,IAAI;oBACd,QAAQ,EAAE,GAAG,CAAC,QAAQ;oBACtB,MAAM,EAAE,GAAG,CAAC,MAAM;iBACnB,CAAC,CAAC;YACL,CAAC;QACH,CAAC;IACH,CAAC;CACF"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { IoCContainer } from '@kurdel/ioc';
|
|
2
|
+
import { IDatabase } from '@kurdel/db';
|
|
3
|
+
import type { AppConfig, AppModule } from '@kurdel/core/app';
|
|
4
|
+
export declare class NoopDatabase implements IDatabase {
|
|
5
|
+
query: () => Promise<void>;
|
|
6
|
+
get: () => Promise<void>;
|
|
7
|
+
all: () => Promise<void>;
|
|
8
|
+
run: () => Promise<void>;
|
|
9
|
+
transaction<T>(): Promise<T>;
|
|
10
|
+
close: () => Promise<void>;
|
|
11
|
+
private error;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* DatabaseModule
|
|
15
|
+
*
|
|
16
|
+
* - Provides a database connection if enabled
|
|
17
|
+
* - Exports the IDatabase token
|
|
18
|
+
* - Falls back to NoopDatabase when disabled
|
|
19
|
+
*/
|
|
20
|
+
export declare class DatabaseModule implements AppModule<AppConfig> {
|
|
21
|
+
readonly exports: {
|
|
22
|
+
db: symbol;
|
|
23
|
+
};
|
|
24
|
+
register(ioc: IoCContainer, config: AppConfig): Promise<void>;
|
|
25
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { IDatabase, DBConnector } from '@kurdel/db';
|
|
2
|
+
import { TOKENS } from '@kurdel/core/tokens';
|
|
3
|
+
export class NoopDatabase {
|
|
4
|
+
constructor() {
|
|
5
|
+
this.query = this.error;
|
|
6
|
+
this.get = this.error;
|
|
7
|
+
this.all = this.error;
|
|
8
|
+
this.run = this.error;
|
|
9
|
+
this.close = this.error;
|
|
10
|
+
}
|
|
11
|
+
async transaction() {
|
|
12
|
+
throw new Error('Database is disabled (db=false in config)');
|
|
13
|
+
}
|
|
14
|
+
async error() {
|
|
15
|
+
throw new Error('Database is disabled (db=false in config)');
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* DatabaseModule
|
|
20
|
+
*
|
|
21
|
+
* - Provides a database connection if enabled
|
|
22
|
+
* - Exports the IDatabase token
|
|
23
|
+
* - Falls back to NoopDatabase when disabled
|
|
24
|
+
*/
|
|
25
|
+
export class DatabaseModule {
|
|
26
|
+
constructor() {
|
|
27
|
+
this.exports = { db: IDatabase };
|
|
28
|
+
}
|
|
29
|
+
async register(ioc, config) {
|
|
30
|
+
if (config.db === false) {
|
|
31
|
+
ioc.bind(IDatabase).toInstance(new NoopDatabase());
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
const connector = new DBConnector();
|
|
35
|
+
const connection = await connector.run();
|
|
36
|
+
ioc.bind(IDatabase).toInstance(connection);
|
|
37
|
+
ioc.get(TOKENS.OnShutdown).push(() => connection.close());
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=database-module.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"database-module.js","sourceRoot":"","sources":["../../src/modules/database-module.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAEpD,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAE7C,MAAM,OAAO,YAAY;IAAzB;QACE,UAAK,GAAG,IAAI,CAAC,KAAK,CAAC;QACnB,QAAG,GAAG,IAAI,CAAC,KAAK,CAAC;QACjB,QAAG,GAAG,IAAI,CAAC,KAAK,CAAC;QACjB,QAAG,GAAG,IAAI,CAAC,KAAK,CAAC;QAIjB,UAAK,GAAG,IAAI,CAAC,KAAK,CAAC;IAKrB,CAAC;IARC,KAAK,CAAC,WAAW;QACf,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAC;IAC/D,CAAC;IAGO,KAAK,CAAC,KAAK;QACjB,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAC;IAC/D,CAAC;CACF;AAED;;;;;;GAMG;AACH,MAAM,OAAO,cAAc;IAA3B;QACW,YAAO,GAAG,EAAE,EAAE,EAAE,SAAS,EAAE,CAAC;IAavC,CAAC;IAXC,KAAK,CAAC,QAAQ,CAAC,GAAiB,EAAE,MAAiB;QACjD,IAAI,MAAM,CAAC,EAAE,KAAK,KAAK,EAAE,CAAC;YACxB,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,UAAU,CAAC,IAAI,YAAY,EAAE,CAAC,CAAC;YACnD,OAAO;QACT,CAAC;QAED,MAAM,SAAS,GAAG,IAAI,WAAW,EAAE,CAAC;QACpC,MAAM,UAAU,GAAG,MAAM,SAAS,CAAC,GAAG,EAAE,CAAC;QACzC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;QAC3C,GAAG,CAAC,GAAG,CAAmB,MAAM,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC,CAAC;IAC9E,CAAC;CACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/modules/index.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Container } from '@kurdel/ioc';
|
|
2
|
+
import type { AppModule, AppConfig } from '@kurdel/core/app';
|
|
3
|
+
export declare class LifecycleModule implements AppModule<AppConfig> {
|
|
4
|
+
readonly exports: {
|
|
5
|
+
onStart: import("@kurdel/ioc").InjectionToken<import("@kurdel/core/app").LifecycleHook[]>;
|
|
6
|
+
onShutdown: import("@kurdel/ioc").InjectionToken<import("@kurdel/core/app").LifecycleHook[]>;
|
|
7
|
+
};
|
|
8
|
+
register(ioc: Container): Promise<void>;
|
|
9
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { TOKENS } from '@kurdel/core/tokens';
|
|
2
|
+
export class LifecycleModule {
|
|
3
|
+
constructor() {
|
|
4
|
+
this.exports = {
|
|
5
|
+
onStart: TOKENS.OnStart,
|
|
6
|
+
onShutdown: TOKENS.OnShutdown,
|
|
7
|
+
};
|
|
8
|
+
}
|
|
9
|
+
async register(ioc) {
|
|
10
|
+
// Initialize arrays only once; if already present, keep them
|
|
11
|
+
if (!ioc.has(TOKENS.OnStart))
|
|
12
|
+
ioc.set(TOKENS.OnStart, []);
|
|
13
|
+
if (!ioc.has(TOKENS.OnShutdown))
|
|
14
|
+
ioc.set(TOKENS.OnShutdown, []);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=lifecycle-module.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lifecycle-module.js","sourceRoot":"","sources":["../../src/modules/lifecycle-module.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAE7C,MAAM,OAAO,eAAe;IAA5B;QACW,YAAO,GAAG;YACjB,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,UAAU,EAAE,MAAM,CAAC,UAAU;SAC9B,CAAC;IAOJ,CAAC;IALC,KAAK,CAAC,QAAQ,CAAC,GAAc;QAC3B,6DAA6D;QAC7D,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC;YAAE,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;QAC1D,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC;YAAE,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;IAClE,CAAC;CACF"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { Container } from '@kurdel/ioc';
|
|
2
|
+
import type { AppModule, ProviderConfig } from '@kurdel/core/app';
|
|
3
|
+
import type { MiddlewareRegistration, MiddlewareRegistry } from '@kurdel/core/http';
|
|
4
|
+
/**
|
|
5
|
+
* MiddlewareModule
|
|
6
|
+
*
|
|
7
|
+
* - Provides a singleton MiddlewareRegistry
|
|
8
|
+
* - Registers default global middlewares and app-provided ones
|
|
9
|
+
*/
|
|
10
|
+
export declare class MiddlewareModule implements AppModule {
|
|
11
|
+
private middlewares;
|
|
12
|
+
readonly exports: {
|
|
13
|
+
registry: import("@kurdel/ioc").InjectionToken<MiddlewareRegistry>;
|
|
14
|
+
};
|
|
15
|
+
readonly providers: ProviderConfig[];
|
|
16
|
+
constructor(middlewares: MiddlewareRegistration[]);
|
|
17
|
+
register(ioc: Container): Promise<void>;
|
|
18
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { TOKENS } from '@kurdel/core/tokens';
|
|
2
|
+
import { RuntimeMiddlewareRegistry } from '../http/runtime-middleware-registry.js';
|
|
3
|
+
import { errorHandler } from '../middlewares/error-handle.js';
|
|
4
|
+
import { jsonBodyParser } from '../middlewares/json-body-parser.js';
|
|
5
|
+
/**
|
|
6
|
+
* MiddlewareModule
|
|
7
|
+
*
|
|
8
|
+
* - Provides a singleton MiddlewareRegistry
|
|
9
|
+
* - Registers default global middlewares and app-provided ones
|
|
10
|
+
*/
|
|
11
|
+
export class MiddlewareModule {
|
|
12
|
+
constructor(middlewares) {
|
|
13
|
+
this.middlewares = middlewares;
|
|
14
|
+
this.exports = {
|
|
15
|
+
registry: TOKENS.MiddlewareRegistry,
|
|
16
|
+
};
|
|
17
|
+
this.providers = [
|
|
18
|
+
{
|
|
19
|
+
provide: TOKENS.MiddlewareRegistry,
|
|
20
|
+
useClass: RuntimeMiddlewareRegistry,
|
|
21
|
+
singleton: true,
|
|
22
|
+
},
|
|
23
|
+
];
|
|
24
|
+
}
|
|
25
|
+
async register(ioc) {
|
|
26
|
+
const registry = ioc.get(TOKENS.MiddlewareRegistry);
|
|
27
|
+
// Recommended order:
|
|
28
|
+
// 1) parsers (json) → 2) user middlewares → 3) error handler (last)
|
|
29
|
+
registry.use(errorHandler, {
|
|
30
|
+
zone: 'pre',
|
|
31
|
+
priority: 0,
|
|
32
|
+
});
|
|
33
|
+
for (const entry of this.middlewares) {
|
|
34
|
+
registry.use(entry.use, {
|
|
35
|
+
zone: entry.zone,
|
|
36
|
+
priority: entry.priority,
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
registry.use(jsonBodyParser, {
|
|
40
|
+
zone: 'post',
|
|
41
|
+
priority: 0,
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=middleware-module.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"middleware-module.js","sourceRoot":"","sources":["../../src/modules/middleware-module.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAI7C,OAAO,EAAE,yBAAyB,EAAE,MAAM,yCAAyC,CAAC;AACpF,OAAO,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAC;AAC/D,OAAO,EAAE,cAAc,EAAE,MAAM,qCAAqC,CAAC;AAErE;;;;;GAKG;AACH,MAAM,OAAO,gBAAgB;IAa3B,YAAoB,WAAqC;QAArC,gBAAW,GAAX,WAAW,CAA0B;QAZhD,YAAO,GAAG;YACjB,QAAQ,EAAE,MAAM,CAAC,kBAAkB;SACpC,CAAC;QAEO,cAAS,GAAqB;YACrC;gBACE,OAAO,EAAE,MAAM,CAAC,kBAAkB;gBAClC,QAAQ,EAAE,yBAAyB;gBACnC,SAAS,EAAE,IAAI;aAChB;SACF,CAAC;IAE0D,CAAC;IAE7D,KAAK,CAAC,QAAQ,CAAC,GAAc;QAC3B,MAAM,QAAQ,GAAG,GAAG,CAAC,GAAG,CAAqB,MAAM,CAAC,kBAAkB,CAAC,CAAC;QAExE,qBAAqB;QACrB,oEAAoE;QACpE,QAAQ,CAAC,GAAG,CAAC,YAAY,EAAE;YACzB,IAAI,EAAE,KAAK;YACX,QAAQ,EAAE,CAAC;SACZ,CAAC,CAAC;QACH,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;YACrC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE;gBACtB,IAAI,EAAE,KAAK,CAAC,IAAI;gBAChB,QAAQ,EAAE,KAAK,CAAC,QAAQ;aACzB,CAAC,CAAC;QACL,CAAC;QACD,QAAQ,CAAC,GAAG,CAAC,cAAc,EAAE;YAC3B,IAAI,EAAE,MAAM;YACZ,QAAQ,EAAE,CAAC;SACZ,CAAC,CAAC;IACL,CAAC;CACF"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { IoCContainer } from '@kurdel/ioc';
|
|
2
|
+
import type { AppModule, AppConfig } from '@kurdel/core/app';
|
|
3
|
+
import type { ModelList } from '@kurdel/core/db';
|
|
4
|
+
/**
|
|
5
|
+
* ModelModule
|
|
6
|
+
*
|
|
7
|
+
* - Registers models from all HttpModules
|
|
8
|
+
* - Models depend on IDatabase
|
|
9
|
+
*/
|
|
10
|
+
export declare class ModelModule implements AppModule<AppConfig> {
|
|
11
|
+
private models;
|
|
12
|
+
readonly imports: {
|
|
13
|
+
db: symbol;
|
|
14
|
+
};
|
|
15
|
+
constructor(models: ModelList);
|
|
16
|
+
register(ioc: IoCContainer): Promise<void>;
|
|
17
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { IDatabase } from '@kurdel/db';
|
|
2
|
+
/**
|
|
3
|
+
* ModelModule
|
|
4
|
+
*
|
|
5
|
+
* - Registers models from all HttpModules
|
|
6
|
+
* - Models depend on IDatabase
|
|
7
|
+
*/
|
|
8
|
+
export class ModelModule {
|
|
9
|
+
constructor(models) {
|
|
10
|
+
this.models = models;
|
|
11
|
+
this.imports = { db: IDatabase };
|
|
12
|
+
}
|
|
13
|
+
async register(ioc) {
|
|
14
|
+
this.models.forEach(model => {
|
|
15
|
+
if ('use' in model) {
|
|
16
|
+
ioc.put(model.use).with({ db: IDatabase, ...model.deps });
|
|
17
|
+
}
|
|
18
|
+
else {
|
|
19
|
+
ioc.put(model).with({ db: IDatabase });
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=model-module.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model-module.js","sourceRoot":"","sources":["../../src/modules/model-module.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAIvC;;;;;GAKG;AACH,MAAM,OAAO,WAAW;IAGtB,YAAoB,MAAiB;QAAjB,WAAM,GAAN,MAAM,CAAW;QAF5B,YAAO,GAAG,EAAE,EAAE,EAAE,SAAS,EAAE,CAAC;IAEG,CAAC;IAEzC,KAAK,CAAC,QAAQ,CAAC,GAAiB;QAC9B,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;YAC1B,IAAI,KAAK,IAAI,KAAK,EAAE,CAAC;gBACnB,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,SAAS,EAAE,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;YAC5D,CAAC;iBAAM,CAAC;gBACN,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC;YACzC,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;CACF"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { Container } from '@kurdel/ioc';
|
|
2
|
+
import { ModulePriority, type AppConfig, type AppModule } from '@kurdel/core/app';
|
|
3
|
+
import type { ServerAdapter, Router, ControllerConfig, MiddlewareRegistry, ControllerResolver } from '@kurdel/core/http';
|
|
4
|
+
/**
|
|
5
|
+
* ServerModule: wires the HTTP ServerAdapter to the Router.
|
|
6
|
+
*
|
|
7
|
+
* ## Responsibilities
|
|
8
|
+
* - Binds the platform-agnostic `ServerAdapter` (provided externally)
|
|
9
|
+
* - Initializes the `Router` with controller metadata and global middlewares
|
|
10
|
+
* - Creates the `RuntimeRequestOrchestrator` to handle per-request execution
|
|
11
|
+
* - Subscribes the orchestrator to incoming HTTP requests from the adapter
|
|
12
|
+
*
|
|
13
|
+
* ## Design Notes
|
|
14
|
+
* - The module itself contains **no platform-specific logic**
|
|
15
|
+
* - Orchestrator fully owns request lifecycle (scope, middleware, controller, render)
|
|
16
|
+
*/
|
|
17
|
+
export declare class ServerModule implements AppModule<AppConfig> {
|
|
18
|
+
readonly priority = ModulePriority.Server;
|
|
19
|
+
readonly imports: {
|
|
20
|
+
router: import("@kurdel/ioc").InjectionToken<Router>;
|
|
21
|
+
registry: import("@kurdel/ioc").InjectionToken<MiddlewareRegistry>;
|
|
22
|
+
controllerConfigs: import("@kurdel/ioc").InjectionToken<ControllerConfig[]>;
|
|
23
|
+
controllerResolver: import("@kurdel/ioc").InjectionToken<ControllerResolver>;
|
|
24
|
+
server: import("@kurdel/ioc").InjectionToken<ServerAdapter<import("@kurdel/common").HttpRequest, import("@kurdel/common").HttpResponse>>;
|
|
25
|
+
};
|
|
26
|
+
readonly exports: {
|
|
27
|
+
server: import("@kurdel/ioc").InjectionToken<ServerAdapter<import("@kurdel/common").HttpRequest, import("@kurdel/common").HttpResponse>>;
|
|
28
|
+
};
|
|
29
|
+
register(ioc: Container): Promise<void>;
|
|
30
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { ModulePriority } from '@kurdel/core/app';
|
|
2
|
+
import { TOKENS } from '@kurdel/core/tokens';
|
|
3
|
+
import { NoopResponseRenderer } from '../http/noop-response-renderer.js';
|
|
4
|
+
import { RuntimeRequestOrchestrator } from '../http/runtime-request-orchestrator.js';
|
|
5
|
+
/**
|
|
6
|
+
* ServerModule: wires the HTTP ServerAdapter to the Router.
|
|
7
|
+
*
|
|
8
|
+
* ## Responsibilities
|
|
9
|
+
* - Binds the platform-agnostic `ServerAdapter` (provided externally)
|
|
10
|
+
* - Initializes the `Router` with controller metadata and global middlewares
|
|
11
|
+
* - Creates the `RuntimeRequestOrchestrator` to handle per-request execution
|
|
12
|
+
* - Subscribes the orchestrator to incoming HTTP requests from the adapter
|
|
13
|
+
*
|
|
14
|
+
* ## Design Notes
|
|
15
|
+
* - The module itself contains **no platform-specific logic**
|
|
16
|
+
* - Orchestrator fully owns request lifecycle (scope, middleware, controller, render)
|
|
17
|
+
*/
|
|
18
|
+
export class ServerModule {
|
|
19
|
+
constructor() {
|
|
20
|
+
this.priority = ModulePriority.Server;
|
|
21
|
+
this.imports = {
|
|
22
|
+
router: TOKENS.Router,
|
|
23
|
+
registry: TOKENS.MiddlewareRegistry,
|
|
24
|
+
controllerConfigs: TOKENS.ControllerConfigs,
|
|
25
|
+
controllerResolver: TOKENS.ControllerResolver,
|
|
26
|
+
server: TOKENS.ServerAdapter,
|
|
27
|
+
};
|
|
28
|
+
this.exports = {
|
|
29
|
+
server: TOKENS.ServerAdapter,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
async register(ioc) {
|
|
33
|
+
const adapter = ioc.get(TOKENS.ServerAdapter);
|
|
34
|
+
const router = ioc.get(TOKENS.Router);
|
|
35
|
+
const registry = ioc.get(TOKENS.MiddlewareRegistry);
|
|
36
|
+
const controllerConfigs = ioc.get(TOKENS.ControllerConfigs);
|
|
37
|
+
const resolver = ioc.get(TOKENS.ControllerResolver);
|
|
38
|
+
const renderer = ioc.get(TOKENS.ResponseRenderer);
|
|
39
|
+
// --- ensure a response renderer exists
|
|
40
|
+
if (!ioc.has(TOKENS.ResponseRenderer)) {
|
|
41
|
+
ioc.bind(TOKENS.ResponseRenderer).toInstance(new NoopResponseRenderer());
|
|
42
|
+
}
|
|
43
|
+
// --- initialize router once with all metadata
|
|
44
|
+
router.init(resolver, controllerConfigs);
|
|
45
|
+
// --- compose orchestrator for request lifecycle
|
|
46
|
+
const orchestrator = new RuntimeRequestOrchestrator(router, renderer, registry);
|
|
47
|
+
// --- connect adapter to orchestrator
|
|
48
|
+
adapter.on(async (req, res) => {
|
|
49
|
+
const scope = ioc.createScope?.() ?? ioc;
|
|
50
|
+
try {
|
|
51
|
+
await orchestrator.execute(req, res, scope);
|
|
52
|
+
}
|
|
53
|
+
catch (err) {
|
|
54
|
+
// fallback-level error safety
|
|
55
|
+
if (process.env.NODE_ENV !== 'test') {
|
|
56
|
+
console.error(`[ServerModule] Uncaught error in orchestrator for ${req.method} ${req.url}:`, err);
|
|
57
|
+
}
|
|
58
|
+
if (res.statusCode !== 500)
|
|
59
|
+
res.statusCode = 500;
|
|
60
|
+
renderer.render(res, { status: 500, kind: 'text', body: 'Internal Server Error' });
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=server-module.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server-module.js","sourceRoot":"","sources":["../../src/modules/server-module.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAkC,MAAM,kBAAkB,CAAC;AAClF,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAU7C,OAAO,EAAE,oBAAoB,EAAE,MAAM,oCAAoC,CAAC;AAC1E,OAAO,EAAE,0BAA0B,EAAE,MAAM,0CAA0C,CAAC;AAEtF;;;;;;;;;;;;GAYG;AACH,MAAM,OAAO,YAAY;IAAzB;QACW,aAAQ,GAAG,cAAc,CAAC,MAAM,CAAC;QAEjC,YAAO,GAAG;YACjB,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,QAAQ,EAAE,MAAM,CAAC,kBAAkB;YACnC,iBAAiB,EAAE,MAAM,CAAC,iBAAiB;YAC3C,kBAAkB,EAAE,MAAM,CAAC,kBAAkB;YAC7C,MAAM,EAAE,MAAM,CAAC,aAAa;SAC7B,CAAC;QAEO,YAAO,GAAG;YACjB,MAAM,EAAE,MAAM,CAAC,aAAa;SAC7B,CAAC;IAwCJ,CAAC;IAtCC,KAAK,CAAC,QAAQ,CAAC,GAAc;QAC3B,MAAM,OAAO,GAAG,GAAG,CAAC,GAAG,CAAgB,MAAM,CAAC,aAAa,CAAC,CAAC;QAC7D,MAAM,MAAM,GAAG,GAAG,CAAC,GAAG,CAAS,MAAM,CAAC,MAAM,CAAC,CAAC;QAC9C,MAAM,QAAQ,GAAG,GAAG,CAAC,GAAG,CAAqB,MAAM,CAAC,kBAAkB,CAAC,CAAC;QACxE,MAAM,iBAAiB,GAAG,GAAG,CAAC,GAAG,CAAqB,MAAM,CAAC,iBAAiB,CAAC,CAAC;QAChF,MAAM,QAAQ,GAAG,GAAG,CAAC,GAAG,CAAqB,MAAM,CAAC,kBAAkB,CAAC,CAAC;QACxE,MAAM,QAAQ,GAAG,GAAG,CAAC,GAAG,CAAmB,MAAM,CAAC,gBAAgB,CAAC,CAAC;QAEpE,wCAAwC;QACxC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,gBAAgB,CAAC,EAAE,CAAC;YACtC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,UAAU,CAAC,IAAI,oBAAoB,EAAE,CAAC,CAAC;QAC3E,CAAC;QAED,+CAA+C;QAC/C,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,iBAAiB,CAAC,CAAC;QAEzC,iDAAiD;QACjD,MAAM,YAAY,GAAG,IAAI,0BAA0B,CAAC,MAAM,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;QAEhF,sCAAsC;QACtC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE;YAC5B,MAAM,KAAK,GAAG,GAAG,CAAC,WAAW,EAAE,EAAE,IAAI,GAAG,CAAC;YAEzC,IAAI,CAAC;gBACH,MAAM,YAAY,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC;YAC9C,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,8BAA8B;gBAC9B,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,MAAM,EAAE,CAAC;oBACpC,OAAO,CAAC,KAAK,CACX,qDAAqD,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,GAAG,GAAG,EAC7E,GAAG,CACJ,CAAC;gBACJ,CAAC;gBACD,IAAK,GAAW,CAAC,UAAU,KAAK,GAAG;oBAAG,GAAW,CAAC,UAAU,GAAG,GAAG,CAAC;gBACnE,QAAQ,CAAC,MAAM,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,uBAAuB,EAAE,CAAC,CAAC;YACrF,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;CACF"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { TOKENS } from '@kurdel/core/tokens';
|
|
2
|
+
import { NoopTemplateEngine } from '../template/noop-template-engine.js';
|
|
3
|
+
export function ensureTemplateEngineBinding(ioc) {
|
|
4
|
+
if (!ioc.has(TOKENS.TemplateEngineToken)) {
|
|
5
|
+
ioc.bind(TOKENS.TemplateEngineToken).toInstance(new NoopTemplateEngine());
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=ensure-template-engine-binding.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ensure-template-engine-binding.js","sourceRoot":"","sources":["../../src/template/ensure-template-engine-binding.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAG7C,OAAO,EAAE,kBAAkB,EAAE,MAAM,sCAAsC,CAAC;AAE1E,MAAM,UAAU,2BAA2B,CAAC,GAAc;IACxD,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,mBAAmB,CAAC,EAAE,CAAC;QACzC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAC,UAAU,CAAC,IAAI,kBAAkB,EAAE,CAAC,CAAC;IAC5E,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/template/index.ts"],"names":[],"mappings":""}
|