@venizia/ignis 0.4.7-0 → 0.4.7-2

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 (177) hide show
  1. package/LICENSE.md +1 -4
  2. package/README.md +2 -2
  3. package/dist/esm/base/applications/base.d.ts.map +1 -1
  4. package/dist/esm/base/applications/base.js +25 -18
  5. package/dist/esm/base/applications/base.js.map +1 -1
  6. package/dist/esm/base/applications/common/index.d.ts +1 -0
  7. package/dist/esm/base/applications/common/index.d.ts.map +1 -1
  8. package/dist/esm/base/applications/common/index.js +1 -0
  9. package/dist/esm/base/applications/common/index.js.map +1 -1
  10. package/dist/esm/base/applications/common/logger-startup.d.ts +11 -0
  11. package/dist/esm/base/applications/common/logger-startup.d.ts.map +1 -0
  12. package/dist/esm/base/applications/common/logger-startup.js +29 -0
  13. package/dist/esm/base/applications/common/logger-startup.js.map +1 -0
  14. package/dist/esm/base/applications/server.d.ts +14 -9
  15. package/dist/esm/base/applications/server.d.ts.map +1 -1
  16. package/dist/esm/base/applications/server.js +36 -29
  17. package/dist/esm/base/applications/server.js.map +1 -1
  18. package/dist/esm/common/constants.d.ts.map +1 -1
  19. package/dist/esm/common/constants.js +2 -2
  20. package/dist/esm/common/constants.js.map +1 -1
  21. package/dist/esm/components/auth/authenticate/component.js +2 -2
  22. package/dist/esm/components/auth/authenticate/component.js.map +1 -1
  23. package/dist/esm/components/auth/authenticate/controllers/factory.d.ts +139 -136
  24. package/dist/esm/components/auth/authenticate/controllers/factory.d.ts.map +1 -1
  25. package/dist/esm/components/auth/authenticate/controllers/factory.js +175 -172
  26. package/dist/esm/components/auth/authenticate/controllers/factory.js.map +1 -1
  27. package/dist/esm/components/auth/authenticate/controllers/jwks/definitions.js +2 -2
  28. package/dist/esm/components/auth/authenticate/controllers/jwks/definitions.js.map +1 -1
  29. package/dist/esm/components/auth/authenticate/controllers/service-certs/definitions.js +2 -2
  30. package/dist/esm/components/auth/authenticate/controllers/service-certs/definitions.js.map +1 -1
  31. package/dist/esm/components/auth/authorize/adapters/base-filtered.js +2 -2
  32. package/dist/esm/components/auth/authorize/adapters/base-filtered.js.map +1 -1
  33. package/dist/esm/components/auth/authorize/adapters/custom-grant-expander.d.ts.map +1 -1
  34. package/dist/esm/components/auth/authorize/adapters/custom-grant-expander.js +2 -2
  35. package/dist/esm/components/auth/authorize/adapters/custom-grant-expander.js.map +1 -1
  36. package/dist/esm/components/auth/models/entities/columns.d.ts +99 -0
  37. package/dist/esm/components/auth/models/entities/columns.d.ts.map +1 -0
  38. package/dist/esm/components/auth/models/entities/columns.js +133 -0
  39. package/dist/esm/components/auth/models/entities/columns.js.map +1 -0
  40. package/dist/esm/components/auth/models/entities/index.d.ts +1 -2
  41. package/dist/esm/components/auth/models/entities/index.d.ts.map +1 -1
  42. package/dist/esm/components/auth/models/entities/index.js +1 -2
  43. package/dist/esm/components/auth/models/entities/index.js.map +1 -1
  44. package/dist/esm/components/auth/models/entities/permission.model.d.ts +1 -12
  45. package/dist/esm/components/auth/models/entities/permission.model.d.ts.map +1 -1
  46. package/dist/esm/components/auth/models/entities/permission.model.js +1 -36
  47. package/dist/esm/components/auth/models/entities/permission.model.js.map +1 -1
  48. package/dist/esm/components/auth/models/entities/policy-definition.model.d.ts +1 -49
  49. package/dist/esm/components/auth/models/entities/policy-definition.model.d.ts.map +1 -1
  50. package/dist/esm/components/auth/models/entities/policy-definition.model.js +1 -69
  51. package/dist/esm/components/auth/models/entities/policy-definition.model.js.map +1 -1
  52. package/dist/esm/components/controller/grpc/grpc.component.js +2 -2
  53. package/dist/esm/components/controller/grpc/grpc.component.js.map +1 -1
  54. package/dist/esm/components/health-check/controller.js +5 -5
  55. package/dist/esm/components/health-check/controller.js.map +1 -1
  56. package/dist/esm/components/index.d.ts +0 -1
  57. package/dist/esm/components/index.d.ts.map +1 -1
  58. package/dist/esm/components/index.js +0 -1
  59. package/dist/esm/components/index.js.map +1 -1
  60. package/dist/esm/components/mail/helpers/transporters/amazon-ses-transporter.helper.d.ts.map +1 -1
  61. package/dist/esm/components/mail/helpers/transporters/amazon-ses-transporter.helper.js +13 -9
  62. package/dist/esm/components/mail/helpers/transporters/amazon-ses-transporter.helper.js.map +1 -1
  63. package/dist/esm/components/mail/helpers/transporters/mailgun-transporter.helper.d.ts.map +1 -1
  64. package/dist/esm/components/mail/helpers/transporters/mailgun-transporter.helper.js +5 -3
  65. package/dist/esm/components/mail/helpers/transporters/mailgun-transporter.helper.js.map +1 -1
  66. package/dist/esm/components/mail/helpers/transporters/nodemail-transporter.helper.d.ts.map +1 -1
  67. package/dist/esm/components/mail/helpers/transporters/nodemail-transporter.helper.js +5 -5
  68. package/dist/esm/components/mail/helpers/transporters/nodemail-transporter.helper.js.map +1 -1
  69. package/dist/esm/components/mail/services/generators/verification-data.d.ts.map +1 -1
  70. package/dist/esm/components/mail/services/generators/verification-data.js +7 -3
  71. package/dist/esm/components/mail/services/generators/verification-data.js.map +1 -1
  72. package/dist/esm/components/mail/services/mail.service.js +7 -7
  73. package/dist/esm/components/mail/services/mail.service.js.map +1 -1
  74. package/dist/esm/components/mail/utilities/address.utility.d.ts +12 -8
  75. package/dist/esm/components/mail/utilities/address.utility.d.ts.map +1 -1
  76. package/dist/esm/components/mail/utilities/address.utility.js +30 -27
  77. package/dist/esm/components/mail/utilities/address.utility.js.map +1 -1
  78. package/dist/esm/components/mail/utilities/attachment.utility.d.ts +31 -29
  79. package/dist/esm/components/mail/utilities/attachment.utility.d.ts.map +1 -1
  80. package/dist/esm/components/mail/utilities/attachment.utility.js +97 -86
  81. package/dist/esm/components/mail/utilities/attachment.utility.js.map +1 -1
  82. package/dist/esm/components/mail/utilities/body.utility.d.ts +6 -4
  83. package/dist/esm/components/mail/utilities/body.utility.d.ts.map +1 -1
  84. package/dist/esm/components/mail/utilities/body.utility.js +14 -12
  85. package/dist/esm/components/mail/utilities/body.utility.js.map +1 -1
  86. package/dist/esm/components/mail/utilities/mime.utility.d.ts +23 -17
  87. package/dist/esm/components/mail/utilities/mime.utility.d.ts.map +1 -1
  88. package/dist/esm/components/mail/utilities/mime.utility.js +109 -102
  89. package/dist/esm/components/mail/utilities/mime.utility.js.map +1 -1
  90. package/dist/esm/components/mail/utilities/verification.utility.d.ts +8 -2
  91. package/dist/esm/components/mail/utilities/verification.utility.d.ts.map +1 -1
  92. package/dist/esm/components/mail/utilities/verification.utility.js +7 -5
  93. package/dist/esm/components/mail/utilities/verification.utility.js.map +1 -1
  94. package/dist/esm/components/socket-io/component.js +3 -3
  95. package/dist/esm/components/socket-io/component.js.map +1 -1
  96. package/dist/esm/components/socket-io/handlers/bun.handler.d.ts +13 -11
  97. package/dist/esm/components/socket-io/handlers/bun.handler.d.ts.map +1 -1
  98. package/dist/esm/components/socket-io/handlers/bun.handler.js +32 -30
  99. package/dist/esm/components/socket-io/handlers/bun.handler.js.map +1 -1
  100. package/dist/esm/components/static-asset/common/commit-token.d.ts +21 -16
  101. package/dist/esm/components/static-asset/common/commit-token.d.ts.map +1 -1
  102. package/dist/esm/components/static-asset/common/commit-token.js +35 -28
  103. package/dist/esm/components/static-asset/common/commit-token.js.map +1 -1
  104. package/dist/esm/components/static-asset/common/constants.d.ts +0 -2
  105. package/dist/esm/components/static-asset/common/constants.d.ts.map +1 -1
  106. package/dist/esm/components/static-asset/common/constants.js +1 -3
  107. package/dist/esm/components/static-asset/common/constants.js.map +1 -1
  108. package/dist/esm/components/static-asset/common/types.d.ts +0 -4
  109. package/dist/esm/components/static-asset/common/types.d.ts.map +1 -1
  110. package/dist/esm/components/static-asset/common/types.js.map +1 -1
  111. package/dist/esm/components/static-asset/component.js +2 -2
  112. package/dist/esm/components/static-asset/component.js.map +1 -1
  113. package/dist/esm/components/static-asset/controller/base.definition.d.ts +6 -6
  114. package/dist/esm/components/static-asset/controller/base.definition.d.ts.map +1 -1
  115. package/dist/esm/components/static-asset/controller/base.definition.js +224 -224
  116. package/dist/esm/components/static-asset/controller/base.definition.js.map +1 -1
  117. package/dist/esm/components/static-asset/controller/factory.d.ts +23 -23
  118. package/dist/esm/components/static-asset/controller/factory.d.ts.map +1 -1
  119. package/dist/esm/components/static-asset/controller/factory.js +105 -76
  120. package/dist/esm/components/static-asset/controller/factory.js.map +1 -1
  121. package/dist/esm/components/static-asset/controller/key-scope.d.ts +28 -26
  122. package/dist/esm/components/static-asset/controller/key-scope.d.ts.map +1 -1
  123. package/dist/esm/components/static-asset/controller/key-scope.js +34 -30
  124. package/dist/esm/components/static-asset/controller/key-scope.js.map +1 -1
  125. package/dist/esm/components/static-asset/controller/meta-link.d.ts +37 -33
  126. package/dist/esm/components/static-asset/controller/meta-link.d.ts.map +1 -1
  127. package/dist/esm/components/static-asset/controller/meta-link.js +86 -84
  128. package/dist/esm/components/static-asset/controller/meta-link.js.map +1 -1
  129. package/dist/esm/components/static-asset/controller/route-options.d.ts +18 -16
  130. package/dist/esm/components/static-asset/controller/route-options.d.ts.map +1 -1
  131. package/dist/esm/components/static-asset/controller/route-options.js +28 -26
  132. package/dist/esm/components/static-asset/controller/route-options.js.map +1 -1
  133. package/dist/esm/components/static-asset/models/base.model.js +3 -3
  134. package/dist/esm/components/static-asset/models/base.model.js.map +1 -1
  135. package/dist/esm/components/websocket/component.js +2 -2
  136. package/dist/esm/components/websocket/component.js.map +1 -1
  137. package/dist/esm/components/websocket/handlers/bun.handler.d.ts +6 -4
  138. package/dist/esm/components/websocket/handlers/bun.handler.d.ts.map +1 -1
  139. package/dist/esm/components/websocket/handlers/bun.handler.js +21 -19
  140. package/dist/esm/components/websocket/handlers/bun.handler.js.map +1 -1
  141. package/dist/esm/testing/assert-application-boots.d.ts +6 -1
  142. package/dist/esm/testing/assert-application-boots.d.ts.map +1 -1
  143. package/dist/esm/testing/assert-application-boots.js +139 -136
  144. package/dist/esm/testing/assert-application-boots.js.map +1 -1
  145. package/dist/esm/utilities/drizzle-result.utility.d.ts +6 -8
  146. package/dist/esm/utilities/drizzle-result.utility.d.ts.map +1 -1
  147. package/dist/esm/utilities/drizzle-result.utility.js +23 -49
  148. package/dist/esm/utilities/drizzle-result.utility.js.map +1 -1
  149. package/dist/esm/utilities/network.utility.d.ts.map +1 -1
  150. package/dist/esm/utilities/network.utility.js +2 -2
  151. package/dist/esm/utilities/network.utility.js.map +1 -1
  152. package/dist/presets/app/files/src/boot.test.ts +2 -2
  153. package/dist/presets/app/files/src/controllers/hello.controller.ts +2 -2
  154. package/dist/presets/app/preset.json +4 -4
  155. package/dist/presets/lib/preset.json +4 -4
  156. package/dist/presets/shared/files/.configs/formatters/.ignore +4 -0
  157. package/dist/presets/shared/files/.configs/lints/.ignore +4 -0
  158. package/dist/presets/shared/files/.configs/lints/eslint.config.mjs +4 -0
  159. package/dist/presets/shared/files/.configs/lints/oxlint.config.mts +4 -0
  160. package/dist/presets/shared/files/README.md +15 -0
  161. package/dist/presets/shared/files/src/index.test.ts +8 -0
  162. package/dist/presets/shared/files/src/index.ts +8 -0
  163. package/dist/presets/shared/files/tsconfig.json +20 -0
  164. package/dist/presets/shared/preset.json +35 -0
  165. package/package.json +11 -11
  166. package/dist/esm/components/auth/models/entities/role.model.d.ts +0 -10
  167. package/dist/esm/components/auth/models/entities/role.model.d.ts.map +0 -1
  168. package/dist/esm/components/auth/models/entities/role.model.js +0 -15
  169. package/dist/esm/components/auth/models/entities/role.model.js.map +0 -1
  170. package/dist/esm/components/auth/models/entities/user.model.d.ts +0 -28
  171. package/dist/esm/components/auth/models/entities/user.model.d.ts.map +0 -1
  172. package/dist/esm/components/auth/models/entities/user.model.js +0 -17
  173. package/dist/esm/components/auth/models/entities/user.model.js.map +0 -1
  174. package/dist/esm/components/controller/index.d.ts +0 -2
  175. package/dist/esm/components/controller/index.d.ts.map +0 -1
  176. package/dist/esm/components/controller/index.js +0 -7
  177. package/dist/esm/components/controller/index.js.map +0 -1
@@ -1,22 +1,24 @@
1
1
  import { UuidHelper } from '@venizia/ignis-helpers/core';
2
- export function createBunFetchHandler(opts) {
3
- const { wsPath, honoServer } = opts;
4
- return async (req, server) => {
5
- const url = new URL(req.url);
6
- const isWebSocketUpgrade = url.pathname === wsPath && req.headers.get('upgrade')?.toLowerCase() === 'websocket';
7
- if (!isWebSocketUpgrade) {
8
- return honoServer.fetch(req, server);
9
- }
10
- // Accept connection — authentication happens post-connect via 'authenticate' event
11
- const isUpgraded = server.upgrade(req, {
12
- data: {
13
- clientId: UuidHelper.getInstance().v4(),
14
- },
15
- });
16
- if (!isUpgraded) {
17
- return new Response('WebSocket upgrade failed', { status: 500 });
18
- }
19
- return undefined;
20
- };
2
+ export class WebSocketBunHandler {
3
+ static createFetchHandler(opts) {
4
+ const { wsPath, honoServer } = opts;
5
+ return async (req, server) => {
6
+ const url = new URL(req.url);
7
+ const isWebSocketUpgrade = url.pathname === wsPath && req.headers.get('upgrade')?.toLowerCase() === 'websocket';
8
+ if (!isWebSocketUpgrade) {
9
+ return honoServer.fetch(req, server);
10
+ }
11
+ // Accept connection - authentication happens post-connect via 'authenticate' event
12
+ const isUpgraded = server.upgrade(req, {
13
+ data: {
14
+ clientId: UuidHelper.getInstance().v4(),
15
+ },
16
+ });
17
+ if (!isUpgraded) {
18
+ return new Response('WebSocket upgrade failed', { status: 500 });
19
+ }
20
+ return undefined;
21
+ };
22
+ }
21
23
  }
22
24
  //# sourceMappingURL=bun.handler.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"bun.handler.js","sourceRoot":"","sources":["../../../../../src/components/websocket/handlers/bun.handler.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAGzD,MAAM,UAAU,qBAAqB,CAAC,IAGrC;IACC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,GAAG,IAAI,CAAC;IAEpC,OAAO,KAAK,EAAE,GAAY,EAAE,MAA0B,EAAiC,EAAE;QACvF,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAC7B,MAAM,kBAAkB,GACtB,GAAG,CAAC,QAAQ,KAAK,MAAM,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,WAAW,EAAE,KAAK,WAAW,CAAC;QAEvF,IAAI,CAAC,kBAAkB,EAAE,CAAC;YACxB,OAAO,UAAU,CAAC,KAAK,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QACvC,CAAC;QAED,mFAAmF;QACnF,MAAM,UAAU,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE;YACrC,IAAI,EAAE;gBACJ,QAAQ,EAAE,UAAU,CAAC,WAAW,EAAE,CAAC,EAAE,EAAE;aACxC;SACF,CAAC,CAAC;QAEH,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,OAAO,IAAI,QAAQ,CAAC,0BAA0B,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;QACnE,CAAC;QAED,OAAO,SAAS,CAAC;IACnB,CAAC,CAAC;AACJ,CAAC","sourcesContent":["import type { TBunServerInstance } from '@/base/applications';\nimport { UuidHelper } from '@venizia/ignis-helpers/core';\nimport type { OpenAPIHono } from '@hono/zod-openapi';\n\nexport function createBunFetchHandler(opts: {\n wsPath: string;\n honoServer: OpenAPIHono;\n}): (req: Request, server: TBunServerInstance) => Promise<Response | undefined> {\n const { wsPath, honoServer } = opts;\n\n return async (req: Request, server: TBunServerInstance): Promise<Response | undefined> => {\n const url = new URL(req.url);\n const isWebSocketUpgrade =\n url.pathname === wsPath && req.headers.get('upgrade')?.toLowerCase() === 'websocket';\n\n if (!isWebSocketUpgrade) {\n return honoServer.fetch(req, server);\n }\n\n // Accept connection — authentication happens post-connect via 'authenticate' event\n const isUpgraded = server.upgrade(req, {\n data: {\n clientId: UuidHelper.getInstance().v4(),\n },\n });\n\n if (!isUpgraded) {\n return new Response('WebSocket upgrade failed', { status: 500 });\n }\n\n return undefined;\n };\n}\n"]}
1
+ {"version":3,"file":"bun.handler.js","sourceRoot":"","sources":["../../../../../src/components/websocket/handlers/bun.handler.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAGzD,MAAM,OAAO,mBAAmB;IAC9B,MAAM,CAAC,kBAAkB,CAAC,IAGzB;QACC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,GAAG,IAAI,CAAC;QAEpC,OAAO,KAAK,EAAE,GAAY,EAAE,MAA0B,EAAiC,EAAE;YACvF,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YAC7B,MAAM,kBAAkB,GACtB,GAAG,CAAC,QAAQ,KAAK,MAAM,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,WAAW,EAAE,KAAK,WAAW,CAAC;YAEvF,IAAI,CAAC,kBAAkB,EAAE,CAAC;gBACxB,OAAO,UAAU,CAAC,KAAK,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;YACvC,CAAC;YAED,mFAAmF;YACnF,MAAM,UAAU,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE;gBACrC,IAAI,EAAE;oBACJ,QAAQ,EAAE,UAAU,CAAC,WAAW,EAAE,CAAC,EAAE,EAAE;iBACxC;aACF,CAAC,CAAC;YAEH,IAAI,CAAC,UAAU,EAAE,CAAC;gBAChB,OAAO,IAAI,QAAQ,CAAC,0BAA0B,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;YACnE,CAAC;YAED,OAAO,SAAS,CAAC;QACnB,CAAC,CAAC;IACJ,CAAC;CACF","sourcesContent":["import type { TBunServerInstance } from '@/base/applications';\nimport { UuidHelper } from '@venizia/ignis-helpers/core';\nimport type { OpenAPIHono } from '@hono/zod-openapi';\n\nexport class WebSocketBunHandler {\n static createFetchHandler(opts: {\n wsPath: string;\n honoServer: OpenAPIHono;\n }): (req: Request, server: TBunServerInstance) => Promise<Response | undefined> {\n const { wsPath, honoServer } = opts;\n\n return async (req: Request, server: TBunServerInstance): Promise<Response | undefined> => {\n const url = new URL(req.url);\n const isWebSocketUpgrade =\n url.pathname === wsPath && req.headers.get('upgrade')?.toLowerCase() === 'websocket';\n\n if (!isWebSocketUpgrade) {\n return honoServer.fetch(req, server);\n }\n\n // Accept connection - authentication happens post-connect via 'authenticate' event\n const isUpgraded = server.upgrade(req, {\n data: {\n clientId: UuidHelper.getInstance().v4(),\n },\n });\n\n if (!isUpgraded) {\n return new Response('WebSocket upgrade failed', { status: 500 });\n }\n\n return undefined;\n };\n }\n}\n"]}
@@ -52,5 +52,10 @@ export interface IAssertApplicationBootsOptions {
52
52
  * It wraps `registerDynamicBindings` and `getBootSequence` on THIS instance only (an application's
53
53
  * own override of either still runs) and restores them whatever happens.
54
54
  */
55
- export declare const assertApplicationBoots: <Application extends BaseApplication>(application: Application | (() => Application | Promise<Application>), options?: IAssertApplicationBootsOptions) => Promise<Application>;
55
+ export declare class ApplicationBootAssertion {
56
+ static assert<Application extends BaseApplication>(opts: {
57
+ application: Application | (() => Application | Promise<Application>);
58
+ options?: IAssertApplicationBootsOptions;
59
+ }): Promise<Application>;
60
+ }
56
61
  //# sourceMappingURL=assert-application-boots.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"assert-application-boots.d.ts","sourceRoot":"","sources":["../../../src/testing/assert-application-boots.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAmB,KAAK,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAC5E,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,+BAA+B,CAAC;AAarE,4HAA4H;AAC5H,MAAM,MAAM,gBAAgB,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,MAAM,CAAC;AAExD,MAAM,WAAW,8BAA8B;IAC7C;;;OAGG;IACH,eAAe,CAAC,EAAE,gBAAgB,EAAE,CAAC;IAErC;;;;OAIG;IACH,cAAc,CAAC,EAAE,gBAAgB,EAAE,CAAC;IAEpC;;;;OAIG;IACH,SAAS,CAAC,EAAE,eAAe,EAAE,CAAC;IAE9B;;;;OAIG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;IAEzB;;;OAGG;IACH,YAAY,CAAC,EAAE,gBAAgB,EAAE,CAAC;IAElC,mIAAmI;IACnI,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAE7B,yHAAyH;IACzH,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAiJD;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,sBAAsB,GAAU,WAAW,SAAS,eAAe,EAC9E,aAAa,WAAW,GAAG,CAAC,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,EACrE,UAAS,8BAAmC,KAC3C,OAAO,CAAC,WAAW,CA0MrB,CAAC"}
1
+ {"version":3,"file":"assert-application-boots.d.ts","sourceRoot":"","sources":["../../../src/testing/assert-application-boots.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAmB,KAAK,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAC5E,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,+BAA+B,CAAC;AAarE,4HAA4H;AAC5H,MAAM,MAAM,gBAAgB,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,MAAM,CAAC;AAExD,MAAM,WAAW,8BAA8B;IAC7C;;;OAGG;IACH,eAAe,CAAC,EAAE,gBAAgB,EAAE,CAAC;IAErC;;;;OAIG;IACH,cAAc,CAAC,EAAE,gBAAgB,EAAE,CAAC;IAEpC;;;;OAIG;IACH,SAAS,CAAC,EAAE,eAAe,EAAE,CAAC;IAE9B;;;;OAIG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;IAEzB;;;OAGG;IACH,YAAY,CAAC,EAAE,gBAAgB,EAAE,CAAC;IAElC,mIAAmI;IACnI,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAE7B,yHAAyH;IACzH,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAiJD;;;;;;;;;;;;;;GAcG;AACH,qBAAa,wBAAwB;WACtB,MAAM,CAAC,WAAW,SAAS,eAAe,EAAE,IAAI,EAAE;QAC7D,WAAW,EAAE,WAAW,GAAG,CAAC,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC;QACtE,OAAO,CAAC,EAAE,8BAA8B,CAAC;KAC1C,GAAG,OAAO,CAAC,WAAW,CAAC;CA4MzB"}
@@ -1,6 +1,6 @@
1
1
  import { ServerBootSteps } from '../base/applications/index.js';
2
2
  import { getError } from '@venizia/ignis-helpers/core';
3
- import { assertBindingsResolve } from '@venizia/ignis-inversion';
3
+ import { BindingVerifier } from '@venizia/ignis-inversion';
4
4
  import { BindingNamespaces, BindingValueTypes, ControllerTransports, CoreBindings, MetadataRegistry, } from '@venizia/ignis-kernel';
5
5
  /** The boot sequence is the contract; these two are what the helper wraps on one instance. */
6
6
  const WRAPPED_METHODS = ['registerDynamicBindings', 'getBootSequence'];
@@ -19,7 +19,7 @@ const matchesTarget = (opts) => {
19
19
  : instance?.constructor === target);
20
20
  };
21
21
  const fail = (message) => {
22
- throw getError({ message: `[assertApplicationBoots] ${message}` });
22
+ throw getError({ message: `[ApplicationBootAssertion.assert] ${message}` });
23
23
  };
24
24
  /** Replaces `object[name]` and returns the way back, even when `name` was inherited. */
25
25
  const patchProperty = (opts) => {
@@ -109,149 +109,152 @@ const assertNoDuplicateRoutes = (opts) => {
109
109
  * It wraps `registerDynamicBindings` and `getBootSequence` on THIS instance only (an application's
110
110
  * own override of either still runs) and restores them whatever happens.
111
111
  */
112
- export const assertApplicationBoots = async (application, options = {}) => {
113
- const { keepDataSources = [], skipComponents = [], skipSteps = DEFAULT_SKIPPED_STEPS, verifyBindings = true, skipBindings = [], allowNoControllers = false, routes = true, } = options;
114
- for (const step of skipSteps) {
115
- if (!ServerBootSteps.isValid(step)) {
116
- fail(`Unknown boot step in skipSteps: '${String(step)}' | Expected one of: ${[...ServerBootSteps.SCHEME_SET].join(', ')}`);
112
+ export class ApplicationBootAssertion {
113
+ static async assert(opts) {
114
+ const { application, options = {} } = opts;
115
+ const { keepDataSources = [], skipComponents = [], skipSteps = DEFAULT_SKIPPED_STEPS, verifyBindings = true, skipBindings = [], allowNoControllers = false, routes = true, } = options;
116
+ for (const step of skipSteps) {
117
+ if (!ServerBootSteps.isValid(step)) {
118
+ fail(`Unknown boot step in skipSteps: '${String(step)}' | Expected one of: ${[...ServerBootSteps.SCHEME_SET].join(', ')}`);
119
+ }
117
120
  }
118
- }
119
- let target;
120
- if (typeof application === 'function') {
121
- const built = await application();
122
- target = built;
123
- }
124
- else {
125
- target = application;
126
- }
127
- if (bootedApplications.has(target) ||
128
- Object.keys(target['registeredBindings'] ?? {}).length > 0) {
129
- fail(`This application instance was already booted | A failed or finished boot leaves registrations behind, so build a new instance (pass a factory) for each call`);
130
- }
131
- bootedApplications.add(target);
132
- for (const name of WRAPPED_METHODS) {
133
- if (typeof target[name] !== 'function') {
134
- fail(`The kernel method '${name}' is missing on this application | The helper cannot keep a boot offline without it, so it refuses to boot`);
121
+ let target;
122
+ if (typeof application === 'function') {
123
+ const built = await application();
124
+ target = built;
135
125
  }
136
- }
137
- const skippedSteps = new Set(skipSteps);
138
- const patches = [];
139
- let sweepsSeen = 0;
140
- // The components whose `configure()` is running, innermost last: when the boot rejects, the last one is where it failed.
141
- const configuringComponents = [];
142
- const neutralise = async (opts) => {
143
- const { namespace, binding } = opts;
144
- const isDataSource = namespace === BindingNamespaces.DATASOURCE;
145
- const isComponent = namespace === BindingNamespaces.COMPONENT;
146
- if (!isDataSource && !isComponent) {
147
- return;
148
- }
149
- const instance = target.get({ key: binding.key, isOptional: false });
150
- if (typeof instance?.configure !== 'function') {
151
- return;
126
+ else {
127
+ target = application;
152
128
  }
153
- const shouldRun = isDataSource
154
- ? matchesTarget({ targets: keepDataSources, binding, instance })
155
- : !matchesTarget({ targets: skipComponents, binding, instance });
156
- if (shouldRun) {
157
- return;
129
+ if (bootedApplications.has(target) ||
130
+ Object.keys(target['registeredBindings'] ?? {}).length > 0) {
131
+ fail(`This application instance was already booted | A failed or finished boot leaves registrations behind, so build a new instance (pass a factory) for each call`);
158
132
  }
159
- patches.push(patchProperty({ object: instance, name: 'configure', value: async () => { } }));
160
- };
161
- const originalRegisterDynamicBindings = target['registerDynamicBindings'];
162
- const originalGetBootSequence = target['getBootSequence'];
163
- const wrappedRegister = async (opts) => {
164
- sweepsSeen += 1;
165
- const userBefore = opts.onBeforeConfigure;
166
- const userAfter = opts.onAfterConfigure;
167
- return originalRegisterDynamicBindings.call(target, {
168
- ...opts,
169
- onBeforeConfigure: async ({ binding }) => {
170
- await neutralise({ namespace: opts.namespace, binding });
171
- if (opts.namespace === BindingNamespaces.COMPONENT) {
172
- const instance = target.get({ key: binding.key, isOptional: true });
173
- configuringComponents.push(String(instance?.constructor?.name ?? binding.key));
174
- }
175
- await userBefore?.({ binding });
176
- },
177
- onAfterConfigure: async ({ binding, instance }) => {
178
- if (opts.namespace === BindingNamespaces.COMPONENT) {
179
- configuringComponents.pop();
180
- }
181
- await userAfter?.({ binding, instance });
182
- },
183
- });
184
- };
185
- patches.push(patchProperty({ object: target, name: 'registerDynamicBindings', value: wrappedRegister }));
186
- patches.push(patchProperty({
187
- object: target,
188
- name: 'getBootSequence',
189
- value: () => originalGetBootSequence.call(target).filter((step) => !skippedSteps.has(step.name)),
190
- }));
191
- if (target['registerDynamicBindings'] !== wrappedRegister) {
192
- patches.forEach((patch) => patch.restore());
193
- fail(`The wrap of 'registerDynamicBindings' did not take effect | Refusing to boot against real infrastructure`);
194
- }
195
- const configs = target['configs'];
196
- const originalBootChecks = configs.bootChecks;
197
- const originalBinding = originalBootChecks?.binding;
198
- configs.bootChecks = {
199
- ...originalBootChecks,
200
- binding: {
201
- allowManual: originalBinding?.allowManual ?? true,
202
- allowOverride: originalBinding?.allowOverride ?? true,
203
- doVerify: false,
204
- },
205
- };
206
- try {
207
- if (!target.isBound({ key: CoreBindings.APPLICATION_INSTANCE })) {
208
- target.init();
209
- }
210
- await target.initialize();
211
- const sweepsExpected = [
212
- ServerBootSteps.REGISTER_DATA_SOURCES,
213
- ServerBootSteps.REGISTER_COMPONENTS,
214
- ServerBootSteps.REGISTER_CONTRIBUTED_DATA_SOURCES,
215
- ].some((step) => !skippedSteps.has(step));
216
- if (sweepsExpected && sweepsSeen === 0) {
217
- fail(`The boot never went through 'registerDynamicBindings' | The wrap did not take effect, so datasources may have been configured`);
133
+ bootedApplications.add(target);
134
+ for (const name of WRAPPED_METHODS) {
135
+ if (typeof target[name] !== 'function') {
136
+ fail(`The kernel method '${name}' is missing on this application | The helper cannot keep a boot offline without it, so it refuses to boot`);
137
+ }
218
138
  }
219
- if (verifyBindings) {
220
- assertBindingsResolve({
221
- container: target,
222
- namespaces: [BindingNamespaces.SERVICE, BindingNamespaces.REPOSITORY],
223
- skip: skipBindings,
224
- scope: 'verifyBindings',
139
+ const skippedSteps = new Set(skipSteps);
140
+ const patches = [];
141
+ let sweepsSeen = 0;
142
+ // The components whose `configure()` is running, innermost last: when the boot rejects, the last one is where it failed.
143
+ const configuringComponents = [];
144
+ const neutralise = async (entry) => {
145
+ const { namespace, binding } = entry;
146
+ const isDataSource = namespace === BindingNamespaces.DATASOURCE;
147
+ const isComponent = namespace === BindingNamespaces.COMPONENT;
148
+ if (!isDataSource && !isComponent) {
149
+ return;
150
+ }
151
+ const instance = target.get({ key: binding.key, isOptional: false });
152
+ if (typeof instance?.configure !== 'function') {
153
+ return;
154
+ }
155
+ const shouldRun = isDataSource
156
+ ? matchesTarget({ targets: keepDataSources, binding, instance })
157
+ : !matchesTarget({ targets: skipComponents, binding, instance });
158
+ if (shouldRun) {
159
+ return;
160
+ }
161
+ patches.push(patchProperty({ object: instance, name: 'configure', value: async () => { } }));
162
+ };
163
+ const originalRegisterDynamicBindings = target['registerDynamicBindings'];
164
+ const originalGetBootSequence = target['getBootSequence'];
165
+ const wrappedRegister = async (sweepOptions) => {
166
+ sweepsSeen += 1;
167
+ const userBefore = sweepOptions.onBeforeConfigure;
168
+ const userAfter = sweepOptions.onAfterConfigure;
169
+ return originalRegisterDynamicBindings.call(target, {
170
+ ...sweepOptions,
171
+ onBeforeConfigure: async ({ binding }) => {
172
+ await neutralise({ namespace: sweepOptions.namespace, binding });
173
+ if (sweepOptions.namespace === BindingNamespaces.COMPONENT) {
174
+ const instance = target.get({ key: binding.key, isOptional: true });
175
+ configuringComponents.push(String(instance?.constructor?.name ?? binding.key));
176
+ }
177
+ await userBefore?.({ binding });
178
+ },
179
+ onAfterConfigure: async ({ binding, instance }) => {
180
+ if (sweepOptions.namespace === BindingNamespaces.COMPONENT) {
181
+ configuringComponents.pop();
182
+ }
183
+ await userAfter?.({ binding, instance });
184
+ },
225
185
  });
186
+ };
187
+ patches.push(patchProperty({ object: target, name: 'registerDynamicBindings', value: wrappedRegister }));
188
+ patches.push(patchProperty({
189
+ object: target,
190
+ name: 'getBootSequence',
191
+ value: () => originalGetBootSequence.call(target).filter((step) => !skippedSteps.has(step.name)),
192
+ }));
193
+ if (target['registerDynamicBindings'] !== wrappedRegister) {
194
+ patches.forEach((patch) => patch.restore());
195
+ fail(`The wrap of 'registerDynamicBindings' did not take effect | Refusing to boot against real infrastructure`);
226
196
  }
227
- if (!allowNoControllers &&
228
- target.findByTag({ tag: BindingNamespaces.CONTROLLER }).length === 0) {
229
- fail(`The application registered no controller | A boot that registers nothing proves nothing: check the artifact index (for example the AutoArtifacts plugin under 'bun test'), or pass { allowNoControllers: true }`);
230
- }
231
- if (routes) {
232
- assertNoDuplicateRoutes({ application: target });
233
- }
234
- return target;
235
- }
236
- catch (error) {
237
- const failing = configuringComponents.at(-1);
238
- if (failing) {
239
- target.logger
240
- .for('assertApplicationBoots')
241
- .warn(`The boot failed inside component ${failing} | If it needs infrastructure, skipComponents: ['${failing}'] skips it, and skipBindings lists the services that depend on it`);
242
- }
243
- throw error;
244
- }
245
- finally {
246
- for (const patch of patches.reverse()) {
247
- patch.restore();
197
+ const configs = target['configs'];
198
+ const originalBootChecks = configs.bootChecks;
199
+ const originalBinding = originalBootChecks?.binding;
200
+ configs.bootChecks = {
201
+ ...originalBootChecks,
202
+ binding: {
203
+ allowManual: originalBinding?.allowManual ?? true,
204
+ allowOverride: originalBinding?.allowOverride ?? true,
205
+ doVerify: false,
206
+ },
207
+ };
208
+ try {
209
+ if (!target.isBound({ key: CoreBindings.APPLICATION_INSTANCE })) {
210
+ target.init();
211
+ }
212
+ await target.initialize();
213
+ const sweepsExpected = [
214
+ ServerBootSteps.REGISTER_DATA_SOURCES,
215
+ ServerBootSteps.REGISTER_COMPONENTS,
216
+ ServerBootSteps.REGISTER_CONTRIBUTED_DATA_SOURCES,
217
+ ].some((step) => !skippedSteps.has(step));
218
+ if (sweepsExpected && sweepsSeen === 0) {
219
+ fail(`The boot never went through 'registerDynamicBindings' | The wrap did not take effect, so datasources may have been configured`);
220
+ }
221
+ if (verifyBindings) {
222
+ BindingVerifier.assertResolve({
223
+ container: target,
224
+ namespaces: [BindingNamespaces.SERVICE, BindingNamespaces.REPOSITORY],
225
+ skip: skipBindings,
226
+ scope: 'verifyBindings',
227
+ });
228
+ }
229
+ if (!allowNoControllers &&
230
+ target.findByTag({ tag: BindingNamespaces.CONTROLLER }).length === 0) {
231
+ fail(`The application registered no controller | A boot that registers nothing proves nothing: check the artifact index (for example the AutoArtifacts plugin under 'bun test'), or pass { allowNoControllers: true }`);
232
+ }
233
+ if (routes) {
234
+ assertNoDuplicateRoutes({ application: target });
235
+ }
236
+ return target;
248
237
  }
249
- if (originalBootChecks === undefined) {
250
- delete configs.bootChecks;
238
+ catch (error) {
239
+ const failing = configuringComponents.at(-1);
240
+ if (failing) {
241
+ target.logger
242
+ .for('ApplicationBootAssertion.assert')
243
+ .warn(`The boot failed inside component ${failing} | If it needs infrastructure, skipComponents: ['${failing}'] skips it, and skipBindings lists the services that depend on it`);
244
+ }
245
+ throw error;
251
246
  }
252
- else {
253
- configs.bootChecks = originalBootChecks;
247
+ finally {
248
+ for (const patch of patches.reverse()) {
249
+ patch.restore();
250
+ }
251
+ if (originalBootChecks === undefined) {
252
+ delete configs.bootChecks;
253
+ }
254
+ else {
255
+ configs.bootChecks = originalBootChecks;
256
+ }
254
257
  }
255
258
  }
256
- };
259
+ }
257
260
  //# sourceMappingURL=assert-application-boots.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"assert-application-boots.js","sourceRoot":"","sources":["../../../src/testing/assert-application-boots.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAwB,MAAM,qBAAqB,CAAC;AAE5E,OAAO,EAAE,QAAQ,EAAE,MAAM,6BAA6B,CAAC;AACvD,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AACjE,OAAO,EAGL,iBAAiB,EACjB,iBAAiB,EACjB,oBAAoB,EACpB,YAAY,EACZ,gBAAgB,GACjB,MAAM,uBAAuB,CAAC;AA8C/B,8FAA8F;AAC9F,MAAM,eAAe,GAAG,CAAC,yBAAyB,EAAE,iBAAiB,CAAU,CAAC;AAEhF,MAAM,qBAAqB,GAAsB;IAC/C,eAAe,CAAC,eAAe;IAC/B,eAAe,CAAC,sBAAsB;CACvC,CAAC;AAEF,kFAAkF;AAClF,MAAM,gBAAgB,GAAG,KAAK,CAAC;AAE/B,MAAM,kBAAkB,GAAG,IAAI,OAAO,EAAU,CAAC;AAiBjD,MAAM,aAAa,GAAG,CAAC,IAItB,EAAW,EAAE;IACZ,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC;IAC5C,MAAM,SAAS,GAAuB,QAAQ,EAAE,WAAW,EAAE,IAAI,CAAC;IAElE,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAC7B,OAAO,MAAM,KAAK,QAAQ;QACxB,CAAC,CAAC,MAAM,KAAK,OAAO,CAAC,GAAG,IAAI,MAAM,KAAK,SAAS;QAChD,CAAC,CAAC,QAAQ,EAAE,WAAW,KAAK,MAAM,CACrC,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,IAAI,GAAG,CAAC,OAAe,EAAS,EAAE;IACtC,MAAM,QAAQ,CAAC,EAAE,OAAO,EAAE,4BAA4B,OAAO,EAAE,EAAE,CAAC,CAAC;AACrE,CAAC,CAAC;AAEF,wFAAwF;AACxF,MAAM,aAAa,GAAG,CAAC,IAAuD,EAAU,EAAE;IACxF,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC;IACrC,MAAM,UAAU,GAAG,MAAM,CAAC,wBAAwB,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAEjE,MAAM,CAAC,cAAc,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,YAAY,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;IAEnF,OAAO;QACL,OAAO,EAAE,GAAG,EAAE;YACZ,IAAI,UAAU,EAAE,CAAC;gBACf,MAAM,CAAC,cAAc,CAAC,MAAM,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC;gBAChD,OAAO;YACT,CAAC;YAED,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC;QACtB,CAAC;KACF,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,aAAa,GAAG,CAAC,IAAY,EAAU,EAAE;IAC7C,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,iBAAiB,EAAE,QAAQ,CAAC,CAAC,OAAO,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;IACrF,OAAO,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC;AAC5E,CAAC,CAAC;AAEF,8GAA8G;AAC9G,MAAM,uBAAuB,GAAG,CAAC,IAAsC,EAAQ,EAAE;IAC/E,MAAM,EAAE,WAAW,EAAE,GAAG,IAAI,CAAC;IAC7B,4EAA4E;IAC5E,MAAM,OAAO,GAAG,IAAI,GAAG,EAA+B,CAAC;IACvD,MAAM,MAAM,GAAG,CAAC,SAAiB,EAAE,GAAW,EAAE,YAAoB,EAAQ,EAAE;QAC5E,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,IAAI,GAAG,EAAkB,CAAC;QACnE,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,YAAY,CAAC,CAAC,CAAC;QAC9D,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;IACjC,CAAC,CAAC;IAEF,KAAK,MAAM,OAAO,IAAI,WAAW,CAAC,SAAS,CAAyB;QAClE,GAAG,EAAE,iBAAiB,CAAC,UAAU;KAClC,CAAC,EAAE,CAAC;QACH,MAAM,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,EAAE,IAAI,EAAE,iBAAiB,CAAC,KAAK,EAAE,CAAC,CAAC;QACzE,MAAM,QAAQ,GAAG,MAAM;YACrB,CAAC,CAAC,gBAAgB,CAAC,WAAW,EAAE,CAAC,qBAAqB,CAAC,EAAE,MAAM,EAAE,CAAC;YAClE,CAAC,CAAC,SAAS,CAAC;QAEd,IAAI,CAAC,QAAQ,EAAE,IAAI,IAAI,QAAQ,CAAC,SAAS,KAAK,oBAAoB,CAAC,IAAI,EAAE,CAAC;YACxE,SAAS;QACX,CAAC;QAED,MAAM,QAAQ,GAAG,WAAW,CAAC,GAAG,CAAyB;YACvD,GAAG,EAAE,OAAO,CAAC,GAAG;YAChB,UAAU,EAAE,IAAI;SACjB,CAAC,CAAC;QACH,iHAAiH;QACjH,oHAAoH;QACpH,KAAK,MAAM,KAAK,IAAI,QAAQ,EAAE,SAAS,EAAE,CAAC,MAAM,IAAI,EAAE,EAAE,CAAC;YACvD,IAAI,KAAK,CAAC,MAAM,KAAK,gBAAgB,EAAE,CAAC;gBACtC,SAAS;YACX,CAAC;YAED,MAAM,CAAC,GAAG,KAAK,CAAC,MAAM,IAAI,aAAa,CAAC,GAAG,QAAQ,CAAC,IAAI,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QAC/F,CAAC;QAED,0GAA0G;QAC1G,8DAA8D;QAC9D,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAkB,CAAC;QAC3C,KAAK,MAAM,KAAK,IAAI,gBAAgB,CAAC,WAAW,EAAE;aAC/C,SAAS,CAAC,EAAE,MAAM,EAAG,MAA0B,CAAC,SAAS,EAAE,CAAC;YAC7D,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,CAAC;YACnB,MAAM,SAAS,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,WAAW,EAAE,IAAI,aAAa,CAAC,GAAG,QAAQ,CAAC,IAAI,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC;YAC7G,QAAQ,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QAC9D,CAAC;QACD,KAAK,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,IAAI,QAAQ,EAAE,CAAC;YACjD,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;QAC/C,CAAC;IACH,CAAC;IAED,MAAM,UAAU,GAAG,CAAC,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,MAAM,CAC9C,CAAC,CAAC,EAAE,MAAM,CAAC,EAAE,EAAE,CACb,MAAM,CAAC,IAAI,GAAG,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,YAAY,EAAE,EAAE,CAAC,YAAY,GAAG,CAAC,CAAC,CACnF,CAAC;IACF,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC5B,OAAO;IACT,CAAC;IAED,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,CAC1B,CAAC,CAAC,SAAS,EAAE,MAAM,CAAC,EAAE,EAAE,CACtB,GAAG,SAAS,mBAAmB,CAAC,GAAG,MAAM,CAAC;SACvC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,YAAY,CAAC,EAAE,EAAE,CAC3B,YAAY,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,cAAc,YAAY,SAAS,CAAC,CAAC,CAAC,GAAG,CACnE;SACA,IAAI,CAAC,IAAI,CAAC,EAAE,CAClB,CAAC;IACF,IAAI,CACF,GAAG,UAAU,CAAC,MAAM,0EAA0E,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,0GAA0G,CAC1N,CAAC;AACJ,CAAC,CAAC;AAEF;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,KAAK,EACzC,WAAqE,EACrE,UAA0C,EAAE,EACtB,EAAE;IACxB,MAAM,EACJ,eAAe,GAAG,EAAE,EACpB,cAAc,GAAG,EAAE,EACnB,SAAS,GAAG,qBAAqB,EACjC,cAAc,GAAG,IAAI,EACrB,YAAY,GAAG,EAAE,EACjB,kBAAkB,GAAG,KAAK,EAC1B,MAAM,GAAG,IAAI,GACd,GAAG,OAAO,CAAC;IAEZ,KAAK,MAAM,IAAI,IAAI,SAAS,EAAE,CAAC;QAC7B,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;YACnC,IAAI,CACF,oCAAoC,MAAM,CAAC,IAAI,CAAC,wBAAwB,CAAC,GAAG,eAAe,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CACrH,CAAC;QACJ,CAAC;IACH,CAAC;IAED,IAAI,MAAmB,CAAC;IACxB,IAAI,OAAO,WAAW,KAAK,UAAU,EAAE,CAAC;QACtC,MAAM,KAAK,GAAG,MAAM,WAAW,EAAE,CAAC;QAClC,MAAM,GAAG,KAAK,CAAC;IACjB,CAAC;SAAM,CAAC;QACN,MAAM,GAAG,WAAW,CAAC;IACvB,CAAC;IAED,IACE,kBAAkB,CAAC,GAAG,CAAC,MAAM,CAAC;QAC9B,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,oBAAoB,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,GAAG,CAAC,EAC1D,CAAC;QACD,IAAI,CACF,8JAA8J,CAC/J,CAAC;IACJ,CAAC;IACD,kBAAkB,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IAE/B,KAAK,MAAM,IAAI,IAAI,eAAe,EAAE,CAAC;QACnC,IAAI,OAAO,MAAM,CAAC,IAAI,CAAC,KAAK,UAAU,EAAE,CAAC;YACvC,IAAI,CACF,sBAAsB,IAAI,4GAA4G,CACvI,CAAC;QACJ,CAAC;IACH,CAAC;IAED,MAAM,YAAY,GAAG,IAAI,GAAG,CAAS,SAAS,CAAC,CAAC;IAChD,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,IAAI,UAAU,GAAG,CAAC,CAAC;IACnB,yHAAyH;IACzH,MAAM,qBAAqB,GAAa,EAAE,CAAC;IAE3C,MAAM,UAAU,GAAG,KAAK,EAAE,IAGzB,EAAiB,EAAE;QAClB,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;QACpC,MAAM,YAAY,GAAG,SAAS,KAAK,iBAAiB,CAAC,UAAU,CAAC;QAChE,MAAM,WAAW,GAAG,SAAS,KAAK,iBAAiB,CAAC,SAAS,CAAC;QAC9D,IAAI,CAAC,YAAY,IAAI,CAAC,WAAW,EAAE,CAAC;YAClC,OAAO;QACT,CAAC;QAED,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAU,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC,CAAC;QAC9E,IAAI,OAAO,QAAQ,EAAE,SAAS,KAAK,UAAU,EAAE,CAAC;YAC9C,OAAO;QACT,CAAC;QAED,MAAM,SAAS,GAAG,YAAY;YAC5B,CAAC,CAAC,aAAa,CAAC,EAAE,OAAO,EAAE,eAAe,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC;YAChE,CAAC,CAAC,CAAC,aAAa,CAAC,EAAE,OAAO,EAAE,cAAc,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC,CAAC;QACnE,IAAI,SAAS,EAAE,CAAC;YACd,OAAO;QACT,CAAC;QAED,OAAO,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,KAAK,IAAI,EAAE,GAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IAC9F,CAAC,CAAC;IAEF,MAAM,+BAA+B,GAAG,MAAM,CAAC,yBAAyB,CAEtD,CAAC;IACnB,MAAM,uBAAuB,GAAG,MAAM,CAAC,iBAAiB,CAEtD,CAAC;IAEH,MAAM,eAAe,GAAG,KAAK,EAAE,IAA6B,EAAiB,EAAE;QAC7E,UAAU,IAAI,CAAC,CAAC;QAChB,MAAM,UAAU,GAAG,IAAI,CAAC,iBAAiB,CAAC;QAC1C,MAAM,SAAS,GAAG,IAAI,CAAC,gBAAgB,CAAC;QAExC,OAAO,+BAA+B,CAAC,IAAI,CAAC,MAAM,EAAE;YAClD,GAAG,IAAI;YACP,iBAAiB,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE;gBACvC,MAAM,UAAU,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,OAAO,EAAE,CAAC,CAAC;gBACzD,IAAI,IAAI,CAAC,SAAS,KAAK,iBAAiB,CAAC,SAAS,EAAE,CAAC;oBACnD,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAU,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC;oBAC7E,qBAAqB,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,WAAW,EAAE,IAAI,IAAI,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC;gBACjF,CAAC;gBACD,MAAM,UAAU,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC;YAClC,CAAC;YACD,gBAAgB,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE;gBAChD,IAAI,IAAI,CAAC,SAAS,KAAK,iBAAiB,CAAC,SAAS,EAAE,CAAC;oBACnD,qBAAqB,CAAC,GAAG,EAAE,CAAC;gBAC9B,CAAC;gBACD,MAAM,SAAS,EAAE,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC,CAAC;YAC3C,CAAC;SACF,CAAC,CAAC;IACL,CAAC,CAAC;IAEF,OAAO,CAAC,IAAI,CACV,aAAa,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,yBAAyB,EAAE,KAAK,EAAE,eAAe,EAAE,CAAC,CAC3F,CAAC;IACF,OAAO,CAAC,IAAI,CACV,aAAa,CAAC;QACZ,MAAM,EAAE,MAAM;QACd,IAAI,EAAE,iBAAiB;QACvB,KAAK,EAAE,GAAG,EAAE,CACV,uBAAuB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;KACtF,CAAC,CACH,CAAC;IAEF,IAAK,MAAM,CAAC,yBAAyB,CAAa,KAAK,eAAe,EAAE,CAAC;QACvE,OAAO,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;QAC5C,IAAI,CACF,0GAA0G,CAC3G,CAAC;IACJ,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC;IAClC,MAAM,kBAAkB,GAAG,OAAO,CAAC,UAAU,CAAC;IAC9C,MAAM,eAAe,GAAG,kBAAkB,EAAE,OAAO,CAAC;IACpD,OAAO,CAAC,UAAU,GAAG;QACnB,GAAG,kBAAkB;QACrB,OAAO,EAAE;YACP,WAAW,EAAE,eAAe,EAAE,WAAW,IAAI,IAAI;YACjD,aAAa,EAAE,eAAe,EAAE,aAAa,IAAI,IAAI;YACrD,QAAQ,EAAE,KAAK;SAChB;KACF,CAAC;IAEF,IAAI,CAAC;QACH,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,GAAG,EAAE,YAAY,CAAC,oBAAoB,EAAE,CAAC,EAAE,CAAC;YAChE,MAAM,CAAC,IAAI,EAAE,CAAC;QAChB,CAAC;QAED,MAAM,MAAM,CAAC,UAAU,EAAE,CAAC;QAE1B,MAAM,cAAc,GAAG;YACrB,eAAe,CAAC,qBAAqB;YACrC,eAAe,CAAC,mBAAmB;YACnC,eAAe,CAAC,iCAAiC;SAClD,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;QAC1C,IAAI,cAAc,IAAI,UAAU,KAAK,CAAC,EAAE,CAAC;YACvC,IAAI,CACF,+HAA+H,CAChI,CAAC;QACJ,CAAC;QAED,IAAI,cAAc,EAAE,CAAC;YACnB,qBAAqB,CAAC;gBACpB,SAAS,EAAE,MAAM;gBACjB,UAAU,EAAE,CAAC,iBAAiB,CAAC,OAAO,EAAE,iBAAiB,CAAC,UAAU,CAAC;gBACrE,IAAI,EAAE,YAAY;gBAClB,KAAK,EAAE,gBAAgB;aACxB,CAAC,CAAC;QACL,CAAC;QAED,IACE,CAAC,kBAAkB;YACnB,MAAM,CAAC,SAAS,CAAC,EAAE,GAAG,EAAE,iBAAiB,CAAC,UAAU,EAAE,CAAC,CAAC,MAAM,KAAK,CAAC,EACpE,CAAC;YACD,IAAI,CACF,iNAAiN,CAClN,CAAC;QACJ,CAAC;QAED,IAAI,MAAM,EAAE,CAAC;YACX,uBAAuB,CAAC,EAAE,WAAW,EAAE,MAAM,EAAE,CAAC,CAAC;QACnD,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,OAAO,GAAG,qBAAqB,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QAC7C,IAAI,OAAO,EAAE,CAAC;YACZ,MAAM,CAAC,MAAM;iBACV,GAAG,CAAC,wBAAwB,CAAC;iBAC7B,IAAI,CACH,oCAAoC,OAAO,oDAAoD,OAAO,oEAAoE,CAC3K,CAAC;QACN,CAAC;QAED,MAAM,KAAK,CAAC;IACd,CAAC;YAAS,CAAC;QACT,KAAK,MAAM,KAAK,IAAI,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC;YACtC,KAAK,CAAC,OAAO,EAAE,CAAC;QAClB,CAAC;QAED,IAAI,kBAAkB,KAAK,SAAS,EAAE,CAAC;YACrC,OAAO,OAAO,CAAC,UAAU,CAAC;QAC5B,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,UAAU,GAAG,kBAAkB,CAAC;QAC1C,CAAC;IACH,CAAC;AACH,CAAC,CAAC","sourcesContent":["import type { BaseApplication } from '@/base/applications';\nimport { ServerBootSteps, type TServerBootStep } from '@/base/applications';\nimport type { AnyType, TClass } from '@venizia/ignis-helpers/common';\nimport { getError } from '@venizia/ignis-helpers/core';\nimport { assertBindingsResolve } from '@venizia/ignis-inversion';\nimport {\n type AbstractRestController,\n type Binding,\n BindingNamespaces,\n BindingValueTypes,\n ControllerTransports,\n CoreBindings,\n MetadataRegistry,\n} from '@venizia/ignis-kernel';\n\n/** A class (matched against the instance's constructor) or a string (matched against the binding key or the class name). */\nexport type TBootProbeTarget = TClass<AnyType> | string;\n\nexport interface IAssertApplicationBootsOptions {\n /**\n * Datasources whose real `configure()` runs. Every other datasource is bound and resolved but not\n * configured, so no connection is made. Close a kept one with `await application.stop()`.\n */\n keepDataSources?: TBootProbeTarget[];\n\n /**\n * Components whose `configure()` (and so their `binding()`) is skipped, for the few that need\n * infrastructure. Components run by default. What a skipped component would have registered is\n * not registered.\n */\n skipComponents?: TBootProbeTarget[];\n\n /**\n * Boot steps that do not run. Default: `hydrateSecrets` and `wireSecretRotatables`, so a remote\n * secrets provider is never contacted. A value REPLACES the default; an unknown name rejects\n * before anything boots.\n */\n skipSteps?: TServerBootStep[];\n\n /**\n * Default `true`: after boot, resolves every service and repository with the shared core of\n * `@venizia/ignis-inversion`, so an injection nobody references at boot still fails. An explicit value\n * wins over the application's own `bootChecks`, whose boot step is off for the run.\n */\n verifyBindings?: boolean;\n\n /**\n * Services or repositories the verification leaves unresolved, for one whose constructor needs\n * infrastructure. A class (exact), a class name or a binding key. A name that matches nothing rejects.\n */\n skipBindings?: TBootProbeTarget[];\n\n /** Default `false`: an application that registered no controller proves nothing, for example when the artifact index was empty. */\n allowNoControllers?: boolean;\n\n /** Default `true`: this helper's own check that no method and path is mounted twice. IGNIS boot does not detect that. */\n routes?: boolean;\n}\n\n/** The boot sequence is the contract; these two are what the helper wraps on one instance. */\nconst WRAPPED_METHODS = ['registerDynamicBindings', 'getBootSequence'] as const;\n\nconst DEFAULT_SKIPPED_STEPS: TServerBootStep[] = [\n ServerBootSteps.HYDRATE_SECRETS,\n ServerBootSteps.WIRE_SECRET_ROTATABLES,\n];\n\n/** Methods a route entry may carry that are middleware, not a mounted handler. */\nconst NON_ROUTE_METHOD = 'ALL';\n\nconst bootedApplications = new WeakSet<object>();\n\ninterface IProbeBinding {\n key: string;\n}\n\ninterface IDynamicBindingsOptions {\n namespace: string;\n onBeforeConfigure?: (opts: { binding: Binding<AnyType> }) => Promise<void>;\n onAfterConfigure?: (opts: { binding: Binding<AnyType>; instance: AnyType }) => Promise<void>;\n}\n\n/** What the helper replaced, so every path puts it back. */\ninterface IPatch {\n restore: () => void;\n}\n\nconst matchesTarget = (opts: {\n targets: TBootProbeTarget[];\n binding: IProbeBinding;\n instance: AnyType;\n}): boolean => {\n const { targets, binding, instance } = opts;\n const className: string | undefined = instance?.constructor?.name;\n\n return targets.some((target) =>\n typeof target === 'string'\n ? target === binding.key || target === className\n : instance?.constructor === target,\n );\n};\n\nconst fail = (message: string): never => {\n throw getError({ message: `[assertApplicationBoots] ${message}` });\n};\n\n/** Replaces `object[name]` and returns the way back, even when `name` was inherited. */\nconst patchProperty = (opts: { object: AnyType; name: string; value: unknown }): IPatch => {\n const { object, name, value } = opts;\n const descriptor = Object.getOwnPropertyDescriptor(object, name);\n\n Object.defineProperty(object, name, { value, configurable: true, writable: true });\n\n return {\n restore: () => {\n if (descriptor) {\n Object.defineProperty(object, name, descriptor);\n return;\n }\n\n delete object[name];\n },\n };\n};\n\nconst normalizePath = (path: string): string => {\n const withParams = path.replace(/:[A-Za-z0-9_]+/g, ':param').replace(/\\/{2,}/g, '/');\n return withParams.length > 1 ? withParams.replace(/\\/$/, '') : withParams;\n};\n\n/** The helper's own check: IGNIS mounts a method and path twice without complaint, and the first one wins. */\nconst assertNoDuplicateRoutes = (opts: { application: BaseApplication }): void => {\n const { application } = opts;\n // signature -> controller key -> how many times that controller declares it\n const mounted = new Map<string, Map<string, number>>();\n const record = (signature: string, key: string, declarations: number): void => {\n const owners = mounted.get(signature) ?? new Map<string, number>();\n owners.set(key, Math.max(owners.get(key) ?? 0, declarations));\n mounted.set(signature, owners);\n };\n\n for (const binding of application.findByTag<AbstractRestController>({\n tag: BindingNamespaces.CONTROLLER,\n })) {\n const target = binding.getBindingMeta({ type: BindingValueTypes.CLASS });\n const metadata = target\n ? MetadataRegistry.getInstance().getControllerMetadata({ target })\n : undefined;\n\n if (!metadata?.path || metadata.transport === ControllerTransports.GRPC) {\n continue;\n }\n\n const instance = application.get<AbstractRestController>({\n key: binding.key,\n isOptional: true,\n });\n // Hono's `routes` has one entry PER HANDLER (a validator, an authenticate and the handler of one route are three\n // entries with the same method and path), so an entry is not a declaration: a controller counts once per signature.\n for (const route of instance?.getRouter().routes ?? []) {\n if (route.method === NON_ROUTE_METHOD) {\n continue;\n }\n\n record(`${route.method} ${normalizePath(`${metadata.path}/${route.path}`)}`, binding.key, 1);\n }\n\n // What the router cannot show: one controller declaring a method and path twice. Decorated routes are one\n // metadata entry per declaration, so those are counted there.\n const declared = new Map<string, number>();\n for (const route of MetadataRegistry.getInstance()\n .getRoutes({ target: (target as TClass<AnyType>).prototype })\n ?.values() ?? []) {\n const signature = `${String(route.method).toUpperCase()} ${normalizePath(`${metadata.path}/${route.path}`)}`;\n declared.set(signature, (declared.get(signature) ?? 0) + 1);\n }\n for (const [signature, declarations] of declared) {\n record(signature, binding.key, declarations);\n }\n }\n\n const duplicates = [...mounted.entries()].filter(\n ([, owners]) =>\n owners.size > 1 || [...owners.values()].some((declarations) => declarations > 1),\n );\n if (duplicates.length === 0) {\n return;\n }\n\n const lines = duplicates.map(\n ([signature, owners]) =>\n `${signature} | controllers: ${[...owners]\n .map(([key, declarations]) =>\n declarations > 1 ? `${key} (declared ${declarations} times)` : key,\n )\n .join(', ')}`,\n );\n fail(\n `${duplicates.length} route(s) are mounted more than once, and only the first one answers | ${lines.join(' ; ')} | This is the helper's own check (IGNIS boot does not detect it); pass { routes: false } to turn it off`,\n );\n};\n\n/**\n * Proves an IGNIS application boots, without a datasource connection, a socket or a secrets provider:\n * it runs the application's own boot sequence (`init()` then `initialize()`) and never calls `start()`,\n * so no socket is opened and no post-start hook runs.\n *\n * Datasources are bound and resolved but not configured, unless named in `keepDataSources`; the\n * secrets steps are skipped; every other step and every component runs as in a real boot. A component\n * that opens Redis, Kafka or S3 in `binding()` therefore runs for real: name it in `skipComponents`.\n * When the boot fails inside a component, one warning names it; the rejection is still the original error. When the\n * boot fails, the rejection is the original error. The application stays booted and is returned;\n * a failed boot leaves a half-booted instance, so build a new one rather than reuse it.\n *\n * It wraps `registerDynamicBindings` and `getBootSequence` on THIS instance only (an application's\n * own override of either still runs) and restores them whatever happens.\n */\nexport const assertApplicationBoots = async <Application extends BaseApplication>(\n application: Application | (() => Application | Promise<Application>),\n options: IAssertApplicationBootsOptions = {},\n): Promise<Application> => {\n const {\n keepDataSources = [],\n skipComponents = [],\n skipSteps = DEFAULT_SKIPPED_STEPS,\n verifyBindings = true,\n skipBindings = [],\n allowNoControllers = false,\n routes = true,\n } = options;\n\n for (const step of skipSteps) {\n if (!ServerBootSteps.isValid(step)) {\n fail(\n `Unknown boot step in skipSteps: '${String(step)}' | Expected one of: ${[...ServerBootSteps.SCHEME_SET].join(', ')}`,\n );\n }\n }\n\n let target: Application;\n if (typeof application === 'function') {\n const built = await application();\n target = built;\n } else {\n target = application;\n }\n\n if (\n bootedApplications.has(target) ||\n Object.keys(target['registeredBindings'] ?? {}).length > 0\n ) {\n fail(\n `This application instance was already booted | A failed or finished boot leaves registrations behind, so build a new instance (pass a factory) for each call`,\n );\n }\n bootedApplications.add(target);\n\n for (const name of WRAPPED_METHODS) {\n if (typeof target[name] !== 'function') {\n fail(\n `The kernel method '${name}' is missing on this application | The helper cannot keep a boot offline without it, so it refuses to boot`,\n );\n }\n }\n\n const skippedSteps = new Set<string>(skipSteps);\n const patches: IPatch[] = [];\n let sweepsSeen = 0;\n // The components whose `configure()` is running, innermost last: when the boot rejects, the last one is where it failed.\n const configuringComponents: string[] = [];\n\n const neutralise = async (opts: {\n namespace: string;\n binding: Binding<AnyType>;\n }): Promise<void> => {\n const { namespace, binding } = opts;\n const isDataSource = namespace === BindingNamespaces.DATASOURCE;\n const isComponent = namespace === BindingNamespaces.COMPONENT;\n if (!isDataSource && !isComponent) {\n return;\n }\n\n const instance = target.get<AnyType>({ key: binding.key, isOptional: false });\n if (typeof instance?.configure !== 'function') {\n return;\n }\n\n const shouldRun = isDataSource\n ? matchesTarget({ targets: keepDataSources, binding, instance })\n : !matchesTarget({ targets: skipComponents, binding, instance });\n if (shouldRun) {\n return;\n }\n\n patches.push(patchProperty({ object: instance, name: 'configure', value: async () => {} }));\n };\n\n const originalRegisterDynamicBindings = target['registerDynamicBindings'] as unknown as (\n opts: IDynamicBindingsOptions,\n ) => Promise<void>;\n const originalGetBootSequence = target['getBootSequence'] as unknown as () => Array<{\n name: string;\n }>;\n\n const wrappedRegister = async (opts: IDynamicBindingsOptions): Promise<void> => {\n sweepsSeen += 1;\n const userBefore = opts.onBeforeConfigure;\n const userAfter = opts.onAfterConfigure;\n\n return originalRegisterDynamicBindings.call(target, {\n ...opts,\n onBeforeConfigure: async ({ binding }) => {\n await neutralise({ namespace: opts.namespace, binding });\n if (opts.namespace === BindingNamespaces.COMPONENT) {\n const instance = target.get<AnyType>({ key: binding.key, isOptional: true });\n configuringComponents.push(String(instance?.constructor?.name ?? binding.key));\n }\n await userBefore?.({ binding });\n },\n onAfterConfigure: async ({ binding, instance }) => {\n if (opts.namespace === BindingNamespaces.COMPONENT) {\n configuringComponents.pop();\n }\n await userAfter?.({ binding, instance });\n },\n });\n };\n\n patches.push(\n patchProperty({ object: target, name: 'registerDynamicBindings', value: wrappedRegister }),\n );\n patches.push(\n patchProperty({\n object: target,\n name: 'getBootSequence',\n value: () =>\n originalGetBootSequence.call(target).filter((step) => !skippedSteps.has(step.name)),\n }),\n );\n\n if ((target['registerDynamicBindings'] as unknown) !== wrappedRegister) {\n patches.forEach((patch) => patch.restore());\n fail(\n `The wrap of 'registerDynamicBindings' did not take effect | Refusing to boot against real infrastructure`,\n );\n }\n\n const configs = target['configs'];\n const originalBootChecks = configs.bootChecks;\n const originalBinding = originalBootChecks?.binding;\n configs.bootChecks = {\n ...originalBootChecks,\n binding: {\n allowManual: originalBinding?.allowManual ?? true,\n allowOverride: originalBinding?.allowOverride ?? true,\n doVerify: false,\n },\n };\n\n try {\n if (!target.isBound({ key: CoreBindings.APPLICATION_INSTANCE })) {\n target.init();\n }\n\n await target.initialize();\n\n const sweepsExpected = [\n ServerBootSteps.REGISTER_DATA_SOURCES,\n ServerBootSteps.REGISTER_COMPONENTS,\n ServerBootSteps.REGISTER_CONTRIBUTED_DATA_SOURCES,\n ].some((step) => !skippedSteps.has(step));\n if (sweepsExpected && sweepsSeen === 0) {\n fail(\n `The boot never went through 'registerDynamicBindings' | The wrap did not take effect, so datasources may have been configured`,\n );\n }\n\n if (verifyBindings) {\n assertBindingsResolve({\n container: target,\n namespaces: [BindingNamespaces.SERVICE, BindingNamespaces.REPOSITORY],\n skip: skipBindings,\n scope: 'verifyBindings',\n });\n }\n\n if (\n !allowNoControllers &&\n target.findByTag({ tag: BindingNamespaces.CONTROLLER }).length === 0\n ) {\n fail(\n `The application registered no controller | A boot that registers nothing proves nothing: check the artifact index (for example the AutoArtifacts plugin under 'bun test'), or pass { allowNoControllers: true }`,\n );\n }\n\n if (routes) {\n assertNoDuplicateRoutes({ application: target });\n }\n\n return target;\n } catch (error) {\n const failing = configuringComponents.at(-1);\n if (failing) {\n target.logger\n .for('assertApplicationBoots')\n .warn(\n `The boot failed inside component ${failing} | If it needs infrastructure, skipComponents: ['${failing}'] skips it, and skipBindings lists the services that depend on it`,\n );\n }\n\n throw error;\n } finally {\n for (const patch of patches.reverse()) {\n patch.restore();\n }\n\n if (originalBootChecks === undefined) {\n delete configs.bootChecks;\n } else {\n configs.bootChecks = originalBootChecks;\n }\n }\n};\n"]}
1
+ {"version":3,"file":"assert-application-boots.js","sourceRoot":"","sources":["../../../src/testing/assert-application-boots.ts"],"names":[],"mappings":"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","sourcesContent":["import type { BaseApplication } from '@/base/applications';\nimport { ServerBootSteps, type TServerBootStep } from '@/base/applications';\nimport type { AnyType, TClass } from '@venizia/ignis-helpers/common';\nimport { getError } from '@venizia/ignis-helpers/core';\nimport { BindingVerifier } from '@venizia/ignis-inversion';\nimport {\n type AbstractRestController,\n type Binding,\n BindingNamespaces,\n BindingValueTypes,\n ControllerTransports,\n CoreBindings,\n MetadataRegistry,\n} from '@venizia/ignis-kernel';\n\n/** A class (matched against the instance's constructor) or a string (matched against the binding key or the class name). */\nexport type TBootProbeTarget = TClass<AnyType> | string;\n\nexport interface IAssertApplicationBootsOptions {\n /**\n * Datasources whose real `configure()` runs. Every other datasource is bound and resolved but not\n * configured, so no connection is made. Close a kept one with `await application.stop()`.\n */\n keepDataSources?: TBootProbeTarget[];\n\n /**\n * Components whose `configure()` (and so their `binding()`) is skipped, for the few that need\n * infrastructure. Components run by default. What a skipped component would have registered is\n * not registered.\n */\n skipComponents?: TBootProbeTarget[];\n\n /**\n * Boot steps that do not run. Default: `hydrateSecrets` and `wireSecretRotatables`, so a remote\n * secrets provider is never contacted. A value REPLACES the default; an unknown name rejects\n * before anything boots.\n */\n skipSteps?: TServerBootStep[];\n\n /**\n * Default `true`: after boot, resolves every service and repository with the shared core of\n * `@venizia/ignis-inversion`, so an injection nobody references at boot still fails. An explicit value\n * wins over the application's own `bootChecks`, whose boot step is off for the run.\n */\n verifyBindings?: boolean;\n\n /**\n * Services or repositories the verification leaves unresolved, for one whose constructor needs\n * infrastructure. A class (exact), a class name or a binding key. A name that matches nothing rejects.\n */\n skipBindings?: TBootProbeTarget[];\n\n /** Default `false`: an application that registered no controller proves nothing, for example when the artifact index was empty. */\n allowNoControllers?: boolean;\n\n /** Default `true`: this helper's own check that no method and path is mounted twice. IGNIS boot does not detect that. */\n routes?: boolean;\n}\n\n/** The boot sequence is the contract; these two are what the helper wraps on one instance. */\nconst WRAPPED_METHODS = ['registerDynamicBindings', 'getBootSequence'] as const;\n\nconst DEFAULT_SKIPPED_STEPS: TServerBootStep[] = [\n ServerBootSteps.HYDRATE_SECRETS,\n ServerBootSteps.WIRE_SECRET_ROTATABLES,\n];\n\n/** Methods a route entry may carry that are middleware, not a mounted handler. */\nconst NON_ROUTE_METHOD = 'ALL';\n\nconst bootedApplications = new WeakSet<object>();\n\ninterface IProbeBinding {\n key: string;\n}\n\ninterface IDynamicBindingsOptions {\n namespace: string;\n onBeforeConfigure?: (opts: { binding: Binding<AnyType> }) => Promise<void>;\n onAfterConfigure?: (opts: { binding: Binding<AnyType>; instance: AnyType }) => Promise<void>;\n}\n\n/** What the helper replaced, so every path puts it back. */\ninterface IPatch {\n restore: () => void;\n}\n\nconst matchesTarget = (opts: {\n targets: TBootProbeTarget[];\n binding: IProbeBinding;\n instance: AnyType;\n}): boolean => {\n const { targets, binding, instance } = opts;\n const className: string | undefined = instance?.constructor?.name;\n\n return targets.some((target) =>\n typeof target === 'string'\n ? target === binding.key || target === className\n : instance?.constructor === target,\n );\n};\n\nconst fail = (message: string): never => {\n throw getError({ message: `[ApplicationBootAssertion.assert] ${message}` });\n};\n\n/** Replaces `object[name]` and returns the way back, even when `name` was inherited. */\nconst patchProperty = (opts: { object: AnyType; name: string; value: unknown }): IPatch => {\n const { object, name, value } = opts;\n const descriptor = Object.getOwnPropertyDescriptor(object, name);\n\n Object.defineProperty(object, name, { value, configurable: true, writable: true });\n\n return {\n restore: () => {\n if (descriptor) {\n Object.defineProperty(object, name, descriptor);\n return;\n }\n\n delete object[name];\n },\n };\n};\n\nconst normalizePath = (path: string): string => {\n const withParams = path.replace(/:[A-Za-z0-9_]+/g, ':param').replace(/\\/{2,}/g, '/');\n return withParams.length > 1 ? withParams.replace(/\\/$/, '') : withParams;\n};\n\n/** The helper's own check: IGNIS mounts a method and path twice without complaint, and the first one wins. */\nconst assertNoDuplicateRoutes = (opts: { application: BaseApplication }): void => {\n const { application } = opts;\n // signature -> controller key -> how many times that controller declares it\n const mounted = new Map<string, Map<string, number>>();\n const record = (signature: string, key: string, declarations: number): void => {\n const owners = mounted.get(signature) ?? new Map<string, number>();\n owners.set(key, Math.max(owners.get(key) ?? 0, declarations));\n mounted.set(signature, owners);\n };\n\n for (const binding of application.findByTag<AbstractRestController>({\n tag: BindingNamespaces.CONTROLLER,\n })) {\n const target = binding.getBindingMeta({ type: BindingValueTypes.CLASS });\n const metadata = target\n ? MetadataRegistry.getInstance().getControllerMetadata({ target })\n : undefined;\n\n if (!metadata?.path || metadata.transport === ControllerTransports.GRPC) {\n continue;\n }\n\n const instance = application.get<AbstractRestController>({\n key: binding.key,\n isOptional: true,\n });\n // Hono's `routes` has one entry PER HANDLER (a validator, an authenticate and the handler of one route are three\n // entries with the same method and path), so an entry is not a declaration: a controller counts once per signature.\n for (const route of instance?.getRouter().routes ?? []) {\n if (route.method === NON_ROUTE_METHOD) {\n continue;\n }\n\n record(`${route.method} ${normalizePath(`${metadata.path}/${route.path}`)}`, binding.key, 1);\n }\n\n // What the router cannot show: one controller declaring a method and path twice. Decorated routes are one\n // metadata entry per declaration, so those are counted there.\n const declared = new Map<string, number>();\n for (const route of MetadataRegistry.getInstance()\n .getRoutes({ target: (target as TClass<AnyType>).prototype })\n ?.values() ?? []) {\n const signature = `${String(route.method).toUpperCase()} ${normalizePath(`${metadata.path}/${route.path}`)}`;\n declared.set(signature, (declared.get(signature) ?? 0) + 1);\n }\n for (const [signature, declarations] of declared) {\n record(signature, binding.key, declarations);\n }\n }\n\n const duplicates = [...mounted.entries()].filter(\n ([, owners]) =>\n owners.size > 1 || [...owners.values()].some((declarations) => declarations > 1),\n );\n if (duplicates.length === 0) {\n return;\n }\n\n const lines = duplicates.map(\n ([signature, owners]) =>\n `${signature} | controllers: ${[...owners]\n .map(([key, declarations]) =>\n declarations > 1 ? `${key} (declared ${declarations} times)` : key,\n )\n .join(', ')}`,\n );\n fail(\n `${duplicates.length} route(s) are mounted more than once, and only the first one answers | ${lines.join(' ; ')} | This is the helper's own check (IGNIS boot does not detect it); pass { routes: false } to turn it off`,\n );\n};\n\n/**\n * Proves an IGNIS application boots, without a datasource connection, a socket or a secrets provider:\n * it runs the application's own boot sequence (`init()` then `initialize()`) and never calls `start()`,\n * so no socket is opened and no post-start hook runs.\n *\n * Datasources are bound and resolved but not configured, unless named in `keepDataSources`; the\n * secrets steps are skipped; every other step and every component runs as in a real boot. A component\n * that opens Redis, Kafka or S3 in `binding()` therefore runs for real: name it in `skipComponents`.\n * When the boot fails inside a component, one warning names it; the rejection is still the original error. When the\n * boot fails, the rejection is the original error. The application stays booted and is returned;\n * a failed boot leaves a half-booted instance, so build a new one rather than reuse it.\n *\n * It wraps `registerDynamicBindings` and `getBootSequence` on THIS instance only (an application's\n * own override of either still runs) and restores them whatever happens.\n */\nexport class ApplicationBootAssertion {\n static async assert<Application extends BaseApplication>(opts: {\n application: Application | (() => Application | Promise<Application>);\n options?: IAssertApplicationBootsOptions;\n }): Promise<Application> {\n const { application, options = {} } = opts;\n const {\n keepDataSources = [],\n skipComponents = [],\n skipSteps = DEFAULT_SKIPPED_STEPS,\n verifyBindings = true,\n skipBindings = [],\n allowNoControllers = false,\n routes = true,\n } = options;\n\n for (const step of skipSteps) {\n if (!ServerBootSteps.isValid(step)) {\n fail(\n `Unknown boot step in skipSteps: '${String(step)}' | Expected one of: ${[...ServerBootSteps.SCHEME_SET].join(', ')}`,\n );\n }\n }\n\n let target: Application;\n if (typeof application === 'function') {\n const built = await application();\n target = built;\n } else {\n target = application;\n }\n\n if (\n bootedApplications.has(target) ||\n Object.keys(target['registeredBindings'] ?? {}).length > 0\n ) {\n fail(\n `This application instance was already booted | A failed or finished boot leaves registrations behind, so build a new instance (pass a factory) for each call`,\n );\n }\n bootedApplications.add(target);\n\n for (const name of WRAPPED_METHODS) {\n if (typeof target[name] !== 'function') {\n fail(\n `The kernel method '${name}' is missing on this application | The helper cannot keep a boot offline without it, so it refuses to boot`,\n );\n }\n }\n\n const skippedSteps = new Set<string>(skipSteps);\n const patches: IPatch[] = [];\n let sweepsSeen = 0;\n // The components whose `configure()` is running, innermost last: when the boot rejects, the last one is where it failed.\n const configuringComponents: string[] = [];\n\n const neutralise = async (entry: {\n namespace: string;\n binding: Binding<AnyType>;\n }): Promise<void> => {\n const { namespace, binding } = entry;\n const isDataSource = namespace === BindingNamespaces.DATASOURCE;\n const isComponent = namespace === BindingNamespaces.COMPONENT;\n if (!isDataSource && !isComponent) {\n return;\n }\n\n const instance = target.get<AnyType>({ key: binding.key, isOptional: false });\n if (typeof instance?.configure !== 'function') {\n return;\n }\n\n const shouldRun = isDataSource\n ? matchesTarget({ targets: keepDataSources, binding, instance })\n : !matchesTarget({ targets: skipComponents, binding, instance });\n if (shouldRun) {\n return;\n }\n\n patches.push(patchProperty({ object: instance, name: 'configure', value: async () => {} }));\n };\n\n const originalRegisterDynamicBindings = target['registerDynamicBindings'] as unknown as (\n opts: IDynamicBindingsOptions,\n ) => Promise<void>;\n const originalGetBootSequence = target['getBootSequence'] as unknown as () => Array<{\n name: string;\n }>;\n\n const wrappedRegister = async (sweepOptions: IDynamicBindingsOptions): Promise<void> => {\n sweepsSeen += 1;\n const userBefore = sweepOptions.onBeforeConfigure;\n const userAfter = sweepOptions.onAfterConfigure;\n\n return originalRegisterDynamicBindings.call(target, {\n ...sweepOptions,\n onBeforeConfigure: async ({ binding }) => {\n await neutralise({ namespace: sweepOptions.namespace, binding });\n if (sweepOptions.namespace === BindingNamespaces.COMPONENT) {\n const instance = target.get<AnyType>({ key: binding.key, isOptional: true });\n configuringComponents.push(String(instance?.constructor?.name ?? binding.key));\n }\n await userBefore?.({ binding });\n },\n onAfterConfigure: async ({ binding, instance }) => {\n if (sweepOptions.namespace === BindingNamespaces.COMPONENT) {\n configuringComponents.pop();\n }\n await userAfter?.({ binding, instance });\n },\n });\n };\n\n patches.push(\n patchProperty({ object: target, name: 'registerDynamicBindings', value: wrappedRegister }),\n );\n patches.push(\n patchProperty({\n object: target,\n name: 'getBootSequence',\n value: () =>\n originalGetBootSequence.call(target).filter((step) => !skippedSteps.has(step.name)),\n }),\n );\n\n if ((target['registerDynamicBindings'] as unknown) !== wrappedRegister) {\n patches.forEach((patch) => patch.restore());\n fail(\n `The wrap of 'registerDynamicBindings' did not take effect | Refusing to boot against real infrastructure`,\n );\n }\n\n const configs = target['configs'];\n const originalBootChecks = configs.bootChecks;\n const originalBinding = originalBootChecks?.binding;\n configs.bootChecks = {\n ...originalBootChecks,\n binding: {\n allowManual: originalBinding?.allowManual ?? true,\n allowOverride: originalBinding?.allowOverride ?? true,\n doVerify: false,\n },\n };\n\n try {\n if (!target.isBound({ key: CoreBindings.APPLICATION_INSTANCE })) {\n target.init();\n }\n\n await target.initialize();\n\n const sweepsExpected = [\n ServerBootSteps.REGISTER_DATA_SOURCES,\n ServerBootSteps.REGISTER_COMPONENTS,\n ServerBootSteps.REGISTER_CONTRIBUTED_DATA_SOURCES,\n ].some((step) => !skippedSteps.has(step));\n if (sweepsExpected && sweepsSeen === 0) {\n fail(\n `The boot never went through 'registerDynamicBindings' | The wrap did not take effect, so datasources may have been configured`,\n );\n }\n\n if (verifyBindings) {\n BindingVerifier.assertResolve({\n container: target,\n namespaces: [BindingNamespaces.SERVICE, BindingNamespaces.REPOSITORY],\n skip: skipBindings,\n scope: 'verifyBindings',\n });\n }\n\n if (\n !allowNoControllers &&\n target.findByTag({ tag: BindingNamespaces.CONTROLLER }).length === 0\n ) {\n fail(\n `The application registered no controller | A boot that registers nothing proves nothing: check the artifact index (for example the AutoArtifacts plugin under 'bun test'), or pass { allowNoControllers: true }`,\n );\n }\n\n if (routes) {\n assertNoDuplicateRoutes({ application: target });\n }\n\n return target;\n } catch (error) {\n const failing = configuringComponents.at(-1);\n if (failing) {\n target.logger\n .for('ApplicationBootAssertion.assert')\n .warn(\n `The boot failed inside component ${failing} | If it needs infrastructure, skipComponents: ['${failing}'] skips it, and skipBindings lists the services that depend on it`,\n );\n }\n\n throw error;\n } finally {\n for (const patch of patches.reverse()) {\n patch.restore();\n }\n\n if (originalBootChecks === undefined) {\n delete configs.bootChecks;\n } else {\n configs.bootChecks = originalBootChecks;\n }\n }\n }\n}\n"]}
@@ -1,9 +1,7 @@
1
- /** Rows affected by a write executed without RETURNING. */
2
- export declare const readAffectedRowCount: (opts: {
3
- result: unknown;
4
- }) => number;
5
- /** Rows returned by `connector.execute(...)`. */
6
- export declare const readResultRows: <TRow>(opts: {
7
- result: unknown;
8
- }) => TRow[];
1
+ export declare class DrizzleResultUtility {
2
+ /** Rows returned by `connector.execute(...)`. */
3
+ static readResultRows<TRow>(opts: {
4
+ result: unknown;
5
+ }): TRow[];
6
+ }
9
7
  //# sourceMappingURL=drizzle-result.utility.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"drizzle-result.utility.d.ts","sourceRoot":"","sources":["../../../src/utilities/drizzle-result.utility.ts"],"names":[],"mappings":"AAEA,2DAA2D;AAC3D,eAAO,MAAM,oBAAoB,GAAI,MAAM;IAAE,MAAM,EAAE,OAAO,CAAA;CAAE,KAAG,MAiChE,CAAC;AAEF,iDAAiD;AACjD,eAAO,MAAM,cAAc,GAAI,IAAI,EAAE,MAAM;IAAE,MAAM,EAAE,OAAO,CAAA;CAAE,KAAG,IAAI,EA4BpE,CAAC"}
1
+ {"version":3,"file":"drizzle-result.utility.d.ts","sourceRoot":"","sources":["../../../src/utilities/drizzle-result.utility.ts"],"names":[],"mappings":"AAEA,qBAAa,oBAAoB;IAC/B,iDAAiD;IACjD,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,IAAI,EAAE;QAAE,MAAM,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI,EAAE;CA6B/D"}
@@ -1,54 +1,28 @@
1
1
  import { getError } from '@venizia/ignis-helpers/core';
2
- /** Rows affected by a write executed without RETURNING. */
3
- export const readAffectedRowCount = (opts) => {
4
- const { result } = opts;
5
- // Drizzle resolves some statements to nothing at all; the callers already treated that as zero.
6
- if (result === null || result === undefined) {
7
- return 0;
8
- }
9
- if (typeof result !== 'object') {
10
- throw getError({
11
- message: `[readAffectedRowCount] Unrecognized driver result | expected pg.QueryResult or postgres-js RowList | got: ${typeof result}`,
12
- });
13
- }
14
- const { rowCount, count } = result;
15
- // node-postgres. `rowCount` is null for statements that affect no rows by definition (e.g. DDL).
16
- if (typeof rowCount === 'number') {
17
- return rowCount;
18
- }
19
- if (rowCount === null) {
20
- return 0;
21
- }
22
- // postgres-js.
23
- if (typeof count === 'number') {
24
- return count;
25
- }
26
- throw getError({
27
- message: `[readAffectedRowCount] Unrecognized driver result | expected 'rowCount' (node-postgres) or 'count' (postgres-js) | got keys: ${Object.keys(result).join(', ')}`,
28
- });
29
- };
30
- /** Rows returned by `connector.execute(...)`. */
31
- export const readResultRows = (opts) => {
32
- const { result } = opts;
33
- if (result === null || result === undefined) {
34
- return [];
35
- }
36
- // postgres-js: the result IS the row list.
37
- if (Array.isArray(result)) {
38
- return result;
39
- }
40
- if (typeof result !== 'object') {
2
+ export class DrizzleResultUtility {
3
+ /** Rows returned by `connector.execute(...)`. */
4
+ static readResultRows(opts) {
5
+ const { result } = opts;
6
+ if (result === null || result === undefined) {
7
+ return [];
8
+ }
9
+ // postgres-js: the result IS the row list.
10
+ if (Array.isArray(result)) {
11
+ return result;
12
+ }
13
+ if (typeof result !== 'object') {
14
+ throw getError({
15
+ message: `[DrizzleResultUtility.readResultRows] Unrecognized driver result | expected pg.QueryResult or postgres-js RowList | got: ${typeof result}`,
16
+ });
17
+ }
18
+ // node-postgres: pg.QueryResult.
19
+ const { rows } = result;
20
+ if (Array.isArray(rows)) {
21
+ return rows;
22
+ }
41
23
  throw getError({
42
- message: `[readResultRows] Unrecognized driver result | expected pg.QueryResult or postgres-js RowList | got: ${typeof result}`,
24
+ message: `[DrizzleResultUtility.readResultRows] Unrecognized driver result | expected an array (postgres-js) or a 'rows' array (node-postgres) | got keys: ${Object.keys(result).join(', ')}`,
43
25
  });
44
26
  }
45
- // node-postgres: pg.QueryResult.
46
- const { rows } = result;
47
- if (Array.isArray(rows)) {
48
- return rows;
49
- }
50
- throw getError({
51
- message: `[readResultRows] Unrecognized driver result | expected an array (postgres-js) or a 'rows' array (node-postgres) | got keys: ${Object.keys(result).join(', ')}`,
52
- });
53
- };
27
+ }
54
28
  //# sourceMappingURL=drizzle-result.utility.js.map