@jskit-ai/kernel 0.1.4

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 (185) hide show
  1. package/README.md +24 -0
  2. package/_testable/index.js +4 -0
  3. package/client/appConfig.js +33 -0
  4. package/client/componentInteraction.js +51 -0
  5. package/client/componentInteraction.test.js +111 -0
  6. package/client/descriptorSections.js +75 -0
  7. package/client/index.d.ts +70 -0
  8. package/client/index.js +3 -0
  9. package/client/logging.js +38 -0
  10. package/client/moduleBootstrap.js +670 -0
  11. package/client/moduleBootstrap.test.js +403 -0
  12. package/client/shellBootstrap.js +233 -0
  13. package/client/shellBootstrap.test.js +185 -0
  14. package/client/shellRouting.js +321 -0
  15. package/client/shellRouting.test.js +113 -0
  16. package/client/vite/clientBootstrapPlugin.js +259 -0
  17. package/client/vite/clientBootstrapPlugin.test.js +563 -0
  18. package/client/vite/index.js +3 -0
  19. package/internal/node/fileSystem.js +21 -0
  20. package/internal/node/installedPackageDescriptor.js +104 -0
  21. package/package.json +43 -0
  22. package/server/actions/ActionRuntimeServiceProvider.js +309 -0
  23. package/server/actions/ActionRuntimeServiceProvider.test.js +551 -0
  24. package/server/actions/index.js +8 -0
  25. package/server/container/ContainerCoreServiceProvider.js +27 -0
  26. package/server/container/index.js +10 -0
  27. package/server/exportPolicy.test.js +68 -0
  28. package/server/http/HttpFastifyServiceProvider.js +25 -0
  29. package/server/http/_testable/index.js +2 -0
  30. package/server/http/index.js +1 -0
  31. package/server/http/lib/controller.js +183 -0
  32. package/server/http/lib/controller.test.js +143 -0
  33. package/server/http/lib/errors.js +12 -0
  34. package/server/http/lib/httpRuntime.js +82 -0
  35. package/server/http/lib/index.js +18 -0
  36. package/server/http/lib/kernel.js +15 -0
  37. package/server/http/lib/kernel.test.js +880 -0
  38. package/server/http/lib/middlewareRuntime.js +149 -0
  39. package/server/http/lib/requestActionExecutor.js +258 -0
  40. package/server/http/lib/requestScope.js +59 -0
  41. package/server/http/lib/routeRegistration.js +165 -0
  42. package/server/http/lib/routeSupport.js +45 -0
  43. package/server/http/lib/routeValidator.js +469 -0
  44. package/server/http/lib/routeValidator.test.js +474 -0
  45. package/server/http/lib/router.js +206 -0
  46. package/server/kernel/KernelCoreServiceProvider.js +27 -0
  47. package/server/kernel/index.js +10 -0
  48. package/server/platform/PlatformServerRuntimeServiceProvider.js +30 -0
  49. package/server/platform/index.js +5 -0
  50. package/server/platform/providerRuntime/descriptorCatalog.js +170 -0
  51. package/server/platform/providerRuntime/helpers.js +45 -0
  52. package/server/platform/providerRuntime/lockfile.js +27 -0
  53. package/server/platform/providerRuntime/providerLoader.js +283 -0
  54. package/server/platform/providerRuntime.js +142 -0
  55. package/server/platform/providerRuntime.test.js +217 -0
  56. package/server/platform/runtime.js +40 -0
  57. package/server/platform/surfaceRuntime.js +150 -0
  58. package/server/platform/surfaceRuntime.test.js +136 -0
  59. package/server/registries/actionSurfaceSourceRegistry.js +150 -0
  60. package/server/registries/bootstrapPayloadContributorRegistry.js +41 -0
  61. package/server/registries/domainEventListenerRegistry.js +61 -0
  62. package/server/registries/index.js +36 -0
  63. package/server/registries/primitives.js +63 -0
  64. package/server/registries/routeVisibilityResolverRegistry.js +87 -0
  65. package/server/registries/serviceRegistrationRegistry.js +431 -0
  66. package/server/runtime/ServerRuntimeCoreServiceProvider.js +65 -0
  67. package/server/runtime/ServerRuntimeCoreServiceProvider.test.js +53 -0
  68. package/server/runtime/apiRoutePolicyParity.test.js +109 -0
  69. package/server/runtime/apiRouteRegistration.js +65 -0
  70. package/server/runtime/bootBootstrapRoutes.js +46 -0
  71. package/server/runtime/bootBootstrapRoutes.test.js +79 -0
  72. package/server/runtime/bootstrapContributors.test.js +114 -0
  73. package/server/runtime/canonicalJson.js +74 -0
  74. package/server/runtime/composition.js +142 -0
  75. package/server/runtime/domainEvents.test.js +114 -0
  76. package/server/runtime/domainRules.js +50 -0
  77. package/server/runtime/domainRules.test.js +87 -0
  78. package/server/runtime/entityChangeEvents.js +182 -0
  79. package/server/runtime/entityChangeEvents.test.js +211 -0
  80. package/server/runtime/errors.js +68 -0
  81. package/server/runtime/errors.test.js +73 -0
  82. package/server/runtime/fastifyBootstrap.js +372 -0
  83. package/server/runtime/fastifyBootstrap.test.js +194 -0
  84. package/server/runtime/index.js +6 -0
  85. package/server/runtime/integers.js +13 -0
  86. package/server/runtime/moduleConfig.js +269 -0
  87. package/server/runtime/moduleConfig.test.js +141 -0
  88. package/server/runtime/pagination.js +13 -0
  89. package/server/runtime/realtimeNormalization.js +21 -0
  90. package/server/runtime/requestUrl.js +38 -0
  91. package/server/runtime/routeUtils.js +20 -0
  92. package/server/runtime/runtimeAssembly.js +113 -0
  93. package/server/runtime/runtimeKernel.js +55 -0
  94. package/server/runtime/securityAudit.js +269 -0
  95. package/server/runtime/securityAudit.test.js +41 -0
  96. package/server/runtime/serviceAuthorization.js +113 -0
  97. package/server/runtime/serviceAuthorization.test.js +100 -0
  98. package/server/runtime/serviceRegistration.test.js +197 -0
  99. package/server/support/SupportCoreServiceProvider.js +25 -0
  100. package/server/support/appConfig.js +37 -0
  101. package/server/support/appConfig.test.js +94 -0
  102. package/server/support/defaultMissingHandler.js +7 -0
  103. package/server/support/index.js +2 -0
  104. package/server/support/routePolicyConfig.js +51 -0
  105. package/server/support/symlinkSafeRequire.js +78 -0
  106. package/server/support/symlinkSafeRequire.test.js +27 -0
  107. package/server/surface/SurfaceRoutingServiceProvider.js +27 -0
  108. package/server/surface/index.js +19 -0
  109. package/shared/actions/actionContributorHelpers.js +34 -0
  110. package/shared/actions/actionContributorHelpers.test.js +16 -0
  111. package/shared/actions/actionDefinitions.js +488 -0
  112. package/shared/actions/actionDefinitions.test.js +212 -0
  113. package/shared/actions/audit.js +7 -0
  114. package/shared/actions/executionContext.js +97 -0
  115. package/shared/actions/executionContext.test.js +66 -0
  116. package/shared/actions/idempotency.js +62 -0
  117. package/shared/actions/index.js +2 -0
  118. package/shared/actions/observability.js +10 -0
  119. package/shared/actions/pipeline.js +287 -0
  120. package/shared/actions/policies.js +342 -0
  121. package/shared/actions/policies.test.js +233 -0
  122. package/shared/actions/registry.js +187 -0
  123. package/shared/actions/registry.test.js +381 -0
  124. package/shared/actions/requestMeta.js +36 -0
  125. package/shared/actions/textNormalization.js +3 -0
  126. package/shared/actions/withActionDefaults.js +34 -0
  127. package/shared/index.js +2 -0
  128. package/shared/runtime/application.js +323 -0
  129. package/shared/runtime/container.js +261 -0
  130. package/shared/runtime/containerErrors.js +22 -0
  131. package/shared/runtime/index.js +18 -0
  132. package/shared/runtime/kernelErrors.js +20 -0
  133. package/shared/runtime/serviceProvider.js +13 -0
  134. package/shared/support/formatDateTime.js +10 -0
  135. package/shared/support/formatDateTime.test.js +15 -0
  136. package/shared/support/index.js +14 -0
  137. package/shared/support/linkPath.js +67 -0
  138. package/shared/support/linkPath.test.js +35 -0
  139. package/shared/support/normalize.js +116 -0
  140. package/shared/support/normalize.test.js +48 -0
  141. package/shared/support/packageDescriptor.test.js +121 -0
  142. package/shared/support/permissions.js +50 -0
  143. package/shared/support/pickOwnProperties.js +17 -0
  144. package/shared/support/pickOwnProperties.test.js +25 -0
  145. package/shared/support/policies.js +11 -0
  146. package/shared/support/queryPath.js +33 -0
  147. package/shared/support/queryPath.test.js +19 -0
  148. package/shared/support/queryResilience.js +34 -0
  149. package/shared/support/queryResilience.test.js +33 -0
  150. package/shared/support/returnToPath.js +153 -0
  151. package/shared/support/returnToPath.test.js +123 -0
  152. package/shared/support/sorting.js +15 -0
  153. package/shared/support/tokens.js +23 -0
  154. package/shared/support/tokens.test.js +17 -0
  155. package/shared/support/visibility.js +56 -0
  156. package/shared/support/visibility.test.js +45 -0
  157. package/shared/surface/apiPaths.js +84 -0
  158. package/shared/surface/escapeRegExp.js +5 -0
  159. package/shared/surface/index.js +6 -0
  160. package/shared/surface/paths.js +273 -0
  161. package/shared/surface/registry.js +135 -0
  162. package/shared/surface/registry.test.js +44 -0
  163. package/shared/surface/runtime.js +357 -0
  164. package/shared/surface/runtime.test.js +319 -0
  165. package/shared/validators/createCursorListValidator.js +42 -0
  166. package/shared/validators/createCursorListValidator.test.js +34 -0
  167. package/shared/validators/cursorPaginationQueryValidator.js +31 -0
  168. package/shared/validators/cursorPaginationQueryValidator.test.js +21 -0
  169. package/shared/validators/index.js +12 -0
  170. package/shared/validators/inputNormalization.js +13 -0
  171. package/shared/validators/mergeObjectSchemas.js +31 -0
  172. package/shared/validators/mergeObjectSchemas.test.js +67 -0
  173. package/shared/validators/mergeValidators.js +89 -0
  174. package/shared/validators/mergeValidators.test.js +116 -0
  175. package/shared/validators/nestValidator.js +53 -0
  176. package/shared/validators/nestValidator.test.js +60 -0
  177. package/shared/validators/recordIdParamsValidator.js +36 -0
  178. package/shared/validators/recordIdParamsValidator.test.js +20 -0
  179. package/shared/validators/resourceRequiredMetadata.js +41 -0
  180. package/shared/validators/resourceRequiredMetadata.test.js +49 -0
  181. package/test/barrelExposure.test.js +106 -0
  182. package/test/dynamicImportPolicy.test.js +89 -0
  183. package/test/exportsContract.test.js +168 -0
  184. package/test/routeInputContractGuard.test.js +78 -0
  185. package/test/surfaceIndependence.test.js +109 -0
@@ -0,0 +1,183 @@
1
+ const DEFAULT_DOMAIN_ERROR_STATUS_BY_CODE = Object.freeze({
2
+ domain_validation_failed: 422,
3
+ validation_failed: 422,
4
+ invalid_input: 422,
5
+ duplicate: 409,
6
+ conflict: 409,
7
+ not_found: 404,
8
+ forbidden: 403,
9
+ unauthorized: 401,
10
+ rate_limited: 429
11
+ });
12
+
13
+ function normalizeStatus(status, fallbackStatus) {
14
+ const numeric = Number(status);
15
+ if (Number.isInteger(numeric) && numeric >= 100 && numeric <= 599) {
16
+ return numeric;
17
+ }
18
+
19
+ const fallbackNumeric = Number(fallbackStatus);
20
+ if (Number.isInteger(fallbackNumeric) && fallbackNumeric >= 100 && fallbackNumeric <= 599) {
21
+ return fallbackNumeric;
22
+ }
23
+
24
+ return 500;
25
+ }
26
+
27
+ function normalizeCode(code) {
28
+ const normalized = String(code || "")
29
+ .trim()
30
+ .toLowerCase();
31
+ return normalized || "";
32
+ }
33
+
34
+ function resolveDomainErrorStatus({
35
+ status,
36
+ code,
37
+ domainErrorStatusByCode = DEFAULT_DOMAIN_ERROR_STATUS_BY_CODE,
38
+ fallbackStatus = 422
39
+ } = {}) {
40
+ const explicitStatus = Number(status);
41
+ if (Number.isInteger(explicitStatus) && explicitStatus >= 100 && explicitStatus <= 599) {
42
+ return explicitStatus;
43
+ }
44
+
45
+ const normalizedCode = normalizeCode(code);
46
+ if (normalizedCode) {
47
+ const mapSource =
48
+ domainErrorStatusByCode && typeof domainErrorStatusByCode === "object"
49
+ ? domainErrorStatusByCode
50
+ : DEFAULT_DOMAIN_ERROR_STATUS_BY_CODE;
51
+ const mappedStatus = Number(mapSource[normalizedCode]);
52
+ if (Number.isInteger(mappedStatus) && mappedStatus >= 100 && mappedStatus <= 599) {
53
+ return mappedStatus;
54
+ }
55
+ }
56
+
57
+ return normalizeStatus(fallbackStatus, 422);
58
+ }
59
+
60
+ function ensureReply(reply, methodName) {
61
+ if (!reply || typeof reply.code !== "function" || typeof reply.send !== "function") {
62
+ throw new TypeError(`${methodName} requires a Fastify reply-like object with code() and send().`);
63
+ }
64
+ }
65
+
66
+ function applyHeaders(reply, headers) {
67
+ if (!headers || typeof headers !== "object" || typeof reply.header !== "function") {
68
+ return;
69
+ }
70
+
71
+ for (const [name, value] of Object.entries(headers)) {
72
+ reply.header(name, value);
73
+ }
74
+ }
75
+
76
+ class BaseController {
77
+ constructor({ domainErrorStatusByCode = DEFAULT_DOMAIN_ERROR_STATUS_BY_CODE } = {}) {
78
+ this.domainErrorStatusByCode =
79
+ domainErrorStatusByCode && typeof domainErrorStatusByCode === "object"
80
+ ? { ...DEFAULT_DOMAIN_ERROR_STATUS_BY_CODE, ...domainErrorStatusByCode }
81
+ : { ...DEFAULT_DOMAIN_ERROR_STATUS_BY_CODE };
82
+ }
83
+
84
+ ok(reply, payload, { status = 200, headers = null } = {}) {
85
+ ensureReply(reply, "BaseController.ok");
86
+ applyHeaders(reply, headers);
87
+
88
+ const normalizedStatus = normalizeStatus(status, 200);
89
+ reply.code(normalizedStatus);
90
+
91
+ if (normalizedStatus === 204) {
92
+ return reply.send();
93
+ }
94
+
95
+ return reply.send(payload);
96
+ }
97
+
98
+ created(reply, payload, { headers = null } = {}) {
99
+ return this.ok(reply, payload, {
100
+ status: 201,
101
+ headers
102
+ });
103
+ }
104
+
105
+ noContent(reply, { headers = null } = {}) {
106
+ return this.ok(reply, undefined, {
107
+ status: 204,
108
+ headers
109
+ });
110
+ }
111
+
112
+ fail(
113
+ reply,
114
+ { status, code, message = "Request failed.", details, fieldErrors, headers = null, fallbackStatus = 422 } = {}
115
+ ) {
116
+ ensureReply(reply, "BaseController.fail");
117
+
118
+ const resolvedStatus = resolveDomainErrorStatus({
119
+ status,
120
+ code,
121
+ domainErrorStatusByCode: this.domainErrorStatusByCode,
122
+ fallbackStatus
123
+ });
124
+
125
+ const payload = {
126
+ error: String(message || "Request failed.")
127
+ };
128
+
129
+ const normalizedCode = normalizeCode(code);
130
+ if (normalizedCode) {
131
+ payload.code = String(code || "").trim();
132
+ }
133
+
134
+ if (details !== undefined) {
135
+ payload.details = details;
136
+ }
137
+
138
+ if (fieldErrors !== undefined) {
139
+ payload.fieldErrors = fieldErrors;
140
+ if (payload.details === undefined) {
141
+ payload.details = { fieldErrors };
142
+ }
143
+ }
144
+
145
+ applyHeaders(reply, headers);
146
+ reply.code(resolvedStatus);
147
+ return reply.send(payload);
148
+ }
149
+
150
+ sendActionResult(
151
+ reply,
152
+ result,
153
+ { successStatus = 200, defaultErrorStatus = 422, defaultErrorMessage = "Request failed." } = {}
154
+ ) {
155
+ if (!result || typeof result !== "object") {
156
+ throw new TypeError("BaseController.sendActionResult requires an object result.");
157
+ }
158
+
159
+ if (result.ok === true) {
160
+ const payload = Object.prototype.hasOwnProperty.call(result, "data") ? result.data : undefined;
161
+ return this.ok(reply, payload, {
162
+ status: result.status ?? successStatus,
163
+ headers: result.headers
164
+ });
165
+ }
166
+
167
+ if (result.ok === false) {
168
+ return this.fail(reply, {
169
+ status: result.status,
170
+ code: result.code,
171
+ message: result.message || defaultErrorMessage,
172
+ details: result.details,
173
+ fieldErrors: result.fieldErrors,
174
+ headers: result.headers,
175
+ fallbackStatus: defaultErrorStatus
176
+ });
177
+ }
178
+
179
+ throw new TypeError("BaseController.sendActionResult expects result.ok to be true or false.");
180
+ }
181
+ }
182
+
183
+ export { BaseController, DEFAULT_DOMAIN_ERROR_STATUS_BY_CODE, resolveDomainErrorStatus };
@@ -0,0 +1,143 @@
1
+ import assert from "node:assert/strict";
2
+ import test from "node:test";
3
+
4
+ import { BaseController, resolveDomainErrorStatus } from "./controller.js";
5
+
6
+ function createReplyStub() {
7
+ const state = {
8
+ statusCode: 200,
9
+ payload: undefined,
10
+ headers: {}
11
+ };
12
+
13
+ return {
14
+ state,
15
+ code(statusCode) {
16
+ state.statusCode = Number(statusCode);
17
+ return this;
18
+ },
19
+ header(name, value) {
20
+ state.headers[name] = value;
21
+ return this;
22
+ },
23
+ send(payload) {
24
+ state.payload = payload;
25
+ return this;
26
+ }
27
+ };
28
+ }
29
+
30
+ test("resolveDomainErrorStatus prefers explicit status", () => {
31
+ const status = resolveDomainErrorStatus({
32
+ status: 418,
33
+ code: "duplicate"
34
+ });
35
+
36
+ assert.equal(status, 418);
37
+ });
38
+
39
+ test("resolveDomainErrorStatus maps known domain codes", () => {
40
+ assert.equal(resolveDomainErrorStatus({ code: "duplicate" }), 409);
41
+ assert.equal(resolveDomainErrorStatus({ code: "domain_validation_failed" }), 422);
42
+ assert.equal(resolveDomainErrorStatus({ code: "not_found" }), 404);
43
+ });
44
+
45
+ test("BaseController.sendActionResult sends success payload and headers", () => {
46
+ const controller = new BaseController();
47
+ const reply = createReplyStub();
48
+
49
+ controller.sendActionResult(reply, {
50
+ ok: true,
51
+ data: { ok: true, value: 42 },
52
+ status: 201,
53
+ headers: {
54
+ "x-test": "success"
55
+ }
56
+ });
57
+
58
+ assert.equal(reply.state.statusCode, 201);
59
+ assert.deepEqual(reply.state.payload, { ok: true, value: 42 });
60
+ assert.equal(reply.state.headers["x-test"], "success");
61
+ });
62
+
63
+ test("BaseController.sendActionResult maps domain failure", () => {
64
+ const controller = new BaseController();
65
+ const reply = createReplyStub();
66
+
67
+ controller.sendActionResult(reply, {
68
+ ok: false,
69
+ code: "duplicate",
70
+ details: ["already exists"]
71
+ });
72
+
73
+ assert.equal(reply.state.statusCode, 409);
74
+ assert.deepEqual(reply.state.payload, {
75
+ error: "Request failed.",
76
+ code: "duplicate",
77
+ details: ["already exists"]
78
+ });
79
+ });
80
+
81
+ test("BaseController supports module-specific domain error codes through overrides", () => {
82
+ const controller = new BaseController({
83
+ domainErrorStatusByCode: {
84
+ duplicate_contact: 409
85
+ }
86
+ });
87
+ const reply = createReplyStub();
88
+
89
+ controller.sendActionResult(reply, {
90
+ ok: false,
91
+ code: "duplicate_contact",
92
+ details: ["already exists"]
93
+ });
94
+
95
+ assert.equal(reply.state.statusCode, 409);
96
+ });
97
+
98
+ test("BaseController.fail includes fieldErrors and default details shape", () => {
99
+ const controller = new BaseController();
100
+ const reply = createReplyStub();
101
+
102
+ controller.fail(reply, {
103
+ code: "domain_validation_failed",
104
+ message: "Validation failed.",
105
+ fieldErrors: {
106
+ email: "Invalid email."
107
+ }
108
+ });
109
+
110
+ assert.equal(reply.state.statusCode, 422);
111
+ assert.deepEqual(reply.state.payload, {
112
+ error: "Validation failed.",
113
+ code: "domain_validation_failed",
114
+ fieldErrors: {
115
+ email: "Invalid email."
116
+ },
117
+ details: {
118
+ fieldErrors: {
119
+ email: "Invalid email."
120
+ }
121
+ }
122
+ });
123
+ });
124
+
125
+ test("BaseController.noContent sends HTTP 204", () => {
126
+ const controller = new BaseController();
127
+ const reply = createReplyStub();
128
+
129
+ controller.noContent(reply);
130
+
131
+ assert.equal(reply.state.statusCode, 204);
132
+ assert.equal(reply.state.payload, undefined);
133
+ });
134
+
135
+ test("BaseController.sendActionResult rejects invalid result shape", () => {
136
+ const controller = new BaseController();
137
+ const reply = createReplyStub();
138
+
139
+ assert.throws(
140
+ () => controller.sendActionResult(reply, { data: { ok: true } }),
141
+ /expects result\.ok to be true or false/
142
+ );
143
+ });
@@ -0,0 +1,12 @@
1
+ class HttpKernelError extends Error {
2
+ constructor(message, details = {}) {
3
+ super(String(message || "HTTP kernel error."));
4
+ this.name = this.constructor.name;
5
+ this.details = details && typeof details === "object" ? { ...details } : {};
6
+ }
7
+ }
8
+
9
+ class RouteDefinitionError extends HttpKernelError {}
10
+ class RouteRegistrationError extends HttpKernelError {}
11
+
12
+ export { HttpKernelError, RouteDefinitionError, RouteRegistrationError };
@@ -0,0 +1,82 @@
1
+ import { KERNEL_TOKENS } from "../../../shared/support/tokens.js";
2
+ import { normalizeObject } from "../../../shared/support/normalize.js";
3
+ import { ensureApiErrorHandling } from "../../runtime/fastifyBootstrap.js";
4
+ import { resolveDefaultSurfaceId } from "../../support/appConfig.js";
5
+ import { RouteRegistrationError } from "./errors.js";
6
+ import { createRouter } from "./router.js";
7
+ import { registerRoutes } from "./routeRegistration.js";
8
+
9
+ function registerHttpRuntime(app, options = {}) {
10
+ if (!app || typeof app.make !== "function") {
11
+ throw new RouteRegistrationError("registerHttpRuntime requires an application instance.");
12
+ }
13
+
14
+ const runtimeOptions = normalizeObject(options);
15
+ const {
16
+ fastifyToken = KERNEL_TOKENS.Fastify,
17
+ routerToken = KERNEL_TOKENS.HttpRouter,
18
+ autoRegisterApiErrorHandling = true,
19
+ apiErrorHandling = {},
20
+ ...routeRegistrationOptions
21
+ } = runtimeOptions;
22
+ const fastify = app.make(fastifyToken);
23
+ const router = app.make(routerToken);
24
+ const routes = typeof router?.list === "function" ? router.list() : [];
25
+ const resolvedDefaultActionSurface = resolveDefaultSurfaceId(app, {
26
+ defaultSurfaceId: routeRegistrationOptions.requestActionDefaultSurface
27
+ });
28
+
29
+ if (autoRegisterApiErrorHandling !== false) {
30
+ ensureApiErrorHandling(app, {
31
+ fastifyToken,
32
+ ...normalizeObject(apiErrorHandling)
33
+ });
34
+ }
35
+
36
+ return registerRoutes(fastify, {
37
+ ...routeRegistrationOptions,
38
+ requestActionDefaultSurface: resolvedDefaultActionSurface,
39
+ app,
40
+ routes
41
+ });
42
+ }
43
+
44
+ function createHttpRuntime(
45
+ {
46
+ app = null,
47
+ fastify = null,
48
+ router = null,
49
+ autoRegisterApiErrorHandling = true,
50
+ apiErrorHandling = {}
51
+ } = {}
52
+ ) {
53
+ if (!app || typeof app.singleton !== "function") {
54
+ throw new RouteRegistrationError("createHttpRuntime requires an application instance.");
55
+ }
56
+
57
+ const runtimeRouter = router || createRouter();
58
+ app.singleton(KERNEL_TOKENS.HttpRouter, () => runtimeRouter);
59
+
60
+ if (fastify) {
61
+ app.instance(KERNEL_TOKENS.Fastify, fastify);
62
+ if (autoRegisterApiErrorHandling !== false) {
63
+ ensureApiErrorHandling(app, {
64
+ fastifyToken: KERNEL_TOKENS.Fastify,
65
+ ...normalizeObject(apiErrorHandling)
66
+ });
67
+ }
68
+ }
69
+
70
+ return {
71
+ router: runtimeRouter,
72
+ registerRoutes(runtimeOptions = {}) {
73
+ return registerHttpRuntime(app, {
74
+ autoRegisterApiErrorHandling,
75
+ apiErrorHandling: normalizeObject(apiErrorHandling),
76
+ ...normalizeObject(runtimeOptions)
77
+ });
78
+ }
79
+ };
80
+ }
81
+
82
+ export { registerHttpRuntime, createHttpRuntime };
@@ -0,0 +1,18 @@
1
+ export { HttpKernelError, RouteDefinitionError, RouteRegistrationError } from "./errors.js";
2
+ export { HttpRouter, createRouter, joinPath } from "./router.js";
3
+ export { defineRouteValidator, compileRouteValidator, resolveRouteValidatorOptions } from "./routeValidator.js";
4
+ export { BaseController, DEFAULT_DOMAIN_ERROR_STATUS_BY_CODE, resolveDomainErrorStatus } from "./controller.js";
5
+ export {
6
+ defaultMissingHandler,
7
+ defaultApplyRoutePolicy,
8
+ normalizeRoutePolicyConfig,
9
+ registerRoutes,
10
+ registerHttpRuntime,
11
+ createHttpRuntime
12
+ } from "./kernel.js";
13
+ export {
14
+ ROUTE_VISIBILITY_RESOLVER_TAG,
15
+ resolveRouteVisibilityResolvers,
16
+ registerRouteVisibilityResolver,
17
+ resolveRouteVisibilityContext
18
+ } from "../../registries/routeVisibilityResolverRegistry.js";
@@ -0,0 +1,15 @@
1
+ import { defaultApplyRoutePolicy, normalizeRoutePolicyConfig } from "../../support/routePolicyConfig.js";
2
+ import { defaultMissingHandler, registerRoutes } from "./routeRegistration.js";
3
+ import { buildActionExecutionContext, attachRequestActionExecutor } from "./requestActionExecutor.js";
4
+ import { registerHttpRuntime, createHttpRuntime } from "./httpRuntime.js";
5
+
6
+ export {
7
+ defaultMissingHandler,
8
+ defaultApplyRoutePolicy,
9
+ normalizeRoutePolicyConfig,
10
+ buildActionExecutionContext,
11
+ attachRequestActionExecutor,
12
+ registerRoutes,
13
+ registerHttpRuntime,
14
+ createHttpRuntime
15
+ };