@pattern-stack/codegen 0.15.1 → 0.15.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +85 -0
- package/dist/chunk-27ETSJ2X.js +84 -0
- package/dist/chunk-27ETSJ2X.js.map +1 -0
- package/dist/chunk-2E224ZSN.js +20 -0
- package/dist/chunk-2E224ZSN.js.map +1 -0
- package/dist/chunk-2FTZLDBP.js +179 -0
- package/dist/chunk-2FTZLDBP.js.map +1 -0
- package/dist/chunk-2N4UG4VD.js +20 -0
- package/dist/chunk-2N4UG4VD.js.map +1 -0
- package/dist/chunk-2TVVBC53.js +92 -0
- package/dist/chunk-2TVVBC53.js.map +1 -0
- package/dist/chunk-2VHZ7EKC.js +37 -0
- package/dist/chunk-2VHZ7EKC.js.map +1 -0
- package/dist/chunk-32BMMV4H.js +109 -0
- package/dist/chunk-32BMMV4H.js.map +1 -0
- package/dist/chunk-32DOFN3T.js +4042 -0
- package/dist/chunk-32DOFN3T.js.map +1 -0
- package/dist/chunk-36U5UGIO.js +107 -0
- package/dist/chunk-36U5UGIO.js.map +1 -0
- package/dist/chunk-3CJFPU6Q.js +14 -0
- package/dist/chunk-3CJFPU6Q.js.map +1 -0
- package/dist/chunk-3NMCDN7L.js +90 -0
- package/dist/chunk-3NMCDN7L.js.map +1 -0
- package/dist/chunk-3SZFUTXE.js +62 -0
- package/dist/chunk-3SZFUTXE.js.map +1 -0
- package/dist/chunk-4DOJBQTP.js +117 -0
- package/dist/chunk-4DOJBQTP.js.map +1 -0
- package/dist/chunk-4H3PETLM.js +290 -0
- package/dist/chunk-4H3PETLM.js.map +1 -0
- package/dist/chunk-4JLJYWJC.js +308 -0
- package/dist/chunk-4JLJYWJC.js.map +1 -0
- package/dist/chunk-4KNXX6TI.js +29 -0
- package/dist/chunk-4KNXX6TI.js.map +1 -0
- package/dist/chunk-4LH67P4U.js +17 -0
- package/dist/chunk-4LH67P4U.js.map +1 -0
- package/dist/chunk-4MF3HKJA.js +94 -0
- package/dist/chunk-4MF3HKJA.js.map +1 -0
- package/dist/chunk-4MVGAMUA.js +40 -0
- package/dist/chunk-4MVGAMUA.js.map +1 -0
- package/dist/chunk-4RFHUZXU.js +635 -0
- package/dist/chunk-4RFHUZXU.js.map +1 -0
- package/dist/chunk-5A432NZJ.js +7 -0
- package/dist/chunk-5A432NZJ.js.map +1 -0
- package/dist/chunk-5Y7W3XR6.js +356 -0
- package/dist/chunk-5Y7W3XR6.js.map +1 -0
- package/dist/chunk-6DWFJNIK.js +15 -0
- package/dist/chunk-6DWFJNIK.js.map +1 -0
- package/dist/chunk-6I7ULIN6.js +15 -0
- package/dist/chunk-6I7ULIN6.js.map +1 -0
- package/dist/chunk-6XY6ZMMD.js +25 -0
- package/dist/chunk-6XY6ZMMD.js.map +1 -0
- package/dist/chunk-7B3RYX45.js +63 -0
- package/dist/chunk-7B3RYX45.js.map +1 -0
- package/dist/chunk-7C3FOSDI.js +1 -0
- package/dist/chunk-7C3FOSDI.js.map +1 -0
- package/dist/chunk-7KOW6PU6.js +59 -0
- package/dist/chunk-7KOW6PU6.js.map +1 -0
- package/dist/chunk-7RELQJIN.js +22 -0
- package/dist/chunk-7RELQJIN.js.map +1 -0
- package/dist/chunk-7YGORYZD.js +112 -0
- package/dist/chunk-7YGORYZD.js.map +1 -0
- package/dist/chunk-AHV4GDYM.js +63 -0
- package/dist/chunk-AHV4GDYM.js.map +1 -0
- package/dist/chunk-AQFQ4BYM.js +81 -0
- package/dist/chunk-AQFQ4BYM.js.map +1 -0
- package/dist/chunk-AS3NAZB6.js +14 -0
- package/dist/chunk-AS3NAZB6.js.map +1 -0
- package/dist/chunk-BGULBWKJ.js +88 -0
- package/dist/chunk-BGULBWKJ.js.map +1 -0
- package/dist/chunk-BIO6F7YI.js +17 -0
- package/dist/chunk-BIO6F7YI.js.map +1 -0
- package/dist/chunk-BOPZWRJK.js +36 -0
- package/dist/chunk-BOPZWRJK.js.map +1 -0
- package/dist/chunk-BPARRK6F.js +14 -0
- package/dist/chunk-BPARRK6F.js.map +1 -0
- package/dist/chunk-CO6LUM72.js +59 -0
- package/dist/chunk-CO6LUM72.js.map +1 -0
- package/dist/chunk-DCCZB4UC.js +100 -0
- package/dist/chunk-DCCZB4UC.js.map +1 -0
- package/dist/chunk-DV4RV2DC.js +59 -0
- package/dist/chunk-DV4RV2DC.js.map +1 -0
- package/dist/chunk-EDKJU5BO.js +11 -0
- package/dist/chunk-EDKJU5BO.js.map +1 -0
- package/dist/chunk-EO2QPOKH.js +116 -0
- package/dist/chunk-EO2QPOKH.js.map +1 -0
- package/dist/chunk-EOLLMEAH.js +155 -0
- package/dist/chunk-EOLLMEAH.js.map +1 -0
- package/dist/chunk-EWYCWP4H.js +14 -0
- package/dist/chunk-EWYCWP4H.js.map +1 -0
- package/dist/chunk-EXVDJMIY.js +33 -0
- package/dist/chunk-EXVDJMIY.js.map +1 -0
- package/dist/chunk-FASRXRX5.js +19 -0
- package/dist/chunk-FASRXRX5.js.map +1 -0
- package/dist/chunk-FBGHYQIZ.js +201 -0
- package/dist/chunk-FBGHYQIZ.js.map +1 -0
- package/dist/chunk-FI34KYZ5.js +1 -0
- package/dist/chunk-FI34KYZ5.js.map +1 -0
- package/dist/chunk-FN2PYDPP.js +1 -0
- package/dist/chunk-FN2PYDPP.js.map +1 -0
- package/dist/chunk-GCYKMF22.js +81 -0
- package/dist/chunk-GCYKMF22.js.map +1 -0
- package/dist/chunk-GM3RMJIJ.js +92 -0
- package/dist/chunk-GM3RMJIJ.js.map +1 -0
- package/dist/chunk-GYGNEQSC.js +9 -0
- package/dist/chunk-GYGNEQSC.js.map +1 -0
- package/dist/chunk-H5NH7KPE.js +21 -0
- package/dist/chunk-H5NH7KPE.js.map +1 -0
- package/dist/chunk-HNWZFNKP.js +168 -0
- package/dist/chunk-HNWZFNKP.js.map +1 -0
- package/dist/chunk-HUH73XGI.js +1 -0
- package/dist/chunk-HUH73XGI.js.map +1 -0
- package/dist/chunk-I6MVCB5A.js +39 -0
- package/dist/chunk-I6MVCB5A.js.map +1 -0
- package/dist/chunk-IBGER4YK.js +12 -0
- package/dist/chunk-IBGER4YK.js.map +1 -0
- package/dist/chunk-IF5I3DAA.js +92 -0
- package/dist/chunk-IF5I3DAA.js.map +1 -0
- package/dist/chunk-IP4OO26U.js +54 -0
- package/dist/chunk-IP4OO26U.js.map +1 -0
- package/dist/chunk-IWAOY6KC.js +1 -0
- package/dist/chunk-IWAOY6KC.js.map +1 -0
- package/dist/chunk-IYNSRIGR.js +122 -0
- package/dist/chunk-IYNSRIGR.js.map +1 -0
- package/dist/chunk-J37YWU7Y.js +19 -0
- package/dist/chunk-J37YWU7Y.js.map +1 -0
- package/dist/chunk-J6KZS54B.js +269 -0
- package/dist/chunk-J6KZS54B.js.map +1 -0
- package/dist/chunk-J6MN42LG.js +19 -0
- package/dist/chunk-J6MN42LG.js.map +1 -0
- package/dist/chunk-J7JMVS2B.js +53 -0
- package/dist/chunk-J7JMVS2B.js.map +1 -0
- package/dist/chunk-JRQO2IOF.js +65 -0
- package/dist/chunk-JRQO2IOF.js.map +1 -0
- package/dist/chunk-JWNHNUYL.js +96 -0
- package/dist/chunk-JWNHNUYL.js.map +1 -0
- package/dist/chunk-K2I6XIK5.js +122 -0
- package/dist/chunk-K2I6XIK5.js.map +1 -0
- package/dist/chunk-KVOWSC5S.js +1 -0
- package/dist/chunk-KVOWSC5S.js.map +1 -0
- package/dist/chunk-KYR3B3OW.js +79 -0
- package/dist/chunk-KYR3B3OW.js.map +1 -0
- package/dist/chunk-L3LZWWSX.js +61 -0
- package/dist/chunk-L3LZWWSX.js.map +1 -0
- package/dist/chunk-L4SDDEEU.js +1 -0
- package/dist/chunk-L4SDDEEU.js.map +1 -0
- package/dist/chunk-L6FTY45T.js +13 -0
- package/dist/chunk-L6FTY45T.js.map +1 -0
- package/dist/chunk-L7BNNRGI.js +134 -0
- package/dist/chunk-L7BNNRGI.js.map +1 -0
- package/dist/chunk-LG57S2SC.js +150 -0
- package/dist/chunk-LG57S2SC.js.map +1 -0
- package/dist/chunk-M6QLSLPO.js +97 -0
- package/dist/chunk-M6QLSLPO.js.map +1 -0
- package/dist/chunk-MZ6GV4YF.js +21 -0
- package/dist/chunk-MZ6GV4YF.js.map +1 -0
- package/dist/chunk-N5OTOWTP.js +55 -0
- package/dist/chunk-N5OTOWTP.js.map +1 -0
- package/dist/chunk-NN7XZEGF.js +14 -0
- package/dist/chunk-NN7XZEGF.js.map +1 -0
- package/dist/chunk-NPFPZ2HO.js +13 -0
- package/dist/chunk-NPFPZ2HO.js.map +1 -0
- package/dist/chunk-NXXDZ6ZF.js +42 -0
- package/dist/chunk-NXXDZ6ZF.js.map +1 -0
- package/dist/chunk-NYBCQZC7.js +11 -0
- package/dist/chunk-NYBCQZC7.js.map +1 -0
- package/dist/chunk-O37C3YE6.js +111 -0
- package/dist/chunk-O37C3YE6.js.map +1 -0
- package/dist/chunk-OFRRBC7M.js +78 -0
- package/dist/chunk-OFRRBC7M.js.map +1 -0
- package/dist/chunk-OGIZXGPY.js +222 -0
- package/dist/chunk-OGIZXGPY.js.map +1 -0
- package/dist/chunk-OKXZ63IA.js +168 -0
- package/dist/chunk-OKXZ63IA.js.map +1 -0
- package/dist/chunk-OSQRXVG2.js +58 -0
- package/dist/chunk-OSQRXVG2.js.map +1 -0
- package/dist/chunk-OTDN3OUQ.js +215 -0
- package/dist/chunk-OTDN3OUQ.js.map +1 -0
- package/dist/chunk-PNZSGAB2.js +114 -0
- package/dist/chunk-PNZSGAB2.js.map +1 -0
- package/dist/chunk-PRWIX6UW.js +21 -0
- package/dist/chunk-PRWIX6UW.js.map +1 -0
- package/dist/chunk-PSXUNOVU.js +7 -0
- package/dist/chunk-PSXUNOVU.js.map +1 -0
- package/dist/chunk-QLTJSCE6.js +44 -0
- package/dist/chunk-QLTJSCE6.js.map +1 -0
- package/dist/chunk-RC23QROE.js +447 -0
- package/dist/chunk-RC23QROE.js.map +1 -0
- package/dist/chunk-RDVTWIYY.js +212 -0
- package/dist/chunk-RDVTWIYY.js.map +1 -0
- package/dist/chunk-RFH7N6EP.js +36 -0
- package/dist/chunk-RFH7N6EP.js.map +1 -0
- package/dist/chunk-RHVN6NA7.js +134 -0
- package/dist/chunk-RHVN6NA7.js.map +1 -0
- package/dist/chunk-S7C6TIIF.js +21 -0
- package/dist/chunk-S7C6TIIF.js.map +1 -0
- package/dist/chunk-SNQ3TOWP.js +20 -0
- package/dist/chunk-SNQ3TOWP.js.map +1 -0
- package/dist/chunk-SOVM2VEK.js +14 -0
- package/dist/chunk-SOVM2VEK.js.map +1 -0
- package/dist/chunk-SQDOBLBP.js +13 -0
- package/dist/chunk-SQDOBLBP.js.map +1 -0
- package/dist/chunk-SR7F3TJY.js +130 -0
- package/dist/chunk-SR7F3TJY.js.map +1 -0
- package/dist/chunk-SZVPIHWE.js +129 -0
- package/dist/chunk-SZVPIHWE.js.map +1 -0
- package/dist/chunk-T4BIIU5E.js +89 -0
- package/dist/chunk-T4BIIU5E.js.map +1 -0
- package/dist/chunk-T6SCOJF4.js +92 -0
- package/dist/chunk-T6SCOJF4.js.map +1 -0
- package/dist/chunk-TNXH7BJS.js +48 -0
- package/dist/chunk-TNXH7BJS.js.map +1 -0
- package/dist/chunk-U64T4YZE.js +9 -0
- package/dist/chunk-U64T4YZE.js.map +1 -0
- package/dist/chunk-UQ5EHOH2.js +39 -0
- package/dist/chunk-UQ5EHOH2.js.map +1 -0
- package/dist/chunk-UTN4GBPQ.js +1 -0
- package/dist/chunk-UTN4GBPQ.js.map +1 -0
- package/dist/chunk-V4AF6DI4.js +16 -0
- package/dist/chunk-V4AF6DI4.js.map +1 -0
- package/dist/chunk-W72PRNJY.js +126 -0
- package/dist/chunk-W72PRNJY.js.map +1 -0
- package/dist/chunk-WL67FZGF.js +21 -0
- package/dist/chunk-WL67FZGF.js.map +1 -0
- package/dist/chunk-WWGYCIJX.js +29 -0
- package/dist/chunk-WWGYCIJX.js.map +1 -0
- package/dist/chunk-X2GMTYPA.js +50 -0
- package/dist/chunk-X2GMTYPA.js.map +1 -0
- package/dist/chunk-XCEI7NUH.js +41 -0
- package/dist/chunk-XCEI7NUH.js.map +1 -0
- package/dist/chunk-Y7GDG744.js +88 -0
- package/dist/chunk-Y7GDG744.js.map +1 -0
- package/dist/chunk-Y7RRSEOC.js +9 -0
- package/dist/chunk-Y7RRSEOC.js.map +1 -0
- package/dist/chunk-YLPAPPLW.js +75 -0
- package/dist/chunk-YLPAPPLW.js.map +1 -0
- package/dist/chunk-YPWODKD5.js +184 -0
- package/dist/chunk-YPWODKD5.js.map +1 -0
- package/dist/chunk-YSLTTQLC.js +25 -0
- package/dist/chunk-YSLTTQLC.js.map +1 -0
- package/dist/chunk-YTN6BKWA.js +121 -0
- package/dist/chunk-YTN6BKWA.js.map +1 -0
- package/dist/chunk-Z7PQCAVK.js +200 -0
- package/dist/chunk-Z7PQCAVK.js.map +1 -0
- package/dist/chunk-ZUKFQL6E.js +47 -0
- package/dist/chunk-ZUKFQL6E.js.map +1 -0
- package/dist/chunk-ZUMULSEQ.js +1 -0
- package/dist/chunk-ZUMULSEQ.js.map +1 -0
- package/dist/runtime/analytics/index.js +8 -41
- package/dist/runtime/analytics/index.js.map +1 -1
- package/dist/runtime/analytics/types.js +8 -41
- package/dist/runtime/analytics/types.js.map +1 -1
- package/dist/runtime/base-classes/activity-entity-repository.js +6 -312
- package/dist/runtime/base-classes/activity-entity-repository.js.map +1 -1
- package/dist/runtime/base-classes/activity-entity-service.js +6 -212
- package/dist/runtime/base-classes/activity-entity-service.js.map +1 -1
- package/dist/runtime/base-classes/base-read-use-cases.js +5 -27
- package/dist/runtime/base-classes/base-read-use-cases.js.map +1 -1
- package/dist/runtime/base-classes/base-repository.js +5 -277
- package/dist/runtime/base-classes/base-repository.js.map +1 -1
- package/dist/runtime/base-classes/base-service.js +5 -184
- package/dist/runtime/base-classes/base-service.js.map +1 -1
- package/dist/runtime/base-classes/index.js +59 -1076
- package/dist/runtime/base-classes/index.js.map +1 -1
- package/dist/runtime/base-classes/integrated-entity-repository.js +6 -486
- package/dist/runtime/base-classes/integrated-entity-repository.js.map +1 -1
- package/dist/runtime/base-classes/integrated-entity-service.js +6 -213
- package/dist/runtime/base-classes/integrated-entity-service.js.map +1 -1
- package/dist/runtime/base-classes/junction-integration-repository.js +8 -448
- package/dist/runtime/base-classes/junction-integration-repository.js.map +1 -1
- package/dist/runtime/base-classes/knowledge-entity-repository.js +6 -283
- package/dist/runtime/base-classes/knowledge-entity-repository.js.map +1 -1
- package/dist/runtime/base-classes/knowledge-entity-service.js +6 -190
- package/dist/runtime/base-classes/knowledge-entity-service.js.map +1 -1
- package/dist/runtime/base-classes/lifecycle-events.js +8 -70
- package/dist/runtime/base-classes/lifecycle-events.js.map +1 -1
- package/dist/runtime/base-classes/metadata-entity-repository.js +6 -330
- package/dist/runtime/base-classes/metadata-entity-repository.js.map +1 -1
- package/dist/runtime/base-classes/metadata-entity-service.js +6 -212
- package/dist/runtime/base-classes/metadata-entity-service.js.map +1 -1
- package/dist/runtime/base-classes/tenant-context.js +10 -36
- package/dist/runtime/base-classes/tenant-context.js.map +1 -1
- package/dist/runtime/base-classes/with-analytics.js +4 -7
- package/dist/runtime/base-classes/with-analytics.js.map +1 -1
- package/dist/runtime/constants/tokens.js +5 -3
- package/dist/runtime/constants/tokens.js.map +1 -1
- package/dist/runtime/eav-helpers.js +2 -0
- package/dist/runtime/eav-helpers.js.map +1 -1
- package/dist/runtime/pipes/zod-validation.pipe.js +3 -10
- package/dist/runtime/pipes/zod-validation.pipe.js.map +1 -1
- package/dist/runtime/shared/openapi/error-response.dto.js +5 -8
- package/dist/runtime/shared/openapi/error-response.dto.js.map +1 -1
- package/dist/runtime/shared/openapi/errors.js +5 -19
- package/dist/runtime/shared/openapi/errors.js.map +1 -1
- package/dist/runtime/shared/openapi/index.js +15 -106
- package/dist/runtime/shared/openapi/index.js.map +1 -1
- package/dist/runtime/shared/openapi/registry.js +6 -103
- package/dist/runtime/shared/openapi/registry.js.map +1 -1
- package/dist/runtime/shared/openapi/registry.tokens.js +4 -2
- package/dist/runtime/shared/openapi/registry.tokens.js.map +1 -1
- package/dist/runtime/subsystems/analytics/analytics.module.js +8 -117
- package/dist/runtime/subsystems/analytics/analytics.module.js.map +1 -1
- package/dist/runtime/subsystems/analytics/analytics.tokens.js +7 -8
- package/dist/runtime/subsystems/analytics/analytics.tokens.js.map +1 -1
- package/dist/runtime/subsystems/analytics/cube-backend.js +6 -71
- package/dist/runtime/subsystems/analytics/cube-backend.js.map +1 -1
- package/dist/runtime/subsystems/analytics/index.js +16 -117
- package/dist/runtime/subsystems/analytics/index.js.map +1 -1
- package/dist/runtime/subsystems/analytics/noop-backend.js +4 -21
- package/dist/runtime/subsystems/analytics/noop-backend.js.map +1 -1
- package/dist/runtime/subsystems/auth/auth-oauth-state.schema.js +4 -8
- package/dist/runtime/subsystems/auth/auth-oauth-state.schema.js.map +1 -1
- package/dist/runtime/subsystems/auth/auth.module.js +12 -359
- package/dist/runtime/subsystems/auth/auth.module.js.map +1 -1
- package/dist/runtime/subsystems/auth/auth.tokens.js +12 -13
- package/dist/runtime/subsystems/auth/auth.tokens.js.map +1 -1
- package/dist/runtime/subsystems/auth/backends/encryption-key/env.js +4 -49
- package/dist/runtime/subsystems/auth/backends/encryption-key/env.js.map +1 -1
- package/dist/runtime/subsystems/auth/backends/state-store.drizzle-backend.js +6 -64
- package/dist/runtime/subsystems/auth/backends/state-store.drizzle-backend.js.map +1 -1
- package/dist/runtime/subsystems/auth/backends/state-store.memory-backend.js +5 -47
- package/dist/runtime/subsystems/auth/backends/state-store.memory-backend.js.map +1 -1
- package/dist/runtime/subsystems/auth/controllers/auth.controller.js +5 -139
- package/dist/runtime/subsystems/auth/controllers/auth.controller.js.map +1 -1
- package/dist/runtime/subsystems/auth/index.js +53 -542
- package/dist/runtime/subsystems/auth/index.js.map +1 -1
- package/dist/runtime/subsystems/auth/middleware/requester-context.js +9 -65
- package/dist/runtime/subsystems/auth/middleware/requester-context.js.map +1 -1
- package/dist/runtime/subsystems/auth/protocols/oauth-state-store.js +4 -9
- package/dist/runtime/subsystems/auth/protocols/oauth-state-store.js.map +1 -1
- package/dist/runtime/subsystems/auth/runtime/connection-broken.error.js +4 -15
- package/dist/runtime/subsystems/auth/runtime/connection-broken.error.js.map +1 -1
- package/dist/runtime/subsystems/auth/runtime/oauth2-refresh.strategy.js +5 -104
- package/dist/runtime/subsystems/auth/runtime/oauth2-refresh.strategy.js.map +1 -1
- package/dist/runtime/subsystems/auth/runtime/session-expired.error.js +5 -16
- package/dist/runtime/subsystems/auth/runtime/session-expired.error.js.map +1 -1
- package/dist/runtime/subsystems/auth/runtime/with-auth-retry.js +5 -29
- package/dist/runtime/subsystems/auth/runtime/with-auth-retry.js.map +1 -1
- package/dist/runtime/subsystems/bridge/assert-tenant-id.js +5 -18
- package/dist/runtime/subsystems/bridge/assert-tenant-id.js.map +1 -1
- package/dist/runtime/subsystems/bridge/bridge-delivery-handler.js +12 -184
- package/dist/runtime/subsystems/bridge/bridge-delivery-handler.js.map +1 -1
- package/dist/runtime/subsystems/bridge/bridge-delivery.drizzle-backend.js +10 -448
- package/dist/runtime/subsystems/bridge/bridge-delivery.drizzle-backend.js.map +1 -1
- package/dist/runtime/subsystems/bridge/bridge-delivery.memory-backend.js +5 -126
- package/dist/runtime/subsystems/bridge/bridge-delivery.memory-backend.js.map +1 -1
- package/dist/runtime/subsystems/bridge/bridge-delivery.schema.js +6 -308
- package/dist/runtime/subsystems/bridge/bridge-delivery.schema.js.map +1 -1
- package/dist/runtime/subsystems/bridge/bridge-errors.js +6 -35
- package/dist/runtime/subsystems/bridge/bridge-errors.js.map +1 -1
- package/dist/runtime/subsystems/bridge/bridge-outbox-drain-hook.js +14 -606
- package/dist/runtime/subsystems/bridge/bridge-outbox-drain-hook.js.map +1 -1
- package/dist/runtime/subsystems/bridge/bridge.module.js +35 -3476
- package/dist/runtime/subsystems/bridge/bridge.module.js.map +1 -1
- package/dist/runtime/subsystems/bridge/bridge.tokens.js +9 -7
- package/dist/runtime/subsystems/bridge/bridge.tokens.js.map +1 -1
- package/dist/runtime/subsystems/bridge/event-flow.service.js +11 -137
- package/dist/runtime/subsystems/bridge/event-flow.service.js.map +1 -1
- package/dist/runtime/subsystems/bridge/generated/registry.js +4 -2
- package/dist/runtime/subsystems/bridge/generated/registry.js.map +1 -1
- package/dist/runtime/subsystems/bridge/index.js +60 -3470
- package/dist/runtime/subsystems/bridge/index.js.map +1 -1
- package/dist/runtime/subsystems/bridge/reserved-pools.js +4 -6
- package/dist/runtime/subsystems/bridge/reserved-pools.js.map +1 -1
- package/dist/runtime/subsystems/cache/cache.drizzle-backend.js +10 -133
- package/dist/runtime/subsystems/cache/cache.drizzle-backend.js.map +1 -1
- package/dist/runtime/subsystems/cache/cache.memory-backend.js +6 -101
- package/dist/runtime/subsystems/cache/cache.memory-backend.js.map +1 -1
- package/dist/runtime/subsystems/cache/cache.module.js +10 -278
- package/dist/runtime/subsystems/cache/cache.module.js.map +1 -1
- package/dist/runtime/subsystems/cache/cache.schema.js +4 -14
- package/dist/runtime/subsystems/cache/cache.schema.js.map +1 -1
- package/dist/runtime/subsystems/cache/cache.tokens.js +6 -7
- package/dist/runtime/subsystems/cache/cache.tokens.js.map +1 -1
- package/dist/runtime/subsystems/cache/index.js +20 -278
- package/dist/runtime/subsystems/cache/index.js.map +1 -1
- package/dist/runtime/subsystems/events/domain-events.schema.js +3 -72
- package/dist/runtime/subsystems/events/domain-events.schema.js.map +1 -1
- package/dist/runtime/subsystems/events/event-bus.drizzle-backend.js +9 -413
- package/dist/runtime/subsystems/events/event-bus.drizzle-backend.js.map +1 -1
- package/dist/runtime/subsystems/events/event-bus.memory-backend.js +7 -235
- package/dist/runtime/subsystems/events/event-bus.memory-backend.js.map +1 -1
- package/dist/runtime/subsystems/events/event-bus.redis-backend.js +8 -20
- package/dist/runtime/subsystems/events/event-bus.redis-backend.js.map +1 -1
- package/dist/runtime/subsystems/events/event-keyset-cursor.js +8 -30
- package/dist/runtime/subsystems/events/event-keyset-cursor.js.map +1 -1
- package/dist/runtime/subsystems/events/event-read.protocol.js +2 -0
- package/dist/runtime/subsystems/events/event-read.protocol.js.map +1 -1
- package/dist/runtime/subsystems/events/events-errors.js +4 -11
- package/dist/runtime/subsystems/events/events-errors.js.map +1 -1
- package/dist/runtime/subsystems/events/events.module.js +15 -949
- package/dist/runtime/subsystems/events/events.module.js.map +1 -1
- package/dist/runtime/subsystems/events/events.tokens.js +10 -11
- package/dist/runtime/subsystems/events/events.tokens.js.map +1 -1
- package/dist/runtime/subsystems/events/generated/bus.js +9 -240
- package/dist/runtime/subsystems/events/generated/bus.js.map +1 -1
- package/dist/runtime/subsystems/events/generated/index.js +23 -240
- package/dist/runtime/subsystems/events/generated/index.js.map +1 -1
- package/dist/runtime/subsystems/events/generated/registry.js +5 -82
- package/dist/runtime/subsystems/events/generated/registry.js.map +1 -1
- package/dist/runtime/subsystems/events/generated/schemas.js +12 -52
- package/dist/runtime/subsystems/events/generated/schemas.js.map +1 -1
- package/dist/runtime/subsystems/events/generated/types.js +1 -0
- package/dist/runtime/subsystems/events/index.js +32 -949
- package/dist/runtime/subsystems/events/index.js.map +1 -1
- package/dist/runtime/subsystems/index.d.ts +5 -1
- package/dist/runtime/subsystems/index.js +182 -5912
- package/dist/runtime/subsystems/index.js.map +1 -1
- package/dist/runtime/subsystems/integration/build-change-source.js +6 -178
- package/dist/runtime/subsystems/integration/build-change-source.js.map +1 -1
- package/dist/runtime/subsystems/integration/deep-equal.differ.js +4 -109
- package/dist/runtime/subsystems/integration/deep-equal.differ.js.map +1 -1
- package/dist/runtime/subsystems/integration/detection-config.schema.js +11 -78
- package/dist/runtime/subsystems/integration/detection-config.schema.js.map +1 -1
- package/dist/runtime/subsystems/integration/entity-change-source-registry.memory.js +5 -30
- package/dist/runtime/subsystems/integration/entity-change-source-registry.memory.js.map +1 -1
- package/dist/runtime/subsystems/integration/entity-change-source-registry.protocol.js +4 -9
- package/dist/runtime/subsystems/integration/entity-change-source-registry.protocol.js.map +1 -1
- package/dist/runtime/subsystems/integration/execute-integration.use-case.js +6 -239
- package/dist/runtime/subsystems/integration/execute-integration.use-case.js.map +1 -1
- package/dist/runtime/subsystems/integration/incremental-read.js +5 -144
- package/dist/runtime/subsystems/integration/incremental-read.js.map +1 -1
- package/dist/runtime/subsystems/integration/index.js +83 -1352
- package/dist/runtime/subsystems/integration/index.js.map +1 -1
- package/dist/runtime/subsystems/integration/integration-audit.schema.js +10 -155
- package/dist/runtime/subsystems/integration/integration-audit.schema.js.map +1 -1
- package/dist/runtime/subsystems/integration/integration-cursor-store.drizzle-backend.js +7 -270
- package/dist/runtime/subsystems/integration/integration-cursor-store.drizzle-backend.js.map +1 -1
- package/dist/runtime/subsystems/integration/integration-cursor-store.memory-backend.js +4 -65
- package/dist/runtime/subsystems/integration/integration-cursor-store.memory-backend.js.map +1 -1
- package/dist/runtime/subsystems/integration/integration-errors.js +5 -15
- package/dist/runtime/subsystems/integration/integration-errors.js.map +1 -1
- package/dist/runtime/subsystems/integration/integration-field-diff.protocol.js +5 -7
- package/dist/runtime/subsystems/integration/integration-field-diff.protocol.js.map +1 -1
- package/dist/runtime/subsystems/integration/integration-run-recorder.drizzle-backend.js +8 -303
- package/dist/runtime/subsystems/integration/integration-run-recorder.drizzle-backend.js.map +1 -1
- package/dist/runtime/subsystems/integration/integration-run-recorder.memory-backend.js +5 -125
- package/dist/runtime/subsystems/integration/integration-run-recorder.memory-backend.js.map +1 -1
- package/dist/runtime/subsystems/integration/integration.module.js +13 -700
- package/dist/runtime/subsystems/integration/integration.module.js.map +1 -1
- package/dist/runtime/subsystems/integration/integration.tokens.js +11 -9
- package/dist/runtime/subsystems/integration/integration.tokens.js.map +1 -1
- package/dist/runtime/subsystems/integration/loopback.middleware.js +4 -16
- package/dist/runtime/subsystems/integration/loopback.middleware.js.map +1 -1
- package/dist/runtime/subsystems/integration/poll-change-source.d.ts +1 -1
- package/dist/runtime/subsystems/integration/poll-change-source.js +4 -89
- package/dist/runtime/subsystems/integration/poll-change-source.js.map +1 -1
- package/dist/runtime/subsystems/integration/webhook-change-source.d.ts +4 -3
- package/dist/runtime/subsystems/integration/webhook-change-source.js +4 -70
- package/dist/runtime/subsystems/integration/webhook-change-source.js.map +1 -1
- package/dist/runtime/subsystems/jobs/bullmq.config.js +9 -140
- package/dist/runtime/subsystems/jobs/bullmq.config.js.map +1 -1
- package/dist/runtime/subsystems/jobs/index.js +88 -2691
- package/dist/runtime/subsystems/jobs/index.js.map +1 -1
- package/dist/runtime/subsystems/jobs/job-handler.base.js +10 -49
- package/dist/runtime/subsystems/jobs/job-handler.base.js.map +1 -1
- package/dist/runtime/subsystems/jobs/job-orchestration.schema.js +13 -152
- package/dist/runtime/subsystems/jobs/job-orchestration.schema.js.map +1 -1
- package/dist/runtime/subsystems/jobs/job-orchestrator.bullmq-backend.js +36 -699
- package/dist/runtime/subsystems/jobs/job-orchestrator.bullmq-backend.js.map +1 -1
- package/dist/runtime/subsystems/jobs/job-orchestrator.drizzle-backend.js +10 -564
- package/dist/runtime/subsystems/jobs/job-orchestrator.drizzle-backend.js.map +1 -1
- package/dist/runtime/subsystems/jobs/job-orchestrator.memory-backend.js +10 -824
- package/dist/runtime/subsystems/jobs/job-orchestrator.memory-backend.js.map +1 -1
- package/dist/runtime/subsystems/jobs/job-run-keyset-cursor.js +9 -51
- package/dist/runtime/subsystems/jobs/job-run-keyset-cursor.js.map +1 -1
- package/dist/runtime/subsystems/jobs/job-run-service.drizzle-backend.js +9 -416
- package/dist/runtime/subsystems/jobs/job-run-service.drizzle-backend.js.map +1 -1
- package/dist/runtime/subsystems/jobs/job-run-service.memory-backend.js +9 -290
- package/dist/runtime/subsystems/jobs/job-run-service.memory-backend.js.map +1 -1
- package/dist/runtime/subsystems/jobs/job-step-service.drizzle-backend.js +5 -213
- package/dist/runtime/subsystems/jobs/job-step-service.drizzle-backend.js.map +1 -1
- package/dist/runtime/subsystems/jobs/job-step-service.memory-backend.js +5 -131
- package/dist/runtime/subsystems/jobs/job-step-service.memory-backend.js.map +1 -1
- package/dist/runtime/subsystems/jobs/job-worker.bullmq-backend.js +9 -175
- package/dist/runtime/subsystems/jobs/job-worker.bullmq-backend.js.map +1 -1
- package/dist/runtime/subsystems/jobs/job-worker.js +14 -613
- package/dist/runtime/subsystems/jobs/job-worker.js.map +1 -1
- package/dist/runtime/subsystems/jobs/job-worker.module.js +23 -2647
- package/dist/runtime/subsystems/jobs/job-worker.module.js.map +1 -1
- package/dist/runtime/subsystems/jobs/jobs-domain.module.js +19 -1897
- package/dist/runtime/subsystems/jobs/jobs-domain.module.js.map +1 -1
- package/dist/runtime/subsystems/jobs/jobs-domain.tokens.js +8 -9
- package/dist/runtime/subsystems/jobs/jobs-domain.tokens.js.map +1 -1
- package/dist/runtime/subsystems/jobs/jobs-errors.js +10 -78
- package/dist/runtime/subsystems/jobs/jobs-errors.js.map +1 -1
- package/dist/runtime/subsystems/jobs/memory-job-store.js +4 -15
- package/dist/runtime/subsystems/jobs/memory-job-store.js.map +1 -1
- package/dist/runtime/subsystems/jobs/pool-config.loader.js +9 -124
- package/dist/runtime/subsystems/jobs/pool-config.loader.js.map +1 -1
- package/dist/runtime/subsystems/observability/index.js +21 -310
- package/dist/runtime/subsystems/observability/index.js.map +1 -1
- package/dist/runtime/subsystems/observability/observability-errors.js +4 -9
- package/dist/runtime/subsystems/observability/observability-errors.js.map +1 -1
- package/dist/runtime/subsystems/observability/observability.module.js +11 -300
- package/dist/runtime/subsystems/observability/observability.module.js.map +1 -1
- package/dist/runtime/subsystems/observability/observability.service.js +9 -197
- package/dist/runtime/subsystems/observability/observability.service.js.map +1 -1
- package/dist/runtime/subsystems/observability/observability.tokens.js +5 -3
- package/dist/runtime/subsystems/observability/observability.tokens.js.map +1 -1
- package/dist/runtime/subsystems/observability/reporters/bridge-metrics.reporter.js +4 -84
- package/dist/runtime/subsystems/observability/reporters/bridge-metrics.reporter.js.map +1 -1
- package/dist/runtime/subsystems/observability/reporters/index.js +5 -84
- package/dist/runtime/subsystems/observability/reporters/index.js.map +1 -1
- package/dist/runtime/subsystems/storage/index.js +15 -200
- package/dist/runtime/subsystems/storage/index.js.map +1 -1
- package/dist/runtime/subsystems/storage/storage.local-backend.js +4 -103
- package/dist/runtime/subsystems/storage/storage.local-backend.js.map +1 -1
- package/dist/runtime/subsystems/storage/storage.memory-backend.js +5 -68
- package/dist/runtime/subsystems/storage/storage.memory-backend.js.map +1 -1
- package/dist/runtime/subsystems/storage/storage.module.js +8 -200
- package/dist/runtime/subsystems/storage/storage.module.js.map +1 -1
- package/dist/runtime/subsystems/storage/storage.tokens.js +5 -6
- package/dist/runtime/subsystems/storage/storage.tokens.js.map +1 -1
- package/dist/runtime/subsystems/storage/storage.utils.js +4 -14
- package/dist/runtime/subsystems/storage/storage.utils.js.map +1 -1
- package/dist/runtime/subsystems/token-key.js +5 -3
- package/dist/runtime/subsystems/token-key.js.map +1 -1
- package/dist/src/cli/index.js +637 -5454
- package/dist/src/cli/index.js.map +1 -1
- package/dist/src/index.js +68 -4170
- package/dist/src/index.js.map +1 -1
- package/package.json +1 -1
- package/runtime/subsystems/bridge/bridge-outbox-drain-hook.ts +44 -21
- package/runtime/subsystems/index.ts +27 -0
- package/runtime/subsystems/integration/poll-change-source.ts +10 -7
- package/runtime/subsystems/integration/webhook-change-source.ts +12 -8
- package/runtime/subsystems/jobs/job-worker.ts +17 -11
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../runtime/subsystems/events/events.module.ts"],"sourcesContent":["/**\n * EventsModule — DynamicModule factory for the event bus subsystem.\n *\n * Register once in AppModule:\n * ```typescript\n * @Module({\n * imports: [\n * EventsModule.forRoot({ backend: 'drizzle' }),\n * ],\n * })\n * export class AppModule {}\n * ```\n *\n * Tests swap to the memory backend without touching application code:\n * ```typescript\n * Test.createTestingModule({\n * imports: [EventsModule.forRoot({ backend: 'memory' })],\n * });\n * ```\n *\n * Per-pool drain isolation (EVT-4):\n * ```typescript\n * EventsModule.forRoot({ backend: 'drizzle', pools: ['events_change'] });\n * ```\n * Each process restricts its drain loop to the pools listed here. `pools`\n * is undefined by default → drain all pending rows (backwards-compatible).\n *\n * Typed facade + multi-tenancy (EVT-6):\n * - `TYPED_EVENT_BUS` resolves to the generated `TypedEventBus` wrapping\n * whichever backend is selected.\n * - `multiTenant: true` makes `TypedEventBus.publish` throw\n * `MissingTenantIdError` when the caller forgets `metadata.tenantId`.\n *\n * `global: true` means entity modules do not need to import EventsModule\n * individually — the EVENT_BUS and TYPED_EVENT_BUS tokens are available\n * project-wide.\n *\n * Async configuration (`forRootAsync`):\n * The async factory returns `EventsModuleOptions`; the EVENT_BUS provider\n * then receives its backend dependencies — DRIZZLE for the drizzle\n * backend, REDIS_URL for the redis backend, the resolved options for the\n * memory backend — through a proper `useFactory` so Nest DI wires them\n * correctly. Earlier revisions hand-constructed backends with\n * `new Class()` which silently left `db` / `redisUrl` undefined\n * (issue #108).\n */\nimport { Module, type DynamicModule, type Provider, type Type } from '@nestjs/common';\nimport {\n EVENT_BUS,\n EVENT_READ_PORT,\n EVENTS_MODULE_OPTIONS,\n EVENTS_MULTI_TENANT,\n REDIS_URL,\n TYPED_EVENT_BUS,\n} from './events.tokens';\nimport { DRIZZLE } from '../../constants/tokens';\nimport type { DrizzleClient } from '../../types/drizzle';\nimport { DrizzleEventBus } from './event-bus.drizzle-backend';\nimport { MemoryEventBus } from './event-bus.memory-backend';\n// #6 — `RedisEventBus` is lazy-loaded only when `backend: 'redis'` is selected.\n// The file is filtered out of the vendor set for non-redis installs (see\n// `backendFileFilter` in src/cli/commands/subsystem.ts); the dynamic-string\n// import below makes TS treat the specifier as `any` so the consumer's tsc\n// never tries to resolve the absent file.\nimport { TypedEventBus } from './generated/bus';\n\n/**\n * Lazy-load the Redis backend. Routed through a non-literal specifier so\n * the consumer's `tsc` doesn't resolve `./event-bus.redis-backend` at type\n * check time — important because that file is filtered out of drizzle/\n * memory installs (#6).\n */\nasync function loadRedisEventBus(): Promise<new (url: string) => object> {\n // Non-literal specifier — TS gives this an `any` module type, sidestepping\n // resolution of a file that may not be vendored.\n const specifier = './event-bus.redis-backend';\n const mod = (await import(specifier)) as { RedisEventBus: new (url: string) => object };\n return mod.RedisEventBus;\n}\n\nexport interface EventsModuleOptions {\n backend: 'drizzle' | 'memory' | 'redis';\n /**\n * Redis connection URL used when `backend` is `'redis'`.\n * Falls back to the REDIS_URL environment variable, then\n * `redis://localhost:6379` if neither is set.\n */\n redisUrl?: string;\n /**\n * Restrict the drain loop to these pools. Each pool name matches the\n * `domain_events.pool` column (populated from `event.metadata.pool` at\n * publish time). Leave undefined to drain all pending rows.\n *\n * Typical lane split: one process per `events_inbound` /\n * `events_change` / `events_outbound` so a slow outbound handler\n * cannot stall change-event propagation (see ADR-022).\n */\n pools?: string[];\n /**\n * Multi-tenancy opt-in (EVT-6).\n *\n * When `true`, every `TypedEventBus.publish()` call must supply\n * `opts.metadata.tenantId` — otherwise it throws `MissingTenantIdError`.\n * The tenantId is preserved on `event.metadata` and, for the Drizzle\n * backend, written to `domain_events.tenant_id` (EVT-4).\n *\n * Drain-side tenant filtering is deferred — the tenant-context model\n * (per-process vs. per-request vs. async-local-storage) is still\n * unsettled; see ADR-024 §Multi-tenancy. Only the publish-side\n * requirement ships here.\n *\n * Defaults to `false`.\n */\n multiTenant?: boolean;\n /**\n * The generated `TypedEventBus` class to bind to `TYPED_EVENT_BUS`.\n *\n * **Package mode (ADR-037).** When the runtime is imported from\n * `@pattern-stack/codegen` (not vendored), the bundled `./generated/bus`\n * `TypedEventBus` is typed to an EMPTY event union and reads the bundled\n * empty `eventRegistry` — a consumer's `events/*.yaml` are scanned into\n * `src/generated/events/bus.ts` (typed to THEIR union, reading THEIR\n * registry), which the package can't import. The generated subsystem barrel\n * therefore threads that class in here:\n * `EventsModule.forRoot({ ..., typedBus: TypedEventBus })`. Nest constructs\n * it with this module's `EVENT_BUS` + `EVENTS_MULTI_TENANT` providers (the\n * generated class injects the same string-valued tokens, which match across\n * the package boundary).\n *\n * Omitted (vendored mode / tests) ⇒ falls back to the bundled\n * `./generated/bus`, which in a vendored tree IS the consumer's generated\n * file. Without this, a package-mode consumer's typed `publish<'…'>()` calls\n * resolve against the empty union and their events never get the right\n * `pool` / `direction` stamped.\n *\n * Only consulted by `forRoot` (the path the barrel emits); `forRootAsync`\n * keeps the bundled bus.\n */\n typedBus?: Type<unknown>;\n}\n\nexport interface EventsModuleAsyncOptions {\n useFactory: (...args: unknown[]) => Promise<EventsModuleOptions> | EventsModuleOptions;\n inject?: unknown[];\n imports?: unknown[];\n}\n\n/**\n * Shared provider set: `TypedEventBus` itself, the `TYPED_EVENT_BUS` token\n * binding, and the resolved `EVENTS_MULTI_TENANT` flag. Returned from one\n * place so every `forRoot` branch and `forRootAsync` agree.\n */\nfunction buildTypedBusProviders(\n multiTenant: boolean,\n typedBus?: Type<unknown>,\n): Provider[] {\n // Package mode threads the consumer's generated `TypedEventBus` (typed to\n // their event union, reading their registry) via `typedBus`; vendored mode\n // omits it and we fall back to the bundled `./generated/bus` (which IS the\n // consumer's generated file in a vendored tree). See `EventsModuleOptions.typedBus`.\n const BusClass = typedBus ?? TypedEventBus;\n return [\n BusClass,\n { provide: TYPED_EVENT_BUS, useExisting: BusClass },\n { provide: EVENTS_MULTI_TENANT, useValue: multiTenant },\n ];\n}\n\n/**\n * Construct the backend instance for the async path, routing constructor\n * arguments through Nest-resolved dependencies.\n *\n * DRIZZLE is declared optional at inject time so that memory-backend\n * consumers aren't required to also import `DatabaseModule`. If the\n * drizzle backend is selected but no DRIZZLE provider is registered, we\n * throw a clear error instead of silently constructing a broken bus.\n */\nasync function buildEventBusAsync(\n options: EventsModuleOptions,\n db: DrizzleClient | null,\n redisUrl: string,\n): Promise<unknown> {\n if (options.backend === 'drizzle') {\n if (!db) {\n throw new Error(\n \"EventsModule.forRootAsync: backend: 'drizzle' selected but DRIZZLE provider is not available. \" +\n 'Ensure DatabaseModule (or another provider exposing DRIZZLE) is imported before EventsModule.forRootAsync.',\n );\n }\n return new DrizzleEventBus(db, options);\n }\n if (options.backend === 'redis') {\n // #6: lazy import — the redis backend ships only with `--backend redis`\n // installs; drizzle/memory consumers never touch the file.\n const RedisEventBus = await loadRedisEventBus();\n return new RedisEventBus(redisUrl);\n }\n return new MemoryEventBus(options);\n}\n\n@Module({})\nexport class EventsModule {\n static forRootAsync(asyncOptions: EventsModuleAsyncOptions): DynamicModule {\n return {\n module: EventsModule,\n global: true,\n imports: (asyncOptions.imports ?? []) as Parameters<typeof Module>[0]['imports'],\n providers: [\n {\n provide: EVENTS_MODULE_OPTIONS,\n useFactory: asyncOptions.useFactory,\n inject: (asyncOptions.inject ?? []) as (string | symbol | Function)[],\n },\n {\n provide: EVENTS_MULTI_TENANT,\n useFactory: (options: EventsModuleOptions) => options.multiTenant ?? false,\n inject: [EVENTS_MODULE_OPTIONS],\n },\n {\n provide: REDIS_URL,\n useFactory: (options: EventsModuleOptions) =>\n options.redisUrl ?? process.env['REDIS_URL'] ?? 'redis://localhost:6379',\n inject: [EVENTS_MODULE_OPTIONS],\n },\n {\n provide: EVENT_BUS,\n useFactory: (\n options: EventsModuleOptions,\n db: DrizzleClient | null,\n redisUrl: string,\n ) => buildEventBusAsync(options, db, redisUrl),\n inject: [\n EVENTS_MODULE_OPTIONS,\n { token: DRIZZLE, optional: true },\n REDIS_URL,\n ],\n },\n {\n // Read port (OBS-LIST-1). Drizzle + memory backends implement\n // IEventReadPort on the EVENT_BUS instance; the redis backend\n // retains no history, so EVENT_READ_PORT resolves to `null` and\n // optional consumers (the observability combiner) degrade to\n // empty results.\n provide: EVENT_READ_PORT,\n useFactory: (options: EventsModuleOptions, bus: unknown) =>\n options.backend === 'redis' ? null : bus,\n inject: [EVENTS_MODULE_OPTIONS, EVENT_BUS],\n },\n TypedEventBus,\n { provide: TYPED_EVENT_BUS, useExisting: TypedEventBus },\n ],\n exports: [EVENT_BUS, EVENT_READ_PORT, TYPED_EVENT_BUS, EVENTS_MULTI_TENANT],\n };\n }\n\n static forRoot(\n options: EventsModuleOptions = { backend: 'drizzle' },\n ): DynamicModule {\n const multiTenant = options.multiTenant ?? false;\n\n if (options.backend === 'redis') {\n const resolvedUrl =\n options.redisUrl ?? process.env['REDIS_URL'] ?? 'redis://localhost:6379';\n\n return {\n module: EventsModule,\n global: true,\n providers: [\n { provide: EVENTS_MODULE_OPTIONS, useValue: options },\n { provide: REDIS_URL, useValue: resolvedUrl },\n {\n // #6: useFactory + dynamic import so the consumer's tsc never\n // needs to resolve `event-bus.redis-backend.ts` for drizzle/\n // memory installs (the file is filtered out by\n // `backendFileFilter`). Nest awaits async factories + manages\n // lifecycle on the returned instance, so we drop the old bare\n // `RedisEventBus` provider entry.\n provide: EVENT_BUS,\n useFactory: async (url: string): Promise<object> => {\n const RedisEventBus = await loadRedisEventBus();\n return new RedisEventBus(url);\n },\n inject: [REDIS_URL],\n },\n ...buildTypedBusProviders(multiTenant, options.typedBus),\n ],\n exports: [EVENT_BUS, TYPED_EVENT_BUS, EVENTS_MULTI_TENANT],\n };\n }\n\n const provider =\n options.backend === 'drizzle'\n ? { provide: EVENT_BUS, useClass: DrizzleEventBus }\n : { provide: EVENT_BUS, useClass: MemoryEventBus };\n\n return {\n module: EventsModule,\n global: true,\n providers: [\n { provide: EVENTS_MODULE_OPTIONS, useValue: options },\n provider,\n // Read port (OBS-LIST-1): drizzle + memory backends implement\n // IEventReadPort on the same instance as EVENT_BUS. The redis\n // backend retains no history and does not provide this token.\n { provide: EVENT_READ_PORT, useExisting: EVENT_BUS },\n ...buildTypedBusProviders(multiTenant, options.typedBus),\n ],\n exports: [EVENT_BUS, EVENT_READ_PORT, TYPED_EVENT_BUS, EVENTS_MULTI_TENANT],\n };\n }\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
// runtime/subsystems/observability/observability-errors.ts
|
|
2
|
+
var ObservabilityError = class extends Error {
|
|
3
|
+
constructor(message, cause) {
|
|
4
|
+
super(message);
|
|
5
|
+
this.cause = cause;
|
|
6
|
+
this.name = "ObservabilityError";
|
|
7
|
+
}
|
|
8
|
+
cause;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export {
|
|
12
|
+
ObservabilityError
|
|
13
|
+
};
|
|
14
|
+
//# sourceMappingURL=chunk-EWYCWP4H.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../runtime/subsystems/observability/observability-errors.ts"],"sourcesContent":["/**\n * Base class for observability-specific errors.\n *\n * Phase-1 `IObservability` methods do not throw — missing sibling ports\n * degrade to empty shapes (see `ObservabilityService`). This class exists\n * so future extensions (OBS-6 reporter misconfiguration, phase-2 Drizzle\n * extensions for `pg_stat_*` sampling, etc.) have a named base without\n * churning the barrel when they land.\n */\nexport class ObservabilityError extends Error {\n constructor(\n message: string,\n override readonly cause?: unknown,\n ) {\n super(message);\n this.name = 'ObservabilityError';\n }\n}\n"],"mappings":";AASO,IAAM,qBAAN,cAAiC,MAAM;AAAA,EAC5C,YACE,SACkB,OAClB;AACA,UAAM,OAAO;AAFK;AAGlB,SAAK,OAAO;AAAA,EACd;AAAA,EAJoB;AAKtB;","names":[]}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
// runtime/base-classes/base-read-use-cases.ts
|
|
2
|
+
var BaseFindByIdUseCase = class {
|
|
3
|
+
constructor(service) {
|
|
4
|
+
this.service = service;
|
|
5
|
+
}
|
|
6
|
+
service;
|
|
7
|
+
/**
|
|
8
|
+
* Find a single entity by its primary key.
|
|
9
|
+
* Returns null if not found.
|
|
10
|
+
*/
|
|
11
|
+
execute(id) {
|
|
12
|
+
return this.service.findById(id);
|
|
13
|
+
}
|
|
14
|
+
};
|
|
15
|
+
var BaseListUseCase = class {
|
|
16
|
+
constructor(service) {
|
|
17
|
+
this.service = service;
|
|
18
|
+
}
|
|
19
|
+
service;
|
|
20
|
+
/**
|
|
21
|
+
* List all entities (no filters).
|
|
22
|
+
* Controllers that need filtered lists should use a dedicated use case.
|
|
23
|
+
*/
|
|
24
|
+
execute() {
|
|
25
|
+
return this.service.list();
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export {
|
|
30
|
+
BaseFindByIdUseCase,
|
|
31
|
+
BaseListUseCase
|
|
32
|
+
};
|
|
33
|
+
//# sourceMappingURL=chunk-EXVDJMIY.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../runtime/base-classes/base-read-use-cases.ts"],"sourcesContent":["/**\n * Base read use cases\n *\n * Abstract base classes for auto-generated per-entity read use cases.\n * Controllers always import use case classes — never services directly (ADR-003).\n *\n * Each entity gets a single generated file with two named exports:\n * - ContactFindByIdUseCase extends BaseFindByIdUseCase<ContactService, Contact>\n * - ContactListUseCase extends BaseListUseCase<ContactService, Contact>\n *\n * Note: @Injectable() is applied on concrete use case classes (not here),\n * matching the pattern established by BaseRepository and BaseService.\n */\n\n// ============================================================================\n// BaseFindByIdUseCase\n// ============================================================================\n\n/**\n * Structural interface for any service that supports findById.\n * Keeps base use cases decoupled from concrete service implementations.\n */\nexport interface IFindByIdService<TEntity> {\n findById(id: string): Promise<TEntity | null>;\n}\n\n/**\n * Base class for generated FindById use cases.\n *\n * Generated usage:\n * ```typescript\n * @Injectable()\n * export class ContactFindByIdUseCase extends BaseFindByIdUseCase<ContactService, Contact> {\n * constructor(service: ContactService) { super(service); }\n * }\n * ```\n */\nexport abstract class BaseFindByIdUseCase<\n TService extends IFindByIdService<TEntity>,\n TEntity,\n> {\n constructor(protected readonly service: TService) {}\n\n /**\n * Find a single entity by its primary key.\n * Returns null if not found.\n */\n execute(id: string): Promise<TEntity | null> {\n return this.service.findById(id);\n }\n}\n\n// ============================================================================\n// BaseListUseCase\n// ============================================================================\n\n/**\n * Structural interface for any service that supports list.\n */\nexport interface IListService<TEntity> {\n list(options?: unknown): Promise<TEntity[]>;\n}\n\n/**\n * Base class for generated List use cases.\n *\n * Generated usage:\n * ```typescript\n * @Injectable()\n * export class ContactListUseCase extends BaseListUseCase<ContactService, Contact> {\n * constructor(service: ContactService) { super(service); }\n * }\n * ```\n */\nexport abstract class BaseListUseCase<\n TService extends IListService<TEntity>,\n TEntity,\n> {\n constructor(protected readonly service: TService) {}\n\n /**\n * List all entities (no filters).\n * Controllers that need filtered lists should use a dedicated use case.\n */\n execute(): Promise<TEntity[]> {\n return this.service.list();\n }\n}\n"],"mappings":";AAqCO,IAAe,sBAAf,MAGL;AAAA,EACA,YAA+B,SAAmB;AAAnB;AAAA,EAAoB;AAAA,EAApB;AAAA;AAAA;AAAA;AAAA;AAAA,EAM/B,QAAQ,IAAqC;AAC3C,WAAO,KAAK,QAAQ,SAAS,EAAE;AAAA,EACjC;AACF;AAwBO,IAAe,kBAAf,MAGL;AAAA,EACA,YAA+B,SAAmB;AAAnB;AAAA,EAAoB;AAAA,EAApB;AAAA;AAAA;AAAA;AAAA;AAAA,EAM/B,UAA8B;AAC5B,WAAO,KAAK,QAAQ,KAAK;AAAA,EAC3B;AACF;","names":[]}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// runtime/subsystems/cache/cache.schema.ts
|
|
2
|
+
import { pgTable, text, jsonb, timestamp } from "drizzle-orm/pg-core";
|
|
3
|
+
var cacheEntries = pgTable(
|
|
4
|
+
"cache_entries",
|
|
5
|
+
{
|
|
6
|
+
/** Cache key — primary key, text (not uuid) to support arbitrary key namespacing. */
|
|
7
|
+
key: text("key").primaryKey(),
|
|
8
|
+
/** Cached value serialised as JSONB. */
|
|
9
|
+
value: jsonb("value").notNull(),
|
|
10
|
+
/** NULL means the entry never expires. */
|
|
11
|
+
expiresAt: timestamp("expires_at", { withTimezone: true })
|
|
12
|
+
}
|
|
13
|
+
// Index: add (expires_at) via migration for cleanup queries
|
|
14
|
+
);
|
|
15
|
+
|
|
16
|
+
export {
|
|
17
|
+
cacheEntries
|
|
18
|
+
};
|
|
19
|
+
//# sourceMappingURL=chunk-FASRXRX5.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../runtime/subsystems/cache/cache.schema.ts"],"sourcesContent":["/**\n * Drizzle schema for the cache_entries table.\n *\n * This table backs the DrizzleCacheService. TTL is enforced by filtering\n * on expiresAt at read time; a periodic cleanup job removes stale rows.\n *\n * Indexes:\n * - PRIMARY KEY on key (point-lookup)\n * - (expiresAt) for the cleanup query\n */\nimport { pgTable, text, jsonb, timestamp } from 'drizzle-orm/pg-core';\nimport type { InferSelectModel } from 'drizzle-orm';\n\nexport const cacheEntries = pgTable(\n 'cache_entries',\n {\n /** Cache key — primary key, text (not uuid) to support arbitrary key namespacing. */\n key: text('key').primaryKey(),\n /** Cached value serialised as JSONB. */\n value: jsonb('value').notNull(),\n /** NULL means the entry never expires. */\n expiresAt: timestamp('expires_at', { withTimezone: true }),\n },\n // Index: add (expires_at) via migration for cleanup queries\n);\n\nexport type CacheEntry = InferSelectModel<typeof cacheEntries>;\n"],"mappings":";AAUA,SAAS,SAAS,MAAM,OAAO,iBAAiB;AAGzC,IAAM,eAAe;AAAA,EAC1B;AAAA,EACA;AAAA;AAAA,IAEE,KAAK,KAAK,KAAK,EAAE,WAAW;AAAA;AAAA,IAE5B,OAAO,MAAM,OAAO,EAAE,QAAQ;AAAA;AAAA,IAE9B,WAAW,UAAU,cAAc,EAAE,cAAc,KAAK,CAAC;AAAA,EAC3D;AAAA;AAEF;","names":[]}
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
import {
|
|
2
|
+
clampLimit,
|
|
3
|
+
decodeKeysetCursor,
|
|
4
|
+
encodeKeysetCursor,
|
|
5
|
+
toJobRunSummary
|
|
6
|
+
} from "./chunk-L3LZWWSX.js";
|
|
7
|
+
import {
|
|
8
|
+
MissingTenantIdError
|
|
9
|
+
} from "./chunk-T4BIIU5E.js";
|
|
10
|
+
import {
|
|
11
|
+
JOBS_MULTI_TENANT,
|
|
12
|
+
JOB_ORCHESTRATOR
|
|
13
|
+
} from "./chunk-BIO6F7YI.js";
|
|
14
|
+
import {
|
|
15
|
+
jobRuns
|
|
16
|
+
} from "./chunk-OKXZ63IA.js";
|
|
17
|
+
import {
|
|
18
|
+
DRIZZLE
|
|
19
|
+
} from "./chunk-U64T4YZE.js";
|
|
20
|
+
import {
|
|
21
|
+
__decorateClass,
|
|
22
|
+
__decorateParam
|
|
23
|
+
} from "./chunk-2E224ZSN.js";
|
|
24
|
+
|
|
25
|
+
// runtime/subsystems/jobs/job-run-service.drizzle-backend.ts
|
|
26
|
+
import { Inject, Injectable } from "@nestjs/common";
|
|
27
|
+
import { and, asc, desc, eq, gte, inArray, isNull, lt, or, sql } from "drizzle-orm";
|
|
28
|
+
var NON_TERMINAL_STATUSES = [
|
|
29
|
+
"pending",
|
|
30
|
+
"running",
|
|
31
|
+
"waiting"
|
|
32
|
+
];
|
|
33
|
+
var DrizzleJobRunService = class {
|
|
34
|
+
constructor(db, orchestrator, multiTenant) {
|
|
35
|
+
this.db = db;
|
|
36
|
+
this.orchestrator = orchestrator;
|
|
37
|
+
this.multiTenant = multiTenant;
|
|
38
|
+
}
|
|
39
|
+
db;
|
|
40
|
+
orchestrator;
|
|
41
|
+
multiTenant;
|
|
42
|
+
/**
|
|
43
|
+
* JOB-8 — produce the tenant WHERE fragment (or `null` to opt out).
|
|
44
|
+
* Returns `null` when multi-tenancy is off (caller skips the predicate).
|
|
45
|
+
* Throws `MissingTenantIdError` when on + `undefined`.
|
|
46
|
+
* When on + explicit `null`, filters `tenant_id IS NULL`.
|
|
47
|
+
*/
|
|
48
|
+
tenantCondition(method, tenantId) {
|
|
49
|
+
if (!this.multiTenant) return null;
|
|
50
|
+
if (tenantId === void 0) throw new MissingTenantIdError(method);
|
|
51
|
+
return tenantId === null ? isNull(jobRuns.tenantId) : eq(jobRuns.tenantId, tenantId);
|
|
52
|
+
}
|
|
53
|
+
async listForScope(entityType, entityId, opts = {}) {
|
|
54
|
+
const conditions = [
|
|
55
|
+
eq(jobRuns.scopeEntityType, entityType),
|
|
56
|
+
eq(jobRuns.scopeEntityId, entityId)
|
|
57
|
+
];
|
|
58
|
+
const tenantCond = this.tenantCondition("listForScope", opts.tenantId);
|
|
59
|
+
if (tenantCond) conditions.push(tenantCond);
|
|
60
|
+
if (opts.status) {
|
|
61
|
+
if (Array.isArray(opts.status)) {
|
|
62
|
+
conditions.push(inArray(jobRuns.status, opts.status));
|
|
63
|
+
} else {
|
|
64
|
+
conditions.push(eq(jobRuns.status, opts.status));
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
if (opts.jobType) {
|
|
68
|
+
conditions.push(eq(jobRuns.jobType, opts.jobType));
|
|
69
|
+
}
|
|
70
|
+
const orderCol = (() => {
|
|
71
|
+
switch (opts.orderBy) {
|
|
72
|
+
case "created_at asc":
|
|
73
|
+
return asc(jobRuns.createdAt);
|
|
74
|
+
case "run_at desc":
|
|
75
|
+
return desc(jobRuns.runAt);
|
|
76
|
+
case "run_at asc":
|
|
77
|
+
return asc(jobRuns.runAt);
|
|
78
|
+
case "created_at desc":
|
|
79
|
+
default:
|
|
80
|
+
return desc(jobRuns.createdAt);
|
|
81
|
+
}
|
|
82
|
+
})();
|
|
83
|
+
let q = this.db.select().from(jobRuns).where(and(...conditions)).orderBy(orderCol).$dynamic();
|
|
84
|
+
if (typeof opts.limit === "number") {
|
|
85
|
+
q = q.limit(opts.limit);
|
|
86
|
+
}
|
|
87
|
+
if (typeof opts.offset === "number") {
|
|
88
|
+
q = q.offset(opts.offset);
|
|
89
|
+
}
|
|
90
|
+
const rows = await q;
|
|
91
|
+
return rows;
|
|
92
|
+
}
|
|
93
|
+
async cancelForScope(entityType, entityId, opts = {}) {
|
|
94
|
+
const tenantCond = this.tenantCondition("cancelForScope", opts.tenantId);
|
|
95
|
+
const conditions = [
|
|
96
|
+
eq(jobRuns.scopeEntityType, entityType),
|
|
97
|
+
eq(jobRuns.scopeEntityId, entityId),
|
|
98
|
+
inArray(jobRuns.status, NON_TERMINAL_STATUSES)
|
|
99
|
+
];
|
|
100
|
+
if (tenantCond) conditions.push(tenantCond);
|
|
101
|
+
const rows = await this.db.select({ id: jobRuns.id }).from(jobRuns).where(and(...conditions));
|
|
102
|
+
for (const { id } of rows) {
|
|
103
|
+
await this.orchestrator.cancel(id, {
|
|
104
|
+
cascade: true,
|
|
105
|
+
tenantId: opts.tenantId
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
async rescheduleForScope(entityType, entityId, newRunAt, opts = {}) {
|
|
110
|
+
const tenantCond = this.tenantCondition("rescheduleForScope", opts.tenantId);
|
|
111
|
+
const conditions = [
|
|
112
|
+
eq(jobRuns.scopeEntityType, entityType),
|
|
113
|
+
eq(jobRuns.scopeEntityId, entityId),
|
|
114
|
+
eq(jobRuns.status, "pending")
|
|
115
|
+
];
|
|
116
|
+
if (tenantCond) conditions.push(tenantCond);
|
|
117
|
+
await this.db.update(jobRuns).set({ runAt: newRunAt, updatedAt: /* @__PURE__ */ new Date() }).where(and(...conditions));
|
|
118
|
+
}
|
|
119
|
+
async countByPoolAndStatus(tenantId) {
|
|
120
|
+
const tenantCond = this.tenantCondition("countByPoolAndStatus", tenantId);
|
|
121
|
+
const rows = await this.db.select({
|
|
122
|
+
pool: jobRuns.pool,
|
|
123
|
+
status: jobRuns.status,
|
|
124
|
+
count: sql`count(*)::int`.as("count")
|
|
125
|
+
}).from(jobRuns).where(tenantCond ?? void 0).groupBy(jobRuns.pool, jobRuns.status);
|
|
126
|
+
return rows.map((r) => ({
|
|
127
|
+
pool: r.pool,
|
|
128
|
+
status: r.status,
|
|
129
|
+
count: Number(r.count)
|
|
130
|
+
}));
|
|
131
|
+
}
|
|
132
|
+
async listRecentFailed(limit, tenantId) {
|
|
133
|
+
const conditions = [eq(jobRuns.status, "failed")];
|
|
134
|
+
const tenantCond = this.tenantCondition("listRecentFailed", tenantId);
|
|
135
|
+
if (tenantCond) conditions.push(tenantCond);
|
|
136
|
+
const rows = await this.db.select().from(jobRuns).where(and(...conditions)).orderBy(desc(jobRuns.finishedAt), desc(jobRuns.updatedAt)).limit(limit);
|
|
137
|
+
return rows.map((r) => ({
|
|
138
|
+
runId: r.id,
|
|
139
|
+
jobType: r.jobType,
|
|
140
|
+
pool: r.pool,
|
|
141
|
+
scopeEntityType: r.scopeEntityType,
|
|
142
|
+
scopeEntityId: r.scopeEntityId,
|
|
143
|
+
tenantId: r.tenantId,
|
|
144
|
+
attempts: r.attempts,
|
|
145
|
+
errorMessage: r.error?.message ?? null,
|
|
146
|
+
failedAt: r.finishedAt ?? r.updatedAt,
|
|
147
|
+
createdAt: r.createdAt
|
|
148
|
+
}));
|
|
149
|
+
}
|
|
150
|
+
async listJobRuns(query = {}) {
|
|
151
|
+
const limit = clampLimit(query.limit);
|
|
152
|
+
const conditions = [];
|
|
153
|
+
const tenantCond = this.tenantCondition("listJobRuns", query.tenantId);
|
|
154
|
+
if (tenantCond) conditions.push(tenantCond);
|
|
155
|
+
if (query.poolId) conditions.push(eq(jobRuns.pool, query.poolId));
|
|
156
|
+
if (query.rootRunId) conditions.push(eq(jobRuns.rootRunId, query.rootRunId));
|
|
157
|
+
if (query.status) conditions.push(eq(jobRuns.status, query.status));
|
|
158
|
+
if (query.since) conditions.push(gte(jobRuns.createdAt, query.since));
|
|
159
|
+
if (query.cursor) {
|
|
160
|
+
const keyset = decodeKeysetCursor(query.cursor);
|
|
161
|
+
if (keyset) {
|
|
162
|
+
conditions.push(
|
|
163
|
+
or(
|
|
164
|
+
lt(jobRuns.createdAt, keyset.createdAt),
|
|
165
|
+
and(
|
|
166
|
+
eq(jobRuns.createdAt, keyset.createdAt),
|
|
167
|
+
lt(jobRuns.id, keyset.id)
|
|
168
|
+
)
|
|
169
|
+
)
|
|
170
|
+
);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
const rows = await this.db.select().from(jobRuns).where(conditions.length > 0 ? and(...conditions) : void 0).orderBy(desc(jobRuns.createdAt), desc(jobRuns.id)).limit(limit + 1);
|
|
174
|
+
const hasMore = rows.length > limit;
|
|
175
|
+
const page = hasMore ? rows.slice(0, limit) : rows;
|
|
176
|
+
const items = page.map(toJobRunSummary);
|
|
177
|
+
const last = page[page.length - 1];
|
|
178
|
+
const nextCursor = hasMore && last ? encodeKeysetCursor({ createdAt: last.createdAt, id: last.id }) : null;
|
|
179
|
+
return { items, nextCursor };
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Internal helper used by cascade paths (not on the public protocol).
|
|
183
|
+
* Exposed as a public method on the concrete class so infrastructure
|
|
184
|
+
* code (cascade tests, debug tools) can call it without a cast.
|
|
185
|
+
*/
|
|
186
|
+
async findByRootRunId(rootRunId) {
|
|
187
|
+
const rows = await this.db.select().from(jobRuns).where(eq(jobRuns.rootRunId, rootRunId));
|
|
188
|
+
return rows;
|
|
189
|
+
}
|
|
190
|
+
};
|
|
191
|
+
DrizzleJobRunService = __decorateClass([
|
|
192
|
+
Injectable(),
|
|
193
|
+
__decorateParam(0, Inject(DRIZZLE)),
|
|
194
|
+
__decorateParam(1, Inject(JOB_ORCHESTRATOR)),
|
|
195
|
+
__decorateParam(2, Inject(JOBS_MULTI_TENANT))
|
|
196
|
+
], DrizzleJobRunService);
|
|
197
|
+
|
|
198
|
+
export {
|
|
199
|
+
DrizzleJobRunService
|
|
200
|
+
};
|
|
201
|
+
//# sourceMappingURL=chunk-FBGHYQIZ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../runtime/subsystems/jobs/job-run-service.drizzle-backend.ts"],"sourcesContent":["/**\n * DrizzleJobRunService — scope-oriented reads and bulk operations against\n * `job_run` (ADR-022, JOB-3).\n *\n * Separate from the orchestrator because the access pattern differs: this\n * service scans by `(scope_entity_type, scope_entity_id)` via\n * `idx_job_run_scope`, whereas orchestrator mutates individual runs by id.\n */\nimport { Inject, Injectable } from '@nestjs/common';\nimport { and, asc, desc, eq, gte, inArray, isNull, lt, or, sql } from 'drizzle-orm';\nimport type { DrizzleClient } from '../../types/drizzle';\nimport { DRIZZLE } from '../../constants/tokens';\nimport { jobRuns, type JobRunRow } from './job-orchestration.schema';\nimport type { JobRun } from './job-orchestrator.protocol';\nimport type {\n IJobRunService,\n ListForScopeOptions,\n CancelForScopeOptions,\n RescheduleForScopeOptions,\n PoolStatusCount,\n JobRunFailure,\n ListJobRunsQuery,\n JobRunPage,\n JobRunSummary,\n} from './job-run-service.protocol';\nimport {\n clampLimit,\n decodeKeysetCursor,\n encodeKeysetCursor,\n toJobRunSummary,\n} from './job-run-keyset-cursor';\nimport type { IJobOrchestrator } from './job-orchestrator.protocol';\nimport { JOB_ORCHESTRATOR, JOBS_MULTI_TENANT } from './jobs-domain.tokens';\nimport { MissingTenantIdError } from './jobs-errors';\n\nconst NON_TERMINAL_STATUSES: JobRunRow['status'][] = [\n 'pending',\n 'running',\n 'waiting',\n];\n\n@Injectable()\nexport class DrizzleJobRunService implements IJobRunService {\n constructor(\n @Inject(DRIZZLE) private readonly db: DrizzleClient,\n @Inject(JOB_ORCHESTRATOR) private readonly orchestrator: IJobOrchestrator,\n @Inject(JOBS_MULTI_TENANT) private readonly multiTenant: boolean,\n ) {}\n\n /**\n * JOB-8 — produce the tenant WHERE fragment (or `null` to opt out).\n * Returns `null` when multi-tenancy is off (caller skips the predicate).\n * Throws `MissingTenantIdError` when on + `undefined`.\n * When on + explicit `null`, filters `tenant_id IS NULL`.\n */\n private tenantCondition(\n method: string,\n tenantId: string | null | undefined,\n ) {\n if (!this.multiTenant) return null;\n if (tenantId === undefined) throw new MissingTenantIdError(method);\n return tenantId === null\n ? isNull(jobRuns.tenantId)\n : eq(jobRuns.tenantId, tenantId);\n }\n\n async listForScope(\n entityType: string,\n entityId: string,\n opts: ListForScopeOptions = {},\n ): Promise<JobRun[]> {\n const conditions = [\n eq(jobRuns.scopeEntityType, entityType),\n eq(jobRuns.scopeEntityId, entityId),\n ];\n const tenantCond = this.tenantCondition('listForScope', opts.tenantId);\n if (tenantCond) conditions.push(tenantCond);\n if (opts.status) {\n if (Array.isArray(opts.status)) {\n conditions.push(inArray(jobRuns.status, opts.status));\n } else {\n conditions.push(eq(jobRuns.status, opts.status));\n }\n }\n if (opts.jobType) {\n conditions.push(eq(jobRuns.jobType, opts.jobType));\n }\n\n const orderCol = (() => {\n switch (opts.orderBy) {\n case 'created_at asc':\n return asc(jobRuns.createdAt);\n case 'run_at desc':\n return desc(jobRuns.runAt);\n case 'run_at asc':\n return asc(jobRuns.runAt);\n case 'created_at desc':\n default:\n return desc(jobRuns.createdAt);\n }\n })();\n\n let q = this.db\n .select()\n .from(jobRuns)\n .where(and(...conditions))\n .orderBy(orderCol)\n .$dynamic();\n\n if (typeof opts.limit === 'number') {\n q = q.limit(opts.limit);\n }\n if (typeof opts.offset === 'number') {\n q = q.offset(opts.offset);\n }\n\n const rows = await q;\n return rows as JobRun[];\n }\n\n async cancelForScope(\n entityType: string,\n entityId: string,\n opts: CancelForScopeOptions = {},\n ): Promise<void> {\n const tenantCond = this.tenantCondition('cancelForScope', opts.tenantId);\n const conditions = [\n eq(jobRuns.scopeEntityType, entityType),\n eq(jobRuns.scopeEntityId, entityId),\n inArray(jobRuns.status, NON_TERMINAL_STATUSES),\n ];\n if (tenantCond) conditions.push(tenantCond);\n\n const rows = await this.db\n .select({ id: jobRuns.id })\n .from(jobRuns)\n .where(and(...conditions));\n\n for (const { id } of rows) {\n // Propagate the tenant gate into cascade-cancel. The scope query has\n // already narrowed to this tenant; passing `tenantId` through keeps\n // the orchestrator's per-row guard consistent under multi-tenant mode.\n await this.orchestrator.cancel(id, {\n cascade: true,\n tenantId: opts.tenantId,\n });\n }\n }\n\n async rescheduleForScope(\n entityType: string,\n entityId: string,\n newRunAt: Date,\n opts: RescheduleForScopeOptions = {},\n ): Promise<void> {\n const tenantCond = this.tenantCondition('rescheduleForScope', opts.tenantId);\n const conditions = [\n eq(jobRuns.scopeEntityType, entityType),\n eq(jobRuns.scopeEntityId, entityId),\n eq(jobRuns.status, 'pending'),\n ];\n if (tenantCond) conditions.push(tenantCond);\n\n await this.db\n .update(jobRuns)\n .set({ runAt: newRunAt, updatedAt: new Date() })\n .where(and(...conditions));\n }\n\n async countByPoolAndStatus(\n tenantId?: string | null,\n ): Promise<PoolStatusCount[]> {\n const tenantCond = this.tenantCondition('countByPoolAndStatus', tenantId);\n const rows = await this.db\n .select({\n pool: jobRuns.pool,\n status: jobRuns.status,\n count: sql<number>`count(*)::int`.as('count'),\n })\n .from(jobRuns)\n .where(tenantCond ?? undefined)\n .groupBy(jobRuns.pool, jobRuns.status);\n\n return rows.map((r) => ({\n pool: r.pool,\n status: r.status,\n count: Number(r.count),\n }));\n }\n\n async listRecentFailed(\n limit: number,\n tenantId?: string | null,\n ): Promise<JobRunFailure[]> {\n const conditions = [eq(jobRuns.status, 'failed' as const)];\n const tenantCond = this.tenantCondition('listRecentFailed', tenantId);\n if (tenantCond) conditions.push(tenantCond);\n\n const rows = await this.db\n .select()\n .from(jobRuns)\n .where(and(...conditions))\n .orderBy(desc(jobRuns.finishedAt), desc(jobRuns.updatedAt))\n .limit(limit);\n\n return rows.map((r) => ({\n runId: r.id,\n jobType: r.jobType,\n pool: r.pool,\n scopeEntityType: r.scopeEntityType,\n scopeEntityId: r.scopeEntityId,\n tenantId: r.tenantId,\n attempts: r.attempts,\n errorMessage: r.error?.message ?? null,\n failedAt: r.finishedAt ?? r.updatedAt,\n createdAt: r.createdAt,\n }));\n }\n\n async listJobRuns(query: ListJobRunsQuery = {}): Promise<JobRunPage> {\n const limit = clampLimit(query.limit);\n const conditions = [];\n\n const tenantCond = this.tenantCondition('listJobRuns', query.tenantId);\n if (tenantCond) conditions.push(tenantCond);\n if (query.poolId) conditions.push(eq(jobRuns.pool, query.poolId));\n if (query.rootRunId) conditions.push(eq(jobRuns.rootRunId, query.rootRunId));\n if (query.status) conditions.push(eq(jobRuns.status, query.status));\n if (query.since) conditions.push(gte(jobRuns.createdAt, query.since));\n\n // Keyset seek: WHERE (created_at, id) < (cursorCreatedAt, cursorId),\n // expanded into a SARGable OR so the same `created_at` index is used.\n if (query.cursor) {\n const keyset = decodeKeysetCursor(query.cursor);\n if (keyset) {\n conditions.push(\n or(\n lt(jobRuns.createdAt, keyset.createdAt),\n and(\n eq(jobRuns.createdAt, keyset.createdAt),\n lt(jobRuns.id, keyset.id),\n ),\n )!,\n );\n }\n }\n\n // Fetch one extra row to determine whether a next page exists without a\n // separate COUNT.\n const rows = await this.db\n .select()\n .from(jobRuns)\n .where(conditions.length > 0 ? and(...conditions) : undefined)\n .orderBy(desc(jobRuns.createdAt), desc(jobRuns.id))\n .limit(limit + 1);\n\n const hasMore = rows.length > limit;\n const page = hasMore ? rows.slice(0, limit) : rows;\n const items = page.map(toJobRunSummary);\n const last = page[page.length - 1];\n const nextCursor =\n hasMore && last\n ? encodeKeysetCursor({ createdAt: last.createdAt, id: last.id })\n : null;\n\n return { items, nextCursor };\n }\n\n /**\n * Internal helper used by cascade paths (not on the public protocol).\n * Exposed as a public method on the concrete class so infrastructure\n * code (cascade tests, debug tools) can call it without a cast.\n */\n async findByRootRunId(rootRunId: string): Promise<JobRun[]> {\n const rows = await this.db\n .select()\n .from(jobRuns)\n .where(eq(jobRuns.rootRunId, rootRunId));\n return rows as JobRun[];\n }\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
//# sourceMappingURL=chunk-FI34KYZ5.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
//# sourceMappingURL=chunk-FN2PYDPP.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import {
|
|
2
|
+
MemoryRunRecorder
|
|
3
|
+
} from "./chunk-EO2QPOKH.js";
|
|
4
|
+
import {
|
|
5
|
+
PostgresCursorStore
|
|
6
|
+
} from "./chunk-DCCZB4UC.js";
|
|
7
|
+
import {
|
|
8
|
+
MemoryCursorStore
|
|
9
|
+
} from "./chunk-AHV4GDYM.js";
|
|
10
|
+
import {
|
|
11
|
+
DrizzleIntegrationRunRecorder
|
|
12
|
+
} from "./chunk-SR7F3TJY.js";
|
|
13
|
+
import {
|
|
14
|
+
DeepEqualDiffer
|
|
15
|
+
} from "./chunk-36U5UGIO.js";
|
|
16
|
+
import {
|
|
17
|
+
INTEGRATION_CURSOR_STORE,
|
|
18
|
+
INTEGRATION_FIELD_DIFFER,
|
|
19
|
+
INTEGRATION_MODULE_OPTIONS,
|
|
20
|
+
INTEGRATION_MULTI_TENANT,
|
|
21
|
+
INTEGRATION_RUN_RECORDER
|
|
22
|
+
} from "./chunk-S7C6TIIF.js";
|
|
23
|
+
import {
|
|
24
|
+
__decorateClass
|
|
25
|
+
} from "./chunk-2E224ZSN.js";
|
|
26
|
+
|
|
27
|
+
// runtime/subsystems/integration/integration.module.ts
|
|
28
|
+
import { Module } from "@nestjs/common";
|
|
29
|
+
var IntegrationModule = class {
|
|
30
|
+
static forRoot(options) {
|
|
31
|
+
const multiTenant = options.multiTenant ?? false;
|
|
32
|
+
const sharedProviders = [
|
|
33
|
+
{ provide: INTEGRATION_MODULE_OPTIONS, useValue: options },
|
|
34
|
+
{ provide: INTEGRATION_MULTI_TENANT, useValue: multiTenant },
|
|
35
|
+
// Default differ — consumers can override by binding a different
|
|
36
|
+
// `IFieldDiffer<T>` to `INTEGRATION_FIELD_DIFFER` in their feature module.
|
|
37
|
+
{ provide: INTEGRATION_FIELD_DIFFER, useValue: new DeepEqualDiffer() }
|
|
38
|
+
];
|
|
39
|
+
const backendProviders = options.backend === "memory" ? [
|
|
40
|
+
// Wired as singletons via `useValue` so tests can pull
|
|
41
|
+
// them out via `moduleRef.get(MemoryCursorStore)` for
|
|
42
|
+
// direct assertions. Matches JOB-4 / MemoryJobStore shape.
|
|
43
|
+
{ provide: MemoryCursorStore, useValue: new MemoryCursorStore() },
|
|
44
|
+
{
|
|
45
|
+
provide: INTEGRATION_CURSOR_STORE,
|
|
46
|
+
useExisting: MemoryCursorStore
|
|
47
|
+
},
|
|
48
|
+
{ provide: MemoryRunRecorder, useValue: new MemoryRunRecorder() },
|
|
49
|
+
{
|
|
50
|
+
provide: INTEGRATION_RUN_RECORDER,
|
|
51
|
+
useExisting: MemoryRunRecorder
|
|
52
|
+
}
|
|
53
|
+
] : [
|
|
54
|
+
// Drizzle backends — injected with DRIZZLE (provided by the
|
|
55
|
+
// consumer's DrizzleModule) + the INTEGRATION_MULTI_TENANT flag
|
|
56
|
+
// we bound above.
|
|
57
|
+
{ provide: INTEGRATION_CURSOR_STORE, useClass: PostgresCursorStore },
|
|
58
|
+
{ provide: INTEGRATION_RUN_RECORDER, useClass: DrizzleIntegrationRunRecorder }
|
|
59
|
+
];
|
|
60
|
+
return {
|
|
61
|
+
module: IntegrationModule,
|
|
62
|
+
global: true,
|
|
63
|
+
providers: [...sharedProviders, ...backendProviders],
|
|
64
|
+
exports: [
|
|
65
|
+
INTEGRATION_MODULE_OPTIONS,
|
|
66
|
+
INTEGRATION_MULTI_TENANT,
|
|
67
|
+
INTEGRATION_FIELD_DIFFER,
|
|
68
|
+
INTEGRATION_CURSOR_STORE,
|
|
69
|
+
INTEGRATION_RUN_RECORDER
|
|
70
|
+
]
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
IntegrationModule = __decorateClass([
|
|
75
|
+
Module({})
|
|
76
|
+
], IntegrationModule);
|
|
77
|
+
|
|
78
|
+
export {
|
|
79
|
+
IntegrationModule
|
|
80
|
+
};
|
|
81
|
+
//# sourceMappingURL=chunk-GCYKMF22.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../runtime/subsystems/integration/integration.module.ts"],"sourcesContent":["/**\n * IntegrationModule — `DynamicModule.forRoot({ backend, multiTenant? })` factory\n * wiring the integration subsystem's substrate (SYNC-6, ADR-008 subsystem pattern).\n *\n * ## What this module provides\n *\n * - `INTEGRATION_CURSOR_STORE` — Drizzle or Memory cursor store\n * - `INTEGRATION_RUN_RECORDER` — Drizzle or Memory run recorder\n * - `INTEGRATION_FIELD_DIFFER` — default `DeepEqualDiffer`\n * - `INTEGRATION_MULTI_TENANT` — resolved boolean flag (defaults to false)\n * - `INTEGRATION_MODULE_OPTIONS` — the options object itself, for backends\n * that need to inspect config at construction time\n *\n * ## What this module does NOT provide\n *\n * - `INTEGRATION_CHANGE_SOURCE` — per-provider per-entity; consumer binds in\n * their feature module (e.g. `OpportunityIntegrationModule` provides a\n * `SalesforceOpportunityChangeSource`). Loopback suppression — when\n * needed — is composed into the primitive's middleware chain via\n * `createLoopbackMiddleware(store)` (#226-5 / ADR-033); the\n * orchestrator no longer accepts a fingerprint store directly.\n * - `INTEGRATION_SINK` — per canonical entity; consumer binds in their feature\n * module.\n * - `ExecuteIntegrationUseCase` — registered by the feature module alongside\n * its source + sink bindings. Providing the orchestrator here would\n * force Nest to resolve INTEGRATION_CHANGE_SOURCE + INTEGRATION_SINK at module\n * compile time, which fails when the feature module hasn't been\n * imported yet. Consumers register `ExecuteIntegrationUseCase` in the same\n * `providers` array as their source + sink so resolution is local\n * to where all three are bound.\n *\n * Same shape as `EventsModule.forRoot` — the module wires the bus; you\n * bring your own handlers. Here: the module wires the substrate; you\n * bring your own source + sink.\n *\n * ## Usage\n *\n * ```ts\n * // AppModule — single source of truth for backend + multi-tenancy.\n * @Module({\n * imports: [IntegrationModule.forRoot({ backend: 'drizzle' })],\n * })\n * export class AppModule {}\n *\n * // Per-entity feature module — binds source + sink, gets the\n * // orchestrator for free.\n * @Module({\n * providers: [\n * { provide: INTEGRATION_CHANGE_SOURCE, useClass: SalesforceOpportunitySource },\n * { provide: INTEGRATION_SINK, useClass: OpportunityIntegrationSink },\n * ExecuteIntegrationUseCase,\n * ],\n * })\n * export class OpportunityIntegrationModule {\n * constructor(\n * private readonly execute: ExecuteIntegrationUseCase<CanonicalOpportunity>,\n * ) {}\n * }\n * ```\n *\n * `global: true` means feature modules do not need to re-import\n * `IntegrationModule` — the substrate tokens are available project-wide.\n */\nimport { Module, type DynamicModule, type Provider } from '@nestjs/common';\nimport {\n INTEGRATION_CURSOR_STORE,\n INTEGRATION_FIELD_DIFFER,\n INTEGRATION_MODULE_OPTIONS,\n INTEGRATION_MULTI_TENANT,\n INTEGRATION_RUN_RECORDER,\n} from './integration.tokens';\nimport { MemoryCursorStore } from './integration-cursor-store.memory-backend';\nimport { MemoryRunRecorder } from './integration-run-recorder.memory-backend';\nimport { PostgresCursorStore } from './integration-cursor-store.drizzle-backend';\nimport { DrizzleIntegrationRunRecorder } from './integration-run-recorder.drizzle-backend';\nimport { DeepEqualDiffer } from './deep-equal.differ';\n\nexport interface IntegrationModuleOptions {\n /**\n * Backend selection. `drizzle` wires the Postgres cursor store +\n * run-log recorder; `memory` wires in-memory doubles suitable for\n * tests + local dev.\n */\n backend: 'drizzle' | 'memory';\n\n /**\n * Multi-tenancy opt-in (SYNC-6).\n *\n * When `true`, every call to the orchestrator + both Drizzle backends\n * must supply a non-null `tenantId`; missing values throw\n * `MissingTenantIdError`. Defense-in-depth: the orchestrator rejects\n * at entry (no dangling `status=running` rows) AND the Drizzle\n * backends reject at their write boundary (belt-and-braces for any\n * path that bypasses the orchestrator). Both sites use the shared\n * `assertTenantId` helper so error messages match.\n *\n * Memory backends accept `tenantId` unconditionally — their state is\n * process-local; cross-tenant isolation there is not meaningful.\n *\n * Defaults to `false`.\n */\n multiTenant?: boolean;\n}\n\n@Module({})\nexport class IntegrationModule {\n static forRoot(options: IntegrationModuleOptions): DynamicModule {\n const multiTenant = options.multiTenant ?? false;\n\n const sharedProviders: Provider[] = [\n { provide: INTEGRATION_MODULE_OPTIONS, useValue: options },\n { provide: INTEGRATION_MULTI_TENANT, useValue: multiTenant },\n // Default differ — consumers can override by binding a different\n // `IFieldDiffer<T>` to `INTEGRATION_FIELD_DIFFER` in their feature module.\n { provide: INTEGRATION_FIELD_DIFFER, useValue: new DeepEqualDiffer() },\n ];\n\n const backendProviders: Provider[] =\n options.backend === 'memory'\n ? [\n // Wired as singletons via `useValue` so tests can pull\n // them out via `moduleRef.get(MemoryCursorStore)` for\n // direct assertions. Matches JOB-4 / MemoryJobStore shape.\n { provide: MemoryCursorStore, useValue: new MemoryCursorStore() },\n {\n provide: INTEGRATION_CURSOR_STORE,\n useExisting: MemoryCursorStore,\n },\n { provide: MemoryRunRecorder, useValue: new MemoryRunRecorder() },\n {\n provide: INTEGRATION_RUN_RECORDER,\n useExisting: MemoryRunRecorder,\n },\n ]\n : [\n // Drizzle backends — injected with DRIZZLE (provided by the\n // consumer's DrizzleModule) + the INTEGRATION_MULTI_TENANT flag\n // we bound above.\n { provide: INTEGRATION_CURSOR_STORE, useClass: PostgresCursorStore },\n { provide: INTEGRATION_RUN_RECORDER, useClass: DrizzleIntegrationRunRecorder },\n ];\n\n return {\n module: IntegrationModule,\n global: true,\n providers: [...sharedProviders, ...backendProviders],\n exports: [\n INTEGRATION_MODULE_OPTIONS,\n INTEGRATION_MULTI_TENANT,\n INTEGRATION_FIELD_DIFFER,\n INTEGRATION_CURSOR_STORE,\n INTEGRATION_RUN_RECORDER,\n ],\n };\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AA+DA,SAAS,cAAiD;AA0CnD,IAAM,oBAAN,MAAwB;AAAA,EAC7B,OAAO,QAAQ,SAAkD;AAC/D,UAAM,cAAc,QAAQ,eAAe;AAE3C,UAAM,kBAA8B;AAAA,MAClC,EAAE,SAAS,4BAA4B,UAAU,QAAQ;AAAA,MACzD,EAAE,SAAS,0BAA0B,UAAU,YAAY;AAAA;AAAA;AAAA,MAG3D,EAAE,SAAS,0BAA0B,UAAU,IAAI,gBAAgB,EAAE;AAAA,IACvE;AAEA,UAAM,mBACJ,QAAQ,YAAY,WAChB;AAAA;AAAA;AAAA;AAAA,MAIE,EAAE,SAAS,mBAAmB,UAAU,IAAI,kBAAkB,EAAE;AAAA,MAChE;AAAA,QACE,SAAS;AAAA,QACT,aAAa;AAAA,MACf;AAAA,MACA,EAAE,SAAS,mBAAmB,UAAU,IAAI,kBAAkB,EAAE;AAAA,MAChE;AAAA,QACE,SAAS;AAAA,QACT,aAAa;AAAA,MACf;AAAA,IACF,IACA;AAAA;AAAA;AAAA;AAAA,MAIE,EAAE,SAAS,0BAA0B,UAAU,oBAAoB;AAAA,MACnE,EAAE,SAAS,0BAA0B,UAAU,8BAA8B;AAAA,IAC/E;AAEN,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,WAAW,CAAC,GAAG,iBAAiB,GAAG,gBAAgB;AAAA,MACnD,SAAS;AAAA,QACP;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAlDa,oBAAN;AAAA,EADN,OAAO,CAAC,CAAC;AAAA,GACG;","names":[]}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getEventMetadata
|
|
3
|
+
} from "./chunk-BGULBWKJ.js";
|
|
4
|
+
import {
|
|
5
|
+
eventPayloadSchemas
|
|
6
|
+
} from "./chunk-JRQO2IOF.js";
|
|
7
|
+
import {
|
|
8
|
+
MissingTenantIdError
|
|
9
|
+
} from "./chunk-V4AF6DI4.js";
|
|
10
|
+
import {
|
|
11
|
+
EVENTS_MULTI_TENANT,
|
|
12
|
+
EVENT_BUS
|
|
13
|
+
} from "./chunk-H5NH7KPE.js";
|
|
14
|
+
import {
|
|
15
|
+
__decorateClass,
|
|
16
|
+
__decorateParam
|
|
17
|
+
} from "./chunk-2E224ZSN.js";
|
|
18
|
+
|
|
19
|
+
// runtime/subsystems/events/generated/bus.ts
|
|
20
|
+
import { Injectable, Inject } from "@nestjs/common";
|
|
21
|
+
import { randomUUID } from "crypto";
|
|
22
|
+
var TypedEventBus = class {
|
|
23
|
+
constructor(bus, multiTenant) {
|
|
24
|
+
this.bus = bus;
|
|
25
|
+
this.multiTenant = multiTenant;
|
|
26
|
+
}
|
|
27
|
+
bus;
|
|
28
|
+
multiTenant;
|
|
29
|
+
async publish(type, aggregateId, payload, opts) {
|
|
30
|
+
const meta = getEventMetadata(type);
|
|
31
|
+
const flag = process.env["CODEGEN_EVENT_VALIDATE"];
|
|
32
|
+
const shouldValidate = flag === void 0 ? true : flag !== "false" && flag !== "0";
|
|
33
|
+
if (shouldValidate) {
|
|
34
|
+
const schema = eventPayloadSchemas[type];
|
|
35
|
+
if (schema) {
|
|
36
|
+
const check = schema.safeParse(payload);
|
|
37
|
+
if (!check.success) {
|
|
38
|
+
console.warn(
|
|
39
|
+
`[TypedEventBus] payload validation failed for ${String(type)}:`,
|
|
40
|
+
check.error.issues
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
const tenantId = opts?.metadata?.["tenantId"];
|
|
46
|
+
if (this.multiTenant && (tenantId === void 0 || tenantId === null)) {
|
|
47
|
+
throw new MissingTenantIdError(type);
|
|
48
|
+
}
|
|
49
|
+
const aggregateType = meta.aggregate ?? meta.source ?? meta.destination ?? type;
|
|
50
|
+
const baseMetadata = { ...opts?.metadata ?? {} };
|
|
51
|
+
if (meta.tier === "audit") {
|
|
52
|
+
if (baseMetadata["pool"] !== void 0 || baseMetadata["direction"] !== void 0) {
|
|
53
|
+
console.debug(
|
|
54
|
+
`[TypedEventBus] tier:audit event '${String(type)}' had pool/direction in opts.metadata; overriding to null.`
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
baseMetadata["pool"] = null;
|
|
58
|
+
baseMetadata["direction"] = null;
|
|
59
|
+
baseMetadata["tier"] = "audit";
|
|
60
|
+
} else {
|
|
61
|
+
baseMetadata["pool"] = meta.pool;
|
|
62
|
+
baseMetadata["direction"] = meta.direction;
|
|
63
|
+
baseMetadata["tier"] = "domain";
|
|
64
|
+
}
|
|
65
|
+
baseMetadata["version"] = meta.version;
|
|
66
|
+
await this.bus.publish(
|
|
67
|
+
{
|
|
68
|
+
id: randomUUID(),
|
|
69
|
+
type,
|
|
70
|
+
aggregateId,
|
|
71
|
+
aggregateType,
|
|
72
|
+
payload,
|
|
73
|
+
occurredAt: /* @__PURE__ */ new Date(),
|
|
74
|
+
metadata: baseMetadata
|
|
75
|
+
},
|
|
76
|
+
opts?.tx
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
subscribe(type, handler) {
|
|
80
|
+
return this.bus.subscribe(type, handler);
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
TypedEventBus = __decorateClass([
|
|
84
|
+
Injectable(),
|
|
85
|
+
__decorateParam(0, Inject(EVENT_BUS)),
|
|
86
|
+
__decorateParam(1, Inject(EVENTS_MULTI_TENANT))
|
|
87
|
+
], TypedEventBus);
|
|
88
|
+
|
|
89
|
+
export {
|
|
90
|
+
TypedEventBus
|
|
91
|
+
};
|
|
92
|
+
//# sourceMappingURL=chunk-GM3RMJIJ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../runtime/subsystems/events/generated/bus.ts"],"sourcesContent":["// AUTO-GENERATED by @pattern-stack/codegen. Do not edit.\n// Run `codegen entity new --all` to refresh.\n\nimport { Injectable, Inject } from '@nestjs/common';\nimport { randomUUID } from 'crypto';\nimport { EVENT_BUS, EVENTS_MULTI_TENANT } from '../events.tokens';\nimport { MissingTenantIdError } from '../events-errors';\nimport type { IEventBus, DrizzleTransaction } from '../event-bus.protocol';\nimport { eventPayloadSchemas } from './schemas';\nimport { getEventMetadata } from './registry';\nimport type { EventTypeName, EventOfType, PayloadOfType } from './types';\n\n/**\n * Typed facade over IEventBus.\n *\n * Stamps `pool`, `direction`, `tier`, and `version` into `event.metadata`\n * from the generated `eventRegistry` before delegating to\n * `IEventBus.publish()`. Downstream backends (DrizzleEventBus) read those\n * values to populate the explicit `domain_events` columns.\n *\n * Tier stamping (AUDIT-3): every event carries `metadata.tier`, sourced\n * from the registry. For `tier: 'audit'` events, the bus FORCES\n * `metadata.pool = null` and `metadata.direction = null` regardless of\n * any caller-supplied values in `opts.metadata` — audit routing is\n * bus-stamped, not caller-controlled. Caller overrides are silently\n * dropped with a debug-level log (callers should not be specifying these\n * for audit events; see ai-docs/specs/issue-242/plan.md §AUDIT-3).\n *\n * Validation gating (EVT-Q5): `CODEGEN_EVENT_VALIDATE` env flag, default on.\n * Uses `safeParse` + `console.warn` — never throws, so a bad publish does\n * not crash a hot path.\n *\n * Multi-tenancy (EVT-6): when the EventsModule is configured with\n * `multiTenant: true`, every publish must supply `opts.metadata.tenantId`\n * — otherwise `publish()` throws `MissingTenantIdError`. When `multiTenant`\n * is `false` (default), no tenantId is required. If a tenantId IS supplied,\n * it is preserved on `event.metadata` and the Drizzle backend writes it to\n * `domain_events.tenant_id` (EVT-4).\n */\n@Injectable()\nexport class TypedEventBus {\n\tconstructor(\n\t\t@Inject(EVENT_BUS) private readonly bus: IEventBus,\n\t\t@Inject(EVENTS_MULTI_TENANT) private readonly multiTenant: boolean,\n\t) {}\n\n\tasync publish<T extends EventTypeName>(\n\t\ttype: T,\n\t\taggregateId: string,\n\t\tpayload: PayloadOfType<T>,\n\t\topts?: { tx?: DrizzleTransaction; metadata?: Record<string, unknown> },\n\t): Promise<void> {\n\t\tconst meta = getEventMetadata(type);\n\n\t\tconst flag = process.env['CODEGEN_EVENT_VALIDATE'];\n\t\tconst shouldValidate =\n\t\t\tflag === undefined ? true : flag !== 'false' && flag !== '0';\n\t\tif (shouldValidate) {\n\t\t\t// `eventPayloadSchemas` is typed as `Record<EventTypeName, z.ZodType>`,\n\t\t\t// so under `noUncheckedIndexedAccess` the indexed lookup widens\n\t\t\t// to `z.ZodType | undefined`. When no events are registered at\n\t\t\t// codegen time `EventTypeName` degrades to `string` and the\n\t\t\t// schemas object is literally `{}` — the guard below is the\n\t\t\t// honest handling of that empty-registry case (skip validation;\n\t\t\t// it's a warn-only best-effort check per the class docblock).\n\t\t\tconst schema = eventPayloadSchemas[type];\n\t\t\tif (schema) {\n\t\t\t\tconst check = schema.safeParse(payload);\n\t\t\t\tif (!check.success) {\n\t\t\t\t\tconsole.warn(\n\t\t\t\t\t\t`[TypedEventBus] payload validation failed for ${String(type)}:`,\n\t\t\t\t\t\tcheck.error.issues,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tconst tenantId = opts?.metadata?.['tenantId'];\n\t\tif (this.multiTenant && (tenantId === undefined || tenantId === null)) {\n\t\t\tthrow new MissingTenantIdError(type as string);\n\t\t}\n\n\t\tconst aggregateType =\n\t\t\tmeta.aggregate ?? meta.source ?? meta.destination ?? (type as string);\n\n\t\t// AUDIT-3: build metadata with tier-aware routing stamping. For\n\t\t// `tier: 'audit'` events the bus FORCES pool/direction to null,\n\t\t// even if the caller supplied them in opts.metadata. Audit routing\n\t\t// is bus-stamped, not caller-controlled (see plan §AUDIT-3).\n\t\tconst baseMetadata: Record<string, unknown> = { ...(opts?.metadata ?? {}) };\n\t\tif (meta.tier === 'audit') {\n\t\t\tif (\n\t\t\t\tbaseMetadata['pool'] !== undefined ||\n\t\t\t\tbaseMetadata['direction'] !== undefined\n\t\t\t) {\n\t\t\t\tconsole.debug(\n\t\t\t\t\t`[TypedEventBus] tier:audit event '${String(type)}' had pool/direction in opts.metadata; overriding to null.`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tbaseMetadata['pool'] = null;\n\t\t\tbaseMetadata['direction'] = null;\n\t\t\tbaseMetadata['tier'] = 'audit';\n\t\t} else {\n\t\t\tbaseMetadata['pool'] = meta.pool;\n\t\t\tbaseMetadata['direction'] = meta.direction;\n\t\t\tbaseMetadata['tier'] = 'domain';\n\t\t}\n\t\tbaseMetadata['version'] = meta.version;\n\n\t\tawait this.bus.publish(\n\t\t\t{\n\t\t\t\tid: randomUUID(),\n\t\t\t\ttype,\n\t\t\t\taggregateId,\n\t\t\t\taggregateType,\n\t\t\t\tpayload: payload as Record<string, unknown>,\n\t\t\t\toccurredAt: new Date(),\n\t\t\t\tmetadata: baseMetadata,\n\t\t\t},\n\t\t\topts?.tx,\n\t\t);\n\t}\n\n\tsubscribe<T extends EventTypeName>(\n\t\ttype: T,\n\t\thandler: (event: EventOfType<T>) => Promise<void>,\n\t): () => void {\n\t\treturn this.bus.subscribe<EventOfType<T>>(type, handler as never);\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAGA,SAAS,YAAY,cAAc;AACnC,SAAS,kBAAkB;AAoCpB,IAAM,gBAAN,MAAoB;AAAA,EAC1B,YACqC,KACU,aAC7C;AAFmC;AACU;AAAA,EAC5C;AAAA,EAFkC;AAAA,EACU;AAAA,EAG/C,MAAM,QACL,MACA,aACA,SACA,MACgB;AAChB,UAAM,OAAO,iBAAiB,IAAI;AAElC,UAAM,OAAO,QAAQ,IAAI,wBAAwB;AACjD,UAAM,iBACL,SAAS,SAAY,OAAO,SAAS,WAAW,SAAS;AAC1D,QAAI,gBAAgB;AAQnB,YAAM,SAAS,oBAAoB,IAAI;AACvC,UAAI,QAAQ;AACX,cAAM,QAAQ,OAAO,UAAU,OAAO;AACtC,YAAI,CAAC,MAAM,SAAS;AACnB,kBAAQ;AAAA,YACP,iDAAiD,OAAO,IAAI,CAAC;AAAA,YAC7D,MAAM,MAAM;AAAA,UACb;AAAA,QACD;AAAA,MACD;AAAA,IACD;AAEA,UAAM,WAAW,MAAM,WAAW,UAAU;AAC5C,QAAI,KAAK,gBAAgB,aAAa,UAAa,aAAa,OAAO;AACtE,YAAM,IAAI,qBAAqB,IAAc;AAAA,IAC9C;AAEA,UAAM,gBACL,KAAK,aAAa,KAAK,UAAU,KAAK,eAAgB;AAMvD,UAAM,eAAwC,EAAE,GAAI,MAAM,YAAY,CAAC,EAAG;AAC1E,QAAI,KAAK,SAAS,SAAS;AAC1B,UACC,aAAa,MAAM,MAAM,UACzB,aAAa,WAAW,MAAM,QAC7B;AACD,gBAAQ;AAAA,UACP,qCAAqC,OAAO,IAAI,CAAC;AAAA,QAClD;AAAA,MACD;AACA,mBAAa,MAAM,IAAI;AACvB,mBAAa,WAAW,IAAI;AAC5B,mBAAa,MAAM,IAAI;AAAA,IACxB,OAAO;AACN,mBAAa,MAAM,IAAI,KAAK;AAC5B,mBAAa,WAAW,IAAI,KAAK;AACjC,mBAAa,MAAM,IAAI;AAAA,IACxB;AACA,iBAAa,SAAS,IAAI,KAAK;AAE/B,UAAM,KAAK,IAAI;AAAA,MACd;AAAA,QACC,IAAI,WAAW;AAAA,QACf;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,YAAY,oBAAI,KAAK;AAAA,QACrB,UAAU;AAAA,MACX;AAAA,MACA,MAAM;AAAA,IACP;AAAA,EACD;AAAA,EAEA,UACC,MACA,SACa;AACb,WAAO,KAAK,IAAI,UAA0B,MAAM,OAAgB;AAAA,EACjE;AACD;AAzFa,gBAAN;AAAA,EADN,WAAW;AAAA,EAGT,0BAAO,SAAS;AAAA,EAChB,0BAAO,mBAAmB;AAAA,GAHhB;","names":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../runtime/subsystems/token-key.ts"],"sourcesContent":["/** Canonical package namespace for cross-boundary DI token keys. MUST be a hardcoded\n * constant (NOT derived from package.json) so a vendored copy — which lives inside the\n * CONSUMER's package — produces the identical key and the two copies share the symbol. */\nexport const PKG = '@pattern-stack/codegen';\n// TODO(token-version): if/when a runtime contract version is adopted, inject it HERE only\n// (e.g. `${PKG}#${ABI}.${area}.${name}`) — this helper is the single chokepoint.\nexport const tokenKey = (area: string, name: string): string => `${PKG}.${area}.${name}`;\n"],"mappings":";AAGO,IAAM,MAAM;AAGZ,IAAM,WAAW,CAAC,MAAc,SAAyB,GAAG,GAAG,IAAI,IAAI,IAAI,IAAI;","names":[]}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import {
|
|
2
|
+
tokenKey
|
|
3
|
+
} from "./chunk-GYGNEQSC.js";
|
|
4
|
+
|
|
5
|
+
// runtime/subsystems/events/events.tokens.ts
|
|
6
|
+
var EVENT_BUS = "EVENT_BUS";
|
|
7
|
+
var EVENT_READ_PORT = "EVENT_READ_PORT";
|
|
8
|
+
var TYPED_EVENT_BUS = "TYPED_EVENT_BUS";
|
|
9
|
+
var EVENTS_MULTI_TENANT = "EVENTS_MULTI_TENANT";
|
|
10
|
+
var REDIS_URL = Symbol.for(tokenKey("events", "redis-url"));
|
|
11
|
+
var EVENTS_MODULE_OPTIONS = "EVENTS_MODULE_OPTIONS";
|
|
12
|
+
|
|
13
|
+
export {
|
|
14
|
+
EVENT_BUS,
|
|
15
|
+
EVENT_READ_PORT,
|
|
16
|
+
TYPED_EVENT_BUS,
|
|
17
|
+
EVENTS_MULTI_TENANT,
|
|
18
|
+
REDIS_URL,
|
|
19
|
+
EVENTS_MODULE_OPTIONS
|
|
20
|
+
};
|
|
21
|
+
//# sourceMappingURL=chunk-H5NH7KPE.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../runtime/subsystems/events/events.tokens.ts"],"sourcesContent":["/**\n * Injection token for the event bus.\n *\n * String constant (not Symbol) so it matches by value across import boundaries.\n * Matches the token in runtime/constants/tokens.ts — both are 'EVENT_BUS'.\n *\n * Usage in use cases:\n * ```typescript\n * constructor(@Inject(EVENT_BUS) private readonly eventBus: IEventBus) {}\n * ```\n */\nimport { tokenKey } from '../token-key';\n\nexport const EVENT_BUS = 'EVENT_BUS' as const;\n\n/**\n * Injection token for the read-side `IEventReadPort` over `domain_events`\n * (OBS-LIST-1).\n *\n * Bound by `EventsModule.forRoot` to the same backend instance as\n * `EVENT_BUS` for the `drizzle` and `memory` backends (both implement\n * `IEventReadPort`). The `redis` backend retains no history and therefore\n * does NOT provide this token — consumers composing it (e.g. the\n * observability combiner) inject it `@Optional()` and degrade to empty\n * results.\n *\n * String constant (not Symbol) so it matches by value across import\n * boundaries — same convention as `EVENT_BUS`.\n */\nexport const EVENT_READ_PORT = 'EVENT_READ_PORT' as const;\n\n/**\n * Injection token for the generated `TypedEventBus` facade.\n *\n * `TypedEventBus` lives in `runtime/subsystems/events/generated/bus.ts` and\n * wraps `IEventBus` with project-specific `AppDomainEvent`-typed `publish<T>()`\n * and `subscribe<T>()`. Use cases inject this token in preference to\n * `EVENT_BUS` when they want compile-time type safety on event shapes.\n *\n * String constant (not Symbol) so it matches by value across import\n * boundaries — same convention as `EVENT_BUS`.\n *\n * Provider registration lands in EVT-6 (EventsModule wiring); the token is\n * declared here so generated code can import it without depending on the\n * still-being-formalised module.\n */\nexport const TYPED_EVENT_BUS = 'TYPED_EVENT_BUS' as const;\n\n/**\n * Injection token for the resolved multi-tenancy flag.\n *\n * Provided by `EventsModule.forRoot(...)` as `options.multiTenant ?? false`.\n * Consumed by `TypedEventBus` to enforce the tenantId-is-required rule at\n * publish time.\n *\n * String constant (not Symbol) so it matches by value across import\n * boundaries — same convention as the other events tokens. (The jobs\n * subsystem uses Symbols for the analogous token; events chose strings\n * from the start and we keep the file internally consistent.)\n */\nexport const EVENTS_MULTI_TENANT = 'EVENTS_MULTI_TENANT' as const;\n\n/**\n * Injection token for the Redis connection URL used by RedisEventBus.\n * Provided automatically by EventsModule.forRoot({ backend: 'redis' }).\n *\n * ADR-037: namespaced `Symbol.for(...)` (via `tokenKey()`) so it matches by value\n * across runtime copies (the sibling string tokens above are already value-stable).\n * Note the jobs subsystem defines its own `REDIS_URL`-equivalent; this is the\n * events one.\n */\nexport const REDIS_URL = Symbol.for(tokenKey('events', 'redis-url'));\n\n/**\n * Injection token for the resolved `EventsModuleOptions` object.\n *\n * Provided automatically by `EventsModule.forRoot(...)` /\n * `EventsModule.forRootAsync(...)`. Backends that need to observe module\n * configuration (e.g. `DrizzleEventBus` reading `opts.pools` for\n * pool-filtered drain) inject via this token.\n *\n * String-valued (not `Symbol`) so it matches by value across import\n * boundaries — same convention as `EVENT_BUS`.\n */\nexport const EVENTS_MODULE_OPTIONS = 'EVENTS_MODULE_OPTIONS' as const;\n"],"mappings":";;;;;AAaO,IAAM,YAAY;AAgBlB,IAAM,kBAAkB;AAiBxB,IAAM,kBAAkB;AAcxB,IAAM,sBAAsB;AAW5B,IAAM,YAAY,OAAO,IAAI,SAAS,UAAU,WAAW,CAAC;AAa5D,IAAM,wBAAwB;","names":[]}
|