@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.
Files changed (117) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +44 -0
  3. package/lib/app/errors/controller-action-missing-result-error.d.ts +9 -0
  4. package/lib/app/errors/controller-action-missing-result-error.js +14 -0
  5. package/lib/app/errors/controller-action-missing-result-error.js.map +1 -0
  6. package/lib/app/errors/module-validation-error.d.ts +25 -0
  7. package/lib/app/errors/module-validation-error.js +29 -0
  8. package/lib/app/errors/module-validation-error.js.map +1 -0
  9. package/lib/app/errors/provider-configuration-error.d.ts +24 -0
  10. package/lib/app/errors/provider-configuration-error.js +28 -0
  11. package/lib/app/errors/provider-configuration-error.js.map +1 -0
  12. package/lib/app/index.d.ts +1 -0
  13. package/lib/app/index.js +2 -0
  14. package/lib/app/index.js.map +1 -0
  15. package/lib/app/lifecycle-manager.d.ts +26 -0
  16. package/lib/app/lifecycle-manager.js +40 -0
  17. package/lib/app/lifecycle-manager.js.map +1 -0
  18. package/lib/app/module-loader.d.ts +29 -0
  19. package/lib/app/module-loader.js +61 -0
  20. package/lib/app/module-loader.js.map +1 -0
  21. package/lib/app/provider-registrar.d.ts +29 -0
  22. package/lib/app/provider-registrar.js +67 -0
  23. package/lib/app/provider-registrar.js.map +1 -0
  24. package/lib/app/runtime-application.d.ts +75 -0
  25. package/lib/app/runtime-application.js +97 -0
  26. package/lib/app/runtime-application.js.map +1 -0
  27. package/lib/app/runtime-composer.d.ts +25 -0
  28. package/lib/app/runtime-composer.js +100 -0
  29. package/lib/app/runtime-composer.js.map +1 -0
  30. package/lib/app/server-runner.d.ts +36 -0
  31. package/lib/app/server-runner.js +65 -0
  32. package/lib/app/server-runner.js.map +1 -0
  33. package/lib/http/index.d.ts +6 -0
  34. package/lib/http/index.js +7 -0
  35. package/lib/http/index.js.map +1 -0
  36. package/lib/http/is-http-error.d.ts +2 -0
  37. package/lib/http/is-http-error.js +7 -0
  38. package/lib/http/is-http-error.js.map +1 -0
  39. package/lib/http/noop-response-renderer.d.ts +7 -0
  40. package/lib/http/noop-response-renderer.js +10 -0
  41. package/lib/http/noop-response-renderer.js.map +1 -0
  42. package/lib/http/render-action-result.d.ts +4 -0
  43. package/lib/http/render-action-result.js +24 -0
  44. package/lib/http/render-action-result.js.map +1 -0
  45. package/lib/http/runtime-controller-pipe.d.ts +16 -0
  46. package/lib/http/runtime-controller-pipe.js +26 -0
  47. package/lib/http/runtime-controller-pipe.js.map +1 -0
  48. package/lib/http/runtime-controller-resolver.d.ts +12 -0
  49. package/lib/http/runtime-controller-resolver.js +29 -0
  50. package/lib/http/runtime-controller-resolver.js.map +1 -0
  51. package/lib/http/runtime-http-context-factory.d.ts +29 -0
  52. package/lib/http/runtime-http-context-factory.js +91 -0
  53. package/lib/http/runtime-http-context-factory.js.map +1 -0
  54. package/lib/http/runtime-middleware-pipe.d.ts +15 -0
  55. package/lib/http/runtime-middleware-pipe.js +31 -0
  56. package/lib/http/runtime-middleware-pipe.js.map +1 -0
  57. package/lib/http/runtime-middleware-registry.d.ts +18 -0
  58. package/lib/http/runtime-middleware-registry.js +39 -0
  59. package/lib/http/runtime-middleware-registry.js.map +1 -0
  60. package/lib/http/runtime-request-orchestrator.d.ts +21 -0
  61. package/lib/http/runtime-request-orchestrator.js +114 -0
  62. package/lib/http/runtime-request-orchestrator.js.map +1 -0
  63. package/lib/http/runtime-response-renderer.d.ts +12 -0
  64. package/lib/http/runtime-response-renderer.js +37 -0
  65. package/lib/http/runtime-response-renderer.js.map +1 -0
  66. package/lib/http/runtime-router.d.ts +37 -0
  67. package/lib/http/runtime-router.js +135 -0
  68. package/lib/http/runtime-router.js.map +1 -0
  69. package/lib/index.d.ts +3 -0
  70. package/lib/index.js +4 -0
  71. package/lib/index.js.map +1 -0
  72. package/lib/middlewares/create-validator.d.ts +7 -0
  73. package/lib/middlewares/create-validator.js +21 -0
  74. package/lib/middlewares/create-validator.js.map +1 -0
  75. package/lib/middlewares/error-handle.d.ts +2 -0
  76. package/lib/middlewares/error-handle.js +30 -0
  77. package/lib/middlewares/error-handle.js.map +1 -0
  78. package/lib/middlewares/index.d.ts +2 -0
  79. package/lib/middlewares/index.js +3 -0
  80. package/lib/middlewares/index.js.map +1 -0
  81. package/lib/middlewares/json-body-parser.d.ts +14 -0
  82. package/lib/middlewares/json-body-parser.js +23 -0
  83. package/lib/middlewares/json-body-parser.js.map +1 -0
  84. package/lib/middlewares/schema-validator.d.ts +13 -0
  85. package/lib/middlewares/schema-validator.js +44 -0
  86. package/lib/middlewares/schema-validator.js.map +1 -0
  87. package/lib/modules/controller-module.d.ts +23 -0
  88. package/lib/modules/controller-module.js +76 -0
  89. package/lib/modules/controller-module.js.map +1 -0
  90. package/lib/modules/database-module.d.ts +25 -0
  91. package/lib/modules/database-module.js +40 -0
  92. package/lib/modules/database-module.js.map +1 -0
  93. package/lib/modules/index.d.ts +1 -0
  94. package/lib/modules/index.js +2 -0
  95. package/lib/modules/index.js.map +1 -0
  96. package/lib/modules/lifecycle-module.d.ts +9 -0
  97. package/lib/modules/lifecycle-module.js +17 -0
  98. package/lib/modules/lifecycle-module.js.map +1 -0
  99. package/lib/modules/middleware-module.d.ts +18 -0
  100. package/lib/modules/middleware-module.js +45 -0
  101. package/lib/modules/middleware-module.js.map +1 -0
  102. package/lib/modules/model-module.d.ts +17 -0
  103. package/lib/modules/model-module.js +24 -0
  104. package/lib/modules/model-module.js.map +1 -0
  105. package/lib/modules/server-module.d.ts +30 -0
  106. package/lib/modules/server-module.js +65 -0
  107. package/lib/modules/server-module.js.map +1 -0
  108. package/lib/template/ensure-template-engine-binding.d.ts +2 -0
  109. package/lib/template/ensure-template-engine-binding.js +8 -0
  110. package/lib/template/ensure-template-engine-binding.js.map +1 -0
  111. package/lib/template/index.d.ts +1 -0
  112. package/lib/template/index.js +2 -0
  113. package/lib/template/index.js.map +1 -0
  114. package/lib/template/noop-template-engine.d.ts +4 -0
  115. package/lib/template/noop-template-engine.js +6 -0
  116. package/lib/template/noop-template-engine.js.map +1 -0
  117. package/package.json +64 -0
@@ -0,0 +1,91 @@
1
+ /**
2
+ * ## RuntimeHttpContextFactory
3
+ *
4
+ * Responsible for constructing per-request {@link HttpContext} objects.
5
+ *
6
+ * Each incoming request receives a fresh, isolated context encapsulating:
7
+ * - HTTP request/response wrappers provided by the adapter
8
+ * - parsed URL, query, params, body
9
+ * - matched route metadata (controller/action/schema/auth)
10
+ * - a request-scoped IoC container
11
+ * - typed constructors for {@link ActionResult}
12
+ *
13
+ * The context object is immutable except for `result`,
14
+ * which is later populated by the orchestrator and renderer.
15
+ */
16
+ export class RuntimeHttpContextFactory {
17
+ /**
18
+ * Constructs a fully initialized {@link HttpContext} instance.
19
+ *
20
+ * @param req - incoming HTTP request
21
+ * @param res - outgoing HTTP response
22
+ * @param match - router resolution result
23
+ * @param scope - request-scoped IoC container
24
+ */
25
+ create(req, res, match, scope) {
26
+ const url = new URL(req.url ?? '/', 'http://internal');
27
+ const query = req.query ??
28
+ Object.fromEntries(url.searchParams.entries());
29
+ return {
30
+ /**
31
+ * Request-scoped IoC container.
32
+ *
33
+ * Used by:
34
+ * - authentication strategies
35
+ * - per-request services (logger, db, tracing)
36
+ * - custom middlewares
37
+ * - controllers needing scoped dependencies
38
+ */
39
+ scope,
40
+ /** Underlying request object */
41
+ req,
42
+ /** Underlying response object */
43
+ res,
44
+ /** Fully parsed URL of the current request */
45
+ url,
46
+ /** Parsed query parameters */
47
+ query,
48
+ /** Path parameters extracted from the matched route */
49
+ params: match.params,
50
+ /** Parsed request body (if available) */
51
+ body: req.body,
52
+ /** Matched route metadata (including schema and controller) */
53
+ route: match,
54
+ /**
55
+ * Authenticated user (if authentication middleware succeeded).
56
+ * Populated later in the pipeline.
57
+ */
58
+ user: undefined,
59
+ /** The latest computed ActionResult (populated later at runtime) */
60
+ result: undefined,
61
+ // ────────────────────────────────
62
+ // Response helper constructors
63
+ // ────────────────────────────────
64
+ /**
65
+ * Creates a JSON ActionResult with a given status and body.
66
+ */
67
+ json(status, body) {
68
+ return { kind: 'json', status, body };
69
+ },
70
+ /**
71
+ * Creates a plain text ActionResult.
72
+ */
73
+ text(status, body) {
74
+ return { kind: 'text', status, body };
75
+ },
76
+ /**
77
+ * Creates a redirect ActionResult to the given location.
78
+ */
79
+ redirect(status, location) {
80
+ return { kind: 'redirect', status, location };
81
+ },
82
+ /**
83
+ * Creates a standard HTTP 204 “No Content” ActionResult.
84
+ */
85
+ noContent() {
86
+ return { kind: 'empty', status: 204 };
87
+ },
88
+ };
89
+ }
90
+ }
91
+ //# sourceMappingURL=runtime-http-context-factory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime-http-context-factory.js","sourceRoot":"","sources":["../../src/http/runtime-http-context-factory.ts"],"names":[],"mappings":"AASA;;;;;;;;;;;;;;GAcG;AACH,MAAM,OAAO,yBAAyB;IACpC;;;;;;;OAOG;IACH,MAAM,CACJ,GAAgB,EAChB,GAAiB,EACjB,KAAiB,EACjB,KAAgB;QAEhB,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI,GAAG,EAAE,iBAAiB,CAAC,CAAC;QAEvD,MAAM,KAAK,GACT,GAAG,CAAC,KAAK;YACT,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,YAAY,CAAC,OAAO,EAAE,CAAC,CAAC;QAEjD,OAAO;YACL;;;;;;;;eAQG;YACH,KAAK;YAEL,gCAAgC;YAChC,GAAG;YAEH,iCAAiC;YACjC,GAAG;YAEH,8CAA8C;YAC9C,GAAG;YAEH,8BAA8B;YAC9B,KAAK;YAEL,uDAAuD;YACvD,MAAM,EAAE,KAAK,CAAC,MAAM;YAEpB,yCAAyC;YACzC,IAAI,EAAE,GAAG,CAAC,IAAI;YAEd,+DAA+D;YAC/D,KAAK,EAAE,KAAK;YAEZ;;;eAGG;YACH,IAAI,EAAE,SAAS;YAEf,oEAAoE;YACpE,MAAM,EAAE,SAAS;YAEjB,mCAAmC;YACnC,+BAA+B;YAC/B,mCAAmC;YAEnC;;eAEG;YACH,IAAI,CAAC,MAAc,EAAE,IAAe;gBAClC,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;YACxC,CAAC;YAED;;eAEG;YACH,IAAI,CAAC,MAAc,EAAE,IAAY;gBAC/B,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;YACxC,CAAC;YAED;;eAEG;YACH,QAAQ,CAAC,MAAc,EAAE,QAAgB;gBACvC,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;YAChD,CAAC;YAED;;eAEG;YACH,SAAS;gBACP,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC;YACxC,CAAC;SACF,CAAC;IACJ,CAAC;CACF"}
@@ -0,0 +1,15 @@
1
+ import type { HttpContext, Middleware, ActionResult } from '@kurdel/core/http';
2
+ /**
3
+ * ## RuntimeMiddlewarePipe
4
+ *
5
+ * Executes middleware chain in declared order.
6
+ *
7
+ * - Stops on returned ActionResult
8
+ * - Stops on thrown error
9
+ * - Calls `next()` only when middleware yields `undefined`
10
+ */
11
+ export declare class RuntimeMiddlewarePipe {
12
+ private readonly middlewares;
13
+ constructor(middlewares?: Middleware[]);
14
+ run(ctx: HttpContext, terminal?: () => Promise<ActionResult | void>): Promise<ActionResult | void>;
15
+ }
@@ -0,0 +1,31 @@
1
+ /**
2
+ * ## RuntimeMiddlewarePipe
3
+ *
4
+ * Executes middleware chain in declared order.
5
+ *
6
+ * - Stops on returned ActionResult
7
+ * - Stops on thrown error
8
+ * - Calls `next()` only when middleware yields `undefined`
9
+ */
10
+ export class RuntimeMiddlewarePipe {
11
+ constructor(middlewares = []) {
12
+ this.middlewares = middlewares;
13
+ }
14
+ async run(ctx, terminal) {
15
+ const dispatch = async (index) => {
16
+ if (index >= this.middlewares.length) {
17
+ return terminal ? await terminal() : undefined;
18
+ }
19
+ const mw = this.middlewares[index];
20
+ const result = await mw(ctx, () => dispatch(index + 1));
21
+ // 🚫 STOP: middleware returned an ActionResult
22
+ if (result !== undefined) {
23
+ return result;
24
+ }
25
+ // otherwise continue automatically (middleware already called next)
26
+ return undefined;
27
+ };
28
+ return dispatch(0);
29
+ }
30
+ }
31
+ //# sourceMappingURL=runtime-middleware-pipe.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime-middleware-pipe.js","sourceRoot":"","sources":["../../src/http/runtime-middleware-pipe.ts"],"names":[],"mappings":"AAEA;;;;;;;;GAQG;AACH,MAAM,OAAO,qBAAqB;IAChC,YAA6B,cAA4B,EAAE;QAA9B,gBAAW,GAAX,WAAW,CAAmB;IAAG,CAAC;IAE/D,KAAK,CAAC,GAAG,CACP,GAAgB,EAChB,QAA6C;QAE7C,MAAM,QAAQ,GAAG,KAAK,EAAE,KAAa,EAAgC,EAAE;YACrE,IAAI,KAAK,IAAI,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC;gBACrC,OAAO,QAAQ,CAAC,CAAC,CAAC,MAAM,QAAQ,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;YACjD,CAAC;YAED,MAAM,EAAE,GAAG,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;YACnC,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC;YAExD,+CAA+C;YAC/C,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;gBACzB,OAAO,MAAM,CAAC;YAChB,CAAC;YAED,oEAAoE;YACpE,OAAO,SAAS,CAAC;QACnB,CAAC,CAAC;QAEF,OAAO,QAAQ,CAAC,CAAC,CAAC,CAAC;IACrB,CAAC;CACF"}
@@ -0,0 +1,18 @@
1
+ import type { Newable } from '@kurdel/common';
2
+ import type { Controller, Middleware, MiddlewareRegistry } from '@kurdel/core/http';
3
+ import type { MiddlewareZone, MiddlewareRegistration } from '@kurdel/core/http';
4
+ export declare class RuntimeMiddlewareRegistry implements MiddlewareRegistry {
5
+ private readonly global;
6
+ private readonly perController;
7
+ use(mw: Middleware, opts?: {
8
+ zone?: MiddlewareZone;
9
+ priority?: number;
10
+ }): void;
11
+ useFor(controller: Newable<Controller>, mw: Middleware, opts?: {
12
+ zone?: MiddlewareZone;
13
+ priority?: number;
14
+ action?: string;
15
+ }): void;
16
+ for(controller: Newable<Controller>, zone?: MiddlewareZone, action?: string): MiddlewareRegistration[];
17
+ all(zone?: MiddlewareZone): MiddlewareRegistration[];
18
+ }
@@ -0,0 +1,39 @@
1
+ export class RuntimeMiddlewareRegistry {
2
+ constructor() {
3
+ this.global = new Map();
4
+ this.perController = new Map();
5
+ }
6
+ use(mw, opts = {}) {
7
+ const zone = opts.zone ?? 'pre';
8
+ const priority = opts.priority ?? 0;
9
+ const entry = { use: mw, zone, priority };
10
+ if (!this.global.has(zone))
11
+ this.global.set(zone, []);
12
+ this.global.get(zone).push(entry);
13
+ }
14
+ useFor(controller, mw, opts = {}) {
15
+ const zone = opts.zone ?? 'pre';
16
+ const priority = opts.priority ?? 0;
17
+ const entry = { use: mw, zone, priority, action: opts.action };
18
+ if (!this.perController.has(controller)) {
19
+ this.perController.set(controller, new Map());
20
+ }
21
+ const zones = this.perController.get(controller);
22
+ if (!zones.has(zone))
23
+ zones.set(zone, []);
24
+ zones.get(zone).push(entry);
25
+ }
26
+ for(controller, zone = 'pre', action) {
27
+ const map = this.perController.get(controller);
28
+ if (!map)
29
+ return [];
30
+ const entries = map.get(zone) ?? [];
31
+ return entries
32
+ .filter(e => !e.action || e.action === action)
33
+ .sort((a, b) => b.priority - a.priority);
34
+ }
35
+ all(zone = 'pre') {
36
+ return (this.global.get(zone) ?? []).sort((a, b) => b.priority - a.priority);
37
+ }
38
+ }
39
+ //# sourceMappingURL=runtime-middleware-registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime-middleware-registry.js","sourceRoot":"","sources":["../../src/http/runtime-middleware-registry.ts"],"names":[],"mappings":"AAIA,MAAM,OAAO,yBAAyB;IAAtC;QACmB,WAAM,GAAG,IAAI,GAAG,EAA4C,CAAC;QAC7D,kBAAa,GAAG,IAAI,GAAG,EAGrC,CAAC;IA4CN,CAAC;IA1CC,GAAG,CAAC,EAAc,EAAE,OAAqD,EAAE;QACzE,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,KAAK,CAAC;QAChC,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,CAAC,CAAC;QACpC,MAAM,KAAK,GAA2B,EAAE,GAAG,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;QAClE,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC;YAAE,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QACtD,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACrC,CAAC;IAED,MAAM,CACJ,UAA+B,EAC/B,EAAc,EACd,OAAsE,EAAE;QAExE,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,KAAK,CAAC;QAChC,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,CAAC,CAAC;QACpC,MAAM,KAAK,GAA2B,EAAE,GAAG,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC;QAEvF,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC;YACxC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,UAAU,EAAE,IAAI,GAAG,EAAE,CAAC,CAAC;QAChD,CAAC;QACD,MAAM,KAAK,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,UAAU,CAAE,CAAC;QAClD,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC;YAAE,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QAC1C,KAAK,CAAC,GAAG,CAAC,IAAI,CAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC/B,CAAC;IAED,GAAG,CACD,UAA+B,EAC/B,OAAuB,KAAK,EAC5B,MAAe;QAEf,MAAM,GAAG,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QAC/C,IAAI,CAAC,GAAG;YAAE,OAAO,EAAE,CAAC;QAEpB,MAAM,OAAO,GAAG,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;QACpC,OAAO,OAAO;aACX,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC;aAC7C,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC;IAC7C,CAAC;IAED,GAAG,CAAC,OAAuB,KAAK;QAC9B,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC;IAC/E,CAAC;CACF"}
@@ -0,0 +1,21 @@
1
+ import type { HttpRequest, HttpResponse } from '@kurdel/common';
2
+ import type { Container } from '@kurdel/ioc';
3
+ import type { ResponseRenderer, Router, MiddlewareRegistry } from '@kurdel/core/http';
4
+ /**
5
+ * ## RuntimeRequestOrchestrator
6
+ *
7
+ * Deterministic pipeline:
8
+ * resolve → validate → auth → pre → controller → render → post → error → final
9
+ */
10
+ export declare class RuntimeRequestOrchestrator {
11
+ private readonly router;
12
+ private readonly renderer;
13
+ private readonly registry;
14
+ private readonly contextFactory;
15
+ private readonly controllerPipe;
16
+ constructor(router: Router, renderer: ResponseRenderer, registry: MiddlewareRegistry);
17
+ execute(req: HttpRequest, res: HttpResponse, scope: Container): Promise<void>;
18
+ private collect;
19
+ private runZone;
20
+ private runFinal;
21
+ }
@@ -0,0 +1,114 @@
1
+ import { HttpError } from '@kurdel/core/http';
2
+ import { ControllerActionMissingResultError } from '../app/errors/controller-action-missing-result-error.js';
3
+ import { RuntimeHttpContextFactory } from '../http/runtime-http-context-factory.js';
4
+ import { RuntimeControllerPipe } from '../http/runtime-controller-pipe.js';
5
+ import { RuntimeMiddlewarePipe } from '../http/runtime-middleware-pipe.js';
6
+ /**
7
+ * ## RuntimeRequestOrchestrator
8
+ *
9
+ * Deterministic pipeline:
10
+ * resolve → validate → auth → pre → controller → render → post → error → final
11
+ */
12
+ export class RuntimeRequestOrchestrator {
13
+ constructor(router, renderer, registry) {
14
+ this.router = router;
15
+ this.renderer = renderer;
16
+ this.registry = registry;
17
+ this.contextFactory = new RuntimeHttpContextFactory();
18
+ this.controllerPipe = new RuntimeControllerPipe();
19
+ }
20
+ async execute(req, res, scope) {
21
+ const method = req.method ?? 'GET';
22
+ const url = req.url ?? '/';
23
+ // --- 1️⃣ Resolve route ---
24
+ const routeMatch = this.router.resolve(method, url, scope);
25
+ if (!routeMatch) {
26
+ this.renderer.handleError(res, new HttpError(404, 'Not Found'));
27
+ return;
28
+ }
29
+ // --- 2️⃣ Build HttpContext ---
30
+ const ctx = this.contextFactory.create(req, res, routeMatch, scope);
31
+ // --- 3️⃣ Validation ---
32
+ try {
33
+ const schema = routeMatch.schema;
34
+ if (schema?.body)
35
+ ctx.body = await schema.body.validate(ctx.body);
36
+ if (schema?.params)
37
+ ctx.params = await schema.params.validate(ctx.params);
38
+ if (schema?.query)
39
+ ctx.query = await schema.query.validate(ctx.query);
40
+ }
41
+ catch (err) {
42
+ this.renderer.handleError(res, err);
43
+ await this.runFinal(ctx, routeMatch);
44
+ return;
45
+ }
46
+ try {
47
+ // --- 4️⃣ AUTH zone ---
48
+ const authResult = await this.runZone('auth', ctx, routeMatch);
49
+ if (authResult) {
50
+ ctx.result = authResult;
51
+ this.renderer.render(res, authResult);
52
+ await this.runFinal(ctx, routeMatch);
53
+ return;
54
+ }
55
+ // --- 5️⃣ PRE middleware ---
56
+ const preResult = await this.runZone('pre', ctx, routeMatch);
57
+ if (preResult) {
58
+ ctx.result = preResult;
59
+ this.renderer.render(res, preResult);
60
+ await this.runFinal(ctx, routeMatch);
61
+ return;
62
+ }
63
+ // --- 6️⃣ Controller execution ---
64
+ const result = await this.controllerPipe.run(routeMatch.controller, ctx, routeMatch.action);
65
+ if (typeof result === 'undefined') {
66
+ throw new ControllerActionMissingResultError(routeMatch.controller, routeMatch.action);
67
+ }
68
+ ctx.result = result;
69
+ this.renderer.render(res, result);
70
+ // --- 7️⃣ POST middleware (only if response was rendered) ---
71
+ if (res.sent) {
72
+ await this.runZone('post', ctx, routeMatch);
73
+ }
74
+ }
75
+ catch (err) {
76
+ // --- 8️⃣ ERROR middleware zone ---
77
+ const errorResult = await this.runZone('error', ctx, routeMatch, err);
78
+ if (errorResult && !res.sent) {
79
+ this.renderer.render(res, errorResult);
80
+ }
81
+ else if (!res.sent) {
82
+ this.renderer.handleError(res, err);
83
+ }
84
+ }
85
+ finally {
86
+ // --- 9️⃣ FINAL always executed ---
87
+ await this.runFinal(ctx, routeMatch);
88
+ }
89
+ }
90
+ // ---------------------------------------------------------------------
91
+ // Middleware helpers
92
+ // ---------------------------------------------------------------------
93
+ collect(zone, match) {
94
+ const ctor = match.controller?.constructor;
95
+ return [
96
+ ...this.registry.all(zone),
97
+ ...(ctor ? this.registry.for(ctor, zone, match.action) : []),
98
+ ].map(m => m.use);
99
+ }
100
+ async runZone(zone, ctx, match, error) {
101
+ const fns = this.collect(zone, match);
102
+ if (!fns.length)
103
+ return undefined;
104
+ const pipe = new RuntimeMiddlewarePipe(fns);
105
+ if (zone === 'error' && error !== undefined) {
106
+ ctx.error = error;
107
+ }
108
+ return pipe.run(ctx);
109
+ }
110
+ async runFinal(ctx, match) {
111
+ return this.runZone('final', ctx, match);
112
+ }
113
+ }
114
+ //# sourceMappingURL=runtime-request-orchestrator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime-request-orchestrator.js","sourceRoot":"","sources":["../../src/http/runtime-request-orchestrator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import type { ActionResult, ResponseRenderer } from '@kurdel/core/http';
2
+ import type { HttpResponse } from '@kurdel/common';
3
+ /**
4
+ * Handles rendering of ActionResult into HttpResponse
5
+ * and unified error translation.
6
+ */
7
+ export declare class RuntimeResponseRenderer implements ResponseRenderer {
8
+ private readonly platformRender;
9
+ constructor(platformRender: (res: HttpResponse, result: ActionResult) => void);
10
+ render(res: HttpResponse, result: ActionResult | void): void;
11
+ handleError(res: HttpResponse, err: unknown): void;
12
+ }
@@ -0,0 +1,37 @@
1
+ import { HttpError } from '@kurdel/core/http';
2
+ /**
3
+ * Handles rendering of ActionResult into HttpResponse
4
+ * and unified error translation.
5
+ */
6
+ export class RuntimeResponseRenderer {
7
+ constructor(platformRender) {
8
+ this.platformRender = platformRender;
9
+ }
10
+ render(res, result) {
11
+ if (!res.sent && result) {
12
+ this.platformRender(res, result);
13
+ }
14
+ }
15
+ handleError(res, err) {
16
+ if (res.sent)
17
+ return;
18
+ if (err instanceof HttpError) {
19
+ this.platformRender(res, {
20
+ kind: 'json',
21
+ status: err.status,
22
+ body: {
23
+ error: err.message,
24
+ details: err.details,
25
+ },
26
+ });
27
+ }
28
+ else {
29
+ this.platformRender(res, {
30
+ kind: 'json',
31
+ status: 500,
32
+ body: { error: 'Internal Server Error' },
33
+ });
34
+ }
35
+ }
36
+ }
37
+ //# sourceMappingURL=runtime-response-renderer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime-response-renderer.js","sourceRoot":"","sources":["../../src/http/runtime-response-renderer.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAG9C;;;GAGG;AACH,MAAM,OAAO,uBAAuB;IAClC,YAA6B,cAAiE;QAAjE,mBAAc,GAAd,cAAc,CAAmD;IAAG,CAAC;IAElG,MAAM,CAAC,GAAiB,EAAE,MAA2B;QACnD,IAAI,CAAC,GAAG,CAAC,IAAI,IAAI,MAAM,EAAE,CAAC;YACxB,IAAI,CAAC,cAAc,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QACnC,CAAC;IACH,CAAC;IAED,WAAW,CAAC,GAAiB,EAAE,GAAY;QACzC,IAAI,GAAG,CAAC,IAAI;YAAE,OAAO;QAErB,IAAI,GAAG,YAAY,SAAS,EAAE,CAAC;YAC7B,IAAI,CAAC,cAAc,CAAC,GAAG,EAAE;gBACvB,IAAI,EAAE,MAAM;gBACZ,MAAM,EAAE,GAAG,CAAC,MAAM;gBAClB,IAAI,EAAE;oBACJ,KAAK,EAAE,GAAG,CAAC,OAAO;oBAClB,OAAO,EAAE,GAAG,CAAC,OAAoB;iBAClC;aACF,CAAC,CAAC;QACL,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,cAAc,CAAC,GAAG,EAAE;gBACvB,IAAI,EAAE,MAAM;gBACZ,MAAM,EAAE,GAAG;gBACX,IAAI,EAAE,EAAE,KAAK,EAAE,uBAAuB,EAAE;aACzC,CAAC,CAAC;QACL,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,37 @@
1
+ import type { Container } from '@kurdel/ioc';
2
+ import type { Method, ControllerConfig, ControllerResolver, Router, RouteMatch, RouteAuth } from '@kurdel/core/http';
3
+ export declare function mergeAuth(base?: RouteAuth, override?: RouteAuth): RouteAuth | undefined;
4
+ /**
5
+ * ## RuntimeRouter
6
+ *
7
+ * Responsible for:
8
+ * - extracting metadata from controller `routes`
9
+ * - compiling patterns into a fast lookup table
10
+ * - performing deterministic route matching at runtime
11
+ *
12
+ * Initialization stages:
13
+ * 1️⃣ iterate controller configs
14
+ * 2️⃣ instantiate controller *only to read routes*
15
+ * 3️⃣ extract `ROUTE_META` from handlers
16
+ * 4️⃣ normalize `prefix + path`
17
+ * 5️⃣ compile regex + param keys
18
+ * 6️⃣ store immutable route entries
19
+ */
20
+ export declare class RuntimeRouter implements Router {
21
+ /** Immutable table of compiled routes. */
22
+ private readonly entries;
23
+ /** Controller instance resolver (DI-based). */
24
+ private resolver;
25
+ /**
26
+ * Builds the route table by reading controller metadata.
27
+ */
28
+ init(resolver: ControllerResolver, controllerConfigs: ControllerConfig[]): void;
29
+ /**
30
+ * Matches an incoming HTTP request to a controller/action.
31
+ */
32
+ resolve(method: Method, url: string, scope: Container): RouteMatch | null;
33
+ /**
34
+ * Adds a compiled route entry into the lookup table.
35
+ */
36
+ private addEntry;
37
+ }
@@ -0,0 +1,135 @@
1
+ import { ROUTE_META } from '@kurdel/core/http';
2
+ /**
3
+ * Joins two path segments safely, preventing `//` occurrences.
4
+ */
5
+ function joinPaths(a, b) {
6
+ return `${a.replace(/\/+$/, '')}/${b.replace(/^\/+/, '')}`;
7
+ }
8
+ /**
9
+ * Extracts path keys and compiles a regex matcher.
10
+ */
11
+ function compilePath(path) {
12
+ const keys = [];
13
+ const pattern = path
14
+ .split('/')
15
+ .filter(Boolean)
16
+ .map(segment => {
17
+ if (segment.startsWith(':')) {
18
+ keys.push(segment.slice(1));
19
+ return '([^/]+)';
20
+ }
21
+ return segment;
22
+ })
23
+ .join('/');
24
+ const regex = pattern ? new RegExp(`^/${pattern}/?$`) : /^\/$/;
25
+ return { regex, keys };
26
+ }
27
+ export function mergeAuth(base, override) {
28
+ if (!base && !override)
29
+ return undefined;
30
+ return {
31
+ public: override?.public ?? base?.public,
32
+ strategy: override?.strategy ?? base?.strategy,
33
+ roles: override?.roles ?? base?.roles,
34
+ };
35
+ }
36
+ /**
37
+ * ## RuntimeRouter
38
+ *
39
+ * Responsible for:
40
+ * - extracting metadata from controller `routes`
41
+ * - compiling patterns into a fast lookup table
42
+ * - performing deterministic route matching at runtime
43
+ *
44
+ * Initialization stages:
45
+ * 1️⃣ iterate controller configs
46
+ * 2️⃣ instantiate controller *only to read routes*
47
+ * 3️⃣ extract `ROUTE_META` from handlers
48
+ * 4️⃣ normalize `prefix + path`
49
+ * 5️⃣ compile regex + param keys
50
+ * 6️⃣ store immutable route entries
51
+ */
52
+ export class RuntimeRouter {
53
+ constructor() {
54
+ /** Immutable table of compiled routes. */
55
+ this.entries = [];
56
+ }
57
+ /**
58
+ * Builds the route table by reading controller metadata.
59
+ */
60
+ init(resolver, controllerConfigs) {
61
+ this.resolver = resolver;
62
+ for (const { use: ControllerClass, prefix = '', auth: ctrlAuth = {} } of controllerConfigs) {
63
+ /**
64
+ * We instantiate the controller *only* to read its static `routes` definition.
65
+ *
66
+ * This instance:
67
+ * - is not created by DI
68
+ * - receives no real dependencies (`{}` is enough)
69
+ * - is never used to execute actions
70
+ *
71
+ * During request handling, controllers are instantiated per-scope
72
+ * via ControllerResolver — this initialization step only extracts metadata.
73
+ */
74
+ const { routes } = new ControllerClass({});
75
+ for (const [action, handler] of Object.entries(routes)) {
76
+ const meta = handler[ROUTE_META];
77
+ if (!meta)
78
+ continue;
79
+ const fullPath = joinPaths(prefix, meta.path);
80
+ const { method, schema } = meta;
81
+ const auth = mergeAuth(ctrlAuth, meta.auth);
82
+ this.addEntry(method, fullPath, ControllerClass, action, auth, schema);
83
+ }
84
+ }
85
+ // Optional debug output
86
+ if (process.env.DEBUG_ROUTES) {
87
+ console.log('[router] Registered:', this.entries.map(e => `${e.method} ${e.path}`));
88
+ }
89
+ }
90
+ /**
91
+ * Matches an incoming HTTP request to a controller/action.
92
+ */
93
+ resolve(method, url, scope) {
94
+ const pathname = (url ?? '/').split('?')[0].replace(/\\/g, '/');
95
+ for (const entry of this.entries) {
96
+ if (entry.method !== method)
97
+ continue;
98
+ const match = entry.regex.exec(pathname);
99
+ if (!match)
100
+ continue;
101
+ const params = {};
102
+ entry.keys.forEach((key, i) => {
103
+ params[key] = match[i + 1];
104
+ });
105
+ const controller = this.resolver.resolve(entry.token, scope);
106
+ return {
107
+ controller,
108
+ method,
109
+ action: entry.action,
110
+ path: entry.path,
111
+ params,
112
+ auth: entry.auth,
113
+ schema: entry.schema,
114
+ };
115
+ }
116
+ return null;
117
+ }
118
+ /**
119
+ * Adds a compiled route entry into the lookup table.
120
+ */
121
+ addEntry(method, path, token, action, auth, schema) {
122
+ const { regex, keys } = compilePath(path);
123
+ this.entries.push({
124
+ method,
125
+ path,
126
+ regex,
127
+ keys,
128
+ token,
129
+ action,
130
+ auth,
131
+ schema,
132
+ });
133
+ }
134
+ }
135
+ //# sourceMappingURL=runtime-router.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime-router.js","sourceRoot":"","sources":["../../src/http/runtime-router.ts"],"names":[],"mappings":"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"}
package/lib/index.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ export * as app from './app/index.js';
2
+ export * as http from './http/index.js';
3
+ export * as middlewares from './middlewares/index.js';
package/lib/index.js ADDED
@@ -0,0 +1,4 @@
1
+ export * as app from './app/index.js';
2
+ export * as http from './http/index.js';
3
+ export * as middlewares from './middlewares/index.js';
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,GAAG,MAAM,gBAAgB,CAAC;AACtC,OAAO,KAAK,IAAI,MAAM,iBAAiB,CAAC;AACxC,OAAO,KAAK,WAAW,MAAM,wBAAwB,CAAC"}
@@ -0,0 +1,7 @@
1
+ import type { ValidationError, SchemaValidator } from '@kurdel/core/http';
2
+ /**
3
+ * Generic adapter factory for schema validators (Zod, Joi, Yup, etc.)
4
+ *
5
+ * Wraps any validation library into a unified `SchemaValidator` interface.
6
+ */
7
+ export declare function createValidator<T>(parse: (data: unknown) => T | Promise<T>, mapError: (err: unknown) => ValidationError | null): SchemaValidator<T>;
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Generic adapter factory for schema validators (Zod, Joi, Yup, etc.)
3
+ *
4
+ * Wraps any validation library into a unified `SchemaValidator` interface.
5
+ */
6
+ export function createValidator(parse, mapError) {
7
+ return {
8
+ async validate(data) {
9
+ try {
10
+ return await parse(data);
11
+ }
12
+ catch (err) {
13
+ const mapped = mapError(err);
14
+ if (mapped)
15
+ throw mapped;
16
+ throw err;
17
+ }
18
+ },
19
+ };
20
+ }
21
+ //# sourceMappingURL=create-validator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-validator.js","sourceRoot":"","sources":["../../src/middlewares/create-validator.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAC7B,KAAwC,EACxC,QAAkD;IAElD,OAAO;QACL,KAAK,CAAC,QAAQ,CAAC,IAAa;YAC1B,IAAI,CAAC;gBACH,OAAO,MAAM,KAAK,CAAC,IAAI,CAAC,CAAC;YAC3B,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,MAAM,MAAM,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC;gBAC7B,IAAI,MAAM;oBAAE,MAAM,MAAM,CAAC;gBACzB,MAAM,GAAG,CAAC;YACZ,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,2 @@
1
+ import type { Middleware } from '@kurdel/core/http';
2
+ export declare const errorHandler: Middleware;