@pattern-stack/codegen 0.15.0 → 0.15.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +111 -0
- package/dist/chunk-24CWKBK5.js +94 -0
- package/dist/chunk-24CWKBK5.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-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-4MVGAMUA.js +40 -0
- package/dist/chunk-4MVGAMUA.js.map +1 -0
- package/dist/chunk-4OMHBMZJ.js +75 -0
- package/dist/chunk-4OMHBMZJ.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-7LKAMLV4.js +92 -0
- package/dist/chunk-7LKAMLV4.js.map +1 -0
- package/dist/chunk-7RELQJIN.js +22 -0
- package/dist/chunk-7RELQJIN.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-COGHTKXY.js +84 -0
- package/dist/chunk-COGHTKXY.js.map +1 -0
- package/dist/chunk-DCCZB4UC.js +100 -0
- package/dist/chunk-DCCZB4UC.js.map +1 -0
- package/dist/chunk-DKKFTHHI.js +53 -0
- package/dist/chunk-DKKFTHHI.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-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-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-I6MG4M3F.js +201 -0
- package/dist/chunk-I6MG4M3F.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-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-JRQO2IOF.js +65 -0
- package/dist/chunk-JRQO2IOF.js.map +1 -0
- package/dist/chunk-JRVNVKN6.js +212 -0
- package/dist/chunk-JRVNVKN6.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-KMZCQASO.js +111 -0
- package/dist/chunk-KMZCQASO.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-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-OZZJDRGW.js +122 -0
- package/dist/chunk-OZZJDRGW.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-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-T6C4LFLC.js +112 -0
- package/dist/chunk-T6C4LFLC.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-WEVWJKOW.js +81 -0
- package/dist/chunk-WEVWJKOW.js.map +1 -0
- package/dist/chunk-WL67FZGF.js +21 -0
- package/dist/chunk-WL67FZGF.js.map +1 -0
- package/dist/chunk-WPXNN6QS.js +290 -0
- package/dist/chunk-WPXNN6QS.js.map +1 -0
- package/dist/chunk-WRUUSZDJ.js +29 -0
- package/dist/chunk-WRUUSZDJ.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-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/{job-orchestrator.protocol-CARhMLCO.d.ts → job-orchestrator.protocol-DubMVbm9.d.ts} +1 -1
- 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.d.ts +2 -2
- 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.d.ts +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.d.ts +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.d.ts +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.d.ts +2 -2
- 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.protocol.d.ts +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.d.ts +2 -2
- 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.d.ts +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.d.ts +2 -2
- 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.d.ts +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/event-registry.d.ts +77 -0
- package/dist/runtime/subsystems/events/event-registry.js +1 -0
- package/dist/runtime/subsystems/events/event-registry.js.map +1 -0
- 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.d.ts +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 +2 -2
- package/dist/runtime/subsystems/index.js +171 -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.js +4 -89
- package/dist/runtime/subsystems/integration/poll-change-source.js.map +1 -1
- 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.d.ts +2 -2
- 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.d.ts +2 -2
- 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.d.ts +2 -2
- 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.d.ts +2 -2
- 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.d.ts +2 -2
- 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-orchestrator.protocol.d.ts +2 -2
- package/dist/runtime/subsystems/jobs/job-run-keyset-cursor.d.ts +2 -2
- 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.d.ts +2 -2
- 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.d.ts +2 -2
- 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-run-service.protocol.d.ts +2 -2
- 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.d.ts +2 -2
- 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.d.ts +2 -2
- 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.d.ts +2 -2
- 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.d.ts +2 -2
- 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.d.ts +2 -2
- 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.protocol.d.ts +2 -2
- package/dist/runtime/subsystems/observability/observability.service.d.ts +2 -2
- 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.d.ts +2 -2
- 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.d.ts +2 -2
- 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 +653 -5444
- 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-delivery-handler.ts +1 -1
- package/runtime/subsystems/bridge/bridge-outbox-drain-hook.ts +45 -22
- package/runtime/subsystems/bridge/bridge.protocol.ts +1 -1
- package/runtime/subsystems/bridge/event-flow.service.ts +1 -1
- package/runtime/subsystems/events/event-registry.ts +77 -0
- package/runtime/subsystems/events/index.ts +12 -0
- package/runtime/subsystems/jobs/job-handler.base.ts +1 -1
- package/runtime/subsystems/jobs/job-worker.ts +17 -11
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,117 @@ All notable changes to this project will be documented in this file.
|
|
|
4
4
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
|
+
## [0.15.2] — 2026-06-03
|
|
8
|
+
|
|
9
|
+
Package-mode **bridge *delivery*** — the first time a `runtime: package` consumer
|
|
10
|
+
(ADR-037) drives a real event→bridge→job round-trip end to end (webhook →
|
|
11
|
+
`domain_events` outbox → `bridge_delivery` → wrapper `@framework/bridge_delivery`
|
|
12
|
+
run → user `@JobHandler`). Three latent defects only this path exercises (codegen's
|
|
13
|
+
own tests are vendored — a single `tsc` compilation, a single in-memory Map, and a
|
|
14
|
+
mocked `tx` that never touches a real FK — so none of them ever surfaced). All three
|
|
15
|
+
fixes are framework-only; vendored mode is unaffected.
|
|
16
|
+
|
|
17
|
+
### Fixed
|
|
18
|
+
|
|
19
|
+
- **Stateful module-singletons are no longer duplicated across dist entry
|
|
20
|
+
chunks** (`tsup.config.ts`: `splitting: false` → `splitting: true`). The
|
|
21
|
+
published bundle is ESM and multi-entry — `runtime/**/*.ts` each emit a physical
|
|
22
|
+
`dist/runtime/.../x.js` so the `./runtime/*` wildcard `exports` map resolves 1:1.
|
|
23
|
+
With splitting off, esbuild INLINED every shared module into each importing entry
|
|
24
|
+
chunk. Harmless for pure functions, but a correctness bug for a stateful
|
|
25
|
+
singleton: `runtime/subsystems/jobs/job-handler.base`'s `JOB_HANDLER_REGISTRY`
|
|
26
|
+
Map (and its `HandlerRegistry` read facade), which the `@JobHandler` decorator
|
|
27
|
+
mutates at import time, got a **second copy** inlined into the `bridge/*` chunk.
|
|
28
|
+
The framework's own `@JobHandler('@framework/bridge_delivery')`
|
|
29
|
+
(`BridgeDeliveryHandler`, bridge chunk) registered into the BRIDGE copy while the
|
|
30
|
+
jobs `JobWorker` read the JOBS copy → the worker never upserted the wrapper's
|
|
31
|
+
`job` row → the bridge's outbox-drain couldn't spawn the wrapper `job_run` (its
|
|
32
|
+
`job_type` FKs `job(type)`), so the `bridge_delivery` insert violated its
|
|
33
|
+
`wrapper_run_id → job_run` FK and looped forever. `splitting: true` hoists each
|
|
34
|
+
shared module into a SINGLE shared chunk that every entry imports, collapsing the
|
|
35
|
+
registry back to one Map. The named per-entry output files are preserved (each
|
|
36
|
+
entry stays a physical `dist/runtime/.../x.js`), so the wildcard `exports` map and
|
|
37
|
+
the deep consumer subpaths (`…/subsystems/jobs/index`, `…/bridge/index`,
|
|
38
|
+
`./subsystems`) still resolve. ESM-only build ⇒ no CJS output to regress. Guarded
|
|
39
|
+
by a new dist-grep regression test.
|
|
40
|
+
- **`BridgeOutboxDrainHook` now inserts the wrapper `job_run` BEFORE the
|
|
41
|
+
`bridge_delivery` that references it** (`bridge-outbox-drain-hook.ts`).
|
|
42
|
+
`bridge_delivery.wrapper_run_id → job_run(id)` is a plain (non-deferrable) FK, so
|
|
43
|
+
the referenced wrapper run must exist before the delivery row is inserted —
|
|
44
|
+
otherwise Postgres rejects the delivery insert immediately. The drain previously
|
|
45
|
+
inserted the delivery (with `wrapper_run_id` set) first, then the wrapper run; the
|
|
46
|
+
unit tests mocked `tx`, so the ordering was never validated against a real FK.
|
|
47
|
+
Idempotency is preserved: the delivery keeps its `ON CONFLICT (event_id,
|
|
48
|
+
trigger_id) DO NOTHING RETURNING`, and when it conflicts (outbox replay or
|
|
49
|
+
facade-eager Case B) the speculatively-inserted wrapper run is DELETEd in the same
|
|
50
|
+
tx, so a skipped delivery leaves no orphan `job_run`.
|
|
51
|
+
- **`JobWorker.nextStepSeq` no longer array-destructures the raw `db.execute()`
|
|
52
|
+
result** (`job-worker.ts`). `db.execute(sql\`…\`)` is driver-shape-dependent and
|
|
53
|
+
not uniformly array-iterable: `drizzle-orm/node-postgres` returns the pg `Result`
|
|
54
|
+
OBJECT (`{ rows, rowCount, … }`), so `const [row] = await this.db.execute(...)`
|
|
55
|
+
threw `TypeError: {} is not iterable`. Every wrapper `@framework/bridge_delivery`
|
|
56
|
+
run calls `ctx.step` → `nextStepSeq`, so the delivery failed on every attempt. The
|
|
57
|
+
result is now normalised to a row array before reading, tolerating both the
|
|
58
|
+
node-postgres `{ rows }` shape and a plain-array shape. Guarded by a new unit test.
|
|
59
|
+
|
|
60
|
+
## [0.15.1] — 2026-06-02
|
|
61
|
+
|
|
62
|
+
Package-mode **bridge/trigger event typing** — the fourth and final package-mode
|
|
63
|
+
seam (after 0.14.1 subsystems, 0.14.2 bridge, 0.15.0 events). Lets a package-mode
|
|
64
|
+
consumer (`runtime: package`, ADR-037) author a `@JobHandler({ triggers: [{ event:
|
|
65
|
+
'<their_event>', map, when }] })` on their OWN event and have it typecheck with
|
|
66
|
+
full per-event payload typing. Vendored mode is byte-stable; everything here is
|
|
67
|
+
additive.
|
|
68
|
+
|
|
69
|
+
### Fixed
|
|
70
|
+
|
|
71
|
+
- **`@JobHandler.triggers` and the generated `bridge-registry.ts` now accept a
|
|
72
|
+
package-mode consumer's own events.** Previously the bridge + job-trigger types
|
|
73
|
+
(`BridgeRegistry`, `BridgeTriggerEntry<T>`, `JobTrigger<TInput>`) keyed off
|
|
74
|
+
`EventTypeName` imported from the bundled `events/generated/types.ts` — which
|
|
75
|
+
in the published package is codegen-patterns' OWN test-fixture union
|
|
76
|
+
(`contact_created`, `deal_created`, …). A consumer's
|
|
77
|
+
`'inbound_webhook_received'` trigger therefore failed to typecheck
|
|
78
|
+
(`'inbound_webhook_received' is not assignable to '"contact_created" | …'`) and
|
|
79
|
+
their generated `bridge-registry.ts` reported "does not exist in type
|
|
80
|
+
'BridgeRegistry'". The bridge/trigger types now key off an **augmentable
|
|
81
|
+
`DomainEventRegistry`** (see below) instead of the bundled fixture union, so in
|
|
82
|
+
the consumer's tsc program they resolve THEIR event union with full
|
|
83
|
+
`EventOfType<T>` payload typing (`e.payload.<field>` is typed, not `unknown`).
|
|
84
|
+
The bundled fixture-based runtime tests stay green: the bundled `TypedEventBus`
|
|
85
|
+
still keys off its local `events/generated/types.ts`, and the fixtures are
|
|
86
|
+
never registered into `DomainEventRegistry`, so they never leak into a
|
|
87
|
+
consumer's `EventTypeName`.
|
|
88
|
+
|
|
89
|
+
### Added
|
|
90
|
+
|
|
91
|
+
- **`DomainEventRegistry` — an augmentable, empty event registry interface**
|
|
92
|
+
(`runtime/subsystems/events/event-registry.ts`, re-exported from the events
|
|
93
|
+
index barrel). `EventTypeName` now derives from it
|
|
94
|
+
(`keyof DomainEventRegistry extends never ? string : keyof DomainEventRegistry &
|
|
95
|
+
string`) and `EventOfType<T>` resolves a registered event's concrete interface
|
|
96
|
+
(falling back to the structural `DomainEvent` base otherwise). Empty in the
|
|
97
|
+
package and in any no-events project ⇒ `EventTypeName` degrades to `string` and
|
|
98
|
+
the bridge/trigger types stay sound (`Record<string, …>` / `(e: DomainEvent) =>
|
|
99
|
+
…`) — exactly the loose shape the package's own fixture tests rely on. The five
|
|
100
|
+
bridge/jobs runtime files that consumed `EventTypeName` / `EventOfType` from the
|
|
101
|
+
bundled `events/generated/types` (`bridge.protocol`, `job-handler.base`,
|
|
102
|
+
`event-flow.service`, `bridge-outbox-drain-hook`, `bridge-delivery-handler`) now
|
|
103
|
+
import them from this augmentable seam.
|
|
104
|
+
- **Event codegen emits a package-mode `declare module` augmentation.** In
|
|
105
|
+
package mode the generated `src/generated/events/types.ts` now appends a
|
|
106
|
+
`declare module '@pattern-stack/codegen/runtime/subsystems/events/index' {
|
|
107
|
+
interface DomainEventRegistry { '<type>': <Type>Event; … } }` block that
|
|
108
|
+
declaration-merges the consumer's events into the runtime's registry through
|
|
109
|
+
the events index module specifier (the stable, public augmentation target).
|
|
110
|
+
Gated on `mode === 'package'` and a non-empty event set; vendored mode emits
|
|
111
|
+
nothing (the bridge/job types import the consumer's vendored `./generated/types`
|
|
112
|
+
directly), so vendored output is byte-stable. Proven end-to-end with a real
|
|
113
|
+
cross-`node_modules` consumer typecheck (declaration merging across the package
|
|
114
|
+
boundary is finicky and is covered by a real-tsc unit test, not string
|
|
115
|
+
assertions alone): an unregistered event type is rejected, and a registered
|
|
116
|
+
one's trigger `map` reads `e.payload.<field>` fully typed.
|
|
117
|
+
|
|
7
118
|
## [0.15.0] — 2026-06-02
|
|
8
119
|
|
|
9
120
|
Package-mode consumer **events** — the seam that lets a project consuming the
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
// runtime/subsystems/integration/poll-change-source.ts
|
|
2
|
+
var PollChangeSource = class {
|
|
3
|
+
label;
|
|
4
|
+
adapter;
|
|
5
|
+
filters;
|
|
6
|
+
externalIdSourceField;
|
|
7
|
+
source;
|
|
8
|
+
/**
|
|
9
|
+
* When `poll.provenance === 'cdc'`, the field on the emitted record from
|
|
10
|
+
* which `Change<T>.dedupKey` is read — sourced from `poll.cursor.field`
|
|
11
|
+
* (Stripe-style event endpoints carry the event id on the record itself
|
|
12
|
+
* and the cursor advances over the same id). `null` for default poll
|
|
13
|
+
* provenance, which does NOT populate `dedupKey`.
|
|
14
|
+
*/
|
|
15
|
+
dedupKeySourceField;
|
|
16
|
+
composed;
|
|
17
|
+
constructor(opts) {
|
|
18
|
+
if (opts.config.mode !== "poll") {
|
|
19
|
+
throw new Error(
|
|
20
|
+
`PollChangeSource requires DetectionConfig.mode === 'poll'; got '${opts.config.mode}'`
|
|
21
|
+
);
|
|
22
|
+
}
|
|
23
|
+
const config = opts.config;
|
|
24
|
+
const externalIdMapping = config.mapping.find(
|
|
25
|
+
(m) => m.target === "external_id"
|
|
26
|
+
);
|
|
27
|
+
if (!externalIdMapping) {
|
|
28
|
+
throw new Error(
|
|
29
|
+
"PollChangeSource: DetectionConfig.mapping must include an entry with target 'external_id' so emitted Change<T>.externalId can be populated"
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
this.externalIdSourceField = externalIdMapping.target;
|
|
33
|
+
this.adapter = opts.adapter;
|
|
34
|
+
this.filters = config.filters;
|
|
35
|
+
const isCdc = config.poll.provenance === "cdc";
|
|
36
|
+
this.source = isCdc ? "cdc" : "poll";
|
|
37
|
+
this.dedupKeySourceField = isCdc ? config.poll.cursor.field : null;
|
|
38
|
+
this.label = opts.label ?? `poll-change-source:${externalIdMapping.source}`;
|
|
39
|
+
const inner = (sub, cur) => this.fetch(sub, cur);
|
|
40
|
+
const middlewares = opts.middlewares ?? [];
|
|
41
|
+
this.composed = middlewares.reduceRight(
|
|
42
|
+
(next, mw) => mw(next),
|
|
43
|
+
inner
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
listChanges(subscription, cursor) {
|
|
47
|
+
return this.composed(subscription, cursor);
|
|
48
|
+
}
|
|
49
|
+
async *fetch(subscription, cursor) {
|
|
50
|
+
const ctx = {
|
|
51
|
+
subscription,
|
|
52
|
+
cursor,
|
|
53
|
+
filters: this.filters
|
|
54
|
+
};
|
|
55
|
+
for await (const { record, cursor: nextCursor } of this.adapter(ctx)) {
|
|
56
|
+
const externalIdRaw = record[this.externalIdSourceField];
|
|
57
|
+
if (typeof externalIdRaw !== "string" || externalIdRaw.length === 0) {
|
|
58
|
+
throw new Error(
|
|
59
|
+
`PollChangeSource: record missing string '${this.externalIdSourceField}' \u2014 emitted records MUST carry the canonical external id keyed by the mapping target`
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
let dedupKey;
|
|
63
|
+
if (this.dedupKeySourceField !== null) {
|
|
64
|
+
const dedupRaw = record[this.dedupKeySourceField];
|
|
65
|
+
if (typeof dedupRaw !== "string" || dedupRaw.length === 0) {
|
|
66
|
+
throw new Error(
|
|
67
|
+
`PollChangeSource: cdc-provenance record missing string '${this.dedupKeySourceField}' \u2014 when poll.provenance === 'cdc' the cursor.field must be present on each record so dedupKey can be populated`
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
dedupKey = dedupRaw;
|
|
71
|
+
}
|
|
72
|
+
const change = {
|
|
73
|
+
externalId: externalIdRaw,
|
|
74
|
+
// Polling cannot distinguish create vs. update vs. delete on its
|
|
75
|
+
// own — all yielded records are surfaced as 'updated'. The
|
|
76
|
+
// orchestrator's diff stage classifies create-vs-update against
|
|
77
|
+
// local state; soft-delete detection is out of scope for the
|
|
78
|
+
// primitive (consumer drives via tombstone records or a separate
|
|
79
|
+
// sweep — see ADR-033).
|
|
80
|
+
operation: "updated",
|
|
81
|
+
record,
|
|
82
|
+
cursor: nextCursor,
|
|
83
|
+
source: this.source,
|
|
84
|
+
...dedupKey !== void 0 ? { dedupKey } : {}
|
|
85
|
+
};
|
|
86
|
+
yield change;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
export {
|
|
92
|
+
PollChangeSource
|
|
93
|
+
};
|
|
94
|
+
//# sourceMappingURL=chunk-24CWKBK5.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../runtime/subsystems/integration/poll-change-source.ts"],"sourcesContent":["/**\n * Integration subsystem — `PollChangeSource<T>` primitive (#226-3, ADR-033).\n *\n * Generic poll-mode `IChangeSource<T>` implementation parameterized by a\n * parsed `DetectionConfig` (poll mode) and a consumer-supplied\n * `PollFetchCallback<T>`. The primitive owns:\n *\n * - filter resolution (flat-AND vocabulary per epic decision Q3 — richer\n * boolean expressions deferred);\n * - field mapping → `Change.externalId` derivation;\n * - cursor strategy passthrough (the orchestrator passes the prior cursor\n * by-value per ADR-033 / #226-2; the callback yields the next cursor\n * per record; the primitive simply stamps it onto `Change<T>`);\n * - `Change<T>.source` provenance (`'poll'` by default);\n * - middleware-chain composition (the `ChangeMiddleware<T>` shape\n * locked in #226-1).\n *\n * Shape locks (decision memo Q5):\n * - `PollFetchContext = { subscription, cursor, filters }` — explicitly\n * NO `userId` / `tenantId`. Run-scope identity is closed over by the\n * consumer at adapter construction (or resolved inside the callback\n * via consumer services). Threading it through the seam would force\n * port expansion every time run-context grows.\n *\n * The adapter callback returns `{ record: T; cursor: PollCursor }` — the\n * primitive does not reach into the record to extract a cursor itself.\n * `cursor.field` from `DetectionConfig.poll.cursor` is metadata for codegen\n * + adapters; the primitive trusts what the callback yielded.\n */\n\nimport type {\n DetectionConfig,\n ResolvedFilter,\n} from './detection-config.schema';\nimport type {\n Change,\n ChangeSource,\n IChangeSource,\n IntegrationSubscriptionView,\n} from './integration-change-source.protocol';\nimport type {\n ChangeIterator,\n ChangeMiddleware,\n} from './integration-middleware.protocol';\n\n// ============================================================================\n// Cursor + adapter callback shapes\n// ============================================================================\n\n/**\n * Opaque poll-cursor shape. Each provider/entity pair binds it concretely\n * via the cursor strategy (`{ systemModstamp }`, `{ replayId }`, etc.); the\n * primitive treats it as an opaque value to pass through.\n */\nexport type PollCursor = unknown;\n\n/**\n * The context the primitive forwards to the adapter callback. Locked to\n * exactly three fields per decision memo Q5 — `userId` / `tenantId` are\n * NOT here on purpose.\n */\nexport interface PollFetchContext {\n readonly subscription: IntegrationSubscriptionView;\n readonly cursor: PollCursor | null;\n readonly filters: readonly ResolvedFilter[];\n}\n\n/**\n * Consumer-supplied fetch callback. Returns an async iterable of\n * `{ record, cursor }` pairs — `record` is already the canonical `T`\n * (the adapter does provider-side translation), `cursor` is the post-record\n * cursor the orchestrator should persist if the run completes successfully.\n */\nexport type PollFetchCallback<T> = (\n ctx: PollFetchContext,\n) => AsyncIterable<{ record: T; cursor: PollCursor }>;\n\n// ============================================================================\n// Constructor options\n// ============================================================================\n\nexport interface PollChangeSourceOptions<T> {\n /** Consumer-supplied fetch callback. */\n readonly adapter: PollFetchCallback<T>;\n /**\n * Parsed detection config. MUST be `mode: 'poll'`; the constructor\n * throws if a webhook config is supplied. Codegen-emitted factories\n * call `DetectionConfigSchema.parse(...)` upstream so this is a safety\n * net, not the primary validation point.\n */\n readonly config: DetectionConfig;\n /**\n * Optional middleware chain. First element is the outermost layer:\n * sees `(subscription, cursor)` first and yielded `Change<T>` last.\n * Locked shape (#226-1) — the primitive composes them with its own\n * `listChanges` implementation as the innermost iterator.\n */\n readonly middlewares?: ReadonlyArray<ChangeMiddleware<T>>;\n /**\n * Optional human label for run logs (e.g. `'salesforce-poll-opportunity'`).\n * Defaults to a derived label based on the subscription domain at\n * construction time fallback — adapters are encouraged to provide one.\n */\n readonly label?: string;\n}\n\n// ============================================================================\n// PollChangeSource<T>\n// ============================================================================\n\nexport class PollChangeSource<T> implements IChangeSource<T> {\n public readonly label: string;\n\n private readonly adapter: PollFetchCallback<T>;\n private readonly filters: readonly ResolvedFilter[];\n private readonly externalIdSourceField: string;\n private readonly source: ChangeSource;\n /**\n * When `poll.provenance === 'cdc'`, the field on the emitted record from\n * which `Change<T>.dedupKey` is read — sourced from `poll.cursor.field`\n * (Stripe-style event endpoints carry the event id on the record itself\n * and the cursor advances over the same id). `null` for default poll\n * provenance, which does NOT populate `dedupKey`.\n */\n private readonly dedupKeySourceField: string | null;\n private readonly composed: ChangeIterator<T>;\n\n constructor(opts: PollChangeSourceOptions<T>) {\n if (opts.config.mode !== 'poll') {\n throw new Error(\n `PollChangeSource requires DetectionConfig.mode === 'poll'; got '${(opts.config as { mode: string }).mode}'`,\n );\n }\n const config = opts.config;\n\n // Field mapping: locate the canonical `external_id` target. Adapters\n // emit T already-mapped, but the primitive needs to know which key on\n // T carries the external id so it can stamp `Change.externalId`. Source\n // of truth is the mapping table — codegen emits it from YAML, the\n // primitive reads it here.\n const externalIdMapping = config.mapping.find(\n (m) => m.target === 'external_id',\n );\n if (!externalIdMapping) {\n throw new Error(\n \"PollChangeSource: DetectionConfig.mapping must include an entry with target 'external_id' so emitted Change<T>.externalId can be populated\",\n );\n }\n this.externalIdSourceField = externalIdMapping.target;\n\n this.adapter = opts.adapter;\n this.filters = config.filters;\n // Provenance: `mode: 'poll'` defaults to `'poll'`; opt into `'cdc'` via\n // `poll.provenance` (Stripe-style event endpoints — wired in #226-4).\n // CDC provenance also stamps `dedupKey` from the cursor's `field`, since\n // those endpoints surface a per-event id on each record (the same id the\n // cursor advances over).\n const isCdc = config.poll.provenance === 'cdc';\n this.source = isCdc ? 'cdc' : 'poll';\n this.dedupKeySourceField = isCdc ? config.poll.cursor.field : null;\n\n this.label =\n opts.label ?? `poll-change-source:${externalIdMapping.source}`;\n\n // Compose middleware chain. The terminal iterator is `this.fetch`\n // bound to `this`. First middleware in the array is the outermost\n // layer (sees subscription/cursor first, yielded changes last).\n const inner: ChangeIterator<T> = (sub, cur) => this.fetch(sub, cur);\n const middlewares = opts.middlewares ?? [];\n this.composed = middlewares.reduceRight<ChangeIterator<T>>(\n (next, mw) => mw(next),\n inner,\n );\n }\n\n listChanges(\n subscription: IntegrationSubscriptionView,\n cursor: unknown | null,\n ): AsyncIterable<Change<T>> {\n return this.composed(subscription, cursor);\n }\n\n private async *fetch(\n subscription: IntegrationSubscriptionView,\n cursor: unknown | null,\n ): AsyncIterable<Change<T>> {\n const ctx: PollFetchContext = {\n subscription,\n cursor: cursor as PollCursor | null,\n filters: this.filters,\n };\n\n for await (const { record, cursor: nextCursor } of this.adapter(ctx)) {\n const externalIdRaw = (record as Record<string, unknown>)[\n this.externalIdSourceField\n ];\n if (typeof externalIdRaw !== 'string' || externalIdRaw.length === 0) {\n throw new Error(\n `PollChangeSource: record missing string '${this.externalIdSourceField}' — emitted records MUST carry the canonical external id keyed by the mapping target`,\n );\n }\n let dedupKey: string | undefined;\n if (this.dedupKeySourceField !== null) {\n const dedupRaw = (record as Record<string, unknown>)[\n this.dedupKeySourceField\n ];\n if (typeof dedupRaw !== 'string' || dedupRaw.length === 0) {\n throw new Error(\n `PollChangeSource: cdc-provenance record missing string '${this.dedupKeySourceField}' — when poll.provenance === 'cdc' the cursor.field must be present on each record so dedupKey can be populated`,\n );\n }\n dedupKey = dedupRaw;\n }\n\n const change: Change<T> = {\n externalId: externalIdRaw,\n // Polling cannot distinguish create vs. update vs. delete on its\n // own — all yielded records are surfaced as 'updated'. The\n // orchestrator's diff stage classifies create-vs-update against\n // local state; soft-delete detection is out of scope for the\n // primitive (consumer drives via tombstone records or a separate\n // sweep — see ADR-033).\n operation: 'updated',\n record,\n cursor: nextCursor,\n source: this.source,\n ...(dedupKey !== undefined ? { dedupKey } : {}),\n };\n yield change;\n }\n }\n}\n"],"mappings":";AA8GO,IAAM,mBAAN,MAAsD;AAAA,EAC3C;AAAA,EAEC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA;AAAA,EACA;AAAA,EAEjB,YAAY,MAAkC;AAC5C,QAAI,KAAK,OAAO,SAAS,QAAQ;AAC/B,YAAM,IAAI;AAAA,QACR,mEAAoE,KAAK,OAA4B,IAAI;AAAA,MAC3G;AAAA,IACF;AACA,UAAM,SAAS,KAAK;AAOpB,UAAM,oBAAoB,OAAO,QAAQ;AAAA,MACvC,CAAC,MAAM,EAAE,WAAW;AAAA,IACtB;AACA,QAAI,CAAC,mBAAmB;AACtB,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AACA,SAAK,wBAAwB,kBAAkB;AAE/C,SAAK,UAAU,KAAK;AACpB,SAAK,UAAU,OAAO;AAMtB,UAAM,QAAQ,OAAO,KAAK,eAAe;AACzC,SAAK,SAAS,QAAQ,QAAQ;AAC9B,SAAK,sBAAsB,QAAQ,OAAO,KAAK,OAAO,QAAQ;AAE9D,SAAK,QACH,KAAK,SAAS,sBAAsB,kBAAkB,MAAM;AAK9D,UAAM,QAA2B,CAAC,KAAK,QAAQ,KAAK,MAAM,KAAK,GAAG;AAClE,UAAM,cAAc,KAAK,eAAe,CAAC;AACzC,SAAK,WAAW,YAAY;AAAA,MAC1B,CAAC,MAAM,OAAO,GAAG,IAAI;AAAA,MACrB;AAAA,IACF;AAAA,EACF;AAAA,EAEA,YACE,cACA,QAC0B;AAC1B,WAAO,KAAK,SAAS,cAAc,MAAM;AAAA,EAC3C;AAAA,EAEA,OAAe,MACb,cACA,QAC0B;AAC1B,UAAM,MAAwB;AAAA,MAC5B;AAAA,MACA;AAAA,MACA,SAAS,KAAK;AAAA,IAChB;AAEA,qBAAiB,EAAE,QAAQ,QAAQ,WAAW,KAAK,KAAK,QAAQ,GAAG,GAAG;AACpE,YAAM,gBAAiB,OACrB,KAAK,qBACP;AACA,UAAI,OAAO,kBAAkB,YAAY,cAAc,WAAW,GAAG;AACnE,cAAM,IAAI;AAAA,UACR,4CAA4C,KAAK,qBAAqB;AAAA,QACxE;AAAA,MACF;AACA,UAAI;AACJ,UAAI,KAAK,wBAAwB,MAAM;AACrC,cAAM,WAAY,OAChB,KAAK,mBACP;AACA,YAAI,OAAO,aAAa,YAAY,SAAS,WAAW,GAAG;AACzD,gBAAM,IAAI;AAAA,YACR,2DAA2D,KAAK,mBAAmB;AAAA,UACrF;AAAA,QACF;AACA,mBAAW;AAAA,MACb;AAEA,YAAM,SAAoB;AAAA,QACxB,YAAY;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAOZ,WAAW;AAAA,QACX;AAAA,QACA,QAAQ;AAAA,QACR,QAAQ,KAAK;AAAA,QACb,GAAI,aAAa,SAAY,EAAE,SAAS,IAAI,CAAC;AAAA,MAC/C;AACA,YAAM;AAAA,IACR;AAAA,EACF;AACF;","names":[]}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
4
|
+
var __decorateClass = (decorators, target, key, kind) => {
|
|
5
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
|
|
6
|
+
for (var i = decorators.length - 1, decorator; i >= 0; i--)
|
|
7
|
+
if (decorator = decorators[i])
|
|
8
|
+
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
9
|
+
if (kind && result) __defProp(target, key, result);
|
|
10
|
+
return result;
|
|
11
|
+
};
|
|
12
|
+
var __decorateParam = (index, decorator) => (target, key) => decorator(target, key, index);
|
|
13
|
+
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
14
|
+
|
|
15
|
+
export {
|
|
16
|
+
__decorateClass,
|
|
17
|
+
__decorateParam,
|
|
18
|
+
__publicField
|
|
19
|
+
};
|
|
20
|
+
//# sourceMappingURL=chunk-2E224ZSN.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
import {
|
|
2
|
+
BaseRepository
|
|
3
|
+
} from "./chunk-J6KZS54B.js";
|
|
4
|
+
|
|
5
|
+
// runtime/base-classes/junction-integration-repository.ts
|
|
6
|
+
import { and, eq } from "drizzle-orm";
|
|
7
|
+
var JunctionIntegrationRepository = class extends BaseRepository {
|
|
8
|
+
/**
|
|
9
|
+
* Upsert ONE junction row by its composite identity, in a single transaction:
|
|
10
|
+
* 1. resolve the REQUIRED left FK (provider-scoped) — STRICT: missing → throws;
|
|
11
|
+
* 2. resolve the REQUIRED right FK (provider-scoped) — STRICT: missing → throws;
|
|
12
|
+
* 3. insert-or-update on the `(left, right[, role])` conflict target.
|
|
13
|
+
*
|
|
14
|
+
* Idempotent. Returns the composite externalId as the projection `id`.
|
|
15
|
+
*
|
|
16
|
+
* @param write parent external ids (`<left>ExternalId`/`<right>ExternalId`)
|
|
17
|
+
* + optional `role` + `userId`
|
|
18
|
+
* @param provider adapter/provider label used to scope the parent lookups
|
|
19
|
+
* @param tx optional outer transaction; when omitted we open our own
|
|
20
|
+
*/
|
|
21
|
+
async integrationUpsertOne(write, provider, tx) {
|
|
22
|
+
const cfg = this.integrationConfig;
|
|
23
|
+
const w = write;
|
|
24
|
+
const leftWriteKey = `${cfg.left.column.replace(/Id$/, "")}ExternalId`;
|
|
25
|
+
const rightWriteKey = `${cfg.right.column.replace(/Id$/, "")}ExternalId`;
|
|
26
|
+
const run = async (db) => {
|
|
27
|
+
const leftId = await this.resolveStrict(
|
|
28
|
+
db,
|
|
29
|
+
cfg.left.refTable,
|
|
30
|
+
w[leftWriteKey],
|
|
31
|
+
provider,
|
|
32
|
+
cfg.left.column
|
|
33
|
+
);
|
|
34
|
+
const rightId = await this.resolveStrict(
|
|
35
|
+
db,
|
|
36
|
+
cfg.right.refTable,
|
|
37
|
+
w[rightWriteKey],
|
|
38
|
+
provider,
|
|
39
|
+
cfg.right.column
|
|
40
|
+
);
|
|
41
|
+
const now = /* @__PURE__ */ new Date();
|
|
42
|
+
const role = cfg.roleColumn ? w["role"] : void 0;
|
|
43
|
+
const values = {
|
|
44
|
+
[cfg.left.column]: leftId,
|
|
45
|
+
[cfg.right.column]: rightId,
|
|
46
|
+
...cfg.roleColumn ? { [cfg.roleColumn]: role } : {},
|
|
47
|
+
...this.behaviors.timestamps ? { updatedAt: now } : {}
|
|
48
|
+
};
|
|
49
|
+
const target = cfg.roleColumn ? [this.table[cfg.left.column], this.table[cfg.right.column], this.table[cfg.roleColumn]] : [this.table[cfg.left.column], this.table[cfg.right.column]];
|
|
50
|
+
const rows = await db.insert(this.table).values(values).onConflictDoUpdate({
|
|
51
|
+
target,
|
|
52
|
+
set: { ...this.behaviors.timestamps ? { updatedAt: now } : {} }
|
|
53
|
+
}).returning();
|
|
54
|
+
const saved = rows[0];
|
|
55
|
+
return this.toProjection(saved, w, provider);
|
|
56
|
+
};
|
|
57
|
+
return tx ? run(tx) : this.db.transaction((t) => run(t));
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Canonical-projected lookup by the COMPOSITE externalId, differ-ready. Parses
|
|
61
|
+
* the composite, resolves BOTH parents NON-throwing (→ null), then selects by
|
|
62
|
+
* the identity tuple. Returns `null` on malformed composite / unresolved
|
|
63
|
+
* parent / no row (a missing "before" side is a create from the differ's view).
|
|
64
|
+
*/
|
|
65
|
+
async findByExternalIdProjected(externalId, provider) {
|
|
66
|
+
const cfg = this.integrationConfig;
|
|
67
|
+
const parsed = parseCompositeExternalId(externalId, cfg.roleColumn !== null);
|
|
68
|
+
if (!parsed) return null;
|
|
69
|
+
const leftId = await this.resolveLoose(this.db, cfg.left.refTable, parsed.left, provider);
|
|
70
|
+
if (leftId === null) return null;
|
|
71
|
+
const rightId = await this.resolveLoose(this.db, cfg.right.refTable, parsed.right, provider);
|
|
72
|
+
if (rightId === null) return null;
|
|
73
|
+
const rows = await this.db.select().from(this.table).where(this.identityWhere(leftId, rightId, parsed.role)).limit(1);
|
|
74
|
+
const row = rows[0];
|
|
75
|
+
if (!row) return null;
|
|
76
|
+
const w = {
|
|
77
|
+
[`${cfg.left.column.replace(/Id$/, "")}ExternalId`]: parsed.left,
|
|
78
|
+
[`${cfg.right.column.replace(/Id$/, "")}ExternalId`]: parsed.right,
|
|
79
|
+
...cfg.roleColumn ? { role: parsed.role } : {},
|
|
80
|
+
userId: ""
|
|
81
|
+
};
|
|
82
|
+
return this.toProjection(row, w, provider);
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Hard-delete the junction by composite externalId. Junctions have no
|
|
86
|
+
* `deleted_at` and no external-linkage columns to clear, so a integration "delete"
|
|
87
|
+
* removes the row. Resolves both parents NON-throwing, then deletes by the
|
|
88
|
+
* identity tuple. Returns the composite id, or `null` when nothing matched.
|
|
89
|
+
*/
|
|
90
|
+
async softDeleteByExternalId(externalId, provider, tx) {
|
|
91
|
+
const cfg = this.integrationConfig;
|
|
92
|
+
const parsed = parseCompositeExternalId(externalId, cfg.roleColumn !== null);
|
|
93
|
+
if (!parsed) return null;
|
|
94
|
+
const db = this.runner(tx);
|
|
95
|
+
const leftId = await this.resolveLoose(db, cfg.left.refTable, parsed.left, provider);
|
|
96
|
+
if (leftId === null) return null;
|
|
97
|
+
const rightId = await this.resolveLoose(db, cfg.right.refTable, parsed.right, provider);
|
|
98
|
+
if (rightId === null) return null;
|
|
99
|
+
const rows = await db.delete(this.table).where(this.identityWhere(leftId, rightId, parsed.role)).returning({ id: this.table[cfg.left.column] });
|
|
100
|
+
return rows[0] ? { id: externalId } : null;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Project a raw junction row to the differ shape: the COMPOSITE externalId
|
|
104
|
+
* `id` (junctions have no surrogate id) plus the local FK columns, role (when
|
|
105
|
+
* role-bearing) and timestamps — matching the emitted
|
|
106
|
+
* `<Junction>IntegrationProjection` interface (id + leftId + rightId + role? +
|
|
107
|
+
* createdAt + updatedAt). Junction projections are purely structural, so this
|
|
108
|
+
* is fully generic over `integrationConfig` — no per-junction override is emitted.
|
|
109
|
+
*/
|
|
110
|
+
toProjection(row, write, _provider) {
|
|
111
|
+
const cfg = this.integrationConfig;
|
|
112
|
+
const r = row;
|
|
113
|
+
const leftExt = write[`${cfg.left.column.replace(/Id$/, "")}ExternalId`];
|
|
114
|
+
const rightExt = write[`${cfg.right.column.replace(/Id$/, "")}ExternalId`];
|
|
115
|
+
const role = cfg.roleColumn ? r[cfg.roleColumn] : void 0;
|
|
116
|
+
const out = {
|
|
117
|
+
id: buildCompositeExternalId(leftExt, rightExt, role),
|
|
118
|
+
[cfg.left.column]: r[cfg.left.column],
|
|
119
|
+
[cfg.right.column]: r[cfg.right.column]
|
|
120
|
+
};
|
|
121
|
+
if (cfg.roleColumn) out[cfg.roleColumn] = r[cfg.roleColumn];
|
|
122
|
+
out["createdAt"] = r["createdAt"];
|
|
123
|
+
out["updatedAt"] = r["updatedAt"];
|
|
124
|
+
return out;
|
|
125
|
+
}
|
|
126
|
+
/** Build the identity WHERE clause `(left, right[, role])`. */
|
|
127
|
+
identityWhere(leftId, rightId, role) {
|
|
128
|
+
const cfg = this.integrationConfig;
|
|
129
|
+
const conds = [
|
|
130
|
+
eq(this.table[cfg.left.column], leftId),
|
|
131
|
+
eq(this.table[cfg.right.column], rightId)
|
|
132
|
+
];
|
|
133
|
+
if (cfg.roleColumn && role !== void 0) {
|
|
134
|
+
conds.push(eq(this.table[cfg.roleColumn], role));
|
|
135
|
+
}
|
|
136
|
+
return and(...conds);
|
|
137
|
+
}
|
|
138
|
+
/** Resolve a parent id (provider-scoped), throwing when unresolved. */
|
|
139
|
+
async resolveStrict(db, refTable, parentExternalId, provider, column) {
|
|
140
|
+
const id = await this.resolveLoose(db, refTable, parentExternalId, provider);
|
|
141
|
+
if (!id) {
|
|
142
|
+
throw new Error(
|
|
143
|
+
`${this.constructor.name}.integrationUpsertOne: unresolved parent '${parentExternalId}' (provider '${provider}') for '${column}' \u2014 parent not integrated yet`
|
|
144
|
+
);
|
|
145
|
+
}
|
|
146
|
+
return id;
|
|
147
|
+
}
|
|
148
|
+
/** Resolve a parent id (provider-scoped), returning null when unresolved. */
|
|
149
|
+
async resolveLoose(db, refTable, parentExternalId, provider) {
|
|
150
|
+
if (!parentExternalId) return null;
|
|
151
|
+
const rows = await db.select({ id: refTable["id"] }).from(refTable).where(
|
|
152
|
+
and(
|
|
153
|
+
eq(refTable["provider"], provider),
|
|
154
|
+
eq(refTable["externalId"], parentExternalId)
|
|
155
|
+
)
|
|
156
|
+
).limit(1);
|
|
157
|
+
return rows[0]?.id ?? null;
|
|
158
|
+
}
|
|
159
|
+
};
|
|
160
|
+
function buildCompositeExternalId(leftExternalId, rightExternalId, role) {
|
|
161
|
+
return role !== void 0 ? `${leftExternalId}::${rightExternalId}::${role}` : `${leftExternalId}::${rightExternalId}`;
|
|
162
|
+
}
|
|
163
|
+
function parseCompositeExternalId(externalId, withRole) {
|
|
164
|
+
const parts = externalId.split("::");
|
|
165
|
+
const expected = withRole ? 3 : 2;
|
|
166
|
+
if (parts.length !== expected || parts.some((p) => p.length === 0)) return null;
|
|
167
|
+
return {
|
|
168
|
+
left: parts[0],
|
|
169
|
+
right: parts[1],
|
|
170
|
+
role: withRole ? parts[2] : void 0
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
export {
|
|
175
|
+
JunctionIntegrationRepository,
|
|
176
|
+
buildCompositeExternalId,
|
|
177
|
+
parseCompositeExternalId
|
|
178
|
+
};
|
|
179
|
+
//# sourceMappingURL=chunk-2FTZLDBP.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../runtime/base-classes/junction-integration-repository.ts"],"sourcesContent":["/**\n * JunctionIntegrationRepository<TEntity, TIntegrationWrite, TIntegrationProjection>\n *\n * Base for junction repos that participate in inbound integration (#374). A junction's\n * integration identity is the tuple `(leftId, rightId[, role])` — there is no native\n * `external_id`/`provider` column, so the integration seam's externalId is a COMPOSITE\n * string `<leftExternalId>::<rightExternalId>[::<role>]` (see the static\n * build/parse helpers below).\n *\n * Both parent FKs are resolved STRICTLY in the write path (a missing parent\n * throws → the orchestrator records a failed item and continues). As of #372\n * role-bearing junctions carry a unique constraint over `(left, right, role)`,\n * so the upsert uses `onConflictDoUpdate` (not the legacy select-then-write).\n * Role-less junctions conflict on `(left, right)`.\n */\nimport { and, eq } from 'drizzle-orm';\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nimport type { PgTableWithColumns } from 'drizzle-orm/pg-core';\nimport type { DrizzleTx } from '../types/drizzle';\nimport { BaseRepository } from './base-repository';\n\nexport interface JunctionIntegrationConfig {\n /** Left endpoint: local FK column (camel) + strict parent table. */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n left: { column: string; refTable: PgTableWithColumns<any> };\n /** Right endpoint: local FK column (camel) + strict parent table. */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n right: { column: string; refTable: PgTableWithColumns<any> };\n /** Role column (camel), or null for a role-less (2-part composite) junction. */\n roleColumn: string | null;\n}\n\nexport abstract class JunctionIntegrationRepository<\n TEntity,\n TIntegrationWrite,\n TIntegrationProjection,\n> extends BaseRepository<TEntity> {\n /**\n * Declarative junction integration surface. Concrete repos declare this — the\n * template emits it with live parent-table handles.\n */\n protected abstract readonly integrationConfig: JunctionIntegrationConfig;\n\n /**\n * Upsert ONE junction row by its composite identity, in a single transaction:\n * 1. resolve the REQUIRED left FK (provider-scoped) — STRICT: missing → throws;\n * 2. resolve the REQUIRED right FK (provider-scoped) — STRICT: missing → throws;\n * 3. insert-or-update on the `(left, right[, role])` conflict target.\n *\n * Idempotent. Returns the composite externalId as the projection `id`.\n *\n * @param write parent external ids (`<left>ExternalId`/`<right>ExternalId`)\n * + optional `role` + `userId`\n * @param provider adapter/provider label used to scope the parent lookups\n * @param tx optional outer transaction; when omitted we open our own\n */\n async integrationUpsertOne(\n write: TIntegrationWrite,\n provider: string,\n tx?: DrizzleTx,\n ): Promise<TIntegrationProjection> {\n const cfg = this.integrationConfig;\n const w = write as Record<string, unknown>;\n const leftWriteKey = `${cfg.left.column.replace(/Id$/, '')}ExternalId`;\n const rightWriteKey = `${cfg.right.column.replace(/Id$/, '')}ExternalId`;\n\n const run = async (db: DrizzleTx): Promise<TIntegrationProjection> => {\n const leftId = await this.resolveStrict(\n db, cfg.left.refTable, w[leftWriteKey] as string, provider, cfg.left.column,\n );\n const rightId = await this.resolveStrict(\n db, cfg.right.refTable, w[rightWriteKey] as string, provider, cfg.right.column,\n );\n\n const now = new Date();\n const role = cfg.roleColumn ? (w['role'] as unknown) : undefined;\n const values: Record<string, unknown> = {\n [cfg.left.column]: leftId,\n [cfg.right.column]: rightId,\n ...(cfg.roleColumn ? { [cfg.roleColumn]: role } : {}),\n ...(this.behaviors.timestamps ? { updatedAt: now } : {}),\n };\n const target = cfg.roleColumn\n ? [this.table[cfg.left.column], this.table[cfg.right.column], this.table[cfg.roleColumn]]\n : [this.table[cfg.left.column], this.table[cfg.right.column]];\n\n const rows = await db\n .insert(this.table)\n .values(values as never)\n .onConflictDoUpdate({\n target,\n set: { ...(this.behaviors.timestamps ? { updatedAt: now } : {}) } as never,\n })\n .returning();\n\n const saved = rows[0] as Record<string, unknown>;\n return this.toProjection(saved as TEntity, w, provider);\n };\n\n return tx ? run(tx) : this.db.transaction((t) => run(t));\n }\n\n /**\n * Canonical-projected lookup by the COMPOSITE externalId, differ-ready. Parses\n * the composite, resolves BOTH parents NON-throwing (→ null), then selects by\n * the identity tuple. Returns `null` on malformed composite / unresolved\n * parent / no row (a missing \"before\" side is a create from the differ's view).\n */\n async findByExternalIdProjected(\n externalId: string,\n provider: string,\n ): Promise<TIntegrationProjection | null> {\n const cfg = this.integrationConfig;\n const parsed = parseCompositeExternalId(externalId, cfg.roleColumn !== null);\n if (!parsed) return null;\n\n const leftId = await this.resolveLoose(this.db, cfg.left.refTable, parsed.left, provider);\n if (leftId === null) return null;\n const rightId = await this.resolveLoose(this.db, cfg.right.refTable, parsed.right, provider);\n if (rightId === null) return null;\n\n const rows = await this.db\n .select()\n .from(this.table)\n .where(this.identityWhere(leftId, rightId, parsed.role))\n .limit(1);\n const row = rows[0] as TEntity | undefined;\n if (!row) return null;\n\n const w: Record<string, unknown> = {\n [`${cfg.left.column.replace(/Id$/, '')}ExternalId`]: parsed.left,\n [`${cfg.right.column.replace(/Id$/, '')}ExternalId`]: parsed.right,\n ...(cfg.roleColumn ? { role: parsed.role } : {}),\n userId: '',\n };\n return this.toProjection(row, w, provider);\n }\n\n /**\n * Hard-delete the junction by composite externalId. Junctions have no\n * `deleted_at` and no external-linkage columns to clear, so a integration \"delete\"\n * removes the row. Resolves both parents NON-throwing, then deletes by the\n * identity tuple. Returns the composite id, or `null` when nothing matched.\n */\n async softDeleteByExternalId(\n externalId: string,\n provider: string,\n tx?: DrizzleTx,\n ): Promise<{ id: string } | null> {\n const cfg = this.integrationConfig;\n const parsed = parseCompositeExternalId(externalId, cfg.roleColumn !== null);\n if (!parsed) return null;\n const db = this.runner(tx);\n\n const leftId = await this.resolveLoose(db, cfg.left.refTable, parsed.left, provider);\n if (leftId === null) return null;\n const rightId = await this.resolveLoose(db, cfg.right.refTable, parsed.right, provider);\n if (rightId === null) return null;\n\n const rows = await db\n .delete(this.table)\n .where(this.identityWhere(leftId, rightId, parsed.role))\n .returning({ id: this.table[cfg.left.column] });\n return rows[0] ? { id: externalId } : null;\n }\n\n /**\n * Project a raw junction row to the differ shape: the COMPOSITE externalId\n * `id` (junctions have no surrogate id) plus the local FK columns, role (when\n * role-bearing) and timestamps — matching the emitted\n * `<Junction>IntegrationProjection` interface (id + leftId + rightId + role? +\n * createdAt + updatedAt). Junction projections are purely structural, so this\n * is fully generic over `integrationConfig` — no per-junction override is emitted.\n */\n protected toProjection(\n row: TEntity,\n write: Record<string, unknown>,\n _provider: string,\n ): TIntegrationProjection {\n const cfg = this.integrationConfig;\n const r = row as Record<string, unknown>;\n const leftExt = write[`${cfg.left.column.replace(/Id$/, '')}ExternalId`] as string;\n const rightExt = write[`${cfg.right.column.replace(/Id$/, '')}ExternalId`] as string;\n const role = cfg.roleColumn ? (r[cfg.roleColumn] as string | undefined) : undefined;\n const out: Record<string, unknown> = {\n id: buildCompositeExternalId(leftExt, rightExt, role),\n [cfg.left.column]: r[cfg.left.column],\n [cfg.right.column]: r[cfg.right.column],\n };\n if (cfg.roleColumn) out[cfg.roleColumn] = r[cfg.roleColumn];\n out['createdAt'] = r['createdAt'];\n out['updatedAt'] = r['updatedAt'];\n return out as TIntegrationProjection;\n }\n\n /** Build the identity WHERE clause `(left, right[, role])`. */\n private identityWhere(leftId: string, rightId: string, role: string | undefined) {\n const cfg = this.integrationConfig;\n const conds = [\n eq(this.table[cfg.left.column], leftId),\n eq(this.table[cfg.right.column], rightId),\n ];\n if (cfg.roleColumn && role !== undefined) {\n conds.push(eq(this.table[cfg.roleColumn], role));\n }\n return and(...conds);\n }\n\n /** Resolve a parent id (provider-scoped), throwing when unresolved. */\n private async resolveStrict(\n db: DrizzleTx,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n refTable: PgTableWithColumns<any>,\n parentExternalId: string,\n provider: string,\n column: string,\n ): Promise<string> {\n const id = await this.resolveLoose(db, refTable, parentExternalId, provider);\n if (!id) {\n throw new Error(\n `${this.constructor.name}.integrationUpsertOne: unresolved parent ` +\n `'${parentExternalId}' (provider '${provider}') for '${column}' — ` +\n `parent not integrated yet`,\n );\n }\n return id;\n }\n\n /** Resolve a parent id (provider-scoped), returning null when unresolved. */\n private async resolveLoose(\n db: DrizzleTx,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n refTable: PgTableWithColumns<any>,\n parentExternalId: string | null | undefined,\n provider: string,\n ): Promise<string | null> {\n if (!parentExternalId) return null;\n const rows = await db\n .select({ id: refTable['id'] })\n .from(refTable)\n .where(\n and(\n eq(refTable['provider'], provider),\n eq(refTable['externalId'], parentExternalId),\n ),\n )\n .limit(1);\n return (rows[0]?.id as string | undefined) ?? null;\n }\n}\n\n// ============================================================================\n// Composite externalId — the junction integration seam's deterministic identity.\n//\n// Format: `<leftExternalId>::<rightExternalId>[::<role>]`\n// e.g. `hubspot:42::hubspot:99::employee` (role-bearing)\n// `hubspot:42::hubspot:99` (role-less)\n//\n// Vendor-prefixed ids use a SINGLE colon, so `::` is an unambiguous delimiter.\n// Kept static in the base (replacing the per-repo free functions) so every\n// junction's lookups + its ChangeSource share one definition.\n// ============================================================================\n\n/**\n * Build the composite externalId from the two parent external ids (+ role when\n * the junction is role-bearing).\n */\nexport function buildCompositeExternalId(\n leftExternalId: string,\n rightExternalId: string,\n role?: string,\n): string {\n return role !== undefined\n ? `${leftExternalId}::${rightExternalId}::${role}`\n : `${leftExternalId}::${rightExternalId}`;\n}\n\n/**\n * Parse a composite externalId. `withRole` selects the expected part count\n * (3 when role-bearing, else 2). Returns `null` when the shape doesn't match\n * or any part is empty.\n */\nexport function parseCompositeExternalId(\n externalId: string,\n withRole: boolean,\n): { left: string; right: string; role: string | undefined } | null {\n const parts = externalId.split('::');\n const expected = withRole ? 3 : 2;\n if (parts.length !== expected || parts.some((p) => p.length === 0)) return null;\n return {\n left: parts[0] as string,\n right: parts[1] as string,\n role: withRole ? (parts[2] as string) : undefined,\n };\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
// runtime/subsystems/auth/runtime/connection-broken.error.ts
|
|
2
|
+
var ConnectionBrokenError = class extends Error {
|
|
3
|
+
constructor(connectionId, errorCode, errorDescription) {
|
|
4
|
+
super(
|
|
5
|
+
`Connection ${connectionId} broken: ${errorCode} - ${errorDescription}`
|
|
6
|
+
);
|
|
7
|
+
this.connectionId = connectionId;
|
|
8
|
+
this.errorCode = errorCode;
|
|
9
|
+
this.errorDescription = errorDescription;
|
|
10
|
+
this.name = "ConnectionBrokenError";
|
|
11
|
+
}
|
|
12
|
+
connectionId;
|
|
13
|
+
errorCode;
|
|
14
|
+
errorDescription;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export {
|
|
18
|
+
ConnectionBrokenError
|
|
19
|
+
};
|
|
20
|
+
//# sourceMappingURL=chunk-2N4UG4VD.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../runtime/subsystems/auth/runtime/connection-broken.error.ts"],"sourcesContent":["/**\n * Thrown when an OAuth2 provider returns `400 invalid_grant`/`invalid_token`\n * on refresh — the refresh token itself is dead (user revoked, org\n * deactivated, token expired beyond the provider's rotation window). The\n * connection should be marked broken so background sync stops picking it\n * up; the user re-initiates OAuth.\n *\n * Shared across every OAuth2 strategy.\n */\nexport class ConnectionBrokenError extends Error {\n constructor(\n readonly connectionId: string,\n readonly errorCode: string,\n readonly errorDescription: string,\n ) {\n super(\n `Connection ${connectionId} broken: ${errorCode} - ${errorDescription}`,\n );\n this.name = 'ConnectionBrokenError';\n }\n}\n"],"mappings":";AASO,IAAM,wBAAN,cAAoC,MAAM;AAAA,EAC/C,YACW,cACA,WACA,kBACT;AACA;AAAA,MACE,cAAc,YAAY,YAAY,SAAS,MAAM,gBAAgB;AAAA,IACvE;AANS;AACA;AACA;AAKT,SAAK,OAAO;AAAA,EACd;AAAA,EARW;AAAA,EACA;AAAA,EACA;AAOb;","names":[]}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import {
|
|
2
|
+
jobRuns
|
|
3
|
+
} from "./chunk-OKXZ63IA.js";
|
|
4
|
+
import {
|
|
5
|
+
domainEvents
|
|
6
|
+
} from "./chunk-OFRRBC7M.js";
|
|
7
|
+
|
|
8
|
+
// runtime/subsystems/bridge/bridge-delivery.schema.ts
|
|
9
|
+
import {
|
|
10
|
+
index,
|
|
11
|
+
jsonb,
|
|
12
|
+
pgEnum,
|
|
13
|
+
pgTable,
|
|
14
|
+
text,
|
|
15
|
+
timestamp,
|
|
16
|
+
unique,
|
|
17
|
+
uuid
|
|
18
|
+
} from "drizzle-orm/pg-core";
|
|
19
|
+
import { sql } from "drizzle-orm";
|
|
20
|
+
var bridgeDeliveryStatusEnum = pgEnum("bridge_delivery_status", [
|
|
21
|
+
"pending",
|
|
22
|
+
"delivered",
|
|
23
|
+
"skipped",
|
|
24
|
+
"failed"
|
|
25
|
+
]);
|
|
26
|
+
var bridgeDelivery = pgTable(
|
|
27
|
+
"bridge_delivery",
|
|
28
|
+
{
|
|
29
|
+
id: uuid("id").primaryKey().defaultRandom(),
|
|
30
|
+
/** FK to the source event in the outbox. */
|
|
31
|
+
eventId: uuid("event_id").notNull().references(() => domainEvents.id),
|
|
32
|
+
/**
|
|
33
|
+
* Stable codegen-emitted identifier for the (job, trigger) pair, of the
|
|
34
|
+
* form `<job_type>#<triggerIndex>` (BRIDGE-6). Forms the second half of
|
|
35
|
+
* the UNIQUE idempotency key.
|
|
36
|
+
*/
|
|
37
|
+
triggerId: text("trigger_id").notNull(),
|
|
38
|
+
/**
|
|
39
|
+
* Wrapper `job_run.id` (the framework `@framework/bridge_delivery` run
|
|
40
|
+
* that drove this delivery). Nullable: the facade-eager path
|
|
41
|
+
* (`publishAndStart` Case B) pre-writes a delivered row with no wrapper.
|
|
42
|
+
*/
|
|
43
|
+
wrapperRunId: uuid("wrapper_run_id").references(() => jobRuns.id),
|
|
44
|
+
/**
|
|
45
|
+
* Spawned user `job_run.id`. Null until status is `delivered`; remains
|
|
46
|
+
* null for `skipped` and `failed` deliveries.
|
|
47
|
+
*/
|
|
48
|
+
userRunId: uuid("user_run_id").references(() => jobRuns.id),
|
|
49
|
+
status: bridgeDeliveryStatusEnum("status").notNull().default("pending"),
|
|
50
|
+
/** Populated when status=`skipped` (e.g. `'when_returned_false'`, `'trigger_unregistered'`). */
|
|
51
|
+
skipReason: text("skip_reason"),
|
|
52
|
+
/** Populated when status=`failed`. Mirrors `job_run.error` shape. */
|
|
53
|
+
error: jsonb("error").$type(),
|
|
54
|
+
/**
|
|
55
|
+
* Emitted unconditionally and nullable (JOB-8 / SYNC-6 precedent).
|
|
56
|
+
* Enforcement gated on `BRIDGE_MULTI_TENANT` at the service layer
|
|
57
|
+
* (BRIDGE-8); no DB constraint.
|
|
58
|
+
*/
|
|
59
|
+
tenantId: text("tenant_id"),
|
|
60
|
+
attemptedAt: timestamp("attempted_at", { withTimezone: true }).notNull().defaultNow(),
|
|
61
|
+
deliveredAt: timestamp("delivered_at", { withTimezone: true })
|
|
62
|
+
},
|
|
63
|
+
(t) => ({
|
|
64
|
+
/**
|
|
65
|
+
* Idempotency ledger. Outbox replays and facade-vs-drain collisions both
|
|
66
|
+
* dedup through this constraint.
|
|
67
|
+
*/
|
|
68
|
+
uqBridgeDeliveryEventTrigger: unique("uq_bridge_delivery_event_trigger").on(
|
|
69
|
+
t.eventId,
|
|
70
|
+
t.triggerId
|
|
71
|
+
),
|
|
72
|
+
/** Lookup all deliveries for an event (fanout report, debugging). */
|
|
73
|
+
idxBridgeDeliveryEvent: index("idx_bridge_delivery_event").on(t.eventId),
|
|
74
|
+
/**
|
|
75
|
+
* Ops dashboard filter — only the actionable states. Partial index keeps
|
|
76
|
+
* it small at scale (the bulk of rows will be `delivered`).
|
|
77
|
+
*/
|
|
78
|
+
idxBridgeDeliveryStatus: index("idx_bridge_delivery_status").on(t.status).where(sql`${t.status} IN ('pending','failed')`),
|
|
79
|
+
/**
|
|
80
|
+
* Reverse lookup from a spawned user run back to its delivery row.
|
|
81
|
+
* Partial — most rows in the bridge ledger but only successful
|
|
82
|
+
* deliveries have a `user_run_id`.
|
|
83
|
+
*/
|
|
84
|
+
idxBridgeDeliveryUserRun: index("idx_bridge_delivery_user_run").on(t.userRunId).where(sql`${t.userRunId} IS NOT NULL`)
|
|
85
|
+
})
|
|
86
|
+
);
|
|
87
|
+
|
|
88
|
+
export {
|
|
89
|
+
bridgeDeliveryStatusEnum,
|
|
90
|
+
bridgeDelivery
|
|
91
|
+
};
|
|
92
|
+
//# sourceMappingURL=chunk-2TVVBC53.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../runtime/subsystems/bridge/bridge-delivery.schema.ts"],"sourcesContent":["/**\n * Drizzle schema for the `bridge_delivery` ledger (ADR-023 Phase 2, BRIDGE-1).\n *\n * The `bridge_delivery` table is the idempotency ledger for the event-to-job\n * bridge. Every (event, trigger) pair the bridge is asked to spawn produces\n * exactly one row; the `UNIQUE (event_id, trigger_id)` constraint guarantees\n * that:\n *\n * 1. Outbox replays of an event do not double-spawn user job runs — the\n * drain attempts to insert the duplicate, the constraint trips, and the\n * drain skips that trigger.\n * 2. The `IEventFlow.publishAndStart` facade can pre-write a\n * `(status='delivered')` row before the drain runs (Case B from ADR-023\n * §`publishAndStart` + existing `triggers:` collision); the drain then\n * hits UNIQUE on that trigger and skips it while still spawning any\n * other triggers for the same event normally.\n *\n * Status values:\n * - `pending` — wrapper run exists; user job not yet started.\n * - `delivered` — user job started; `user_run_id` populated.\n * - `skipped` — intentional no-op (`when:` returned false, or\n * facade-eager path pre-empted the bridge spawn).\n * - `failed` — wrapper exhausted retry policy; no auto-retry past that\n * (mirrors events outbox stance — ops eyes only).\n *\n * `wrapper_run_id` is **nullable**: the facade-eager path (Case B) pre-writes\n * `bridge_delivery` with no wrapper. The bridge-drain path always populates\n * it.\n *\n * `tenant_id` is emitted **unconditionally and nullable** (per JOB-8\n * 2026-04-20 reversal); enforcement is service-layer (BRIDGE-8) gated on the\n * `BRIDGE_MULTI_TENANT` DI token, not a DB constraint.\n *\n * Indexes:\n * - `bridge_delivery_event_idx` — lookup all deliveries for an event.\n * - `bridge_delivery_status_idx` — partial; ops dashboards filter by\n * `pending | failed`.\n * - `bridge_delivery_user_run_idx` — partial; reverse lookup from a\n * spawned user run back to its delivery row.\n *\n * No service logic, no DI wiring — this is the schema foundation. Backends\n * (memory + drizzle) and the framework handler land in BRIDGE-3 / BRIDGE-4 /\n * BRIDGE-5.\n */\nimport {\n index,\n jsonb,\n pgEnum,\n pgTable,\n text,\n timestamp,\n unique,\n uuid,\n} from 'drizzle-orm/pg-core';\nimport { sql } from 'drizzle-orm';\nimport type { InferSelectModel } from 'drizzle-orm';\n\nimport { domainEvents } from '../events/domain-events.schema';\nimport { jobRuns } from '../jobs/job-orchestration.schema';\n\n// ─── Enum ───────────────────────────────────────────────────────────────────\n\nexport const bridgeDeliveryStatusEnum = pgEnum('bridge_delivery_status', [\n 'pending',\n 'delivered',\n 'skipped',\n 'failed',\n]);\n\n// ─── Table ──────────────────────────────────────────────────────────────────\n\nexport const bridgeDelivery = pgTable(\n 'bridge_delivery',\n {\n id: uuid('id').primaryKey().defaultRandom(),\n /** FK to the source event in the outbox. */\n eventId: uuid('event_id')\n .notNull()\n .references(() => domainEvents.id),\n /**\n * Stable codegen-emitted identifier for the (job, trigger) pair, of the\n * form `<job_type>#<triggerIndex>` (BRIDGE-6). Forms the second half of\n * the UNIQUE idempotency key.\n */\n triggerId: text('trigger_id').notNull(),\n /**\n * Wrapper `job_run.id` (the framework `@framework/bridge_delivery` run\n * that drove this delivery). Nullable: the facade-eager path\n * (`publishAndStart` Case B) pre-writes a delivered row with no wrapper.\n */\n wrapperRunId: uuid('wrapper_run_id').references(() => jobRuns.id),\n /**\n * Spawned user `job_run.id`. Null until status is `delivered`; remains\n * null for `skipped` and `failed` deliveries.\n */\n userRunId: uuid('user_run_id').references(() => jobRuns.id),\n status: bridgeDeliveryStatusEnum('status').notNull().default('pending'),\n /** Populated when status=`skipped` (e.g. `'when_returned_false'`, `'trigger_unregistered'`). */\n skipReason: text('skip_reason'),\n /** Populated when status=`failed`. Mirrors `job_run.error` shape. */\n error: jsonb('error').$type<Record<string, unknown>>(),\n /**\n * Emitted unconditionally and nullable (JOB-8 / SYNC-6 precedent).\n * Enforcement gated on `BRIDGE_MULTI_TENANT` at the service layer\n * (BRIDGE-8); no DB constraint.\n */\n tenantId: text('tenant_id'),\n attemptedAt: timestamp('attempted_at', { withTimezone: true })\n .notNull()\n .defaultNow(),\n deliveredAt: timestamp('delivered_at', { withTimezone: true }),\n },\n (t) => ({\n /**\n * Idempotency ledger. Outbox replays and facade-vs-drain collisions both\n * dedup through this constraint.\n */\n uqBridgeDeliveryEventTrigger: unique('uq_bridge_delivery_event_trigger').on(\n t.eventId,\n t.triggerId,\n ),\n /** Lookup all deliveries for an event (fanout report, debugging). */\n idxBridgeDeliveryEvent: index('idx_bridge_delivery_event').on(t.eventId),\n /**\n * Ops dashboard filter — only the actionable states. Partial index keeps\n * it small at scale (the bulk of rows will be `delivered`).\n */\n idxBridgeDeliveryStatus: index('idx_bridge_delivery_status')\n .on(t.status)\n .where(sql`${t.status} IN ('pending','failed')`),\n /**\n * Reverse lookup from a spawned user run back to its delivery row.\n * Partial — most rows in the bridge ledger but only successful\n * deliveries have a `user_run_id`.\n */\n idxBridgeDeliveryUserRun: index('idx_bridge_delivery_user_run')\n .on(t.userRunId)\n .where(sql`${t.userRunId} IS NOT NULL`),\n }),\n);\n\nexport type BridgeDeliveryRecord = InferSelectModel<typeof bridgeDelivery>;\n"],"mappings":";;;;;;;;AA4CA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,WAAW;AAQb,IAAM,2BAA2B,OAAO,0BAA0B;AAAA,EACvE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAIM,IAAM,iBAAiB;AAAA,EAC5B;AAAA,EACA;AAAA,IACE,IAAI,KAAK,IAAI,EAAE,WAAW,EAAE,cAAc;AAAA;AAAA,IAE1C,SAAS,KAAK,UAAU,EACrB,QAAQ,EACR,WAAW,MAAM,aAAa,EAAE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAMnC,WAAW,KAAK,YAAY,EAAE,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAMtC,cAAc,KAAK,gBAAgB,EAAE,WAAW,MAAM,QAAQ,EAAE;AAAA;AAAA;AAAA;AAAA;AAAA,IAKhE,WAAW,KAAK,aAAa,EAAE,WAAW,MAAM,QAAQ,EAAE;AAAA,IAC1D,QAAQ,yBAAyB,QAAQ,EAAE,QAAQ,EAAE,QAAQ,SAAS;AAAA;AAAA,IAEtE,YAAY,KAAK,aAAa;AAAA;AAAA,IAE9B,OAAO,MAAM,OAAO,EAAE,MAA+B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAMrD,UAAU,KAAK,WAAW;AAAA,IAC1B,aAAa,UAAU,gBAAgB,EAAE,cAAc,KAAK,CAAC,EAC1D,QAAQ,EACR,WAAW;AAAA,IACd,aAAa,UAAU,gBAAgB,EAAE,cAAc,KAAK,CAAC;AAAA,EAC/D;AAAA,EACA,CAAC,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA,IAKN,8BAA8B,OAAO,kCAAkC,EAAE;AAAA,MACvE,EAAE;AAAA,MACF,EAAE;AAAA,IACJ;AAAA;AAAA,IAEA,wBAAwB,MAAM,2BAA2B,EAAE,GAAG,EAAE,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA,IAKvE,yBAAyB,MAAM,4BAA4B,EACxD,GAAG,EAAE,MAAM,EACX,MAAM,MAAM,EAAE,MAAM,0BAA0B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAMjD,0BAA0B,MAAM,8BAA8B,EAC3D,GAAG,EAAE,SAAS,EACd,MAAM,MAAM,EAAE,SAAS,cAAc;AAAA,EAC1C;AACF;","names":[]}
|