@burdenoff/be-sdk 2026.710.1 → 2026.710.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/dist/auth/index.d.ts +2 -2
- package/dist/cache/index.d.ts +1 -1
- package/dist/cache/index.js +1 -1
- package/dist/{chunk-OOHO33FX.js → chunk-3XJUXXES.js} +4 -4
- package/dist/{chunk-OOHO33FX.js.map → chunk-3XJUXXES.js.map} +1 -1
- package/dist/{chunk-ROKCS4QL.js → chunk-3YZWPBKP.js} +3 -3
- package/dist/{chunk-ROKCS4QL.js.map → chunk-3YZWPBKP.js.map} +1 -1
- package/dist/{chunk-Q23NPVWQ.js → chunk-5A5GGMWK.js} +31 -5
- package/dist/chunk-5A5GGMWK.js.map +1 -0
- package/dist/{chunk-UIMPJNWC.js → chunk-7UJXIX4I.js} +7 -3
- package/dist/chunk-7UJXIX4I.js.map +1 -0
- package/dist/{chunk-UYE4IEPT.js → chunk-CAI5GJJ6.js} +51 -11
- package/dist/chunk-CAI5GJJ6.js.map +1 -0
- package/dist/{chunk-5BCCI2FV.js → chunk-GCY2FTHD.js} +3 -3
- package/dist/{chunk-5BCCI2FV.js.map → chunk-GCY2FTHD.js.map} +1 -1
- package/dist/{chunk-IDKU7OGF.js → chunk-GVZ5BDER.js} +4 -4
- package/dist/{chunk-IDKU7OGF.js.map → chunk-GVZ5BDER.js.map} +1 -1
- package/dist/{chunk-WHSIZCJX.js → chunk-LHLOJS52.js} +2 -2
- package/dist/{chunk-WHSIZCJX.js.map → chunk-LHLOJS52.js.map} +1 -1
- package/dist/{chunk-IDJ7P2O3.js → chunk-Y7X5AYKY.js} +3 -3
- package/dist/{chunk-IDJ7P2O3.js.map → chunk-Y7X5AYKY.js.map} +1 -1
- package/dist/{client-ODOgzzs0.d.ts → client-u23M69Qt.d.ts} +2 -0
- package/dist/export/index.js +4 -4
- package/dist/gateway/index.js +3 -3
- package/dist/gateway/security/index.js +1 -1
- package/dist/graph/index.d.ts +2 -2
- package/dist/graph/index.js +2 -2
- package/dist/{index-Bui1kclE.d.ts → index-2jyc-oTr.d.ts} +1 -1
- package/dist/{index-DkObbJD_.d.ts → index-Mr2ATGnY.d.ts} +1 -0
- package/dist/{index-Bxzzlu4x.d.ts → index-qg-t-NT2.d.ts} +1 -1
- package/dist/index.d.ts +6 -6
- package/dist/index.js +11 -11
- package/dist/init/index.js +4 -4
- package/dist/layer/index.js +1 -1
- package/dist/prisma/index.d.ts +2 -2
- package/dist/prisma/index.js +2 -2
- package/dist/server/index.d.ts +3 -3
- package/dist/{types-DNF8bOx0.d.ts → types-De9M0Yin.d.ts} +1 -1
- package/package.json +1 -1
- package/dist/chunk-Q23NPVWQ.js.map +0 -1
- package/dist/chunk-UIMPJNWC.js.map +0 -1
- package/dist/chunk-UYE4IEPT.js.map +0 -1
package/dist/server/index.d.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { W as WorkspaceSecret, I as IActor, J as JWTPayload, S as ServerDefinition, a as ServerInstance, b as ITenant, G as GraphQLContext, Y as YogaPlugin } from '../types-
|
|
2
|
-
export { C as ConsentContext, E as ElysiaApp, c as IContextFilterInput, d as IOperationContext, e as IOrganization, f as IProduct, g as IProject, h as ITracking, i as IWorkspace, M as ModuleGraphConfig, P as PrismaClientConstructor, R as RESTEndpoint, j as ServerConfig, k as ServerI18nConfig, l as ServerInfo, m as WspaceGraphQLContext } from '../types-
|
|
1
|
+
import { W as WorkspaceSecret, I as IActor, J as JWTPayload, S as ServerDefinition, a as ServerInstance, b as ITenant, G as GraphQLContext, Y as YogaPlugin } from '../types-De9M0Yin.js';
|
|
2
|
+
export { C as ConsentContext, E as ElysiaApp, c as IContextFilterInput, d as IOperationContext, e as IOrganization, f as IProduct, g as IProject, h as ITracking, i as IWorkspace, M as ModuleGraphConfig, P as PrismaClientConstructor, R as RESTEndpoint, j as ServerConfig, k as ServerI18nConfig, l as ServerInfo, m as WspaceGraphQLContext } from '../types-De9M0Yin.js';
|
|
3
3
|
import * as jose from 'jose';
|
|
4
4
|
import { VerifyOptions } from 'jsonwebtoken';
|
|
5
5
|
import { I as I18n } from '../i18n-DrdPTann.js';
|
|
6
6
|
import { GraphQLError } from 'graphql';
|
|
7
7
|
export { I as I18nContext, L as LocaleCode } from '../types-C8TbSdEj.js';
|
|
8
|
-
export { P as PrismaClientBase } from '../client-
|
|
8
|
+
export { P as PrismaClientBase } from '../client-u23M69Qt.js';
|
|
9
9
|
import 'graphql-yoga';
|
|
10
10
|
import '../workspace-extension-TquhDEKU.js';
|
|
11
11
|
import '@prisma/adapter-pg';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { GraphQLSchema } from 'graphql';
|
|
2
2
|
import { PubSub } from 'graphql-yoga';
|
|
3
|
-
import { P as PrismaClientBase, a as PrismaClientConstructorOptions } from './client-
|
|
3
|
+
import { P as PrismaClientBase, a as PrismaClientConstructorOptions } from './client-u23M69Qt.js';
|
|
4
4
|
import { W as WorkspaceExtensionConfig } from './workspace-extension-TquhDEKU.js';
|
|
5
5
|
import { I as I18nContext, L as LocaleCode } from './types-C8TbSdEj.js';
|
|
6
6
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@burdenoff/be-sdk",
|
|
3
|
-
"version": "2026.710.
|
|
3
|
+
"version": "2026.710.3",
|
|
4
4
|
"description": "Backend SDK for Burdenoff products providing unified access to notifications, RBAC, activity tracking, usage monitoring, and more",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/graph/utils/registry.ts","../src/graph/utils/helpers.ts","../src/prisma/client.ts","../src/graph/middleware/prisma-extension.ts"],"names":["GraphRegistry","entityMappings","Map","relationshipMappings","registeredModules","Set","resolveFields","entityType","config","Array","isArray","fields","logger","warn","registerModule","moduleName","entities","relationships","has","info","entityCount","entityConfig","Object","entries","enabled","resolvedFields","resolvedConfig","set","relationshipCount","relationshipType","relationshipConfig","add","getEntityConfig","get","getRelationshipConfig","getAllEntityTypes","from","keys","getAllRelationshipTypes","getRegisteredModules","isEntityRegistered","isRelationshipRegistered","getOrganizationId","data","getOrgId","undefined","getWorkspaceId","getRbacConfig","rbac","resolveRbacMetadata","entityData","rbacConfig","name","extractName","identifier","extractIdentifier","parentResourceIdentifier","parentResourceField","resourceTypeName","createResource","getStats","collections","edgeTypes","values","collection","label","modules","size","clear","getRelationshipsForEntity","result","key","push","printStatus","stats","join","uuidv4","crypto","randomUUID","createEntityEvent","eventType","organizationId","entity","metadata","productSource","eventId","process","env","timestamp","Date","toISOString","userId","correlationId","createRelationshipEvent","relationship","id","to","type","extractMinimalFields","modelName","minimal","field","parseRelationship","String","fromField","extractMetadata","getCollectionForEntity","extractEntityTitle","extractTitle","shouldSyncEntity","shouldSyncRelationship","createConnectionPool","poolConfig","connectionString","databaseUrl","max","maxConnections","idleTimeoutMillis","connectionTimeoutMillis","applicationName","application_name","statementTimeoutMillis","statement_timeout","idleInTransactionTimeoutMillis","idle_in_transaction_session_timeout","lockTimeoutMillis","lock_timeout","Pool","ensureServiceApplicationName","productName","createPrismaAdapter","pool","PrismaPg","configurePrismaLogging","client","isDevelopment","slowQueryThreshold","enableQueryLogging","$on","e","duration","query","substring","length","params","debug","error","message","target","PrismaClientWrapper","connectionState","isConnected","attempts","isDisconnecting","getClient","getPool","getConnectionState","connect","retries","delay","attempt","$connect","lastConnectedAt","lastError","errorMessage","Error","waitTime","Math","pow","Promise","resolve","setTimeout","disconnect","$disconnect","end","includes","registerShutdownHandlers","shutdownHandler","signal","exit","on","createPrismaClient","PrismaClientConstructor","adapter","logLevels","emit","level","log","defaultConfig","monitoredOperations","extractEntityInfo","model","record","extractContext","args","actorId","workspaceId","emitEntityEvent","entityInfo","entityTypes","context","minimalData","orgId","rbacMetadata","hasName","eventEmitter","publishEntityEvent","catch","emitRelationshipEvents","fromId","relationshipKey","foreignKeyValue","targetType","polymorphicTypeField","description","relationType","addGraphExtension","baseClient","fullConfig","prismaClient","$extends","$allModels","create","update","delete","updateMany","deleteMany"],"mappings":";;;;;;AA+BO,IAAMA,gBAAN,MAAMA;EA/Bb;;;EAgCE,OAAeC,cAAAA,uBAA6DC,GAAAA,EAAAA;EAC5E,OAAeC,oBAAAA,uBAAiED,GAAAA,EAAAA;EAChF,OAAeE,iBAAAA,uBAAqCC,GAAAA,EAAAA;;;;;;;;EASpD,OAAeC,aAAAA,CAAcC,YAAoBC,MAAAA,EAAqC;AACpF,IAAA,IAAIC,KAAAA,CAAMC,OAAAA,CAAQF,MAAAA,CAAOG,MAAM,CAAA,EAAG;AAChC,MAAA,OAAOH,MAAAA,CAAOG,MAAAA;AAChB,IAAA;AAGAC,IAAAA,MAAAA,CAAOC,IAAAA,CAAK,CAAA,4CAAA,EAA+CN,UAAAA,CAAAA,mBAAAA,CAA+B,CAAA;AAC1F,IAAA,OAAO,EAAA;AACT,EAAA;;;;;AAMA,EAAA,OAAOO,eAAeN,MAAAA,EAAiC;AACrD,IAAA,MAAM,EAAEO,UAAAA,EAAYC,QAAAA,EAAUC,aAAAA,EAAa,GAAKT,MAAAA;AAEhD,IAAA,IAAI,IAAA,CAAKJ,iBAAAA,CAAkBc,GAAAA,CAAIH,UAAAA,CAAAA,EAAa;AAC1CH,MAAAA,MAAAA,CAAOC,IAAAA,CAAK,CAAA,wBAAA,EAA2BE,UAAAA,CAAAA,8BAAAA,CAA0C,CAAA;AACjF,MAAA;AACF,IAAA;AAEAH,IAAAA,MAAAA,CAAOO,IAAAA,CAAK,CAAA,oCAAA,EAAuCJ,UAAAA,CAAAA,CAAY,CAAA;AAG/D,IAAA,IAAIK,WAAAA,GAAc,CAAA;AAClB,IAAA,KAAA,MAAW,CAACb,UAAAA,EAAYc,YAAAA,KAAiBC,MAAAA,CAAOC,OAAAA,CAAQP,QAAAA,CAAAA,EAAW;AACjE,MAAA,IAAIK,YAAAA,CAAaG,YAAY,KAAA,EAAO;AAElC,QAAA,MAAMC,cAAAA,GAAiB,IAAA,CAAKnB,aAAAA,CAAcC,UAAAA,EAAYc,YAAAA,CAAAA;AAGtD,QAAA,MAAMK,cAAAA,GAA4C;UAChD,GAAGL,YAAAA;UACHV,MAAAA,EAAQc;AACV,SAAA;AAEA,QAAA,IAAA,CAAKxB,cAAAA,CAAe0B,GAAAA,CAAIpB,UAAAA,EAAYmB,cAAAA,CAAAA;AACpCN,QAAAA,WAAAA,EAAAA;AACF,MAAA;AACF,IAAA;AAGA,IAAA,IAAIQ,iBAAAA,GAAoB,CAAA;AACxB,IAAA,IAAIX,aAAAA,EAAe;AACjB,MAAA,KAAA,MAAW,CAACY,gBAAAA,EAAkBC,kBAAAA,KAAuBR,MAAAA,CAAOC,OAAAA,CAAQN,aAAAA,CAAAA,EAAgB;AAClF,QAAA,IAAIa,kBAAAA,CAAmBN,YAAY,KAAA,EAAO;AACxC,UAAA,IAAA,CAAKrB,oBAAAA,CAAqBwB,GAAAA,CAAIE,gBAAAA,EAAkBC,kBAAAA,CAAAA;AAChDF,UAAAA,iBAAAA,EAAAA;AACF,QAAA;AACF,MAAA;AACF,IAAA;AAEA,IAAA,IAAA,CAAKxB,iBAAAA,CAAkB2B,IAAIhB,UAAAA,CAAAA;AAC3BH,IAAAA,MAAAA,CAAOO,KACL,CAAA,kCAAA,EAAgCJ,UAAAA,KAAeK,WAAAA,CAAAA,WAAAA,EAAyBQ,iBAAAA,CAAAA,cAAAA,CAAiC,CAAA;AAE7G,EAAA;;;;;;AAOA,EAAA,OAAOI,gBAAgBzB,UAAAA,EAA2D;AAChF,IAAA,OAAO,IAAA,CAAKN,cAAAA,CAAegC,GAAAA,CAAI1B,UAAAA,CAAAA;AACjC,EAAA;;;;;;AAOA,EAAA,OAAO2B,sBAAsBL,gBAAAA,EAA+D;AAC1F,IAAA,OAAO,IAAA,CAAK1B,oBAAAA,CAAqB8B,GAAAA,CAAIJ,gBAAAA,CAAAA;AACvC,EAAA;;;;;AAMA,EAAA,OAAOM,iBAAAA,GAA8B;AACnC,IAAA,OAAO1B,KAAAA,CAAM2B,IAAAA,CAAK,IAAA,CAAKnC,cAAAA,CAAeoC,MAAI,CAAA;AAC5C,EAAA;;;;;AAMA,EAAA,OAAOC,uBAAAA,GAAoC;AACzC,IAAA,OAAO7B,KAAAA,CAAM2B,IAAAA,CAAK,IAAA,CAAKjC,oBAAAA,CAAqBkC,MAAI,CAAA;AAClD,EAAA;;;;;AAMA,EAAA,OAAOE,oBAAAA,GAAiC;AACtC,IAAA,OAAO9B,KAAAA,CAAM2B,IAAAA,CAAK,IAAA,CAAKhC,iBAAiB,CAAA;AAC1C,EAAA;;;;;;AAOA,EAAA,OAAOoC,mBAAmBjC,UAAAA,EAA6B;AACrD,IAAA,OAAO,IAAA,CAAKN,cAAAA,CAAeiB,GAAAA,CAAIX,UAAAA,CAAAA;AACjC,EAAA;;;;;;AAOA,EAAA,OAAOkC,yBAAyBZ,gBAAAA,EAAmC;AACjE,IAAA,OAAO,IAAA,CAAK1B,oBAAAA,CAAqBe,GAAAA,CAAIW,gBAAAA,CAAAA;AACvC,EAAA;;;;;;;EAQA,OAAOa,iBAAAA,CAAkBnC,YAAoBoC,IAAAA,EAAmD;AAC9F,IAAA,MAAMnC,MAAAA,GAAS,IAAA,CAAKP,cAAAA,CAAegC,GAAAA,CAAI1B,UAAAA,CAAAA;AACvC,IAAA,IAAI,CAACC,MAAAA,IAAU,CAACA,MAAAA,CAAOoC,QAAAA,EAAU;AAC/B,MAAA,OAAOC,MAAAA;AACT,IAAA;AACA,IAAA,OAAOrC,MAAAA,CAAOoC,SAASD,IAAAA,CAAAA;AACzB,EAAA;;;;;;;EAQA,OAAOG,cAAAA,CAAevC,YAAoBoC,IAAAA,EAAmD;AAC3F,IAAA,MAAMnC,MAAAA,GAAS,IAAA,CAAKP,cAAAA,CAAegC,GAAAA,CAAI1B,UAAAA,CAAAA;AACvC,IAAA,IAAI,CAACC,MAAAA,IAAU,CAACA,MAAAA,CAAOsC,cAAAA,EAAgB;AACrC,MAAA,OAAOD,MAAAA;AACT,IAAA;AACA,IAAA,OAAOrC,MAAAA,CAAOsC,eAAeH,IAAAA,CAAAA;AAC/B,EAAA;;;;;;;AAQA,EAAA,OAAOI,cAAcxC,UAAAA,EAA0D;AAC7E,IAAA,MAAMC,MAAAA,GAAS,IAAA,CAAKP,cAAAA,CAAegC,GAAAA,CAAI1B,UAAAA,CAAAA;AACvC,IAAA,OAAOC,MAAAA,EAAQwC,IAAAA;AACjB,EAAA;;;;;;;;;EAUA,OAAOC,mBAAAA,CACL1C,YACA2C,UAAAA,EASY;AACZ,IAAA,MAAMC,UAAAA,GAAa,IAAA,CAAKJ,aAAAA,CAAcxC,UAAAA,CAAAA;AACtC,IAAA,IAAI,CAAC4C,UAAAA,EAAY;AACf,MAAA,OAAON,MAAAA;AACT,IAAA;AAEA,IAAA,MAAMO,OAAOD,UAAAA,CAAWE,WAAAA,GAAcF,UAAAA,CAAWE,WAAAA,CAAYH,UAAAA,CAAAA,GAAcL,MAAAA;AAC3E,IAAA,MAAMS,aAAaH,UAAAA,CAAWI,iBAAAA,GAAoBJ,UAAAA,CAAWI,iBAAAA,CAAkBL,UAAAA,CAAAA,GAAcL,MAAAA;AAC7F,IAAA,MAAMW,2BAA2BL,UAAAA,CAAWM,mBAAAA,GACvCP,UAAAA,CAAWC,UAAAA,CAAWM,mBAAmB,CAAA,GAC1CZ,MAAAA;AAEJ,IAAA,OAAO;AACLa,MAAAA,gBAAAA,EAAkBP,UAAAA,CAAWO,gBAAAA;AAC7B,MAAA,GAAIN,IAAAA,IAAQ;AAAEA,QAAAA;AAAK,OAAA;AACnB,MAAA,GAAIE,UAAAA,IAAc;AAAEA,QAAAA;AAAW,OAAA;AAC/B,MAAA,GAAIE,wBAAAA,IAA4B;AAAEA,QAAAA;AAAyB,OAAA;MAC3D,GAAIL,UAAAA,CAAWQ,mBAAmBd,MAAAA,IAAa;AAAEc,QAAAA,cAAAA,EAAgBR,UAAAA,CAAWQ;AAAe;AAC7F,KAAA;AACF,EAAA;;;;;AAMA,EAAA,OAAOC,QAAAA,GAML;AACA,IAAA,MAAMC,WAAAA,uBAAkBxD,GAAAA,EAAAA;AACxB,IAAA,MAAMyD,SAAAA,uBAAgBzD,GAAAA,EAAAA;AAEtB,IAAA,KAAA,MAAWG,MAAAA,IAAU,IAAA,CAAKP,cAAAA,CAAe8D,MAAAA,EAAM,EAAI;AACjDF,MAAAA,WAAAA,CAAY9B,GAAAA,CAAIvB,MAAAA,CAAOwD,UAAAA,IAAc,kBAAA,CAAA;AACvC,IAAA;AAEA,IAAA,KAAA,MAAWxD,MAAAA,IAAU,IAAA,CAAKL,oBAAAA,CAAqB4D,MAAAA,EAAM,EAAI;AACvD,MAAA,IAAIvD,OAAOyD,KAAAA,EAAO;AAChBH,QAAAA,SAAAA,CAAU/B,GAAAA,CAAIvB,OAAOyD,KAAK,CAAA;AAC5B,MAAA;AACF,IAAA;AAEA,IAAA,OAAO;AACLC,MAAAA,OAAAA,EAAS,KAAK9D,iBAAAA,CAAkB+D,IAAAA;AAChCnD,MAAAA,QAAAA,EAAU,KAAKf,cAAAA,CAAekE,IAAAA;AAC9BlD,MAAAA,aAAAA,EAAe,KAAKd,oBAAAA,CAAqBgE,IAAAA;AACzCN,MAAAA,WAAAA;AACAC,MAAAA;AACF,KAAA;AACF,EAAA;;;;AAKA,EAAA,OAAOM,KAAAA,GAAc;AACnB,IAAA,IAAA,CAAKnE,eAAemE,KAAAA,EAAK;AACzB,IAAA,IAAA,CAAKjE,qBAAqBiE,KAAAA,EAAK;AAC/B,IAAA,IAAA,CAAKhE,kBAAkBgE,KAAAA,EAAK;AAC5BxD,IAAAA,MAAAA,CAAOO,KAAK,2CAAA,CAAA;AACd,EAAA;;;;;;;AAQA,EAAA,OAAOkD,0BAA0B9D,UAAAA,EAA8D;AAC7F,IAAA,MAAM+D,SAAmD,EAAA;AAEzD,IAAA,KAAA,MAAW,CAACC,GAAAA,EAAK/D,MAAAA,KAAW,IAAA,CAAKL,oBAAAA,CAAqBoB,SAAO,EAAI;AAC/D,MAAA,IAAIf,MAAAA,CAAO4B,SAAS7B,UAAAA,EAAY;AAC9B+D,QAAAA,MAAAA,CAAOE,IAAAA,CAAK;AAACD,UAAAA,GAAAA;AAAK/D,UAAAA;AAAO,SAAA,CAAA;AAC3B,MAAA;AACF,IAAA;AAEA,IAAA,OAAO8D,MAAAA;AACT,EAAA;;;;AAKA,EAAA,OAAOG,WAAAA,GAAoB;AACzB,IAAA,MAAMC,KAAAA,GAAQ,KAAKd,QAAAA,EAAQ;AAC3BhD,IAAAA,MAAAA,CAAOO,KAAK,EAAA,CAAA;AACZP,IAAAA,MAAAA,CAAOO,KAAK,iCAAA,CAAA;AACZP,IAAAA,MAAAA,CAAOO,KAAK,0BAAA,CAAA;AACZP,IAAAA,MAAAA,CAAOO,IAAAA,CAAK,CAAA,oBAAA,EAAuBuD,KAAAA,CAAMR,OAAO,CAAA,CAAE,CAAA;AAClDtD,IAAAA,MAAAA,CAAOO,IAAAA,CAAK,CAAA,gBAAA,EAAmBuD,KAAAA,CAAM1D,QAAQ,CAAA,CAAE,CAAA;AAC/CJ,IAAAA,MAAAA,CAAOO,IAAAA,CAAK,CAAA,qBAAA,EAAwBuD,KAAAA,CAAMzD,aAAa,CAAA,CAAE,CAAA;AACzDL,IAAAA,MAAAA,CAAOO,IAAAA,CAAK,CAAA,oBAAA,EAAuBuD,KAAAA,CAAMb,WAAAA,CAAYM,IAAI,CAAA,CAAE,CAAA;AAC3DvD,IAAAA,MAAAA,CAAOO,IAAAA,CAAK,CAAA,YAAA,EAAeuD,KAAAA,CAAMZ,SAAAA,CAAUK,IAAI,CAAA,CAAE,CAAA;AACjDvD,IAAAA,MAAAA,CAAOO,KAAK,EAAA,CAAA;AACZP,IAAAA,MAAAA,CAAOO,KAAK,qBAAA,EAAuB,IAAA,CAAKoB,sBAAoB,CAAGoC,IAAAA,CAAK,IAAA,CAAA,CAAA;AACpE/D,IAAAA,MAAAA,CAAOO,KAAK,EAAA,CAAA;AACd,EAAA;AACF;;;AClTA,IAAMyD,MAAAA,mBAAS,MAAA,CAAA,MAAcC,MAAAA,CAAOC,UAAAA,EAAU,EAA/B,QAAA,CAAA;AAKR,SAASC,iBAAAA,CACdC,SAAAA,EACAC,cAAAA,EACAC,MAAAA,EAKAC,UAMAC,aAAAA,EAAsB;AAEtB,EAAA,OAAO;IACLC,OAAAA,EAAS,CAAA,IAAA,EAAOT,QAAAA,CAAAA,CAAAA;AAChBI,IAAAA,SAAAA;AACAC,IAAAA,cAAAA;AACAG,IAAAA,aAAAA,EAAeA,aAAAA,IAAiBE,OAAAA,CAAQC,GAAAA,CAAI,gBAAA,CAAA,IAAqB,SAAA;IACjEC,SAAAA,EAAAA,iBAAW,IAAIC,IAAAA,EAAAA,EAAOC,WAAAA,EAAW;AACjCR,IAAAA,MAAAA;IACAC,QAAAA,EAAU;AACRQ,MAAAA,MAAAA,EAAQR,QAAAA,EAAUQ,MAAAA;AAClBC,MAAAA,aAAAA,EAAeT,QAAAA,EAAUS,aAAAA,IAAiB,CAAA,IAAA,EAAOhB,MAAAA,EAAAA,CAAAA;AACnD;AACF,GAAA;AACF;AA5BgBG,MAAAA,CAAAA,iBAAAA,EAAAA,mBAAAA,CAAAA;AAiCT,SAASc,uBAAAA,CACdb,SAAAA,EACAC,cAAAA,EACAa,YAAAA,EAMAX,UAIAC,aAAAA,EAAsB;AAEtB,EAAA,OAAO;IACLC,OAAAA,EAAS,CAAA,IAAA,EAAOT,QAAAA,CAAAA,CAAAA;AAChBI,IAAAA,SAAAA;AACAC,IAAAA,cAAAA;AACAG,IAAAA,aAAAA,EAAeA,aAAAA,IAAiBE,OAAAA,CAAQC,GAAAA,CAAI,gBAAA,CAAA,IAAqB,SAAA;IACjEC,SAAAA,EAAAA,iBAAW,IAAIC,IAAAA,EAAAA,EAAOC,WAAAA,EAAW;IACjCR,MAAAA,EAAQ;AACNa,MAAAA,EAAAA,EAAI,GAAGD,YAAAA,CAAa1D,IAAAA,CAAK2D,EAAE,CAAA,CAAA,EAAID,YAAAA,CAAaE,GAAGD,EAAE,CAAA,CAAA;AACjDE,MAAAA,IAAAA,EAAMH,YAAAA,CAAaG,IAAAA;AACnBtD,MAAAA,IAAAA,EAAM;AACR,KAAA;AACAmD,IAAAA,YAAAA;IACAX,QAAAA,EAAU;AACRQ,MAAAA,MAAAA,EAAQR,QAAAA,EAAUQ,MAAAA;AAClBC,MAAAA,aAAAA,EAAeT,QAAAA,EAAUS,aAAAA,IAAiB,CAAA,IAAA,EAAOhB,MAAAA,EAAAA,CAAAA;AACnD;AACF,GAAA;AACF;AAhCgBiB,MAAAA,CAAAA,uBAAAA,EAAAA,yBAAAA,CAAAA;AAyCT,SAASK,oBAAAA,CAAqBC,WAAmBjB,MAAAA,EAA+B;AAErF,EAAA,MAAM1E,MAAAA,GAASR,aAAAA,CAAcgC,eAAAA,CAAgBmE,SAAAA,CAAAA;AAE7C,EAAA,IAAI,CAAC3F,MAAAA,EAAQ;AAEXI,IAAAA,MAAAA,CAAOC,IAAAA,CAAK,CAAA,sDAAA,EAAyDsF,SAAAA,CAAAA,gBAAAA,CAA2B,CAAA;AAChG,IAAA,MAAMC,WAAmC,EAAC;AAE1C,IAAA,IAAIlB,MAAAA,CAAO,IAAA,CAAA,EAAOkB,SAAQ,IAAA,CAAA,GAAQlB,OAAO,IAAA,CAAA;AACzC,IAAA,IAAIA,MAAAA,CAAO,aAAA,CAAA,EAAgBkB,SAAQ,aAAA,CAAA,GAAiBlB,OAAO,aAAA,CAAA;AAC3D,IAAA,IAAIA,MAAAA,CAAO,aAAA,CAAA,EAAgBkB,SAAQ,aAAA,CAAA,GAAiBlB,OAAO,aAAA,CAAA;AAE3D,IAAA,OAAOkB,QAAAA;AACT,EAAA;AAGA,EAAA,MAAMA,UAAmC,EAAC;AAE1C,EAAA,KAAA,MAAWC,KAAAA,IAAS7F,OAAOG,MAAAA,EAAQ;AACjC,IAAA,IAAIuE,MAAAA,CAAOmB,KAAAA,CAAAA,KAAWxD,MAAAA,EAAW;AAC/BuD,MAAAA,OAAAA,CAAQC,KAAAA,CAAAA,GAASnB,MAAAA,CAAOmB,KAAAA,CAAAA;AAC1B,IAAA;AACF,EAAA;AAEA,EAAA,OAAOD,OAAAA;AACT;AA1BgBF,MAAAA,CAAAA,oBAAAA,EAAAA,sBAAAA,CAAAA;AAmCT,SAASI,iBAAAA,CACdH,WACAL,YAAAA,EAAqC;AAQrC,EAAA,MAAMtF,MAAAA,GAASR,aAAAA,CAAckC,qBAAAA,CAAsBiE,SAAAA,CAAAA;AAEnD,EAAA,IAAI,CAAC3F,MAAAA,EAAQ;AACXI,IAAAA,MAAAA,CAAOC,IAAAA,CAAK,CAAA,4DAAA,EAA+DsF,SAAAA,CAAAA,gBAAAA,CAA2B,CAAA;AACtG,IAAA,OAAO;MACL/D,IAAAA,EAAM;QAAE2D,EAAAA,EAAI,SAAA;QAAWE,IAAAA,EAAM;AAAU,OAAA;MACvCD,EAAAA,EAAI;QAAED,EAAAA,EAAI,SAAA;QAAWE,IAAAA,EAAM;AAAU,OAAA;MACrCpE,gBAAAA,EAAkB,YAAA;AAClBsD,MAAAA,QAAAA,EAAU;AACZ,KAAA;AACF,EAAA;AAGA,EAAA,OAAO;IACL/C,IAAAA,EAAM;AACJ2D,MAAAA,EAAAA,EAAIQ,MAAAA,CAAOT,YAAAA,CAAatF,MAAAA,CAAOgG,SAAS,KAAK,SAAA,CAAA;AAC7CP,MAAAA,IAAAA,EAAMzF,MAAAA,CAAO4B;AACf,KAAA;IACA4D,EAAAA,EAAI;AACFD,MAAAA,EAAAA,EAAIQ,MAAAA,CAAOT,YAAAA,CAAatF,MAAAA,CAAOwF,EAAE,KAAK,SAAA,CAAA;AACtCC,MAAAA,IAAAA,EAAMzF,MAAAA,CAAOwF;AACf,KAAA;AACAnE,IAAAA,gBAAAA,EAAkBrB,OAAOyD,KAAAA,IAAS,YAAA;AAClCkB,IAAAA,QAAAA,EAAU3E,MAAAA,CAAOiG,eAAAA,GAAkBX,YAAAA,CAAAA,IAAiB;AACtD,GAAA;AACF;AAnCgBQ,MAAAA,CAAAA,iBAAAA,EAAAA,mBAAAA,CAAAA;AA2CT,SAASI,uBAAuBnG,UAAAA,EAAkB;AACvD,EAAA,MAAMC,MAAAA,GAASR,aAAAA,CAAcgC,eAAAA,CAAgBzB,UAAAA,CAAAA;AAE7C,EAAA,IAAI,CAACC,MAAAA,EAAQ;AAEX,IAAA,OAAO,QAAA;AACT,EAAA;AAEA,EAAA,OAAOA,OAAOwD,UAAAA,IAAc,QAAA;AAC9B;AATgB0C,MAAAA,CAAAA,sBAAAA,EAAAA,wBAAAA,CAAAA;AAkBT,SAASC,kBAAAA,CAAmBpG,YAAoB2E,MAAAA,EAA+B;AACpF,EAAA,MAAM1E,MAAAA,GAASR,aAAAA,CAAcgC,eAAAA,CAAgBzB,UAAAA,CAAAA;AAG7C,EAAA,IAAIC,QAAQoG,YAAAA,EAAc;AACxB,IAAA,OAAOpG,MAAAA,CAAOoG,aAAa1B,MAAAA,CAAAA;AAC7B,EAAA;AAGA,EAAA,OAAOqB,MAAAA,CAAOrB,MAAAA,CAAO,MAAA,CAAA,IAAWA,MAAAA,CAAO,OAAA,CAAA,IAAYA,MAAAA,CAAO,OAAA,CAAA,IAAYA,MAAAA,CAAO,IAAA,KAAS,UAAA,CAAA;AACxF;AAVgByB,MAAAA,CAAAA,kBAAAA,EAAAA,oBAAAA,CAAAA;AAkBT,SAASE,iBAAiBtG,UAAAA,EAAkB;AACjD,EAAA,MAAMC,MAAAA,GAASR,aAAAA,CAAcgC,eAAAA,CAAgBzB,UAAAA,CAAAA;AAE7C,EAAA,IAAI,CAACC,MAAAA,EAAQ;AAEX,IAAA,OAAO,KAAA;AACT,EAAA;AAGA,EAAA,OAAOA,OAAOgB,OAAAA,KAAY,KAAA;AAC5B;AAVgBqF,MAAAA,CAAAA,gBAAAA,EAAAA,kBAAAA,CAAAA;AAkBT,SAASC,uBAAuBjF,gBAAAA,EAAwB;AAC7D,EAAA,MAAMrB,MAAAA,GAASR,aAAAA,CAAckC,qBAAAA,CAAsBL,gBAAAA,CAAAA;AAEnD,EAAA,IAAI,CAACrB,MAAAA,EAAQ;AAEX,IAAA,OAAO,KAAA;AACT,EAAA;AAGA,EAAA,OAAOA,OAAOgB,OAAAA,KAAY,KAAA;AAC5B;AAVgBsF,MAAAA,CAAAA,sBAAAA,EAAAA,wBAAAA,CAAAA;AC9GT,SAASC,qBAAqBvG,MAAAA,EAA0B;AAC7D,EAAA,MAAMwG,UAAAA,GAAyB;AAC7BC,IAAAA,gBAAAA,EAAkBzG,MAAAA,CAAO0G,WAAAA;AACzBC,IAAAA,GAAAA,EAAK3G,OAAO4G,cAAAA,IAAkB,EAAA;AAC9BC,IAAAA,iBAAAA,EAAmB7G,OAAO6G,iBAAAA,IAAqB,GAAA;AAC/CC,IAAAA,uBAAAA,EAAyB9G,OAAO8G,uBAAAA,IAA2B;AAC7D,GAAA;AAGA,EAAA,IAAI9G,OAAO+G,eAAAA,EAAiB;AAC1BP,IAAAA,UAAAA,CAAWQ,mBAAmBhH,MAAAA,CAAO+G,eAAAA;AACvC,EAAA;AAIA,EAAA,IAAI/G,MAAAA,CAAOiH,sBAAAA,IAA0B,IAAA,IAAQjH,MAAAA,CAAOiH,yBAAyB,CAAA,EAAG;AAC9ET,IAAAA,UAAAA,CAAWU,oBAAoBlH,MAAAA,CAAOiH,sBAAAA;AACxC,EAAA;AACA,EAAA,IAAIjH,MAAAA,CAAOmH,8BAAAA,IAAkC,IAAA,IAAQnH,MAAAA,CAAOmH,iCAAiC,CAAA,EAAG;AAC9FX,IAAAA,UAAAA,CAAWY,sCAAsCpH,MAAAA,CAAOmH,8BAAAA;AAC1D,EAAA;AACA,EAAA,IAAInH,MAAAA,CAAOqH,iBAAAA,IAAqB,IAAA,IAAQrH,MAAAA,CAAOqH,oBAAoB,CAAA,EAAG;AACpEb,IAAAA,UAAAA,CAAWc,eAAetH,MAAAA,CAAOqH,iBAAAA;AACnC,EAAA;AAEA,EAAA,OAAO,IAAIE,KAAKf,UAAAA,CAAAA;AAClB;AA1BgBD,MAAAA,CAAAA,oBAAAA,EAAAA,sBAAAA,CAAAA;AA2CT,SAASiB,6BAA6BC,WAAAA,EAA+B;AAC1E,EAAA,IAAIA,WAAAA,IAAe,CAAC3C,OAAAA,CAAQC,GAAAA,CAAI,WAAA,CAAA,EAAc;AAC5CD,IAAAA,OAAAA,CAAQC,GAAAA,CAAI,WAAA,CAAA,GAAe,CAAA,IAAA,EAAO0C,WAAAA,CAAAA,CAAAA;AACpC,EAAA;AACF;AAJgBD,MAAAA,CAAAA,4BAAAA,EAAAA,8BAAAA,CAAAA;AAST,SAASE,oBAAoBC,IAAAA,EAAU;AAC5C,EAAA,OAAO,IAAIC,SAASD,IAAAA,CAAAA;AACtB;AAFgBD,MAAAA,CAAAA,mBAAAA,EAAAA,qBAAAA,CAAAA;AAOT,SAASG,sBAAAA,CAAmDC,QAAW9H,MAAAA,EAA0B;AACtG,EAAA,MAAM+H,aAAAA,GAAgBjD,OAAAA,CAAQC,GAAAA,CAAI,UAAA,CAAA,KAAgB,aAAA;AAClD,EAAA,MAAMiD,kBAAAA,GAAqBhI,MAAAA,CAAOgI,kBAAAA,KAAuBD,aAAAA,GAAgB,GAAA,GAAM,GAAA,CAAA;AAG/E,EAAA,IAAI/H,MAAAA,CAAOiI,sBAAsBF,aAAAA,EAAe;AAC9CD,IAAAA,MAAAA,CAAOI,GAAAA,CAAI,OAAA,EAAS,CAACC,CAAAA,KAAAA;AACnB,MAAA,IAAI,OAAA,IAAWA,CAAAA,IAAK,UAAA,IAAcA,CAAAA,EAAG;AACnC,QAAA,IAAIA,CAAAA,CAAEC,WAAWJ,kBAAAA,EAAoB;AACnC5H,UAAAA,MAAAA,CAAOC,KAAK,8BAAA,EAAgC;YAC1CgI,KAAAA,EAAOF,CAAAA,CAAEE,KAAAA,CAAMC,SAAAA,CAAU,CAAA,EAAG,GAAA,KAAQH,CAAAA,CAAEE,KAAAA,CAAME,MAAAA,GAAS,GAAA,GAAM,KAAA,GAAQ,EAAA,CAAA;AACnEC,YAAAA,MAAAA,EAAQL,CAAAA,CAAEK,MAAAA;YACVJ,QAAAA,EAAU,CAAA,EAAGD,EAAEC,QAAQ,CAAA,EAAA;WACzB,CAAA;QACF,CAAA,MAAO;AACLhI,UAAAA,MAAAA,CAAOqI,MAAM,gBAAA,EAAkB;YAC7BJ,KAAAA,EAAOF,CAAAA,CAAEE,KAAAA,CAAMC,SAAAA,CAAU,CAAA,EAAG,GAAA,KAAQH,CAAAA,CAAEE,KAAAA,CAAME,MAAAA,GAAS,GAAA,GAAM,KAAA,GAAQ,EAAA,CAAA;YACnEH,QAAAA,EAAU,CAAA,EAAGD,EAAEC,QAAQ,CAAA,EAAA;WACzB,CAAA;AACF,QAAA;AACF,MAAA;IACF,CAAA,CAAA;AACF,EAAA;AAGAN,EAAAA,MAAAA,CAAOI,GAAAA,CAAI,OAAA,EAAS,CAACC,CAAAA,KAAAA;AACnB,IAAA,IAAI,aAAaA,CAAAA,EAAG;AAClB/H,MAAAA,MAAAA,CAAOsI,MAAM,yBAAA,EAA2B;AACtCC,QAAAA,OAAAA,EAASR,CAAAA,CAAEQ,OAAAA;AACXC,QAAAA,MAAAA,EAAQT,CAAAA,CAAES;OACZ,CAAA;AACF,IAAA;EACF,CAAA,CAAA;AAGAd,EAAAA,MAAAA,CAAOI,GAAAA,CAAI,MAAA,EAAQ,CAACC,CAAAA,KAAAA;AAClB,IAAA,IAAI,aAAaA,CAAAA,EAAG;AAClB/H,MAAAA,MAAAA,CAAOC,KAAK,2BAAA,EAA6B;AACvCsI,QAAAA,OAAAA,EAASR,CAAAA,CAAEQ,OAAAA;AACXC,QAAAA,MAAAA,EAAQT,CAAAA,CAAES;OACZ,CAAA;AACF,IAAA;EACF,CAAA,CAAA;AAEA,EAAA,OAAOd,MAAAA;AACT;AA7CgBD,MAAAA,CAAAA,sBAAAA,EAAAA,wBAAAA,CAAAA;AAkDT,IAAMgB,sBAAN,MAAMA;EA/Nb;;;AAgOUf,EAAAA,MAAAA;AACAH,EAAAA,IAAAA;EACAmB,eAAAA,GAAmC;IACzCC,WAAAA,EAAa,KAAA;IACbC,QAAAA,EAAU;AACZ,GAAA;EACQC,eAAAA,GAAkB,KAAA;EAE1B,WAAA,CAAYnB,MAAAA,EAAWH,MAAY3H,MAAAA,EAA4B;AAC7D,IAAA,IAAA,CAAK8H,MAAAA,GAASA,MAAAA;AACd,IAAA,IAAA,CAAKH,IAAAA,GAAOA,IAAAA;AAGZE,IAAAA,sBAAAA,CAAuB,IAAA,CAAKC,QAAQ9H,MAAAA,CAAAA;AACtC,EAAA;;;;EAKOkJ,SAAAA,GAAe;AACpB,IAAA,OAAO,IAAA,CAAKpB,MAAAA;AACd,EAAA;;;;EAKOqB,OAAAA,GAAgB;AACrB,IAAA,OAAO,IAAA,CAAKxB,IAAAA;AACd,EAAA;;;;EAKOyB,kBAAAA,GAAsC;AAC3C,IAAA,OAAO;AAAE,MAAA,GAAG,IAAA,CAAKN;AAAgB,KAAA;AACnC,EAAA;;;;AAKA,EAAA,MAAaO,OAAAA,CAAQC,OAAAA,GAAU,CAAA,EAAGC,KAAAA,GAAQ,GAAA,EAAqB;AAC7D,IAAA,IAAI,IAAA,CAAKT,gBAAgBC,WAAAA,EAAa;AACpC3I,MAAAA,MAAAA,CAAOO,KAAK,wCAAA,CAAA;AACZ,MAAA;AACF,IAAA;AAEA,IAAA,KAAA,IAAS6I,OAAAA,GAAU,CAAA,EAAGA,OAAAA,IAAWF,OAAAA,EAASE,OAAAA,EAAAA,EAAW;AACnD,MAAA,IAAA,CAAKV,gBAAgBE,QAAAA,GAAWQ,OAAAA;AAEhC,MAAA,IAAI;AACF,QAAA,MAAM,IAAA,CAAK1B,OAAO2B,QAAAA,EAAQ;AAC1B,QAAA,IAAA,CAAKX,gBAAgBC,WAAAA,GAAc,IAAA;AACnC,QAAA,IAAA,CAAKD,eAAAA,CAAgBY,eAAAA,mBAAkB,IAAIzE,IAAAA,EAAAA;AAC3C,QAAA,IAAA,CAAK6D,gBAAgBa,SAAAA,GAAYtH,KAAAA,CAAAA;AAEjCjC,QAAAA,MAAAA,CAAOO,KAAK,6CAAA,CAAA;AACZ,QAAA;AACF,MAAA,CAAA,CAAA,OAAS+H,KAAAA,EAAO;AACd,QAAA,MAAMkB,eAAelB,KAAAA,YAAiBmB,KAAAA,GAAQnB,KAAAA,CAAMC,OAAAA,GAAU5C,OAAO2C,KAAAA,CAAAA;AACrE,QAAA,IAAA,CAAKI,gBAAgBa,SAAAA,GAAYC,YAAAA;AAEjCxJ,QAAAA,MAAAA,CAAOsI,KAAAA,CAAM,CAAA,4BAAA,EAA+Bc,OAAAA,CAAAA,CAAAA,EAAWF,OAAAA,CAAAA,OAAAA,CAAAA,EAAkB;UACvEZ,KAAAA,EAAOkB;SACT,CAAA;AAEA,QAAA,IAAIJ,YAAYF,OAAAA,EAAS;AACvBlJ,UAAAA,MAAAA,CAAOsI,MAAM,yCAAA,CAAA;AACb,UAAA,MAAMA,KAAAA;AACR,QAAA;AAGA,QAAA,MAAMoB,WAAWP,KAAAA,GAAQQ,IAAAA,CAAKC,GAAAA,CAAI,CAAA,EAAGR,UAAU,CAAA,CAAA;AAC/CpJ,QAAAA,MAAAA,CAAOO,IAAAA,CAAK,CAAA,qBAAA,EAAwBmJ,QAAAA,CAAAA,KAAAA,CAAe,CAAA;AACnD,QAAA,MAAM,IAAIG,OAAAA,CAAQ,CAACC,YAAYC,UAAAA,CAAWD,OAAAA,EAASJ,QAAAA,CAAAA,CAAAA;AACrD,MAAA;AACF,IAAA;AACF,EAAA;;;;AAKA,EAAA,MAAaM,UAAAA,GAA4B;AAEvC,IAAA,IAAI,KAAKnB,eAAAA,EAAiB;AACxB7I,MAAAA,MAAAA,CAAOqI,MAAM,mDAAA,CAAA;AACb,MAAA;AACF,IAAA;AAEA,IAAA,IAAI,CAAC,IAAA,CAAKK,eAAAA,CAAgBC,WAAAA,EAAa;AACrC3I,MAAAA,MAAAA,CAAOO,KAAK,wCAAA,CAAA;AACZ,MAAA;AACF,IAAA;AAGA,IAAA,IAAA,CAAKsI,eAAAA,GAAkB,IAAA;AAEvB,IAAA,IAAI;AACF,MAAA,MAAM,IAAA,CAAKnB,OAAOuC,WAAAA,EAAW;AAC7B,MAAA,MAAM,IAAA,CAAK1C,KAAK2C,GAAAA,EAAG;AACnB,MAAA,IAAA,CAAKxB,gBAAgBC,WAAAA,GAAc,KAAA;AAEnC3I,MAAAA,MAAAA,CAAOO,KAAK,kDAAA,CAAA;AACd,IAAA,CAAA,CAAA,OAAS+H,KAAAA,EAAO;AACd,MAAA,MAAMkB,eAAelB,KAAAA,YAAiBmB,KAAAA,GAAQnB,KAAAA,CAAMC,OAAAA,GAAU5C,OAAO2C,KAAAA,CAAAA;AAGrE,MAAA,IAAIkB,YAAAA,CAAaW,QAAAA,CAAS,mCAAA,CAAA,EAAsC;AAC9DnK,QAAAA,MAAAA,CAAOqI,MAAM,0DAAA,CAAA;AACb,QAAA,IAAA,CAAKK,gBAAgBC,WAAAA,GAAc,KAAA;AACnC,QAAA;AACF,MAAA;AAEA3I,MAAAA,MAAAA,CAAOsI,MAAM,4CAAA,EAA8C;QACzDA,KAAAA,EAAOkB;OACT,CAAA;AACA,MAAA,MAAMlB,KAAAA;IACR,CAAA,SAAA;AACE,MAAA,IAAA,CAAKO,eAAAA,GAAkB,KAAA;AACzB,IAAA;AACF,EAAA;;;;EAKOuB,wBAAAA,GAAiC;AACtC,IAAA,MAAMC,eAAAA,iCAAyBC,MAAAA,KAAAA;AAC7BtK,MAAAA,MAAAA,CAAOO,IAAAA,CAAK,CAAA,kBAAA,EAAqB+J,MAAAA,CAAAA,+BAAAA,CAAuC,CAAA;AAExE,MAAA,IAAI;AACF,QAAA,MAAM,KAAKN,UAAAA,EAAU;AACrBtF,QAAAA,OAAAA,CAAQ6F,KAAK,CAAA,CAAA;AACf,MAAA,CAAA,CAAA,OAASjC,KAAAA,EAAO;AACdtI,QAAAA,MAAAA,CAAOsI,MAAM,yCAAA,EAA2C;AACtDA,UAAAA,KAAAA,EAAOA,KAAAA,YAAiBmB,KAAAA,GAAQnB,KAAAA,CAAMC,OAAAA,GAAU5C,OAAO2C,KAAAA;SACzD,CAAA;AACA5D,QAAAA,OAAAA,CAAQ6F,KAAK,CAAA,CAAA;AACf,MAAA;IACF,CAAA,EAZwB,iBAAA,CAAA;AAexB7F,IAAAA,OAAAA,CAAQ8F,GAAG,QAAA,EAAU,MAAM,KAAKH,eAAAA,CAAgB,QAAA,CAAA,CAAA;AAChD3F,IAAAA,OAAAA,CAAQ8F,GAAG,SAAA,EAAW,MAAM,KAAKH,eAAAA,CAAgB,SAAA,CAAA,CAAA;AACjD3F,IAAAA,OAAAA,CAAQ8F,GAAG,YAAA,EAAc,MAAM,KAAK,IAAA,CAAKR,YAAU,CAAA;AACrD,EAAA;AACF;AA0CO,SAASS,kBAAAA,CACdC,yBACA9K,MAAAA,EAA0B;AAE1B,EAAA,MAAM+H,aAAAA,GAAgBjD,OAAAA,CAAQC,GAAAA,CAAI,UAAA,CAAA,KAAgB,aAAA;AAGlD,EAAA,MAAM4C,IAAAA,GAAOpB,qBAAqBvG,MAAAA,CAAAA;AAGlC,EAAA,MAAM+K,OAAAA,GAAUrD,oBAAoBC,IAAAA,CAAAA;AAGpC,EAAA,MAAMqD,SAAAA,GACHhL,MAAAA,CAAOgL,SAAAA,KACPjD,aAAAA,GACG;AACE,IAAA;MAAEkD,IAAAA,EAAM,OAAA;MAASC,KAAAA,EAAO;AAAQ,KAAA;AAChC,IAAA;MAAED,IAAAA,EAAM,OAAA;MAASC,KAAAA,EAAO;AAAO,KAAA;AAC/B,IAAA;MAAED,IAAAA,EAAM,OAAA;MAASC,KAAAA,EAAO;AAAO,KAAA;AAC/B,IAAA;MAAED,IAAAA,EAAM,OAAA;MAASC,KAAAA,EAAO;AAAQ;AAElC,GAAA,GAAA;AACE,IAAA;MAAED,IAAAA,EAAM,OAAA;MAASC,KAAAA,EAAO;AAAO,KAAA;AAC/B,IAAA;MAAED,IAAAA,EAAM,OAAA;MAASC,KAAAA,EAAO;AAAQ;;AAIxC,EAAA,MAAMpD,MAAAA,GAAS,IAAIgD,uBAAAA,CAAwB;AACzCC,IAAAA,OAAAA;IACAI,GAAAA,EAAKH;GACP,CAAA;AAGA,EAAA,OAAO,IAAInC,mBAAAA,CAAoBf,MAAAA,EAAQH,IAAAA,EAAM3H,MAAAA,CAAAA;AAC/C;AAnCgB6K,MAAAA,CAAAA,kBAAAA,EAAAA,oBAAAA,CAAAA;;;AC9UhB,IAAMO,aAAAA,GAGF;EACFpK,OAAAA,EAAS,IAAA;EACTqK,mBAAAA,EAAqB;AAAC,IAAA,QAAA;AAAU,IAAA,QAAA;AAAU,IAAA,QAAA;AAAU,IAAA,YAAA;AAAc,IAAA;;AACpE,CAAA;AAKA,SAASC,iBAAAA,CACPC,OACAzH,MAAAA,EAAe;AAEf,EAAA,IAAI,CAACA,MAAAA,IAAU,OAAOA,MAAAA,KAAW,QAAA,EAAU;AACzC,IAAA,OAAO,IAAA;AACT,EAAA;AAEA,EAAA,MAAM0H,MAAAA,GAAS1H,MAAAA;AACf,EAAA,MAAMyB,EAAAA,GAAKiG,OAAO,IAAA,CAAA;AAElB,EAAA,IAAI,CAACjG,EAAAA,EAAI;AACP,IAAA,OAAO,IAAA;AACT,EAAA;AAEA,EAAA,OAAO;AACLA,IAAAA,EAAAA;IACAE,IAAAA,EAAM8F,KAAAA;IACNpJ,IAAAA,EAAMqJ;AACR,GAAA;AACF;AApBSF,MAAAA,CAAAA,iBAAAA,EAAAA,mBAAAA,CAAAA;AAyBT,SAASG,eAAeC,IAAAA,EAAa;AAKnC,EAAA,IAAI,CAACA,IAAAA,IAAQ,OAAOA,IAAAA,KAAS,QAAA,EAAU;AACrC,IAAA,OAAO,EAAC;AACV,EAAA;AAEA,EAAA,MAAMvJ,IAAAA,GACHuJ,IAAAA,CAA6E,MAAA,CAAA,IAC7EA,KAA6C,OAAA,CAAA;AAEhD,EAAA,IAAI,CAACvJ,IAAAA,IAAQ,OAAOA,IAAAA,KAAS,QAAA,EAAU;AACrC,IAAA,OAAO,EAAC;AACV,EAAA;AAEA,EAAA,OAAO;AACLsC,IAAAA,cAAAA,EAAgBtC,KAAK,gBAAA,CAAA;IACrBwJ,OAAAA,EACGxJ,IAAAA,CAAK,SAAA,CAAA,IACLA,IAAAA,CAAK,WAAA,KACLA,IAAAA,CAAK,WAAA,CAAA,IACLA,IAAAA,CAAK,QAAA,CAAA;AACRyJ,IAAAA,WAAAA,EAAczJ,IAAAA,CAAK,aAAA,CAAA,IAA0CA,IAAAA,CAAK,aAAA;AACpE,GAAA;AACF;AA1BSsJ,MAAAA,CAAAA,cAAAA,EAAAA,gBAAAA,CAAAA;AA+BT,SAASI,eAAAA,CACPrH,SAAAA,EACA+G,KAAAA,EACAzH,MAAAA,EACA4H,MACA1L,MAAAA,EAA6B;AAE7B,EAAA,MAAM8L,UAAAA,GAAaR,iBAAAA,CAAkBC,KAAAA,EAAOzH,MAAAA,CAAAA;AAC5C,EAAA,IAAI,CAACgI,UAAAA,EAAY;AACf,IAAA;AACF,EAAA;AAGA,EAAA,IAAI,CAACtM,aAAAA,CAAcwC,kBAAAA,CAAmBuJ,KAAAA,CAAAA,EAAQ;AAC5C,IAAA;AACF,EAAA;AAGA,EAAA,IAAIvL,MAAAA,CAAO+L,WAAAA,IAAe/L,MAAAA,CAAO+L,WAAAA,CAAYxD,MAAAA,GAAS,CAAA,IAAK,CAACvI,MAAAA,CAAO+L,WAAAA,CAAYxB,QAAAA,CAASgB,KAAAA,CAAAA,EAAQ;AAC9F,IAAA;AACF,EAAA;AAEA,EAAA,MAAMS,OAAAA,GAAUP,eAAeC,IAAAA,CAAAA;AAC/B,EAAA,MAAMO,WAAAA,GAAcvG,oBAAAA,CAAqB6F,KAAAA,EAAOO,UAAAA,CAAW3J,IAAI,CAAA;AAI/D,EAAA,MAAM+J,KAAAA,GAAQ1M,cAAc0C,iBAAAA,CAAkBqJ,KAAAA,EAAOO,WAAW3J,IAAI,CAAA,IAAK6J,QAAQvH,cAAAA,IAAkB,SAAA;AACnG,EAAA,MAAMmH,cAAcpM,aAAAA,CAAc8C,cAAAA,CAAeiJ,OAAOO,UAAAA,CAAW3J,IAAI,KAAK6J,OAAAA,CAAQJ,WAAAA;AACpF,EAAA,MAAMD,OAAAA,GAAUK,QAAQL,OAAAA,IAAW,SAAA;AAGnC,EAAA,MAAMQ,YAAAA,GAAe3M,aAAAA,CAAciD,mBAAAA,CAAoB8I,KAAAA,EAAOO,WAAW3J,IAAI,CAAA;AAE7E,EAAA,IAAIgK,YAAAA,EAAc;AAChB/L,IAAAA,MAAAA,CAAOqI,KAAAA,CAAM,CAAA,8CAAA,EAAiD8C,KAAAA,CAAAA,CAAAA,EAAS;AACrErI,MAAAA,gBAAAA,EAAkBiJ,YAAAA,CAAajJ,gBAAAA;MAC/BkJ,OAAAA,EAAS,CAAC,CAACD,YAAAA,CAAavJ;KAC1B,CAAA;AACF,EAAA;AAGA5C,EAAAA,MAAAA,CAAOqM,YAAAA,CACJC,mBACC9H,SAAAA,EACA;AACEe,IAAAA,EAAAA,EAAIuG,UAAAA,CAAWvG,EAAAA;AACfE,IAAAA,IAAAA,EAAMqG,UAAAA,CAAWrG,IAAAA;IACjBtD,IAAAA,EAAM8J;GACR,EACA;AACExE,IAAAA,WAAAA,EAAazH,MAAAA,CAAOyH,WAAAA;IACpBhD,cAAAA,EAAgByH,KAAAA;AAChBP,IAAAA,OAAAA;AACAC,IAAAA;AACF,GAAA,EACAO,YAAAA,CAAAA,CAEDI,KAAAA,CAAM,CAAC7D,KAAAA,KAAAA;AACNtI,IAAAA,MAAAA,CAAOsI,KAAAA,CAAM,2CAA2CA,KAAAA,CAAAA;EAC1D,CAAA,CAAA;AAIF,EAAA,IAAIlE,SAAAA,KAAc,gBAAA,IAAoBA,SAAAA,KAAc,gBAAA,EAAkB;AACpEgI,IAAAA,sBAAAA,CAAuBjB,KAAAA,EAAOO,UAAAA,CAAW3J,IAAAA,EAAM+J,KAAAA,EAAOlM,MAAAA,CAAAA;AACxD,EAAA;AACF;AAnES6L,MAAAA,CAAAA,eAAAA,EAAAA,iBAAAA,CAAAA;AAyET,SAASW,sBAAAA,CACPzM,UAAAA,EACA2C,UAAAA,EACA+B,cAAAA,EACAzE,MAAAA,EAA6B;AAG7B,EAAA,MAAMS,aAAAA,GAAgBjB,aAAAA,CAAcqE,yBAAAA,CAA0B9D,UAAAA,CAAAA;AAE9D,EAAA,IAAIU,aAAAA,CAAc8H,WAAW,CAAA,EAAG;AAC9B,IAAA;AACF,EAAA;AAEA,EAAA,MAAMkE,MAAAA,GAAS/J,WAAW,IAAA,CAAA;AAC1B,EAAA,IAAI,CAAC+J,MAAAA,EAAQ;AACX,IAAA;AACF,EAAA;AAGA,EAAA,KAAA,MAAW,CAACC,eAAAA,EAAiBpL,kBAAAA,CAAAA,IAAuBb,aAAAA,EAAe;AACjE,IAAA,MAAMkM,eAAAA,GAAkBjK,UAAAA,CAAWpB,kBAAAA,CAAmB0E,SAAS,CAAA;AAG/D,IAAA,IAAI,CAAC2G,eAAAA,EAAiB;AACpB,MAAA;AACF,IAAA;AAGA,IAAA,IAAIC,aAAatL,kBAAAA,CAAmBkE,EAAAA;AACpC,IAAA,IAAIlE,kBAAAA,CAAmBkE,OAAO,GAAA,EAAK;AACjC,MAAA,IAAIlE,mBAAmBuL,oBAAAA,EAAsB;AAC3CD,QAAAA,UAAAA,GAAalK,UAAAA,CAAWpB,mBAAmBuL,oBAAoB,CAAA;AAC/D,QAAA,IAAI,CAACD,UAAAA,EAAY;AACfxM,UAAAA,MAAAA,CAAOC,IAAAA,CAAK,CAAA,2CAAA,EAA8CqM,eAAAA,CAAAA,wBAAAA,CAAyC,CAAA;AACnG,UAAA;AACF,QAAA;MACF,CAAA,MAAO;AACLtM,QAAAA,MAAAA,CAAOqI,KAAAA,CAAM,CAAA,wEAAA,EAA2EiE,eAAAA,CAAAA,CAAiB,CAAA;AACzG,QAAA;AACF,MAAA;AACF,IAAA;AAGA,IAAA,MAAM/H,WAAWrD,kBAAAA,CAAmB2E,eAAAA,GAChC3E,kBAAAA,CAAmB2E,eAAAA,CAAgBvD,UAAAA,CAAAA,GACnC;AAAEoK,MAAAA,WAAAA,EAAaxL,kBAAAA,CAAmBwL;AAAY,KAAA;AAGlD9M,IAAAA,MAAAA,CAAOqM,YAAAA,CACJC,mBACC,sBAAA,EACA;MACE/G,EAAAA,EAAI,CAAA,EAAGkH,MAAAA,CAAAA,CAAAA,EAAUE,eAAAA,CAAAA,CAAAA;AACjBlH,MAAAA,IAAAA,EAAMnE,kBAAAA,CAAmBmC,KAAAA;MACzBtB,IAAAA,EAAM;QACJP,IAAAA,EAAM;UACJ2D,EAAAA,EAAIkH,MAAAA;UACJhH,IAAAA,EAAM1F;AACR,SAAA;QACAyF,EAAAA,EAAI;UACFD,EAAAA,EAAIoH,eAAAA;UACJlH,IAAAA,EAAMmH;AACR,SAAA;AACAG,QAAAA,YAAAA,EAAczL,kBAAAA,CAAmBmC,KAAAA;AACjCkB,QAAAA;AACF;KACF,EACA;AACE8C,MAAAA,WAAAA,EAAazH,MAAAA,CAAOyH,WAAAA;AACpBhD,MAAAA;KACF,CAAA,CAED8H,KAAAA,CAAM,CAAC7D,KAAAA,KAAAA;AACNtI,MAAAA,MAAAA,CAAOsI,KAAAA,CAAM,CAAA,wDAAA,EAA2DgE,eAAAA,CAAAA,CAAAA,CAAAA,EAAoBhE,KAAAA,CAAAA;IAC9F,CAAA,CAAA;AAEFtI,IAAAA,MAAAA,CAAOqI,KAAAA,CACL,CAAA,gDAAA,EAAmDnH,kBAAAA,CAAmBmC,KAAK,CAAA,EAAA,EAAK1D,UAAAA,CAAAA,CAAAA,EAAc0M,MAAAA,CAAAA,IAAAA,EAAaG,UAAAA,CAAAA,CAAAA,EAAcD,eAAAA,CAAAA,CAAAA,CAAkB,CAAA;AAE/I,EAAA;AACF;AAhFSH,MAAAA,CAAAA,sBAAAA,EAAAA,wBAAAA,CAAAA;AA2GF,SAASQ,iBAAAA,CAAqBC,YAAejN,MAAAA,EAA6B;AAC/E,EAAA,MAAMkN,UAAAA,GAAa;IAAE,GAAG9B,aAAAA;IAAe,GAAGpL;AAAO,GAAA;AAEjD,EAAA,IAAI,CAACkN,WAAWlM,OAAAA,EAAS;AACvBZ,IAAAA,MAAAA,CAAOO,KAAK,uDAAA,CAAA;AACZ,IAAA,OAAOsM,UAAAA;AACT,EAAA;AAGA,EAAA,MAAME,YAAAA,GAAeF,UAAAA;AAErB,EAAA,OAAOE,aAAaC,QAAAA,CAAS;IAC3B/E,KAAAA,EAAO;MACLgF,UAAAA,EAAY;AACV,QAAA,MAAMC,MAAAA,CAAO,EACX/B,KAAAA,EACAG,IAAAA,EACArD,OAAK,EAKN;AACC,UAAA,MAAMvE,MAAAA,GAAS,MAAMuE,KAAAA,CAAMqD,IAAAA,CAAAA;AAE3B,UAAA,IAAIwB,UAAAA,CAAW7B,mBAAAA,EAAqBd,QAAAA,CAAS,QAAA,CAAA,EAAW;AACtDsB,YAAAA,eAAAA,CAAgB,gBAAA,EAAkBN,KAAAA,EAAOzH,MAAAA,EAAQ4H,IAAAA,EAAMwB,UAAAA,CAAAA;AACzD,UAAA;AAEA,UAAA,OAAOpJ,MAAAA;AACT,QAAA,CAAA;AAEA,QAAA,MAAMyJ,MAAAA,CAAO,EACXhC,KAAAA,EACAG,IAAAA,EACArD,OAAK,EAKN;AACC,UAAA,MAAMvE,MAAAA,GAAS,MAAMuE,KAAAA,CAAMqD,IAAAA,CAAAA;AAE3B,UAAA,IAAIwB,UAAAA,CAAW7B,mBAAAA,EAAqBd,QAAAA,CAAS,QAAA,CAAA,EAAW;AACtDsB,YAAAA,eAAAA,CAAgB,gBAAA,EAAkBN,KAAAA,EAAOzH,MAAAA,EAAQ4H,IAAAA,EAAMwB,UAAAA,CAAAA;AACzD,UAAA;AAEA,UAAA,OAAOpJ,MAAAA;AACT,QAAA,CAAA;AAEA,QAAA,MAAM0J,MAAAA,CAAO,EACXjC,KAAAA,EACAG,IAAAA,EACArD,OAAK,EAKN;AACC,UAAA,MAAMvE,MAAAA,GAAS,MAAMuE,KAAAA,CAAMqD,IAAAA,CAAAA;AAE3B,UAAA,IAAIwB,UAAAA,CAAW7B,mBAAAA,EAAqBd,QAAAA,CAAS,QAAA,CAAA,EAAW;AACtDsB,YAAAA,eAAAA,CAAgB,gBAAA,EAAkBN,KAAAA,EAAOzH,MAAAA,EAAQ4H,IAAAA,EAAMwB,UAAAA,CAAAA;AACzD,UAAA;AAEA,UAAA,OAAOpJ,MAAAA;AACT,QAAA,CAAA;AAEA,QAAA,MAAM2J,UAAAA,CAAW,EACflC,KAAAA,EACAG,IAAAA,EACArD,OAAK,EAKN;AACC,UAAA,MAAMvE,MAAAA,GAAS,MAAMuE,KAAAA,CAAMqD,IAAAA,CAAAA;AAE3B,UAAA,IAAIwB,UAAAA,CAAW7B,mBAAAA,EAAqBd,QAAAA,CAAS,YAAA,CAAA,EAAe;AAC1DnK,YAAAA,MAAAA,CAAOO,IAAAA,CAAK,CAAA,iCAAA,EAAoC4K,KAAAA,CAAAA,0CAAAA,CAAiD,CAAA;AACnG,UAAA;AAEA,UAAA,OAAOzH,MAAAA;AACT,QAAA,CAAA;AAEA,QAAA,MAAM4J,UAAAA,CAAW,EACfnC,KAAAA,EACAG,IAAAA,EACArD,OAAK,EAKN;AACC,UAAA,MAAMvE,MAAAA,GAAS,MAAMuE,KAAAA,CAAMqD,IAAAA,CAAAA;AAE3B,UAAA,IAAIwB,UAAAA,CAAW7B,mBAAAA,EAAqBd,QAAAA,CAAS,YAAA,CAAA,EAAe;AAC1DnK,YAAAA,MAAAA,CAAOO,IAAAA,CAAK,CAAA,iCAAA,EAAoC4K,KAAAA,CAAAA,0CAAAA,CAAiD,CAAA;AACnG,UAAA;AAEA,UAAA,OAAOzH,MAAAA;AACT,QAAA;AACF;AACF;GACF,CAAA;AACF;AA1GgBkJ,MAAAA,CAAAA,iBAAAA,EAAAA,mBAAAA,CAAAA","file":"chunk-Q23NPVWQ.js","sourcesContent":["/**\n * Graph Registry - Decentralized Graph Configuration System\n *\n * This registry allows each module to define its own graph configuration\n * without touching the central graph module. Modules register their entity\n * and relationship mappings, which are then used by the graph sync service.\n *\n * @module graph-registry\n * @category Graph\n */\nimport { logger } from '../../logger/index.js';\nimport type {\n EntityGraphConfig,\n ModuleGraphConfig,\n RelationshipGraphConfig,\n RegistryEntityRbacConfig,\n} from '../types.js';\n\n/**\n * Internal representation of entity config with resolved fields\n */\ninterface ResolvedEntityGraphConfig extends Omit<EntityGraphConfig, 'fields'> {\n fields: string[];\n getOrgId?: (data: Record<string, unknown>) => string | undefined;\n getWorkspaceId?: (data: Record<string, unknown>) => string | undefined;\n rbac?: RegistryEntityRbacConfig;\n}\n\n/**\n * Central registry for all graph configurations\n */\nexport class GraphRegistry {\n private static entityMappings: Map<string, ResolvedEntityGraphConfig> = new Map();\n private static relationshipMappings: Map<string, RelationshipGraphConfig> = new Map();\n private static registeredModules: Set<string> = new Set();\n\n /**\n * Resolve fields from entity configuration\n *\n * @param entityType - Name of the entity type\n * @param config - Entity configuration\n * @returns Resolved array of field names\n */\n private static resolveFields(entityType: string, config: EntityGraphConfig): string[] {\n if (Array.isArray(config.fields)) {\n return config.fields;\n }\n\n // Fallback: empty array if fields not configured\n logger.warn(`[GraphRegistry] No fields configuration for ${entityType}, using empty array`);\n return [];\n }\n\n /**\n * Register a module's graph configuration\n * @param config - Module graph configuration\n */\n static registerModule(config: ModuleGraphConfig): void {\n const { moduleName, entities, relationships } = config;\n\n if (this.registeredModules.has(moduleName)) {\n logger.warn(`[GraphRegistry] Module '${moduleName}' already registered, skipping`);\n return;\n }\n\n logger.info(`[GraphRegistry] Registering module: ${moduleName}`);\n\n // Register entities\n let entityCount = 0;\n for (const [entityType, entityConfig] of Object.entries(entities)) {\n if (entityConfig.enabled !== false) {\n // Resolve fields\n const resolvedFields = this.resolveFields(entityType, entityConfig);\n\n // Store resolved configuration\n const resolvedConfig: ResolvedEntityGraphConfig = {\n ...entityConfig,\n fields: resolvedFields,\n };\n\n this.entityMappings.set(entityType, resolvedConfig);\n entityCount++;\n }\n }\n\n // Register relationships\n let relationshipCount = 0;\n if (relationships) {\n for (const [relationshipType, relationshipConfig] of Object.entries(relationships)) {\n if (relationshipConfig.enabled !== false) {\n this.relationshipMappings.set(relationshipType, relationshipConfig);\n relationshipCount++;\n }\n }\n }\n\n this.registeredModules.add(moduleName);\n logger.info(\n `[GraphRegistry] ✅ Registered ${moduleName}: ${entityCount} entities, ${relationshipCount} relationships`\n );\n }\n\n /**\n * Get entity configuration by entity type\n * @param entityType - Entity type name (e.g., 'Calendar', 'Group')\n * @returns Entity configuration or undefined (with resolved fields)\n */\n static getEntityConfig(entityType: string): ResolvedEntityGraphConfig | undefined {\n return this.entityMappings.get(entityType);\n }\n\n /**\n * Get relationship configuration by relationship type\n * @param relationshipType - Relationship type name (e.g., 'EventAttendee', 'GroupMembership')\n * @returns Relationship configuration or undefined\n */\n static getRelationshipConfig(relationshipType: string): RelationshipGraphConfig | undefined {\n return this.relationshipMappings.get(relationshipType);\n }\n\n /**\n * Get all registered entity types\n * @returns Array of entity type names\n */\n static getAllEntityTypes(): string[] {\n return Array.from(this.entityMappings.keys());\n }\n\n /**\n * Get all registered relationship types\n * @returns Array of relationship type names\n */\n static getAllRelationshipTypes(): string[] {\n return Array.from(this.relationshipMappings.keys());\n }\n\n /**\n * Get all registered module names\n * @returns Array of module names\n */\n static getRegisteredModules(): string[] {\n return Array.from(this.registeredModules);\n }\n\n /**\n * Check if an entity type is registered\n * @param entityType - Entity type to check\n * @returns True if registered\n */\n static isEntityRegistered(entityType: string): boolean {\n return this.entityMappings.has(entityType);\n }\n\n /**\n * Check if a relationship type is registered\n * @param relationshipType - Relationship type to check\n * @returns True if registered\n */\n static isRelationshipRegistered(relationshipType: string): boolean {\n return this.relationshipMappings.has(relationshipType);\n }\n\n /**\n * Extract organization ID from entity data using configured mapping function\n * @param entityType - Entity type name\n * @param data - Entity data record\n * @returns Organization ID or undefined\n */\n static getOrganizationId(entityType: string, data: Record<string, unknown>): string | undefined {\n const config = this.entityMappings.get(entityType);\n if (!config || !config.getOrgId) {\n return undefined;\n }\n return config.getOrgId(data);\n }\n\n /**\n * Extract workspace ID from entity data using configured mapping function\n * @param entityType - Entity type name\n * @param data - Entity data record\n * @returns Workspace ID or undefined\n */\n static getWorkspaceId(entityType: string, data: Record<string, unknown>): string | undefined {\n const config = this.entityMappings.get(entityType);\n if (!config || !config.getWorkspaceId) {\n return undefined;\n }\n return config.getWorkspaceId(data);\n }\n\n /**\n * Get RBAC configuration for an entity type\n * Used by the Prisma graph extension to include RBAC metadata in entity events\n * @param entityType - Entity type name (e.g., 'Conversation', 'Agent')\n * @returns RBAC config or undefined if no RBAC is configured for this entity\n */\n static getRbacConfig(entityType: string): RegistryEntityRbacConfig | undefined {\n const config = this.entityMappings.get(entityType);\n return config?.rbac;\n }\n\n /**\n * Resolve RBAC event metadata from entity data\n * Converts the registry's function-based RBAC config into the flat metadata\n * structure expected by the RBAC consumer in the NATS event payload.\n * @param entityType - Entity type name\n * @param entityData - The entity data record\n * @returns RBAC metadata for the event or undefined\n */\n static resolveRbacMetadata(\n entityType: string,\n entityData: Record<string, unknown>\n ):\n | {\n resourceTypeName: string;\n name?: string;\n identifier?: string;\n parentResourceIdentifier?: string;\n createResource?: boolean;\n }\n | undefined {\n const rbacConfig = this.getRbacConfig(entityType);\n if (!rbacConfig) {\n return undefined;\n }\n\n const name = rbacConfig.extractName ? rbacConfig.extractName(entityData) : undefined;\n const identifier = rbacConfig.extractIdentifier ? rbacConfig.extractIdentifier(entityData) : undefined;\n const parentResourceIdentifier = rbacConfig.parentResourceField\n ? (entityData[rbacConfig.parentResourceField] as string | undefined)\n : undefined;\n\n return {\n resourceTypeName: rbacConfig.resourceTypeName,\n ...(name && { name }),\n ...(identifier && { identifier }),\n ...(parentResourceIdentifier && { parentResourceIdentifier }),\n ...(rbacConfig.createResource !== undefined && { createResource: rbacConfig.createResource }),\n };\n }\n\n /**\n * Get statistics about registered configurations\n * @returns Statistics object\n */\n static getStats(): {\n modules: number;\n entities: number;\n relationships: number;\n collections: Set<string>;\n edgeTypes: Set<string>;\n } {\n const collections = new Set<string>();\n const edgeTypes = new Set<string>();\n\n for (const config of this.entityMappings.values()) {\n collections.add(config.collection || 'product_entities');\n }\n\n for (const config of this.relationshipMappings.values()) {\n if (config.label) {\n edgeTypes.add(config.label);\n }\n }\n\n return {\n modules: this.registeredModules.size,\n entities: this.entityMappings.size,\n relationships: this.relationshipMappings.size,\n collections,\n edgeTypes,\n };\n }\n\n /**\n * Clear all registrations (for testing)\n */\n static clear(): void {\n this.entityMappings.clear();\n this.relationshipMappings.clear();\n this.registeredModules.clear();\n logger.info('[GraphRegistry] Cleared all registrations');\n }\n\n /**\n * Get all relationships where the given entity type is the \"from\" side\n * This is used for automatic relationship event emission when entities are created/updated\n * @param entityType - Entity type name (e.g., 'UniversalTag')\n * @returns Array of [relationshipKey, config] tuples\n */\n static getRelationshipsForEntity(entityType: string): Array<[string, RelationshipGraphConfig]> {\n const result: Array<[string, RelationshipGraphConfig]> = [];\n\n for (const [key, config] of this.relationshipMappings.entries()) {\n if (config.from === entityType) {\n result.push([key, config]);\n }\n }\n\n return result;\n }\n\n /**\n * Print registry status to console\n */\n static printStatus(): void {\n const stats = this.getStats();\n logger.info('');\n logger.info('📊 Graph Registry Status');\n logger.info('========================');\n logger.info(`Registered Modules: ${stats.modules}`);\n logger.info(`Total Entities: ${stats.entities}`);\n logger.info(`Total Relationships: ${stats.relationships}`);\n logger.info(`Vertex Collections: ${stats.collections.size}`);\n logger.info(`Edge Types: ${stats.edgeTypes.size}`);\n logger.info('');\n logger.info('Registered Modules:', this.getRegisteredModules().join(', '));\n logger.info('');\n }\n}\n","/**\n * Event Helpers - Registry-Based Graph Event Utilities\n *\n * This version uses the GraphRegistry to dynamically load entity and relationship\n * configurations from module-level graph.config.ts files.\n *\n * @module graph-helpers\n * @category Graph\n */\nimport { logger } from '../../logger/index.js';\nimport type { GraphEvent, GraphEventType } from '../types.js';\nimport { GraphRegistry } from './registry.js';\n\nconst uuidv4 = (): string => crypto.randomUUID();\n\n/**\n * Create an entity event for the graph\n */\nexport function createEntityEvent(\n eventType: GraphEventType,\n organizationId: string,\n entity: {\n id: string;\n type: string;\n data: Record<string, unknown>;\n },\n metadata?: {\n userId?: string;\n correlationId?: string;\n workspaceId?: string;\n projectId?: string;\n },\n productSource?: string\n): GraphEvent {\n return {\n eventId: `evt_${uuidv4()}`,\n eventType,\n organizationId,\n productSource: productSource || process.env['PRODUCT_SOURCE'] || 'default',\n timestamp: new Date().toISOString(),\n entity,\n metadata: {\n userId: metadata?.userId,\n correlationId: metadata?.correlationId || `req_${uuidv4()}`,\n },\n };\n}\n\n/**\n * Create a relationship event for the graph\n */\nexport function createRelationshipEvent(\n eventType: GraphEventType,\n organizationId: string,\n relationship: {\n from: { id: string; type: string };\n to: { id: string; type: string };\n type: string;\n metadata: Record<string, unknown>;\n },\n metadata?: {\n userId?: string;\n correlationId?: string;\n },\n productSource?: string\n): GraphEvent {\n return {\n eventId: `evt_${uuidv4()}`,\n eventType,\n organizationId,\n productSource: productSource || process.env['PRODUCT_SOURCE'] || 'default',\n timestamp: new Date().toISOString(),\n entity: {\n id: `${relationship.from.id}_${relationship.to.id}`,\n type: relationship.type,\n data: {},\n },\n relationship,\n metadata: {\n userId: metadata?.userId,\n correlationId: metadata?.correlationId || `req_${uuidv4()}`,\n },\n };\n}\n\n/**\n * Extract minimal fields for syncing to graph (uses registry)\n *\n * @param modelName - Prisma model name (e.g., 'Calendar', 'Group')\n * @param entity - Full entity data from Prisma\n * @returns Minimal entity data for graph sync\n */\nexport function extractMinimalFields(modelName: string, entity: Record<string, unknown>): Record<string, unknown> {\n // Get entity config from registry\n const config = GraphRegistry.getEntityConfig(modelName);\n\n if (!config) {\n // Fallback: if entity not registered, just use id and workspaceID\n logger.warn(`[GraphHelpers] No graph config found for entity type: ${modelName}, using fallback`);\n const minimal: Record<string, unknown> = {};\n\n if (entity['id']) minimal['id'] = entity['id'];\n if (entity['workspaceID']) minimal['workspaceID'] = entity['workspaceID'];\n if (entity['workspaceId']) minimal['workspaceId'] = entity['workspaceId'];\n\n return minimal;\n }\n\n // Extract configured fields\n const minimal: Record<string, unknown> = {};\n\n for (const field of config.fields) {\n if (entity[field] !== undefined) {\n minimal[field] = entity[field];\n }\n }\n\n return minimal;\n}\n\n/**\n * Parse relationship from join table models (uses registry)\n *\n * @param modelName - Relationship model name (e.g., 'EventAttendee', 'GroupMembership')\n * @param relationship - Full relationship data from Prisma\n * @returns Parsed relationship with from/to/type/metadata\n */\nexport function parseRelationship(\n modelName: string,\n relationship: Record<string, unknown>\n): {\n from: { id: string; type: string };\n to: { id: string; type: string };\n relationshipType: string;\n metadata: Record<string, unknown>;\n} {\n // Get relationship config from registry\n const config = GraphRegistry.getRelationshipConfig(modelName);\n\n if (!config) {\n logger.warn(`[GraphHelpers] No graph config found for relationship type: ${modelName}, using fallback`);\n return {\n from: { id: 'unknown', type: 'Unknown' },\n to: { id: 'unknown', type: 'Unknown' },\n relationshipType: 'relates_to',\n metadata: {},\n };\n }\n\n // Extract relationship data using config\n return {\n from: {\n id: String(relationship[config.fromField] || 'unknown'),\n type: config.from,\n },\n to: {\n id: String(relationship[config.to] || 'unknown'),\n type: config.to,\n },\n relationshipType: config.label || 'relates_to',\n metadata: config.extractMetadata?.(relationship) ?? {},\n };\n}\n\n/**\n * Get the graph vertex label for an entity type (uses registry)\n *\n * @param entityType - Entity type name\n * @returns Collection name\n */\nexport function getCollectionForEntity(entityType: string): string {\n const config = GraphRegistry.getEntityConfig(entityType);\n\n if (!config) {\n // Default to product_entities if not registered\n return 'entity';\n }\n\n return config.collection || 'entity';\n}\n\n/**\n * Extract title from entity (uses registry or fallback)\n *\n * @param entityType - Entity type name\n * @param entity - Entity data\n * @returns Title string\n */\nexport function extractEntityTitle(entityType: string, entity: Record<string, unknown>): string {\n const config = GraphRegistry.getEntityConfig(entityType);\n\n // Use custom title extractor if provided\n if (config?.extractTitle) {\n return config.extractTitle(entity);\n }\n\n // Fallback: try common title fields\n return String(entity['name'] || entity['title'] || entity['email'] || entity['id'] || 'Untitled');\n}\n\n/**\n * Check if an entity type should be synced to the graph\n *\n * @param entityType - Entity type name\n * @returns True if entity should be synced\n */\nexport function shouldSyncEntity(entityType: string): boolean {\n const config = GraphRegistry.getEntityConfig(entityType);\n\n if (!config) {\n // If not registered, don't sync\n return false;\n }\n\n // Check if explicitly disabled\n return config.enabled !== false;\n}\n\n/**\n * Check if a relationship type should be synced to the graph\n *\n * @param relationshipType - Relationship type name\n * @returns True if relationship should be synced\n */\nexport function shouldSyncRelationship(relationshipType: string): boolean {\n const config = GraphRegistry.getRelationshipConfig(relationshipType);\n\n if (!config) {\n // If not registered, don't sync\n return false;\n }\n\n // Check if explicitly disabled\n return config.enabled !== false;\n}\n","/**\n * Prisma 7 Client Factory with PostgreSQL Adapter\n *\n * This module provides a generic factory for creating Prisma clients\n * configured with the PostgreSQL driver adapter as required by Prisma 7.\n *\n * Breaking Changes in Prisma 7:\n * - Must use database driver adapter (@prisma/adapter-pg for PostgreSQL)\n * - Datasource URL moved from schema.prisma to prisma.config.ts\n * - DMMF no longer available at runtime (use generator for build-time access)\n *\n * @module prisma/client\n */\n\nimport { PrismaPg } from '@prisma/adapter-pg';\nimport { Pool, type PoolConfig } from 'pg';\nimport { logger } from '../logger/index.js';\nimport type { PrismaClientConfig, ConnectionState } from './types.js';\n\n/**\n * Prisma event object types\n */\nexport interface PrismaQueryEvent {\n query: string;\n params: string;\n duration: number;\n target?: string;\n}\n\nexport interface PrismaLogEvent {\n message: string;\n target?: string;\n}\n\nexport type PrismaEvent = PrismaQueryEvent | PrismaLogEvent;\n\n/**\n * Transaction options for Prisma $transaction method\n */\nexport interface PrismaTransactionOptions {\n maxWait?: number;\n timeout?: number;\n isolationLevel?: string;\n}\n\n/**\n * Base Prisma client interface with required methods\n *\n * This interface defines the MINIMUM contract required for server bootstrapping.\n * It only includes methods actually used by the SDK's server module.\n *\n * Note: Service-specific model properties (e.g., universalTag, user, workspace, etc.)\n * and full method signatures should be accessed by casting to the service's\n * generated Prisma client type.\n *\n * @example\n * ```typescript\n * // In your service's context type:\n * import type { PrismaClient } from './generated/prisma/client.js';\n * import type { GraphQLContext } from '@burdenoff/be-sdk';\n *\n * export interface Context extends GraphQLContext {\n * db: PrismaClient;\n * }\n * ```\n */\nexport interface PrismaClientBase {\n /** Connect to the database */\n $connect(): Promise<void>;\n /** Disconnect from the database */\n $disconnect(): Promise<void>;\n /** Register event handlers for logging */\n $on(event: string, callback: (e: PrismaEvent) => void): void;\n /** Execute a raw SQL query */\n $queryRaw<T = unknown>(query: TemplateStringsArray, ...values: unknown[]): Promise<T>;\n}\n\n/**\n * Database client return type for getDb()\n *\n * Returns the service's PrismaClient type (T) with a `client` property\n * for backwards compatibility. All model access and typing comes from\n * the service's own generated Prisma types.\n *\n * @example\n * ```typescript\n * // In your service - import YOUR generated PrismaClient\n * import { PrismaClient } from './generated/prisma/client.js';\n * import { getDb } from '@burdenoff/be-sdk/prisma';\n *\n * // Pass your PrismaClient type for full type safety\n * const db = getDb<PrismaClient>();\n * const tags = await db.client.universalTag.findMany(); // Fully typed!\n * ```\n */\nexport type DatabaseReturnType<T extends PrismaClientBase = PrismaClientBase> = T & {\n /**\n * Client property for explicit model access.\n * This is the same as the db object itself, provided for API consistency.\n */\n client: T;\n};\n\n/**\n * Create a PostgreSQL connection pool.\n *\n * The base pool sizing (max / idle / connection timeout) is unchanged. The\n * optional tuning fields (`applicationName`, `statementTimeoutMillis`,\n * `idleInTransactionTimeoutMillis`, `lockTimeoutMillis`) are only attached to\n * the pool config when explicitly provided — when they are all unset, the\n * resulting pool is byte-for-byte identical to the previous behavior. This keeps\n * the change safe to roll out fleet-wide: `application_name` is pure diagnostic\n * metadata, and every DB-enforced timeout defaults to OFF (pg default).\n */\nexport function createConnectionPool(config: PrismaClientConfig): Pool {\n const poolConfig: PoolConfig = {\n connectionString: config.databaseUrl,\n max: config.maxConnections ?? 20,\n idleTimeoutMillis: config.idleTimeoutMillis ?? 30000,\n connectionTimeoutMillis: config.connectionTimeoutMillis ?? 10000,\n };\n\n // Diagnostic metadata only — no effect on query behavior.\n if (config.applicationName) {\n poolConfig.application_name = config.applicationName;\n }\n\n // DB-enforced safety timeouts — only applied when explicitly opted in, so the\n // default (unset) preserves the current no-server-timeout behavior exactly.\n if (config.statementTimeoutMillis != null && config.statementTimeoutMillis > 0) {\n poolConfig.statement_timeout = config.statementTimeoutMillis;\n }\n if (config.idleInTransactionTimeoutMillis != null && config.idleInTransactionTimeoutMillis > 0) {\n poolConfig.idle_in_transaction_session_timeout = config.idleInTransactionTimeoutMillis;\n }\n if (config.lockTimeoutMillis != null && config.lockTimeoutMillis > 0) {\n poolConfig.lock_timeout = config.lockTimeoutMillis;\n }\n\n return new Pool(poolConfig);\n}\n\n/**\n * Ensure a per-service Postgres `application_name` is set process-wide.\n *\n * node-postgres reads the libpq `PGAPPNAME` environment variable as the\n * `application_name` fallback for every Client/Pool it creates. Setting it here\n * guarantees per-service attribution in pg_stat_activity / pg_stat_statements for\n * ALL pools a service opens — including pools a service constructs itself (e.g.\n * via `createPrismaGraphIntegration`'s `createPrismaClient` closure) that bypass\n * `createConnectionPool`.\n *\n * Behavior-preserving: this is pure diagnostic metadata, it is only applied when\n * `PGAPPNAME` is not already set (so an explicit operator/env value wins), and an\n * explicit `application_name` in a pool config still takes precedence over the\n * env fallback.\n */\nexport function ensureServiceApplicationName(productName: string | undefined): void {\n if (productName && !process.env['PGAPPNAME']) {\n process.env['PGAPPNAME'] = `svc=${productName}`;\n }\n}\n\n/**\n * Create a Prisma PostgreSQL adapter\n */\nexport function createPrismaAdapter(pool: Pool): PrismaPg {\n return new PrismaPg(pool);\n}\n\n/**\n * Configure Prisma client logging\n */\nexport function configurePrismaLogging<T extends PrismaClientBase>(client: T, config: PrismaClientConfig): T {\n const isDevelopment = process.env['NODE_ENV'] === 'development';\n const slowQueryThreshold = config.slowQueryThreshold ?? (isDevelopment ? 100 : 500);\n\n // Query logging\n if (config.enableQueryLogging ?? isDevelopment) {\n client.$on('query', (e: PrismaEvent) => {\n if ('query' in e && 'duration' in e) {\n if (e.duration > slowQueryThreshold) {\n logger.warn('[Prisma] Slow query detected', {\n query: e.query.substring(0, 200) + (e.query.length > 200 ? '...' : ''),\n params: e.params,\n duration: `${e.duration}ms`,\n });\n } else {\n logger.debug('[Prisma] Query', {\n query: e.query.substring(0, 100) + (e.query.length > 100 ? '...' : ''),\n duration: `${e.duration}ms`,\n });\n }\n }\n });\n }\n\n // Error logging\n client.$on('error', (e: PrismaEvent) => {\n if ('message' in e) {\n logger.error('[Prisma] Database error', {\n message: e.message,\n target: e.target,\n });\n }\n });\n\n // Warning logging\n client.$on('warn', (e: PrismaEvent) => {\n if ('message' in e) {\n logger.warn('[Prisma] Database warning', {\n message: e.message,\n target: e.target,\n });\n }\n });\n\n return client;\n}\n\n/**\n * Prisma Client Wrapper with connection management\n */\nexport class PrismaClientWrapper<T extends PrismaClientBase> {\n private client: T;\n private pool: Pool;\n private connectionState: ConnectionState = {\n isConnected: false,\n attempts: 0,\n };\n private isDisconnecting = false;\n\n constructor(client: T, pool: Pool, config: PrismaClientConfig) {\n this.client = client;\n this.pool = pool;\n\n // Configure logging\n configurePrismaLogging(this.client, config);\n }\n\n /**\n * Get the Prisma client instance\n */\n public getClient(): T {\n return this.client;\n }\n\n /**\n * Get the connection pool\n */\n public getPool(): Pool {\n return this.pool;\n }\n\n /**\n * Get connection state\n */\n public getConnectionState(): ConnectionState {\n return { ...this.connectionState };\n }\n\n /**\n * Connect to database with retry logic\n */\n public async connect(retries = 5, delay = 1000): Promise<void> {\n if (this.connectionState.isConnected) {\n logger.info('[Prisma] Already connected to database');\n return;\n }\n\n for (let attempt = 1; attempt <= retries; attempt++) {\n this.connectionState.attempts = attempt;\n\n try {\n await this.client.$connect();\n this.connectionState.isConnected = true;\n this.connectionState.lastConnectedAt = new Date();\n this.connectionState.lastError = undefined;\n\n logger.info('[Prisma] Successfully connected to database');\n return;\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n this.connectionState.lastError = errorMessage;\n\n logger.error(`[Prisma] Connection attempt ${attempt}/${retries} failed`, {\n error: errorMessage,\n });\n\n if (attempt === retries) {\n logger.error('[Prisma] Max connection retries reached');\n throw error;\n }\n\n // Exponential backoff\n const waitTime = delay * Math.pow(2, attempt - 1);\n logger.info(`[Prisma] Retrying in ${waitTime}ms...`);\n await new Promise((resolve) => setTimeout(resolve, waitTime));\n }\n }\n }\n\n /**\n * Gracefully disconnect from database\n */\n public async disconnect(): Promise<void> {\n // Guard against multiple disconnect calls\n if (this.isDisconnecting) {\n logger.debug('[Prisma] Disconnect already in progress, skipping');\n return;\n }\n\n if (!this.connectionState.isConnected) {\n logger.info('[Prisma] Database already disconnected');\n return;\n }\n\n // Mark as disconnecting to prevent concurrent disconnect calls\n this.isDisconnecting = true;\n\n try {\n await this.client.$disconnect();\n await this.pool.end();\n this.connectionState.isConnected = false;\n\n logger.info('[Prisma] Successfully disconnected from database');\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n\n // Ignore \"Called end on pool more than once\" errors\n if (errorMessage.includes('Called end on pool more than once')) {\n logger.debug('[Prisma] Pool already ended, ignoring duplicate end call');\n this.connectionState.isConnected = false;\n return;\n }\n\n logger.error('[Prisma] Error disconnecting from database', {\n error: errorMessage,\n });\n throw error;\n } finally {\n this.isDisconnecting = false;\n }\n }\n\n /**\n * Register graceful shutdown handlers\n */\n public registerShutdownHandlers(): void {\n const shutdownHandler = async (signal: string): Promise<void> => {\n logger.info(`[Prisma] Received ${signal}, starting graceful shutdown...`);\n\n try {\n await this.disconnect();\n process.exit(0);\n } catch (error) {\n logger.error('[Prisma] Error during graceful shutdown', {\n error: error instanceof Error ? error.message : String(error),\n });\n process.exit(1);\n }\n };\n\n // Register shutdown handlers\n process.on('SIGINT', () => void shutdownHandler('SIGINT'));\n process.on('SIGTERM', () => void shutdownHandler('SIGTERM'));\n process.on('beforeExit', () => void this.disconnect());\n }\n}\n\n/**\n * Create a configured Prisma client wrapper\n *\n * @example\n * ```typescript\n * import { PrismaClient } from './generated/prisma/client.js';\n * import { createPrismaClient } from '@burdenoff/be-sdk';\n *\n * const wrapper = createPrismaClient(PrismaClient, {\n * databaseUrl: process.env.DATABASE_URL!,\n * });\n *\n * await wrapper.connect();\n * const prisma = wrapper.getClient();\n *\n * // Use prisma client\n * const users = await prisma.user.findMany();\n * ```\n */\n/**\n * Prisma log level options\n */\nexport type PrismaLogLevel = 'info' | 'query' | 'warn' | 'error';\n\n/**\n * Prisma log definition\n */\nexport interface PrismaLogDefinition {\n level: PrismaLogLevel;\n emit: 'stdout' | 'event';\n}\n\n/**\n * Prisma client constructor options\n */\nexport interface PrismaClientConstructorOptions {\n adapter: PrismaPg;\n log?: (PrismaLogLevel | PrismaLogDefinition)[];\n}\n\nexport function createPrismaClient<T extends PrismaClientBase>(\n PrismaClientConstructor: new (options: PrismaClientConstructorOptions) => T,\n config: PrismaClientConfig\n): PrismaClientWrapper<T> {\n const isDevelopment = process.env['NODE_ENV'] === 'development';\n\n // Create connection pool\n const pool = createConnectionPool(config);\n\n // Create adapter\n const adapter = createPrismaAdapter(pool);\n\n // Determine log levels\n const logLevels: PrismaLogDefinition[] =\n (config.logLevels as PrismaLogDefinition[] | undefined) ??\n (isDevelopment\n ? [\n { emit: 'event', level: 'query' },\n { emit: 'event', level: 'info' },\n { emit: 'event', level: 'warn' },\n { emit: 'event', level: 'error' },\n ]\n : [\n { emit: 'event', level: 'warn' },\n { emit: 'event', level: 'error' },\n ]);\n\n // Create Prisma client\n const client = new PrismaClientConstructor({\n adapter,\n log: logLevels,\n });\n\n // Create and return wrapper\n return new PrismaClientWrapper(client, pool, config);\n}\n","/**\n * Prisma Middleware for Graph Event Emission\n *\n * Automatically emits events to the graph event queue when entities are\n * created, updated, or deleted in PostgreSQL.\n *\n * This is a product-agnostic Prisma extension that can be used by any Burdenoff product.\n *\n * @module prisma-graph-extension\n * @category Graph\n */\nimport { logger } from '../../logger/index.js';\nimport { extractMinimalFields } from '../utils/helpers.js';\nimport { GraphRegistry } from '../utils/registry.js';\n\n/**\n * Event types for entity operations\n */\nexport type EntityEventType =\n | 'entity.created'\n | 'entity.updated'\n | 'entity.deleted'\n | 'relationship.created'\n | 'relationship.deleted';\n\n/**\n * RBAC metadata for entity events (resolved from graph config)\n */\nexport interface EntityEventRbacMetadata {\n resourceTypeName: string;\n name?: string;\n identifier?: string;\n parentResourceIdentifier?: string;\n createResource?: boolean;\n}\n\n/**\n * Event emitter interface - products must provide their own implementation\n */\nexport interface GraphEventEmitter {\n publishEntityEvent(\n eventType: EntityEventType,\n entity: {\n id: string;\n type: string;\n data: Record<string, unknown>;\n },\n context: {\n productName: string;\n organizationId: string;\n actorId?: string;\n workspaceId?: string;\n },\n rbac?: EntityEventRbacMetadata\n ): Promise<void>;\n}\n\n/**\n * Configuration for graph middleware\n */\nexport interface GraphMiddlewareConfig {\n /** Whether middleware is enabled */\n enabled: boolean;\n /** Product name for event metadata */\n productName: string;\n /** Event emitter implementation */\n eventEmitter: GraphEventEmitter;\n /** Entity types to monitor (if empty, monitors all registered types) */\n entityTypes?: string[];\n /** Operations to monitor */\n monitoredOperations?: Array<'create' | 'update' | 'delete' | 'deleteMany' | 'updateMany'>;\n}\n\n/**\n * Default configuration\n */\nconst defaultConfig: {\n enabled: boolean;\n monitoredOperations: Array<'create' | 'update' | 'delete' | 'deleteMany' | 'updateMany'>;\n} = {\n enabled: true,\n monitoredOperations: ['create', 'update', 'delete', 'deleteMany', 'updateMany'],\n};\n\n/**\n * Extract entity information from Prisma result\n */\nfunction extractEntityInfo(\n model: string,\n result: unknown\n): { id: string; type: string; data: Record<string, unknown> } | null {\n if (!result || typeof result !== 'object') {\n return null;\n }\n\n const record = result as Record<string, unknown>;\n const id = record['id'] as string;\n\n if (!id) {\n return null;\n }\n\n return {\n id,\n type: model,\n data: record,\n };\n}\n\n/**\n * Extract organization and user context from Prisma arguments\n */\nfunction extractContext(args: unknown): {\n organizationId?: string;\n actorId?: string;\n workspaceId?: string;\n} {\n if (!args || typeof args !== 'object') {\n return {};\n }\n\n const data =\n (args as { data?: Record<string, unknown>; where?: Record<string, unknown> })['data'] ||\n (args as { where?: Record<string, unknown> })['where'];\n\n if (!data || typeof data !== 'object') {\n return {};\n }\n\n return {\n organizationId: data['organizationId'] as string | undefined,\n actorId:\n (data['actorId'] as string | undefined) ||\n (data['createdBy'] as string | undefined) ||\n (data['updatedBy'] as string | undefined) ||\n (data['userId'] as string | undefined),\n workspaceId: (data['workspaceId'] as string | undefined) || (data['workspaceID'] as string | undefined),\n };\n}\n\n/**\n * Emit event for entity operation\n */\nfunction emitEntityEvent(\n eventType: EntityEventType,\n model: string,\n result: unknown,\n args: unknown,\n config: GraphMiddlewareConfig\n): void {\n const entityInfo = extractEntityInfo(model, result);\n if (!entityInfo) {\n return;\n }\n\n // Check if this entity type is registered in the graph registry\n if (!GraphRegistry.isEntityRegistered(model)) {\n return;\n }\n\n // Check if we should monitor this entity type\n if (config.entityTypes && config.entityTypes.length > 0 && !config.entityTypes.includes(model)) {\n return;\n }\n\n const context = extractContext(args);\n const minimalData = extractMinimalFields(model, entityInfo.data);\n\n // Use GraphRegistry to extract organization and workspace IDs from entity data\n // This allows entity-specific field mappings (e.g., tenantId → organizationId)\n const orgId = GraphRegistry.getOrganizationId(model, entityInfo.data) || context.organizationId || 'unknown';\n const workspaceId = GraphRegistry.getWorkspaceId(model, entityInfo.data) || context.workspaceId;\n const actorId = context.actorId || 'unknown';\n\n // Resolve RBAC metadata from GraphRegistry (if entity has rbac config)\n const rbacMetadata = GraphRegistry.resolveRbacMetadata(model, entityInfo.data);\n\n if (rbacMetadata) {\n logger.debug(`[GraphMiddleware] Including RBAC metadata for ${model}`, {\n resourceTypeName: rbacMetadata.resourceTypeName,\n hasName: !!rbacMetadata.name,\n });\n }\n\n // Emit event (non-blocking) — includes RBAC metadata when configured\n config.eventEmitter\n .publishEntityEvent(\n eventType,\n {\n id: entityInfo.id,\n type: entityInfo.type,\n data: minimalData,\n },\n {\n productName: config.productName,\n organizationId: orgId,\n actorId,\n workspaceId,\n },\n rbacMetadata\n )\n .catch((error: unknown) => {\n logger.error('[GraphMiddleware] Failed to emit event:', error);\n });\n\n // After emitting entity event, check for relationship events\n // Only for create/update operations\n if (eventType === 'entity.created' || eventType === 'entity.updated') {\n emitRelationshipEvents(model, entityInfo.data, orgId, config);\n }\n}\n\n/**\n * Emit relationship events based on foreign key values\n * This automatically creates edges in the graph when entities with foreign keys are created/updated\n */\nfunction emitRelationshipEvents(\n entityType: string,\n entityData: Record<string, unknown>,\n organizationId: string,\n config: GraphMiddlewareConfig\n): void {\n // Get all relationships where this entity type is the \"from\" side\n const relationships = GraphRegistry.getRelationshipsForEntity(entityType);\n\n if (relationships.length === 0) {\n return;\n }\n\n const fromId = entityData['id'] as string;\n if (!fromId) {\n return;\n }\n\n // For each relationship, check if the foreign key field has a value\n for (const [relationshipKey, relationshipConfig] of relationships) {\n const foreignKeyValue = entityData[relationshipConfig.fromField] as string | null | undefined;\n\n // Skip if foreign key is null/undefined (no relationship)\n if (!foreignKeyValue) {\n continue;\n }\n\n // Handle polymorphic relationships\n let targetType = relationshipConfig.to;\n if (relationshipConfig.to === '*') {\n if (relationshipConfig.polymorphicTypeField) {\n targetType = entityData[relationshipConfig.polymorphicTypeField] as string;\n if (!targetType) {\n logger.warn(`[GraphMiddleware] Polymorphic relationship ${relationshipKey} has no type field value`);\n continue;\n }\n } else {\n logger.debug(`[GraphMiddleware] Skipping polymorphic relationship without type field: ${relationshipKey}`);\n continue;\n }\n }\n\n // Extract metadata if configured\n const metadata = relationshipConfig.extractMetadata\n ? relationshipConfig.extractMetadata(entityData)\n : { description: relationshipConfig.description };\n\n // Emit relationship.created event\n config.eventEmitter\n .publishEntityEvent(\n 'relationship.created',\n {\n id: `${fromId}_${foreignKeyValue}`,\n type: relationshipConfig.label,\n data: {\n from: {\n id: fromId,\n type: entityType,\n },\n to: {\n id: foreignKeyValue,\n type: targetType,\n },\n relationType: relationshipConfig.label,\n metadata,\n },\n },\n {\n productName: config.productName,\n organizationId,\n }\n )\n .catch((error: unknown) => {\n logger.error(`[GraphMiddleware] Failed to emit relationship event for ${relationshipKey}:`, error);\n });\n\n logger.debug(\n `[GraphMiddleware] Emitted relationship.created: ${relationshipConfig.label} (${entityType}:${fromId} -> ${targetType}:${foreignKeyValue})`\n );\n }\n}\n\n/**\n * Add graph extension to Prisma client for automatic event emission\n *\n * This function uses Prisma Client Extensions (Prisma 6+) to intercept\n * database operations and emit events to the graph event queue.\n *\n * @param baseClient - Base Prisma client instance\n * @param config - Configuration for the middleware\n * @returns Extended Prisma client with graph event emission\n *\n * @example\n * ```typescript\n * import { PrismaClient } from '@prisma/client';\n * import { addGraphExtension } from '@burdenoff/be-sdk/graph';\n * import { eventQueue } from './event-queue';\n *\n * const baseClient = new PrismaClient();\n * const client = addGraphExtension(baseClient, {\n * enabled: true,\n * productName: 'workspaces',\n * eventEmitter: eventQueue,\n * entityTypes: ['Project', 'Group', 'Workspace'], // Optional: monitor specific types\n * });\n * ```\n */\nexport function addGraphExtension<T>(baseClient: T, config: GraphMiddlewareConfig): T {\n const fullConfig = { ...defaultConfig, ...config };\n\n if (!fullConfig.enabled) {\n logger.info('[GraphMiddleware] Extension disabled by configuration');\n return baseClient;\n }\n\n // Type assertion for Prisma client\n const prismaClient = baseClient as { $extends: (args: unknown) => T };\n\n return prismaClient.$extends({\n query: {\n $allModels: {\n async create({\n model,\n args,\n query,\n }: {\n model: string;\n args: unknown;\n query: (args: unknown) => Promise<unknown>;\n }) {\n const result = await query(args);\n\n if (fullConfig.monitoredOperations?.includes('create')) {\n emitEntityEvent('entity.created', model, result, args, fullConfig);\n }\n\n return result;\n },\n\n async update({\n model,\n args,\n query,\n }: {\n model: string;\n args: unknown;\n query: (args: unknown) => Promise<unknown>;\n }) {\n const result = await query(args);\n\n if (fullConfig.monitoredOperations?.includes('update')) {\n emitEntityEvent('entity.updated', model, result, args, fullConfig);\n }\n\n return result;\n },\n\n async delete({\n model,\n args,\n query,\n }: {\n model: string;\n args: unknown;\n query: (args: unknown) => Promise<unknown>;\n }) {\n const result = await query(args);\n\n if (fullConfig.monitoredOperations?.includes('delete')) {\n emitEntityEvent('entity.deleted', model, result, args, fullConfig);\n }\n\n return result;\n },\n\n async updateMany({\n model,\n args,\n query,\n }: {\n model: string;\n args: unknown;\n query: (args: unknown) => Promise<unknown>;\n }) {\n const result = await query(args);\n\n if (fullConfig.monitoredOperations?.includes('updateMany')) {\n logger.info(`[GraphMiddleware] updateMany for ${model} (bulk operation not tracked individually)`);\n }\n\n return result;\n },\n\n async deleteMany({\n model,\n args,\n query,\n }: {\n model: string;\n args: unknown;\n query: (args: unknown) => Promise<unknown>;\n }) {\n const result = await query(args);\n\n if (fullConfig.monitoredOperations?.includes('deleteMany')) {\n logger.info(`[GraphMiddleware] deleteMany for ${model} (bulk operation not tracked individually)`);\n }\n\n return result;\n },\n },\n },\n });\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/layer/index.ts"],"names":["LayerManager","config","gatewayConfig","resourceConfig","routingConfig","serviceIdentity","serviceName","DEFAULT_GATEWAY_ROUTING","layer","resolveGatewayConfig","resolveResourceConfig","logger","debug","envPrefix","toUpperCase","internalGatewayUrl","process","env","internalGateway","host","port","graphqlPath","crossLayerEnvPrefix","crossLayerGatewayUrl","crossLayerGateway","defaults","DEFAULT_LAYER_RESOURCES","eventQueueUrl","valkeyUrl","temporalAddress","temporalNamespace","rbacGatewayUrl","getLayer","getServiceName","getServiceIdentity","getInternalGatewayUrl","getCrossLayerGatewayUrl","getEventQueueUrl","getValkeyUrl","getTemporalAddress","getTemporalNamespace","getRbacGatewayUrl","getDefaultStreams","DEFAULT_LAYER_STREAMS","getFullConfig","gateways","resources","isWspaceLayer","isGlobalLayer","getOppositeLayer","createLayerManagerFromEnv","Error","detectLayerFromServiceName","startsWith","undefined","getGatewayUrlForLayer","sourceLayer","targetLayer","sourceManager","routing","validateLayerConfig","expectedPrefix","warn"],"mappings":"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","file":"chunk-UIMPJNWC.js","sourcesContent":["/**\n * Layer Detection and Configuration Module\n *\n * Provides layer-aware configuration and gateway URL resolution\n * for wspace (workspace) and global (tenant) service layers.\n *\n * @module layer\n * @category Configuration\n *\n * @example\n * ```typescript\n * import { LayerManager } from '@burdenoff/be-sdk/layer';\n *\n * // Create layer manager for a wspace service\n * const layer = new LayerManager({\n * layer: 'wspace',\n * serviceName: 'wspace-tags-svc',\n * });\n *\n * // Get gateway URLs\n * const internalUrl = layer.getInternalGatewayUrl(); // wspace-int-gateway\n * const crossLayerUrl = layer.getCrossLayerGatewayUrl(); // global-public-gateway\n * ```\n */\n\nimport {\n type ServiceLayer,\n type LayerConfig,\n type LayerGatewayConfig,\n type LayerResourceUrls,\n type LayerFullConfig,\n type GatewayRoutingConfig,\n DEFAULT_GATEWAY_ROUTING,\n DEFAULT_LAYER_RESOURCES,\n DEFAULT_LAYER_STREAMS,\n} from '../types/layer.js';\nimport { logger } from '../logger/index.js';\n\n/**\n * Layer Manager - Provides layer-aware configuration and URL resolution\n */\nexport class LayerManager {\n private config: LayerConfig;\n private gatewayConfig: LayerGatewayConfig;\n private resourceConfig: LayerResourceUrls;\n private routingConfig: GatewayRoutingConfig;\n\n constructor(config: LayerConfig) {\n this.config = {\n serviceIdentity: config.serviceName, // Default to service name\n ...config,\n };\n\n // Load routing config for layer\n this.routingConfig = DEFAULT_GATEWAY_ROUTING[config.layer];\n\n // Initialize gateway config\n this.gatewayConfig = this.resolveGatewayConfig();\n\n // Initialize resource config\n this.resourceConfig = this.resolveResourceConfig();\n\n logger.debug('[LayerManager] Initialized', {\n layer: this.config.layer,\n serviceName: this.config.serviceName,\n serviceIdentity: this.config.serviceIdentity,\n });\n }\n\n /**\n * Resolve gateway configuration from environment or defaults\n */\n private resolveGatewayConfig(): LayerGatewayConfig {\n const envPrefix = this.config.layer.toUpperCase();\n\n // Internal gateway URL\n const internalGatewayUrl =\n process.env[`${envPrefix}_INT_GATEWAY_URL`] ||\n `http://${this.routingConfig.internalGateway.host}:${this.routingConfig.internalGateway.port}${this.routingConfig.internalGateway.graphqlPath}`;\n\n // Cross-layer gateway URL\n const crossLayerEnvPrefix = this.config.layer === 'wspace' ? 'GLOBAL' : 'WSPACE';\n const crossLayerGatewayUrl =\n process.env[`${crossLayerEnvPrefix}_PUBLIC_GATEWAY_URL`] ||\n `http://${this.routingConfig.crossLayerGateway.host}:${this.routingConfig.crossLayerGateway.port}${this.routingConfig.crossLayerGateway.graphqlPath}`;\n\n return {\n internalGatewayUrl,\n crossLayerGatewayUrl,\n };\n }\n\n /**\n * Resolve resource configuration from environment or defaults\n */\n private resolveResourceConfig(): LayerResourceUrls {\n const envPrefix = this.config.layer.toUpperCase();\n const defaults = DEFAULT_LAYER_RESOURCES[this.config.layer];\n\n return {\n // Event queue is fleet-shared (ACA Managed Redis or local shared-valkey).\n // REDIS_URL (set in ACA KV / local .env) always wins; the per-layer\n // default is only the local-dev compose fallback.\n eventQueueUrl: process.env['REDIS_URL'] || defaults.eventQueueUrl,\n valkeyUrl: process.env[`${envPrefix}_VALKEY_URL`] || defaults.valkeyUrl,\n temporalAddress: process.env[`${envPrefix}_TEMPORAL_ADDRESS`] || defaults.temporalAddress,\n temporalNamespace: process.env[`${envPrefix}_TEMPORAL_NAMESPACE`] || defaults.temporalNamespace,\n rbacGatewayUrl: process.env[`${envPrefix}_RBAC_GATEWAY_URL`] || defaults.rbacGatewayUrl,\n };\n }\n\n /**\n * Get the layer type\n */\n getLayer(): ServiceLayer {\n return this.config.layer;\n }\n\n /**\n * Get the service name\n */\n getServiceName(): string {\n return this.config.serviceName;\n }\n\n /**\n * Get the service identity (for bypass headers)\n */\n getServiceIdentity(): string {\n return this.config.serviceIdentity || this.config.serviceName;\n }\n\n /**\n * Get internal gateway URL (same layer M2M calls)\n */\n getInternalGatewayUrl(): string {\n return this.gatewayConfig.internalGatewayUrl;\n }\n\n /**\n * Get cross-layer gateway URL (cross layer calls via public gateway)\n */\n getCrossLayerGatewayUrl(): string {\n return this.gatewayConfig.crossLayerGatewayUrl;\n }\n\n /**\n * Get event queue (Redis Streams) URL for this layer\n */\n getEventQueueUrl(): string {\n return this.resourceConfig.eventQueueUrl;\n }\n\n /**\n * Get Valkey URL for this layer\n */\n getValkeyUrl(): string {\n return this.resourceConfig.valkeyUrl;\n }\n\n /**\n * Get Temporal address for this layer\n */\n getTemporalAddress(): string {\n return this.resourceConfig.temporalAddress;\n }\n\n /**\n * Get Temporal namespace for this layer\n */\n getTemporalNamespace(): string {\n return this.resourceConfig.temporalNamespace;\n }\n\n /**\n * Get RBAC gateway URL for this layer\n */\n getRbacGatewayUrl(): string {\n return this.resourceConfig.rbacGatewayUrl;\n }\n\n /**\n * Get default streams for this layer\n */\n getDefaultStreams(): Array<{ name: string; subjects: string[]; description?: string }> {\n return DEFAULT_LAYER_STREAMS[this.config.layer];\n }\n\n /**\n * Get full configuration\n */\n getFullConfig(): LayerFullConfig {\n return {\n ...this.config,\n gateways: this.gatewayConfig,\n resources: this.resourceConfig,\n };\n }\n\n /**\n * Check if this is a wspace layer service\n */\n isWspaceLayer(): boolean {\n return this.config.layer === 'wspace';\n }\n\n /**\n * Check if this is a global layer service\n */\n isGlobalLayer(): boolean {\n return this.config.layer === 'global';\n }\n\n /**\n * Get the opposite layer\n */\n getOppositeLayer(): ServiceLayer {\n return this.config.layer === 'wspace' ? 'global' : 'wspace';\n }\n}\n\n/**\n * Create LayerManager from environment variables\n *\n * Environment variables:\n * - SERVICE_LAYER: 'wspace' | 'global'\n * - SERVICE_NAME: Service name (e.g., 'wspace-tags-svc')\n * - SERVICE_IDENTITY: Service identity for bypass headers (defaults to SERVICE_NAME)\n *\n * @throws Error if SERVICE_LAYER is not set or invalid\n */\nexport function createLayerManagerFromEnv(): LayerManager {\n const layer = process.env['SERVICE_LAYER'] as ServiceLayer;\n\n if (!layer || (layer !== 'wspace' && layer !== 'global')) {\n throw new Error(\n `[LayerManager] Invalid or missing SERVICE_LAYER environment variable. ` +\n `Expected 'wspace' or 'global', got '${layer}'`\n );\n }\n\n const serviceName = process.env['SERVICE_NAME'];\n if (!serviceName) {\n throw new Error('[LayerManager] SERVICE_NAME environment variable is required');\n }\n\n const serviceIdentity = process.env['SERVICE_IDENTITY'] || serviceName;\n\n return new LayerManager({\n layer,\n serviceName,\n serviceIdentity,\n });\n}\n\n/**\n * Detect layer from service name\n *\n * @param serviceName - Service name (e.g., 'wspace-tags-svc', 'global-auth-svc')\n * @returns Detected layer or undefined if unable to detect\n */\nexport function detectLayerFromServiceName(serviceName: string): ServiceLayer | undefined {\n if (serviceName.startsWith('wspace-')) {\n return 'wspace';\n }\n if (serviceName.startsWith('global-')) {\n return 'global';\n }\n return undefined;\n}\n\n/**\n * Get gateway URL for a target layer from a source layer\n *\n * @param sourceLayer - Layer making the call\n * @param targetLayer - Layer being called\n * @param sourceManager - LayerManager for the source layer (optional, for URL resolution)\n * @returns Gateway URL to use for the call\n */\nexport function getGatewayUrlForLayer(\n sourceLayer: ServiceLayer,\n targetLayer: ServiceLayer,\n sourceManager?: LayerManager\n): string {\n // Same layer = internal gateway\n if (sourceLayer === targetLayer) {\n if (sourceManager) {\n return sourceManager.getInternalGatewayUrl();\n }\n const routing = DEFAULT_GATEWAY_ROUTING[sourceLayer];\n return `http://${routing.internalGateway.host}:${routing.internalGateway.port}${routing.internalGateway.graphqlPath}`;\n }\n\n // Different layer = cross-layer public gateway\n if (sourceManager) {\n return sourceManager.getCrossLayerGatewayUrl();\n }\n const routing = DEFAULT_GATEWAY_ROUTING[sourceLayer];\n return `http://${routing.crossLayerGateway.host}:${routing.crossLayerGateway.port}${routing.crossLayerGateway.graphqlPath}`;\n}\n\n/**\n * Validate layer configuration\n *\n * @param config - Layer configuration to validate\n * @throws Error if configuration is invalid\n */\nexport function validateLayerConfig(config: LayerConfig): void {\n if (!config.layer) {\n throw new Error('[LayerManager] layer is required');\n }\n if (config.layer !== 'wspace' && config.layer !== 'global') {\n throw new Error(`[LayerManager] Invalid layer '${config.layer}'. Must be 'wspace' or 'global'`);\n }\n if (!config.serviceName) {\n throw new Error('[LayerManager] serviceName is required');\n }\n\n // Validate naming convention\n const expectedPrefix = `${config.layer}-`;\n if (!config.serviceName.startsWith(expectedPrefix)) {\n logger.warn('[LayerManager] Service name does not follow naming convention', {\n serviceName: config.serviceName,\n expectedPrefix,\n layer: config.layer,\n });\n }\n}\n\n// Re-export types for convenience\nexport type {\n ServiceLayer,\n LayerConfig,\n LayerGatewayConfig,\n LayerResourceUrls,\n LayerFullConfig,\n GatewayRoutingConfig,\n} from '../types/layer.js';\n\nexport { DEFAULT_GATEWAY_ROUTING, DEFAULT_LAYER_RESOURCES, DEFAULT_LAYER_STREAMS } from '../types/layer.js';\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cache/index.ts","../src/cache/implementations/memory/MemoryCacheProvider.ts","../src/cache/implementations/valkey/ValkeyGlideProvider.ts","../src/cache/factory/CacheFactory.ts","../src/cache/types/config.ts"],"names":["MemoryCacheProvider","cache","Map","namespace","defaultTTL","maxSize","enableLogging","connected","stats","hits","misses","sets","deletes","evictions","config","startCleanupInterval","connect","Promise","resolve","logger","info","disconnect","clear","isConnected","healthCheck","status","timestamp","Date","toISOString","latencyMs","details","provider","cacheSize","size","getStatistics","totalOperations","hitRate","memoryUsed","keyCount","buildKey","key","isExpired","expiresAt","now","evictIfNeeded","firstKey","keys","next","value","delete","cleanup","cleaned","entries","debug","setInterval","get","_options","cacheKey","cached","set","entry","data","options","ttlSeconds","ttl","metadata","deleted","has","remaining","Math","floor","expire","mget","result","mset","mdel","matchPattern","pattern","includes","parts","split","position","i","length","part","index","indexOf","lastPart","endsWith","clearPattern","searchPattern","matchedKeys","prefix","push","replace","limitedKeys","limit","slice","nextCursor","totalCount","cleared","Array","from","startsWith","increment","amount","current","newValue","decrement","getOrSet","fetcher","invalidateTags","tags","totalDeleted","tag","CONNECT_RETRY_COOLDOWN_MS","ValkeyGlideProvider","client","clusterScanCursor","clientIsCluster","connectPromise","lastConnectFailureAt","errors","process","env","serverReportsCluster","test","scanClusterKeys","clusterClient","cursor","batch","scan","match","count","isFinished","getKeys","ensureConnected","Error","sinceFailureMs","finally","glideModule","GlideClient","default","GlideClusterClient","ClusterScanCursor","host","port","password","username","useTLSFromUrl","databaseFromUrl","url","rawUrl","URL","hostname","parseInt","decodeURIComponent","dbMatch","exec","pathname","isAzureManagedRedis","warn","String","addresses","clusterNodes","baseClientConfig","useTLS","credentials","undefined","clientName","name","databaseId","db","connectionTimeout","connectionBackoff","numberOfRetries","maxReconnectAttempts","factor","reconnectTimeWait","exponentBase","readFrom","cluster","createClient","periodicChecks","duration_in_sec","advancedConfiguration","refreshTopologyFromInitialNodes","standaloneClient","close","error","startTime","ping","message","memoryRegex","memoryMatch","dbsize","JSON","parse","stringify","expiry","type","del","exists","cacheKeys","map","values","requested","found","keyValuePairs","Object","cleanKeys","incrBy","decrBy","CacheFactory","instances","parseBoolean","normalized","trim","toLowerCase","parseClusterNodes","nodes","node","filter","Boolean","rawPort","Number","isFinite","resolvePort","layerPort","genericPort","defaultPort","createCache","keyPrefix","tls","enabled","createCacheFromEnv","envType","getInstance","instanceKey","closeInstance","closeAll","promises","all","createCacheForLayer","layer","serviceName","envPrefix","toUpperCase","defaults","DEFAULT_LAYER_RESOURCES","valkeyUrl","resolvedPort","getInstanceForLayer","CacheProviderType","getCache","getValkeyClient","valkeyConfig","VALKEY","closeAllCaches"],"mappings":"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","file":"chunk-UYE4IEPT.js","sourcesContent":["/**\n * Cache - Public API\n *\n * This module provides a complete abstraction over caching systems (Valkey, Memory, etc.)\n * allowing the application to cache data without direct dependency on any specific caching implementation.\n *\n * Usage:\n *\n * // Create cache from environment variables (workspaces-backend)\n * import { createCache } from '@burdenoff/be-sdk/cache';\n *\n * const cache = createCache('my-module');\n * await cache.connect();\n *\n * // Set value\n * await cache.set('user:123', { name: 'John', email: 'john@example.com' }, { ttl: 3600 });\n *\n * // Get value\n * const user = await cache.get<User>('user:123');\n *\n * // Delete value\n * await cache.delete('user:123');\n *\n * // Disconnect when done\n * await cache.disconnect();\n */\n// Import factory for use in convenience functions\nimport { CacheFactory } from './factory/CacheFactory.js';\nimport type { ICacheProvider } from './interfaces/ICacheProvider.js';\n// Re-export for convenience\nimport type { CacheConfig, ValkeyCacheConfig } from './types/config.js';\nimport { CacheProviderType } from './types/config.js';\n\n// Export interfaces\nexport type { ICache } from './interfaces/ICache.js';\nexport type { ICacheProvider } from './interfaces/ICacheProvider.js';\n\n// Export types\nexport type { CacheEntry, CacheOptions, BatchCacheOptions, PatternOptions, PatternResult } from './types/cache.js';\n\nexport type {\n BaseCacheConfig,\n ValkeyCacheConfig,\n MemoryCacheConfig,\n MemcachedCacheConfig,\n CacheConfig,\n CacheHealthCheckResult,\n CacheStatistics,\n CacheProviderTypeLiteral,\n} from './types/config.js';\n\nexport { CacheProviderType } from './types/config.js';\n\n// Export factory\nexport { CacheFactory } from './factory/CacheFactory.js';\n\n// Export implementations (in case direct access is needed)\nexport { ValkeyGlideProvider } from './implementations/valkey/ValkeyGlideProvider.js';\nexport type { ValkeyGlideConfig } from './implementations/valkey/ValkeyGlideProvider.js';\nexport { MemoryCacheProvider } from './implementations/memory/MemoryCacheProvider.js';\n\n/**\n * Create a cache instance from environment configuration\n * Convenience function for creating a cache without manual config\n *\n * @param namespace - Cache namespace (e.g., 'analytics', 'files', 'users')\n * @returns Cache provider instance\n */\nexport function createCache(namespace: string = 'default'): ICacheProvider {\n return CacheFactory.createCacheFromEnv(namespace);\n}\n\n/**\n * Get or create a singleton cache instance\n * Convenience function for getting/creating a singleton cache\n *\n * @param namespace - Cache namespace\n * @param config - Optional cache configuration\n * @returns Singleton cache provider instance\n */\nexport function getCache(namespace: string = 'default', config?: CacheConfig): ICacheProvider {\n return CacheFactory.getInstance(namespace, config);\n}\n\n/**\n * Valkey Glide client interface for raw Valkey operations\n */\nexport interface ValkeyGlideClient {\n get(key: string): Promise<string | null>;\n set(key: string, value: string, options?: { EX?: number }): Promise<string | null>;\n del(keys: string[]): Promise<number>;\n exists(keys: string[]): Promise<number>;\n ttl(key: string): Promise<number>;\n expire(key: string, seconds: number): Promise<boolean>;\n mget(keys: string[]): Promise<(string | null)[]>;\n mset(keyValuePairs: Record<string, string>): Promise<string | null>;\n keys(pattern: string): Promise<string[]>;\n incrBy(key: string, amount: number): Promise<number>;\n decrBy(key: string, amount: number): Promise<number>;\n ping(): Promise<string>;\n info(section?: string): Promise<string>;\n dbsize(): Promise<number>;\n close(): Promise<void>;\n // Additional list operations\n lpush(key: string, ...values: string[]): Promise<number>;\n rpush(key: string, ...values: string[]): Promise<number>;\n lpop(key: string): Promise<string | null>;\n rpop(key: string): Promise<string | null>;\n lrange(key: string, start: number, stop: number): Promise<string[]>;\n llen(key: string): Promise<number>;\n // Additional set operations\n sadd(key: string, ...members: string[]): Promise<number>;\n srem(key: string, ...members: string[]): Promise<number>;\n smembers(key: string): Promise<string[]>;\n sismember(key: string, member: string): Promise<boolean>;\n // Additional hash operations\n hset(key: string, field: string, value: string): Promise<number>;\n hget(key: string, field: string): Promise<string | null>;\n hdel(key: string, ...fields: string[]): Promise<number>;\n hgetall(key: string): Promise<Record<string, string>>;\n // Pub/Sub operations\n publish(channel: string, message: string): Promise<number>;\n}\n\n/**\n * Get direct access to Valkey client via @valkey/valkey-glide\n * Useful for cases where you need raw Valkey operations beyond caching\n *\n * @param config - Optional Valkey configuration. If not provided, uses environment variables\n * @returns ValkeyGlideClient instance from @valkey/valkey-glide\n *\n * @example\n * ```typescript\n * import { getValkeyClient } from '@burdenoff/be-sdk';\n *\n * const valkey = await getValkeyClient();\n * await valkey.lpush('mylist', 'value');\n * ```\n */\nexport async function getValkeyClient(config?: ValkeyCacheConfig): Promise<ValkeyGlideClient> {\n const glideModule = await import('@valkey/valkey-glide');\n const GlideClient = glideModule.GlideClient || glideModule.default;\n\n const valkeyConfig: ValkeyCacheConfig = config || {\n type: CacheProviderType.VALKEY,\n url: process.env['VALKEY_URL'],\n host: process.env['VALKEY_HOST'] || 'localhost',\n port: process.env['VALKEY_PORT'] ? parseInt(process.env['VALKEY_PORT'], 10) : 6379,\n password: process.env['VALKEY_PASSWORD'],\n db: process.env['VALKEY_DB'] ? parseInt(process.env['VALKEY_DB'], 10) : 0,\n username: process.env['VALKEY_USERNAME'],\n };\n\n // Parse URL if provided\n let host = valkeyConfig.host || 'localhost';\n let port = valkeyConfig.port || 6379;\n\n if (valkeyConfig.url) {\n const url = new URL(valkeyConfig.url.replace('valkey://', 'redis://'));\n host = url.hostname;\n port = parseInt(url.port || '6379', 10);\n }\n\n // Create Glide client\n const createClient = GlideClient as {\n createClient: (config: {\n addresses: Array<{ host: string; port: number }>;\n useTLS?: boolean;\n credentials?: { password?: string; username?: string };\n clientName?: string;\n readFrom?: string;\n }) => Promise<ValkeyGlideClient>;\n };\n\n return createClient.createClient({\n addresses: [{ host, port }],\n useTLS: valkeyConfig.useTLS,\n credentials: valkeyConfig.password\n ? {\n password: valkeyConfig.password,\n username: valkeyConfig.username,\n }\n : undefined,\n clientName: valkeyConfig.name || 'valkey-glide-client',\n readFrom: 'primary',\n });\n}\n\n/**\n * Close all cache connections\n * Call this during application shutdown\n */\nexport async function closeAllCaches(): Promise<void> {\n await CacheFactory.closeAll();\n}\n","/**\n * Memory Cache Provider\n * In-memory cache implementation (for testing and fallback)\n */\nimport { logger } from '../../../logger/index.js';\n\nimport type { ICacheProvider } from '../../interfaces/ICacheProvider.js';\nimport type {\n BatchCacheOptions,\n CacheEntry,\n CacheOptions,\n CacheStatistics,\n CacheHealthCheckResult,\n MemoryCacheConfig,\n PatternOptions,\n PatternResult,\n} from '../../types/index.js';\n\n/**\n * Memory cache provider implementation (LRU-based)\n */\nexport class MemoryCacheProvider implements ICacheProvider {\n private cache: Map<string, { entry: CacheEntry<unknown>; expiresAt: number }> = new Map();\n private readonly namespace: string;\n private readonly defaultTTL: number;\n private readonly maxSize: number;\n private readonly enableLogging: boolean;\n private connected: boolean = false;\n\n // Statistics\n private stats = {\n hits: 0,\n misses: 0,\n sets: 0,\n deletes: 0,\n evictions: 0,\n };\n\n constructor(config: MemoryCacheConfig, namespace: string = 'default') {\n this.namespace = namespace;\n this.defaultTTL = config.defaultTTL || 300; // 5 minutes default\n this.maxSize = config.maxSize || 1000; // Max 1000 entries by default\n this.enableLogging = config.enableLogging ?? false;\n\n // Start cleanup interval for expired entries\n this.startCleanupInterval();\n }\n\n /**\n * Connect (no-op for memory cache)\n */\n async connect(): Promise<void> {\n await Promise.resolve();\n this.connected = true;\n if (this.enableLogging) {\n logger.info(`[MemoryCacheProvider:${this.namespace}] Connected (in-memory)`);\n }\n }\n\n /**\n * Disconnect (cleanup)\n */\n async disconnect(): Promise<void> {\n await Promise.resolve();\n this.connected = false;\n this.cache.clear();\n if (this.enableLogging) {\n logger.info(`[MemoryCacheProvider:${this.namespace}] Disconnected`);\n }\n }\n\n /**\n * Check if connected\n */\n isConnected(): boolean {\n return this.connected;\n }\n\n /**\n * Health check\n */\n async healthCheck(): Promise<CacheHealthCheckResult> {\n await Promise.resolve();\n return {\n status: 'healthy',\n timestamp: new Date().toISOString(),\n connected: this.connected,\n latencyMs: 0,\n details: {\n provider: 'memory',\n cacheSize: this.cache.size,\n maxSize: this.maxSize,\n },\n };\n }\n\n /**\n * Get statistics\n */\n async getStatistics(): Promise<CacheStatistics> {\n await Promise.resolve();\n const totalOperations = this.stats.hits + this.stats.misses;\n const hitRate = totalOperations > 0 ? this.stats.hits / totalOperations : 0;\n\n // Calculate approximate memory usage (rough estimate)\n const memoryUsed = this.cache.size * 500; // Assume ~500 bytes per entry\n\n return {\n hits: this.stats.hits,\n misses: this.stats.misses,\n hitRate,\n keyCount: this.cache.size,\n memoryUsed,\n totalOperations,\n details: {\n sets: this.stats.sets,\n deletes: this.stats.deletes,\n evictions: this.stats.evictions,\n maxSize: this.maxSize,\n },\n };\n }\n\n /**\n * Build cache key with namespace\n */\n private buildKey(key: string): string {\n return `${this.namespace}:${key}`;\n }\n\n /**\n * Check if entry is expired\n */\n private isExpired(expiresAt: number): boolean {\n return Date.now() > expiresAt;\n }\n\n /**\n * Evict LRU entry if cache is full\n */\n private evictIfNeeded(): void {\n if (this.cache.size >= this.maxSize) {\n // Evict the first (oldest) entry (simple LRU)\n const firstKey = this.cache.keys().next().value;\n if (firstKey) {\n this.cache.delete(firstKey);\n this.stats.evictions++;\n }\n }\n }\n\n /**\n * Cleanup expired entries\n */\n private cleanup(): void {\n let cleaned = 0;\n\n for (const [key, value] of this.cache.entries()) {\n if (this.isExpired(value.expiresAt)) {\n this.cache.delete(key);\n cleaned++;\n }\n }\n\n if (cleaned > 0 && this.enableLogging) {\n logger.debug(`[MemoryCacheProvider:${this.namespace}] Cleaned up ${cleaned} expired entries`);\n }\n }\n\n /**\n * Start cleanup interval\n */\n private startCleanupInterval(): void {\n setInterval(() => this.cleanup(), 60000); // Cleanup every minute\n }\n\n /**\n * Get value from cache\n */\n async get<T>(key: string, _options?: CacheOptions): Promise<T | null> {\n await Promise.resolve();\n const cacheKey = this.buildKey(key);\n const cached = this.cache.get(cacheKey);\n\n if (!cached) {\n this.stats.misses++;\n if (this.enableLogging) {\n logger.debug(`[MemoryCacheProvider:${this.namespace}] Cache miss`, { key });\n }\n return null;\n }\n\n // Check if expired\n if (this.isExpired(cached.expiresAt)) {\n this.cache.delete(cacheKey);\n this.stats.misses++;\n if (this.enableLogging) {\n logger.debug(`[MemoryCacheProvider:${this.namespace}] Cache miss (expired)`, { key });\n }\n return null;\n }\n\n this.stats.hits++;\n if (this.enableLogging) {\n logger.debug(`[MemoryCacheProvider:${this.namespace}] Cache hit`, { key });\n }\n\n // Move to end (LRU)\n this.cache.delete(cacheKey);\n this.cache.set(cacheKey, cached);\n\n return cached.entry.data as T;\n }\n\n /**\n * Set value in cache\n */\n async set<T>(key: string, value: T, options?: CacheOptions): Promise<boolean> {\n await Promise.resolve();\n const cacheKey = this.buildKey(key);\n const ttlSeconds = options?.ttl || this.defaultTTL;\n\n this.evictIfNeeded();\n\n const entry: CacheEntry<T> = {\n data: value,\n timestamp: Date.now(),\n ttl: ttlSeconds,\n metadata: options?.metadata,\n };\n\n this.cache.set(cacheKey, {\n entry: entry,\n expiresAt: Date.now() + ttlSeconds * 1000,\n });\n\n this.stats.sets++;\n if (this.enableLogging) {\n logger.debug(`[MemoryCacheProvider:${this.namespace}] Cache set`, {\n key,\n ttl: ttlSeconds,\n });\n }\n\n return true;\n }\n\n /**\n * Delete value from cache\n */\n async delete(key: string): Promise<boolean> {\n await Promise.resolve();\n const cacheKey = this.buildKey(key);\n const deleted = this.cache.delete(cacheKey);\n\n if (deleted) {\n this.stats.deletes++;\n if (this.enableLogging) {\n logger.debug(`[MemoryCacheProvider:${this.namespace}] Cache delete`, { key });\n }\n }\n\n return deleted;\n }\n\n /**\n * Check if key exists\n */\n async has(key: string): Promise<boolean> {\n await Promise.resolve();\n const cacheKey = this.buildKey(key);\n const cached = this.cache.get(cacheKey);\n\n if (!cached) {\n return false;\n }\n\n // Check if expired\n if (this.isExpired(cached.expiresAt)) {\n this.cache.delete(cacheKey);\n return false;\n }\n\n return true;\n }\n\n /**\n * Get TTL for key\n */\n async ttl(key: string): Promise<number> {\n await Promise.resolve();\n const cacheKey = this.buildKey(key);\n const cached = this.cache.get(cacheKey);\n\n if (!cached) {\n return -2; // Key doesn't exist\n }\n\n const remaining = Math.floor((cached.expiresAt - Date.now()) / 1000);\n\n if (remaining <= 0) {\n this.cache.delete(cacheKey);\n return -2;\n }\n\n return remaining;\n }\n\n /**\n * Update TTL for key\n */\n async expire(key: string, ttl: number): Promise<boolean> {\n await Promise.resolve();\n const cacheKey = this.buildKey(key);\n const cached = this.cache.get(cacheKey);\n\n if (!cached) {\n return false;\n }\n\n cached.expiresAt = Date.now() + ttl * 1000;\n cached.entry.ttl = ttl;\n\n return true;\n }\n\n /**\n * Get multiple values (batch operation)\n */\n async mget<T>(keys: string[], _options?: BatchCacheOptions): Promise<Map<string, T>> {\n const result = new Map<string, T>();\n\n for (const key of keys) {\n const value = await this.get<T>(key);\n if (value !== null) {\n result.set(key, value);\n }\n }\n\n return result;\n }\n\n /**\n * Set multiple values (batch operation)\n */\n async mset<T>(entries: Map<string, T>, options?: BatchCacheOptions): Promise<boolean> {\n for (const [key, value] of entries) {\n await this.set(key, value, options);\n }\n\n return true;\n }\n\n /**\n * Delete multiple keys (batch operation)\n */\n async mdel(keys: string[]): Promise<number> {\n let deleted = 0;\n\n for (const key of keys) {\n const result = await this.delete(key);\n if (result) {\n deleted++;\n }\n }\n\n return deleted;\n }\n\n /**\n * Match key against pattern (supports * wildcard)\n */\n private matchPattern(key: string, pattern: string): boolean {\n // Simple wildcard matching without regex\n if (!pattern.includes('*')) {\n return key === pattern;\n }\n\n const parts = pattern.split('*');\n let position = 0;\n\n for (let i = 0; i < parts.length; i++) {\n const part = parts[i];\n if (!part || part === '') continue;\n\n const index = key.indexOf(part, position);\n if (index === -1) return false;\n if (i === 0 && index !== 0) return false;\n position = index + part.length;\n }\n\n const lastPart = parts[parts.length - 1];\n return !lastPart || lastPart === '' || key.endsWith(lastPart);\n }\n\n /**\n * Clear keys by pattern\n */\n async clearPattern(pattern: string): Promise<number> {\n await Promise.resolve();\n const searchPattern = this.buildKey(pattern);\n let deleted = 0;\n\n for (const key of this.cache.keys()) {\n if (this.matchPattern(key, searchPattern)) {\n this.cache.delete(key);\n deleted++;\n }\n }\n\n if (this.enableLogging) {\n logger.debug(`[MemoryCacheProvider:${this.namespace}] Pattern cleared`, {\n pattern,\n deleted,\n });\n }\n\n return deleted;\n }\n\n /**\n * Get keys by pattern\n */\n async keys(options: PatternOptions): Promise<PatternResult> {\n await Promise.resolve();\n const searchPattern = this.buildKey(options.pattern);\n const matchedKeys: string[] = [];\n const prefix = `${this.namespace}:`;\n\n for (const key of this.cache.keys()) {\n if (this.matchPattern(key, searchPattern)) {\n matchedKeys.push(key.replace(prefix, ''));\n }\n }\n\n // Apply limit if specified\n const limitedKeys = options.limit ? matchedKeys.slice(0, options.limit) : matchedKeys;\n\n return {\n keys: limitedKeys,\n nextCursor: null,\n totalCount: matchedKeys.length,\n };\n }\n\n /**\n * Clear all keys in namespace\n */\n async clear(): Promise<boolean> {\n await Promise.resolve();\n const prefix = `${this.namespace}:`;\n let cleared = 0;\n\n for (const key of Array.from(this.cache.keys())) {\n if (key.startsWith(prefix)) {\n this.cache.delete(key);\n cleared++;\n }\n }\n\n if (this.enableLogging) {\n logger.info(`[MemoryCacheProvider:${this.namespace}] Cleared ${cleared} keys`);\n }\n\n return true;\n }\n\n /**\n * Increment numeric value\n */\n async increment(key: string, amount: number = 1): Promise<number> {\n const current = await this.get<number>(key);\n const newValue = (current || 0) + amount;\n await this.set(key, newValue);\n return newValue;\n }\n\n /**\n * Decrement numeric value\n */\n async decrement(key: string, amount: number = 1): Promise<number> {\n const current = await this.get<number>(key);\n const newValue = (current || 0) - amount;\n await this.set(key, newValue);\n return newValue;\n }\n\n /**\n * Get or set value\n */\n async getOrSet<T>(key: string, fetcher: () => Promise<T>, options?: CacheOptions): Promise<T> {\n const cached = await this.get<T>(key, options);\n if (cached !== null) {\n return cached;\n }\n\n const value = await fetcher();\n await this.set(key, value, options);\n\n return value;\n }\n\n /**\n * Invalidate by tags\n */\n async invalidateTags(tags: string[]): Promise<number> {\n let totalDeleted = 0;\n\n for (const tag of tags) {\n const pattern = `*:tag:${tag}:*`;\n const deleted = await this.clearPattern(pattern);\n totalDeleted += deleted;\n }\n\n return totalDeleted;\n }\n}\n","/**\n * Valkey Glide Cache Provider\n *\n * Implements ICacheProvider using @valkey/valkey-glide client.\n * Provides a modern, high-performance Valkey/Redis client implementation.\n *\n * @module cache/implementations/valkey/ValkeyGlideProvider\n * @category Cache\n *\n * @example\n * ```typescript\n * import { ValkeyGlideProvider } from '@burdenoff/be-sdk/cache';\n *\n * const cache = new ValkeyGlideProvider({\n * type: 'valkey-glide',\n * url: 'valkey://localhost:6379',\n * defaultTTL: 300,\n * }, 'my-namespace');\n *\n * await cache.connect();\n * await cache.set('key', 'value', { ttl: 60 });\n * const value = await cache.get('key');\n * ```\n */\n\nimport { logger } from '../../../logger/index.js';\nimport type { ICacheProvider } from '../../interfaces/ICacheProvider.js';\nimport type {\n BatchCacheOptions,\n CacheEntry,\n CacheOptions,\n CacheStatistics,\n CacheHealthCheckResult,\n PatternOptions,\n PatternResult,\n} from '../../types/index.js';\n\n/**\n * Valkey Glide configuration\n */\nexport interface ValkeyGlideConfig {\n /**\n * Cache provider type\n */\n type: 'valkey-glide';\n\n /**\n * Valkey server URL\n * @example 'valkey://localhost:6379' or 'redis://localhost:6379'\n */\n url?: string;\n\n /**\n * Valkey host\n * @default 'localhost'\n */\n host?: string;\n\n /**\n * Valkey port\n * @default 6379\n */\n port?: number;\n\n /**\n * Password for authentication\n */\n password?: string;\n\n /**\n * Username for authentication\n */\n username?: string;\n\n /**\n * Database number\n * @default 0\n */\n db?: number;\n\n /**\n * Key prefix for all keys\n * @default 'cache'\n */\n keyPrefix?: string;\n\n /**\n * Default TTL in seconds\n * @default 300 (5 minutes)\n */\n defaultTTL?: number;\n\n /**\n * Enable logging\n * @default NODE_ENV === 'development'\n */\n enableLogging?: boolean;\n\n /**\n * Connection timeout in milliseconds\n * @default 10000\n */\n connectionTimeout?: number;\n\n /**\n * Max reconnect attempts\n * @default -1 (infinite)\n */\n maxReconnectAttempts?: number;\n\n /**\n * Reconnect time wait in milliseconds\n * @default 2000\n */\n reconnectTimeWait?: number;\n\n /**\n * Client name for identification\n */\n name?: string;\n\n /**\n * Use TLS for connection\n * @default false\n */\n useTLS?: boolean;\n\n /**\n * Force Valkey Cluster mode. If unset, the provider auto-detects cluster mode.\n */\n cluster?: boolean;\n\n /**\n * Seed nodes for Valkey Cluster topology discovery.\n */\n clusterNodes?: Array<{ host: string; port: number }>;\n}\n\n/**\n * Valkey Glide TimeUnit enum (mirror of @valkey/valkey-glide's TimeUnit).\n * We re-declare locally so this file has zero compile-time dependency on the\n * peer-dep types — the enum values are ABI-stable Redis expiry tokens\n * (\"EX\", \"PX\", \"EXAT\", \"PXAT\", \"KEEPTTL\") so the runtime client accepts them\n * regardless of whether the peer package is installed.\n */\nconst enum GlideTimeUnit {\n Seconds = 'EX',\n Milliseconds = 'PX',\n UnixSeconds = 'EXAT',\n UnixMilliseconds = 'PXAT',\n KeepExisting = 'KEEPTTL',\n}\n\n/**\n * Valkey Glide set()-options shape. The real client takes\n * `{ expiry: { type: TimeUnit, count: number } }` and silently ignores the\n * legacy `{ EX: number }` shape — that silent drop caused rate-limit\n * counters to persist forever (no TTL on the key). See\n * node_modules/@valkey/valkey-glide/build-ts/BaseClient.d.ts `set(...)`.\n */\ninterface GlideSetOptions {\n expiry?: 'persist' | { type: GlideTimeUnit; count: number; duration?: number };\n conditionalSet?: 'onlyIfExists' | 'onlyIfDoesNotExist' | 'onlyIfEqual';\n returnOldValue?: boolean;\n}\n\ninterface GlideAddress {\n host: string;\n port: number;\n}\n\ninterface GlideCreateClientConfig {\n addresses: GlideAddress[];\n useTLS?: boolean;\n credentials?: { password?: string; username?: string };\n clientName?: string;\n readFrom?: string;\n databaseId?: number;\n connectionTimeout?: number;\n // Reconnection backoff for an established client that drops its connection.\n // GLIDE waits `factor * (exponentBase ^ N)` between attempt N, then keeps\n // using the last (capped) delay. Without this GLIDE uses its built-in\n // default; wiring it lets a transient drop recover smoothly instead of\n // churning. See @valkey/valkey-glide BaseClientConfiguration.connectionBackoff.\n connectionBackoff?: { numberOfRetries: number; factor: number; exponentBase: number };\n periodicChecks?: { duration_in_sec?: number };\n advancedConfiguration?: { refreshTopologyFromInitialNodes?: boolean };\n}\n\n/**\n * After a failed connect, fail subsequent ops fast (treated as a cache miss by\n * callers) for this cooldown instead of issuing a fresh `createClient` on every\n * operation. Per-operation connect hammering is what turned a brief Redis\n * hiccup into thousands of \"Failed to connect\" log lines/min and a\n * self-amplifying reconnect storm across the platform.\n */\nconst CONNECT_RETRY_COOLDOWN_MS = 3000;\n\ninterface GlideClientFactory {\n createClient(config: GlideCreateClientConfig): Promise<ValkeyGlideClient>;\n}\n\ninterface ClusterScanCursorLike {\n getCursor(): string;\n isFinished(): boolean;\n}\n\ntype ClusterScanCursorConstructor = new (newCursor?: string | undefined | null) => ClusterScanCursorLike;\n\ninterface ValkeyGlideModule {\n GlideClient?: GlideClientFactory;\n GlideClusterClient?: GlideClientFactory;\n ClusterScanCursor?: ClusterScanCursorConstructor;\n default?: GlideClientFactory;\n}\n\n/**\n * Valkey Glide client interface (minimal type definition)\n * This is a simplified interface - full types come from @valkey/valkey-glide\n */\ninterface ValkeyGlideClient {\n get(key: string): Promise<string | null>;\n set(key: string, value: string, options?: GlideSetOptions): Promise<string | null>;\n del(keys: string[]): Promise<number>;\n exists(keys: string[]): Promise<number>;\n ttl(key: string): Promise<number>;\n expire(key: string, seconds: number): Promise<boolean>;\n mget(keys: string[]): Promise<(string | null)[]>;\n mset(keyValuePairs: Record<string, string>): Promise<string | null>;\n keys?(pattern: string): Promise<string[]>;\n incrBy(key: string, amount: number): Promise<number>;\n decrBy(key: string, amount: number): Promise<number>;\n ping(): Promise<string>;\n info(section?: string): Promise<string>;\n dbsize(): Promise<number>;\n close(): Promise<void>;\n}\n\ninterface ValkeyGlideClusterClient extends ValkeyGlideClient {\n scan(\n cursor: ClusterScanCursorLike,\n options?: { match?: string; count?: number }\n ): Promise<[ClusterScanCursorLike, string[]]>;\n}\n\n/**\n * Valkey Glide cache provider implementation\n */\nexport class ValkeyGlideProvider implements ICacheProvider {\n private client: ValkeyGlideClient | null = null;\n private clusterScanCursor: ClusterScanCursorConstructor | null = null;\n private clientIsCluster = false;\n private connected = false;\n // Single in-flight connect promise so concurrent first-time `get/set` calls\n // share one connect attempt instead of racing into N parallel `createClient`\n // invocations. Reset to `null` after connect resolves/rejects so the next\n // call after an explicit disconnect() (or a connect failure) can retry.\n private connectPromise: Promise<void> | null = null;\n // Timestamp (ms) of the last failed connect attempt; 0 when the last attempt\n // succeeded. Drives the connect circuit-breaker in ensureConnected().\n private lastConnectFailureAt = 0;\n private readonly config: ValkeyGlideConfig;\n // Mutable: when a URL like `…/4` lands on Azure Managed Redis we fold the\n // DB index into the namespace at connect time to preserve per-service\n // isolation on the forced-DB-0 connection. Not const, but only ever\n // appended to once during connect().\n private namespace: string;\n private readonly defaultTTL: number;\n private readonly enableLogging: boolean;\n\n // Statistics\n private stats = {\n hits: 0,\n misses: 0,\n sets: 0,\n deletes: 0,\n errors: 0,\n };\n\n constructor(config: ValkeyGlideConfig, namespace: string = 'default') {\n this.config = config;\n this.namespace = namespace;\n this.defaultTTL = config.defaultTTL || 300;\n this.enableLogging = config.enableLogging ?? process.env['NODE_ENV'] === 'development';\n }\n\n private async serverReportsCluster(client: ValkeyGlideClient): Promise<boolean> {\n try {\n const info = await client.info('cluster');\n return /(?:^|\\n)cluster_enabled:1(?:\\r?\\n|$)/.test(info);\n } catch {\n return false;\n }\n }\n\n private async scanClusterKeys(pattern: string): Promise<string[]> {\n if (!this.client || !this.clientIsCluster || !this.clusterScanCursor) {\n return [];\n }\n\n const clusterClient = this.client as ValkeyGlideClusterClient;\n let cursor: ClusterScanCursorLike = new this.clusterScanCursor();\n const keys: string[] = [];\n\n do {\n const [nextCursor, batch] = await clusterClient.scan(cursor, { match: pattern, count: 1000 });\n keys.push(...batch);\n cursor = nextCursor;\n } while (!cursor.isFinished());\n\n return keys;\n }\n\n private async getKeys(pattern: string): Promise<string[]> {\n const client = await this.ensureConnected();\n\n if (this.clientIsCluster) {\n return this.scanClusterKeys(pattern);\n }\n\n if (!client.keys) {\n throw new Error('KEYS command is not available on this Valkey client');\n }\n\n return client.keys(pattern);\n }\n\n /**\n * Connect to Valkey server using @valkey/valkey-glide\n */\n /**\n * Lazy-connect helper used by every public operation so callers can just do\n * `const cache = createCache('x'); await cache.set(...)` without an explicit\n * `await cache.connect()`. Multiple concurrent ops share the same in-flight\n * connect promise.\n */\n private async ensureConnected(): Promise<ValkeyGlideClient> {\n if (!(this.connected && this.client)) {\n // Circuit-breaker: if a recent connect attempt failed and none is\n // currently in flight, fail fast (the caller treats the rejection as a\n // cache miss and falls through to its source) instead of starting yet\n // another createClient. This caps connect attempts at ~1 per cooldown\n // per instance during an outage rather than one per cache operation.\n if (!this.connectPromise && this.lastConnectFailureAt > 0) {\n const sinceFailureMs = Date.now() - this.lastConnectFailureAt;\n if (sinceFailureMs < CONNECT_RETRY_COOLDOWN_MS) {\n throw new Error('Valkey connect in cooldown after a recent failure');\n }\n }\n if (!this.connectPromise) {\n this.connectPromise = this.connect().finally(() => {\n this.connectPromise = null;\n });\n }\n await this.connectPromise;\n }\n if (!this.client) {\n throw new Error('Valkey client connect failed');\n }\n return this.client;\n }\n\n async connect(): Promise<void> {\n if (this.connected && this.client) {\n return;\n }\n\n try {\n // Dynamically import @valkey/valkey-glide\n const glideModule = (await import('@valkey/valkey-glide')) as ValkeyGlideModule;\n const GlideClient = glideModule.GlideClient || glideModule.default;\n const GlideClusterClient = glideModule.GlideClusterClient;\n this.clusterScanCursor = glideModule.ClusterScanCursor ?? null;\n\n if (!GlideClient) {\n throw new Error('Valkey GLIDE standalone client is unavailable');\n }\n\n // Parse URL if provided\n let host = this.config.host || 'localhost';\n let port = this.config.port || 6379;\n let password = this.config.password;\n let username = this.config.username;\n // Auto-detect TLS from URL scheme. `rediss://` (Redis-over-TLS) and\n // `valkeys://` are the canonical \"TLS-required\" schemes — Azure Managed\n // Redis on port 10000 only accepts TLS, so missing this flag manifests as\n // a connect timeout (plaintext handshake on a TLS-only socket).\n let useTLSFromUrl: boolean | undefined;\n let databaseFromUrl: number | undefined;\n\n if (this.config.url) {\n const rawUrl = this.config.url;\n useTLSFromUrl = /^(rediss|valkeys):\\/\\//i.test(rawUrl);\n const url = new URL(rawUrl.replace(/^valkey:\\/\\//i, 'redis://').replace(/^valkeys:\\/\\//i, 'rediss://'));\n host = url.hostname;\n port = parseInt(url.port || '6379', 10);\n if (!password && url.password) {\n try {\n password = decodeURIComponent(url.password);\n } catch {\n password = url.password;\n }\n }\n if (!username && url.username) {\n try {\n username = decodeURIComponent(url.username);\n } catch {\n username = url.username;\n }\n }\n // Pull DB number from path (e.g. `/0`, `/1`).\n //\n // Azure Managed Redis Balanced/B0 only exposes DB 0. If the URL pins\n // a non-zero DB index, glide's CLIENT SETINFO + SELECT chain fails\n // on every connect with `ERR DB index is out of range`. Detect the\n // Azure hostname and force DB 0 — also fold the original DB # into\n // the per-instance namespace so two services pointed at the same\n // managed-redis with different `/N` paths stay isolated by key.\n const dbMatch = /^\\/(\\d+)$/.exec(url.pathname);\n if (dbMatch && dbMatch[1]) {\n databaseFromUrl = parseInt(dbMatch[1], 10);\n const isAzureManagedRedis = /\\.redis\\.azure\\.net$/i.test(host);\n if (isAzureManagedRedis && databaseFromUrl > 0) {\n logger.warn(\n `[ValkeyGlideProvider] Azure Managed Redis only supports DB 0; ` +\n `ignoring /${String(databaseFromUrl)} in URL and folding it into namespace.`\n );\n // Suffix the namespace with `:db{N}` so two services that used to\n // rely on the URL's DB index for isolation keep getting disjoint\n // keysets on the shared DB 0.\n this.namespace = `${this.namespace}:db${String(databaseFromUrl)}`;\n databaseFromUrl = 0;\n }\n }\n }\n\n const addresses = this.config.clusterNodes?.length ? this.config.clusterNodes : [{ host, port }];\n const baseClientConfig: GlideCreateClientConfig = {\n addresses,\n useTLS: this.config.useTLS ?? useTLSFromUrl,\n credentials:\n password || username\n ? {\n password,\n username,\n }\n : undefined,\n clientName: this.config.name || `valkey-glide-${this.namespace}`,\n databaseId: this.config.db ?? databaseFromUrl,\n connectionTimeout: this.config.connectionTimeout,\n // Honour the configured reconnect tuning. Previously\n // maxReconnectAttempts/reconnectTimeWait were read into config but never\n // handed to GLIDE, so the client used its built-in default backoff. A\n // dropped connection now recovers on an exponential schedule seeded by\n // reconnectTimeWait, capped after numberOfRetries attempts.\n connectionBackoff: {\n numberOfRetries:\n this.config.maxReconnectAttempts && this.config.maxReconnectAttempts > 0\n ? this.config.maxReconnectAttempts\n : 5,\n factor: this.config.reconnectTimeWait ?? 1000,\n exponentBase: 2,\n },\n readFrom: 'primary',\n };\n\n if (this.config.cluster === true) {\n if (!GlideClusterClient) {\n throw new Error('Valkey GLIDE cluster client is unavailable');\n }\n this.client = await GlideClusterClient.createClient({\n ...baseClientConfig,\n periodicChecks: { duration_in_sec: 30 },\n advancedConfiguration: { refreshTopologyFromInitialNodes: true },\n });\n this.clientIsCluster = true;\n } else {\n const standaloneClient = await GlideClient.createClient(baseClientConfig);\n if (this.config.cluster !== false && (await this.serverReportsCluster(standaloneClient))) {\n if (!GlideClusterClient) {\n throw new Error('Valkey server is clustered but GLIDE cluster client is unavailable');\n }\n await standaloneClient.close();\n this.client = await GlideClusterClient.createClient({\n ...baseClientConfig,\n periodicChecks: { duration_in_sec: 30 },\n advancedConfiguration: { refreshTopologyFromInitialNodes: true },\n });\n this.clientIsCluster = true;\n } else {\n this.client = standaloneClient;\n this.clientIsCluster = false;\n }\n }\n\n this.connected = true;\n // Clear the circuit-breaker — a healthy connect re-opens the gate.\n this.lastConnectFailureAt = 0;\n\n if (this.enableLogging) {\n logger.info(`[ValkeyGlideProvider:${this.namespace}] Connected to Valkey`, {\n host,\n port,\n cluster: this.clientIsCluster,\n });\n }\n } catch (error) {\n this.stats.errors++;\n // Arm the circuit-breaker so the next ops fail fast instead of each\n // re-attempting connect (which produced the platform-wide connect storm).\n this.lastConnectFailureAt = Date.now();\n logger.error(`[ValkeyGlideProvider:${this.namespace}] Failed to connect:`, error);\n throw error;\n }\n }\n\n /**\n * Disconnect from Valkey server\n */\n async disconnect(): Promise<void> {\n if (this.client) {\n await this.client.close();\n this.client = null;\n this.clientIsCluster = false;\n this.connected = false;\n // Clear the circuit-breaker so an explicit disconnect→connect cycle\n // (e.g. a deliberate reconnect) is never blocked by a stale cooldown.\n this.lastConnectFailureAt = 0;\n\n if (this.enableLogging) {\n logger.info(`[ValkeyGlideProvider:${this.namespace}] Disconnected`);\n }\n }\n }\n\n /**\n * Check if connected\n */\n isConnected(): boolean {\n return this.connected && this.client !== null;\n }\n\n /**\n * Health check\n */\n async healthCheck(): Promise<CacheHealthCheckResult> {\n const startTime = Date.now();\n\n try {\n if (!this.client) {\n return {\n status: 'unhealthy',\n timestamp: new Date().toISOString(),\n connected: false,\n error: 'Not connected',\n };\n }\n\n const result = await this.client.ping();\n const latencyMs = Date.now() - startTime;\n\n if (result === 'PONG') {\n return {\n status: 'healthy',\n timestamp: new Date().toISOString(),\n connected: true,\n latencyMs,\n };\n }\n\n return {\n status: 'unhealthy',\n timestamp: new Date().toISOString(),\n connected: false,\n error: 'Unexpected ping response',\n };\n } catch (error) {\n return {\n status: 'unhealthy',\n timestamp: new Date().toISOString(),\n connected: false,\n error: error instanceof Error ? error.message : 'Unknown error',\n latencyMs: Date.now() - startTime,\n };\n }\n }\n\n /**\n * Get statistics\n */\n async getStatistics(): Promise<CacheStatistics> {\n const totalOperations = this.stats.hits + this.stats.misses;\n const hitRate = totalOperations > 0 ? this.stats.hits / totalOperations : 0;\n\n try {\n const client = await this.ensureConnected();\n\n const info = await client.info('memory');\n const memoryRegex = /used_memory:(\\d+)/;\n const memoryMatch = memoryRegex.exec(info);\n const memoryUsed = memoryMatch && memoryMatch[1] ? parseInt(memoryMatch[1], 10) : undefined;\n\n const keyCount = await client.dbsize();\n\n return {\n hits: this.stats.hits,\n misses: this.stats.misses,\n hitRate,\n keyCount,\n memoryUsed,\n totalOperations,\n details: {\n sets: this.stats.sets,\n deletes: this.stats.deletes,\n errors: this.stats.errors,\n },\n };\n } catch (error) {\n logger.error(`[ValkeyGlideProvider:${this.namespace}] Failed to get statistics:`, error);\n return {\n hits: this.stats.hits,\n misses: this.stats.misses,\n hitRate,\n totalOperations,\n details: {\n sets: this.stats.sets,\n deletes: this.stats.deletes,\n errors: this.stats.errors,\n },\n };\n }\n }\n\n /**\n * Build cache key with namespace\n */\n private buildKey(key: string): string {\n return `${this.namespace}:${key}`;\n }\n\n /**\n * Get value from cache\n */\n async get<T>(key: string, _options?: CacheOptions): Promise<T | null> {\n try {\n const client = await this.ensureConnected();\n\n const cacheKey = this.buildKey(key);\n const value = await client.get(cacheKey);\n\n if (value === null) {\n this.stats.misses++;\n if (this.enableLogging) {\n logger.debug(`[ValkeyGlideProvider:${this.namespace}] Cache miss`, { key });\n }\n return null;\n }\n\n this.stats.hits++;\n if (this.enableLogging) {\n logger.debug(`[ValkeyGlideProvider:${this.namespace}] Cache hit`, { key });\n }\n\n const entry: CacheEntry<T> = JSON.parse(value);\n return entry.data;\n } catch (error) {\n this.stats.errors++;\n logger.error(`[ValkeyGlideProvider:${this.namespace}] Error getting cache key:`, error);\n return null;\n }\n }\n\n /**\n * Set value in cache\n */\n async set<T>(key: string, value: T, options?: CacheOptions): Promise<boolean> {\n try {\n const client = await this.ensureConnected();\n\n const cacheKey = this.buildKey(key);\n const ttlSeconds = options?.ttl || this.defaultTTL;\n\n const entry: CacheEntry<T> = {\n data: value,\n timestamp: Date.now(),\n ttl: ttlSeconds,\n metadata: options?.metadata,\n };\n\n // Valkey Glide expects `{ expiry: { type: TimeUnit.Seconds, count } }`\n // and silently ignores the legacy `{ EX }` shape — passing EX meant\n // keys were written with no TTL, which wedged rate-limit counters\n // (e.g. APP_TOKEN_GENERATION bucket filling up permanently).\n await client.set(cacheKey, JSON.stringify(entry), {\n expiry: { type: GlideTimeUnit.Seconds, count: ttlSeconds },\n });\n\n this.stats.sets++;\n if (this.enableLogging) {\n logger.debug(`[ValkeyGlideProvider:${this.namespace}] Cache set`, {\n key,\n ttl: ttlSeconds,\n });\n }\n\n return true;\n } catch (error) {\n this.stats.errors++;\n logger.error(`[ValkeyGlideProvider:${this.namespace}] Error setting cache key:`, error);\n return false;\n }\n }\n\n /**\n * Delete value from cache\n */\n async delete(key: string): Promise<boolean> {\n try {\n const client = await this.ensureConnected();\n\n const cacheKey = this.buildKey(key);\n const result = await client.del([cacheKey]);\n\n this.stats.deletes++;\n if (this.enableLogging) {\n logger.debug(`[ValkeyGlideProvider:${this.namespace}] Cache delete`, {\n key,\n deleted: result > 0,\n });\n }\n\n return result > 0;\n } catch (error) {\n this.stats.errors++;\n logger.error(`[ValkeyGlideProvider:${this.namespace}] Error deleting cache key:`, error);\n return false;\n }\n }\n\n /**\n * Check if key exists\n */\n async has(key: string): Promise<boolean> {\n try {\n const client = await this.ensureConnected();\n\n const cacheKey = this.buildKey(key);\n const exists = await client.exists([cacheKey]);\n return exists === 1;\n } catch (error) {\n this.stats.errors++;\n logger.error(`[ValkeyGlideProvider:${this.namespace}] Error checking cache key:`, error);\n return false;\n }\n }\n\n /**\n * Get TTL for key\n */\n async ttl(key: string): Promise<number> {\n try {\n const client = await this.ensureConnected();\n\n const cacheKey = this.buildKey(key);\n return await client.ttl(cacheKey);\n } catch (error) {\n this.stats.errors++;\n logger.error(`[ValkeyGlideProvider:${this.namespace}] Error getting TTL:`, error);\n return -2;\n }\n }\n\n /**\n * Update TTL for key\n */\n async expire(key: string, ttl: number): Promise<boolean> {\n try {\n const client = await this.ensureConnected();\n\n const cacheKey = this.buildKey(key);\n return await client.expire(cacheKey, ttl);\n } catch (error) {\n this.stats.errors++;\n logger.error(`[ValkeyGlideProvider:${this.namespace}] Error setting expiration:`, error);\n return false;\n }\n }\n\n /**\n * Get multiple values (batch operation)\n */\n async mget<T>(keys: string[], _options?: BatchCacheOptions): Promise<Map<string, T>> {\n const result = new Map<string, T>();\n\n if (keys.length === 0) {\n return result;\n }\n\n try {\n const client = await this.ensureConnected();\n\n const cacheKeys = keys.map((key) => this.buildKey(key));\n const values = await client.mget(cacheKeys);\n\n for (let i = 0; i < keys.length; i++) {\n const key = keys[i];\n if (!key) continue;\n\n if (values[i] !== null) {\n const entry: CacheEntry<T> = JSON.parse(values[i]!);\n result.set(key, entry.data);\n this.stats.hits++;\n } else {\n this.stats.misses++;\n }\n }\n\n if (this.enableLogging) {\n logger.debug(`[ValkeyGlideProvider:${this.namespace}] Batch get`, {\n requested: keys.length,\n found: result.size,\n });\n }\n\n return result;\n } catch (error) {\n this.stats.errors++;\n logger.error(`[ValkeyGlideProvider:${this.namespace}] Error in batch get:`, error);\n return result;\n }\n }\n\n /**\n * Set multiple values (batch operation)\n */\n async mset<T>(entries: Map<string, T>, options?: BatchCacheOptions): Promise<boolean> {\n if (entries.size === 0) {\n return true;\n }\n\n try {\n const client = await this.ensureConnected();\n\n const ttlSeconds = options?.ttl || this.defaultTTL;\n const keyValuePairs: Record<string, string> = {};\n\n for (const [key, value] of entries) {\n const cacheKey = this.buildKey(key);\n const entry: CacheEntry<T> = {\n data: value,\n timestamp: Date.now(),\n ttl: ttlSeconds,\n metadata: options?.metadata,\n };\n keyValuePairs[cacheKey] = JSON.stringify(entry);\n }\n\n await client.mset(keyValuePairs);\n\n // Set TTL for each key (mset doesn't support TTL directly)\n for (const cacheKey of Object.keys(keyValuePairs)) {\n await client.expire(cacheKey, ttlSeconds);\n }\n\n this.stats.sets += entries.size;\n if (this.enableLogging) {\n logger.debug(`[ValkeyGlideProvider:${this.namespace}] Batch set`, {\n count: entries.size,\n ttl: ttlSeconds,\n });\n }\n\n return true;\n } catch (error) {\n this.stats.errors++;\n logger.error(`[ValkeyGlideProvider:${this.namespace}] Error in batch set:`, error);\n return false;\n }\n }\n\n /**\n * Delete multiple keys (batch operation)\n */\n async mdel(keys: string[]): Promise<number> {\n if (keys.length === 0) {\n return 0;\n }\n\n try {\n const client = await this.ensureConnected();\n\n const cacheKeys = keys.map((key) => this.buildKey(key));\n const result = await client.del(cacheKeys);\n\n this.stats.deletes += result;\n if (this.enableLogging) {\n logger.debug(`[ValkeyGlideProvider:${this.namespace}] Batch delete`, {\n requested: keys.length,\n deleted: result,\n });\n }\n\n return result;\n } catch (error) {\n this.stats.errors++;\n logger.error(`[ValkeyGlideProvider:${this.namespace}] Error in batch delete:`, error);\n return 0;\n }\n }\n\n /**\n * Clear keys by pattern\n */\n async clearPattern(pattern: string): Promise<number> {\n try {\n const client = await this.ensureConnected();\n\n const searchPattern = this.buildKey(pattern);\n const keys = await this.getKeys(searchPattern);\n\n if (keys.length === 0) {\n return 0;\n }\n\n const result = await client.del(keys);\n\n if (this.enableLogging) {\n logger.debug(`[ValkeyGlideProvider:${this.namespace}] Pattern cleared`, {\n pattern,\n deleted: result,\n });\n }\n\n return result;\n } catch (error) {\n this.stats.errors++;\n logger.error(`[ValkeyGlideProvider:${this.namespace}] Error clearing pattern:`, error);\n return 0;\n }\n }\n\n /**\n * Get keys by pattern\n */\n async keys(options: PatternOptions): Promise<PatternResult> {\n try {\n await this.ensureConnected();\n\n const searchPattern = this.buildKey(options.pattern);\n const keys = await this.getKeys(searchPattern);\n\n const prefix = `${this.namespace}:`;\n const cleanKeys = keys.map((key) => key.replace(prefix, ''));\n\n const limitedKeys = options.limit ? cleanKeys.slice(0, options.limit) : cleanKeys;\n\n return {\n keys: limitedKeys,\n nextCursor: null,\n totalCount: cleanKeys.length,\n };\n } catch (error) {\n this.stats.errors++;\n logger.error(`[ValkeyGlideProvider:${this.namespace}] Error getting keys:`, error);\n return {\n keys: [],\n nextCursor: null,\n totalCount: 0,\n };\n }\n }\n\n /**\n * Clear all keys in namespace\n */\n async clear(): Promise<boolean> {\n try {\n const client = await this.ensureConnected();\n\n const pattern = this.buildKey('*');\n const keys = await this.getKeys(pattern);\n\n if (keys.length > 0) {\n await client.del(keys);\n if (this.enableLogging) {\n logger.info(`[ValkeyGlideProvider:${this.namespace}] Cleared ${keys.length} keys`);\n }\n }\n\n return true;\n } catch (error) {\n this.stats.errors++;\n logger.error(`[ValkeyGlideProvider:${this.namespace}] Error clearing cache:`, error);\n return false;\n }\n }\n\n /**\n * Increment numeric value\n */\n async increment(key: string, amount: number = 1): Promise<number> {\n try {\n const client = await this.ensureConnected();\n\n const cacheKey = this.buildKey(key);\n return await client.incrBy(cacheKey, amount);\n } catch (error) {\n this.stats.errors++;\n logger.error(`[ValkeyGlideProvider:${this.namespace}] Error incrementing:`, error);\n throw error;\n }\n }\n\n /**\n * Decrement numeric value\n */\n async decrement(key: string, amount: number = 1): Promise<number> {\n try {\n const client = await this.ensureConnected();\n\n const cacheKey = this.buildKey(key);\n return await client.decrBy(cacheKey, amount);\n } catch (error) {\n this.stats.errors++;\n logger.error(`[ValkeyGlideProvider:${this.namespace}] Error decrementing:`, error);\n throw error;\n }\n }\n\n /**\n * Get or set value\n */\n async getOrSet<T>(key: string, fetcher: () => Promise<T>, options?: CacheOptions): Promise<T> {\n const cached = await this.get<T>(key, options);\n if (cached !== null) {\n return cached;\n }\n\n const value = await fetcher();\n await this.set(key, value, options);\n\n return value;\n }\n\n /**\n * Invalidate by tags\n */\n async invalidateTags(tags: string[]): Promise<number> {\n try {\n let totalDeleted = 0;\n\n for (const tag of tags) {\n const pattern = `*:tag:${tag}:*`;\n const deleted = await this.clearPattern(pattern);\n totalDeleted += deleted;\n }\n\n if (this.enableLogging) {\n logger.debug(`[ValkeyGlideProvider:${this.namespace}] Tags invalidated`, {\n tags,\n deleted: totalDeleted,\n });\n }\n\n return totalDeleted;\n } catch (error) {\n this.stats.errors++;\n logger.error(`[ValkeyGlideProvider:${this.namespace}] Error invalidating tags:`, error);\n return 0;\n }\n }\n}\n","/**\n * Cache Factory\n * Creates appropriate cache provider instances based on configuration\n */\nimport { logger } from '../../logger/index.js';\nimport type { ServiceLayer } from '../../types/layer.js';\nimport { DEFAULT_LAYER_RESOURCES } from '../../types/layer.js';\n\nimport { MemoryCacheProvider } from '../implementations/memory/MemoryCacheProvider.js';\nimport { ValkeyGlideProvider } from '../implementations/valkey/ValkeyGlideProvider.js';\nimport type { ICacheProvider } from '../interfaces/ICacheProvider.js';\nimport type { CacheConfig, CacheProviderTypeLiteral } from '../types/config.js';\n\n/**\n * Factory for creating cache instances\n */\nexport class CacheFactory {\n private static instances: Map<string, ICacheProvider> = new Map();\n\n private static parseBoolean(value: string | undefined): boolean | undefined {\n if (value === undefined) return undefined;\n const normalized = value.trim().toLowerCase();\n if (['1', 'true', 'yes', 'on'].includes(normalized)) return true;\n if (['0', 'false', 'no', 'off'].includes(normalized)) return false;\n return undefined;\n }\n\n private static parseClusterNodes(value: string | undefined): Array<{ host: string; port: number }> | undefined {\n if (!value) return undefined;\n\n const nodes = value\n .split(',')\n .map((node) => node.trim())\n .filter(Boolean)\n .map((node) => {\n const [host, rawPort] = node\n .replace(/^redis:\\/\\//, '')\n .replace(/^valkey:\\/\\//, '')\n .split(':');\n if (!host) return null;\n return { host, port: rawPort ? parseInt(rawPort, 10) : 6379 };\n })\n .filter((node): node is { host: string; port: number } => node !== null && Number.isFinite(node.port));\n\n return nodes.length > 0 ? nodes : undefined;\n }\n\n /**\n * Resolve port from multiple environment variable sources\n * @param layerPort - Layer-specific port environment variable value\n * @param genericPort - Generic port environment variable value\n * @param defaultPort - Default port if none provided\n * @returns Resolved port number\n */\n private static resolvePort(\n layerPort: string | undefined,\n genericPort: string | undefined,\n defaultPort: number = 6379\n ): number {\n if (layerPort) {\n return parseInt(layerPort, 10);\n }\n if (genericPort) {\n return parseInt(genericPort, 10);\n }\n return defaultPort;\n }\n\n /**\n * Create a cache provider based on configuration\n */\n static createCache(config: CacheConfig, namespace: string = 'default'): ICacheProvider {\n logger.info('[CacheFactory] Creating cache provider', {\n type: config.type,\n namespace,\n });\n\n switch (config.type) {\n case 'valkey':\n case 'redis': // Backwards compatibility - redis maps to valkey\n return new ValkeyGlideProvider(\n {\n type: 'valkey-glide',\n url: config.url,\n host: config.host,\n port: config.port,\n password: config.password,\n username: config.username,\n db: config.db,\n keyPrefix: config.keyPrefix,\n defaultTTL: config.defaultTTL,\n enableLogging: config.enableLogging,\n maxReconnectAttempts: config.maxReconnectAttempts,\n reconnectTimeWait: config.reconnectTimeWait,\n connectionTimeout: config.connectionTimeout,\n name: config.name,\n useTLS: config.tls?.enabled,\n cluster: config.cluster,\n clusterNodes: config.clusterNodes,\n },\n namespace\n );\n\n case 'memory':\n return new MemoryCacheProvider(config, namespace);\n\n // Future implementations can be added here\n // case 'memcached':\n // return new MemcachedCacheProvider(config as MemcachedCacheConfig, namespace);\n\n default:\n throw new Error(`Unsupported cache provider type: ${config.type}`);\n }\n }\n\n /**\n * Create a cache from environment variables\n */\n static createCacheFromEnv(namespace: string = 'default'): ICacheProvider {\n const envType = process.env['CACHE_PROVIDER_TYPE'] as CacheProviderTypeLiteral | undefined;\n // Default to valkey, but treat 'redis' as 'valkey' for backwards compatibility\n const type = envType === 'memory' ? 'memory' : 'valkey';\n\n const config: CacheConfig =\n type === 'valkey'\n ? {\n type: 'valkey',\n url: process.env['VALKEY_URL'],\n host: process.env['VALKEY_HOST'] || 'localhost',\n port: process.env['VALKEY_PORT'] ? parseInt(process.env['VALKEY_PORT'], 10) : 6379,\n password: process.env['VALKEY_PASSWORD'],\n db: process.env['VALKEY_DB'] ? parseInt(process.env['VALKEY_DB'], 10) : 0,\n username: process.env['VALKEY_USERNAME'],\n keyPrefix: process.env['CACHE_KEY_PREFIX'] || 'cache',\n defaultTTL: process.env['CACHE_DEFAULT_TTL'] ? parseInt(process.env['CACHE_DEFAULT_TTL'], 10) : 300,\n enableLogging: process.env['CACHE_ENABLE_LOGGING'] === 'true',\n maxReconnectAttempts: process.env['VALKEY_MAX_RECONNECT_ATTEMPTS']\n ? parseInt(process.env['VALKEY_MAX_RECONNECT_ATTEMPTS'], 10)\n : -1,\n reconnectTimeWait: process.env['VALKEY_RECONNECT_TIME_WAIT']\n ? parseInt(process.env['VALKEY_RECONNECT_TIME_WAIT'], 10)\n : 2000,\n connectionTimeout: process.env['VALKEY_CONNECTION_TIMEOUT']\n ? parseInt(process.env['VALKEY_CONNECTION_TIMEOUT'], 10)\n : 10000,\n name: process.env['CACHE_CLIENT_NAME'] || `cache-${namespace}`,\n cluster: CacheFactory.parseBoolean(process.env['VALKEY_CLUSTER'] || process.env['CACHE_CLUSTER']),\n clusterNodes: CacheFactory.parseClusterNodes(\n process.env['VALKEY_CLUSTER_NODES'] || process.env['CACHE_CLUSTER_NODES']\n ),\n }\n : {\n type: 'memory',\n maxSize: process.env['CACHE_MAX_SIZE'] ? parseInt(process.env['CACHE_MAX_SIZE'], 10) : 1000,\n defaultTTL: process.env['CACHE_DEFAULT_TTL'] ? parseInt(process.env['CACHE_DEFAULT_TTL'], 10) : 300,\n enableLogging: process.env['CACHE_ENABLE_LOGGING'] === 'true',\n keyPrefix: process.env['CACHE_KEY_PREFIX'] || 'cache',\n };\n\n return CacheFactory.createCache(config, namespace);\n }\n\n /**\n * Get or create a singleton cache instance for a namespace\n */\n static getInstance(namespace: string = 'default', config?: CacheConfig): ICacheProvider {\n const instanceKey = `${config?.type || 'default'}:${namespace}`;\n\n if (!CacheFactory.instances.has(instanceKey)) {\n const cache = config ? CacheFactory.createCache(config, namespace) : CacheFactory.createCacheFromEnv(namespace);\n CacheFactory.instances.set(instanceKey, cache);\n }\n\n return CacheFactory.instances.get(instanceKey)!;\n }\n\n /**\n * Close a specific cache instance\n */\n static async closeInstance(namespace: string): Promise<void> {\n for (const [key, cache] of CacheFactory.instances.entries()) {\n if (key.endsWith(`:${namespace}`)) {\n await cache.disconnect();\n CacheFactory.instances.delete(key);\n logger.info('[CacheFactory] Closed cache instance', { namespace });\n }\n }\n }\n\n /**\n * Close all cache instances\n * Call this during application shutdown\n */\n static async closeAll(): Promise<void> {\n const promises = Array.from(CacheFactory.instances.values()).map(async (cache) => cache.disconnect());\n await Promise.all(promises);\n CacheFactory.instances.clear();\n logger.info('[CacheFactory] All cache instances closed');\n }\n\n // ========================================================================\n // Layer-Aware Factory Methods\n // ========================================================================\n\n /**\n * Create a cache provider for a specific layer\n *\n * @param layer - Service layer ('wspace' or 'global')\n * @param serviceName - Service name for identification\n * @param namespace - Cache namespace (default: 'default')\n * @returns Cache provider configured for the layer\n *\n * @example\n * ```typescript\n * const cache = CacheFactory.createCacheForLayer('wspace', 'wspace-tags-svc');\n * await cache.connect();\n * await cache.set('key', { data: 'value' });\n * ```\n */\n static createCacheForLayer(layer: ServiceLayer, serviceName: string, namespace: string = 'default'): ICacheProvider {\n const envPrefix = layer.toUpperCase();\n const defaults = DEFAULT_LAYER_RESOURCES[layer];\n\n // Build Valkey URL from layer-specific or generic env vars\n const url = process.env[`${envPrefix}_VALKEY_URL`] || process.env['VALKEY_URL'] || defaults.valkeyUrl;\n\n // Resolve port with fallback chain\n const resolvedPort = CacheFactory.resolvePort(process.env[`${envPrefix}_VALKEY_PORT`], process.env['VALKEY_PORT']);\n\n const config: CacheConfig = {\n type: 'valkey',\n url,\n host: process.env[`${envPrefix}_VALKEY_HOST`] || process.env['VALKEY_HOST'] || 'localhost',\n port: resolvedPort,\n password: process.env['VALKEY_PASSWORD'],\n db: process.env['VALKEY_DB'] ? parseInt(process.env['VALKEY_DB'], 10) : 0,\n username: process.env['VALKEY_USERNAME'],\n keyPrefix: process.env['CACHE_KEY_PREFIX'] || `${layer}-cache`,\n defaultTTL: process.env['CACHE_DEFAULT_TTL'] ? parseInt(process.env['CACHE_DEFAULT_TTL'], 10) : 300,\n enableLogging: process.env['CACHE_ENABLE_LOGGING'] === 'true',\n maxReconnectAttempts: process.env['VALKEY_MAX_RECONNECT_ATTEMPTS']\n ? parseInt(process.env['VALKEY_MAX_RECONNECT_ATTEMPTS'], 10)\n : -1,\n reconnectTimeWait: process.env['VALKEY_RECONNECT_TIME_WAIT']\n ? parseInt(process.env['VALKEY_RECONNECT_TIME_WAIT'], 10)\n : 2000,\n connectionTimeout: process.env['VALKEY_CONNECTION_TIMEOUT']\n ? parseInt(process.env['VALKEY_CONNECTION_TIMEOUT'], 10)\n : 10000,\n name: serviceName,\n cluster: CacheFactory.parseBoolean(\n process.env[`${envPrefix}_VALKEY_CLUSTER`] || process.env['VALKEY_CLUSTER'] || process.env['CACHE_CLUSTER']\n ),\n clusterNodes: CacheFactory.parseClusterNodes(\n process.env[`${envPrefix}_VALKEY_CLUSTER_NODES`] ||\n process.env['VALKEY_CLUSTER_NODES'] ||\n process.env['CACHE_CLUSTER_NODES']\n ),\n };\n\n logger.info('[CacheFactory] Creating layer cache', {\n layer,\n serviceName,\n namespace,\n url: config.url,\n });\n\n return CacheFactory.createCache(config, namespace);\n }\n\n /**\n * Get or create a singleton cache instance for a layer\n *\n * @param layer - Service layer ('wspace' or 'global')\n * @param serviceName - Service name for identification\n * @param namespace - Cache namespace (default: 'default')\n * @returns Singleton cache provider for the layer\n */\n static getInstanceForLayer(layer: ServiceLayer, serviceName: string, namespace: string = 'default'): ICacheProvider {\n const instanceKey = `${layer}:${serviceName}:${namespace}`;\n\n if (!CacheFactory.instances.has(instanceKey)) {\n const cache = CacheFactory.createCacheForLayer(layer, serviceName, namespace);\n CacheFactory.instances.set(instanceKey, cache);\n }\n\n return CacheFactory.instances.get(instanceKey)!;\n }\n}\n","/**\n * Cache Configuration Types\n */\n\n/**\n * Cache provider type enum\n */\nexport enum CacheProviderType {\n VALKEY = 'valkey',\n MEMORY = 'memory',\n MEMCACHED = 'memcached',\n}\n\n/**\n * Cache provider type string literal\n */\nexport type CacheProviderTypeLiteral = 'valkey' | 'redis' | 'memory' | 'memcached';\n\n/**\n * Base configuration for cache\n */\nexport interface BaseCacheConfig {\n /** Cache provider type */\n type: CacheProviderType | CacheProviderTypeLiteral;\n /** Connection URL or host */\n url?: string;\n /** Cache key prefix */\n keyPrefix?: string;\n /** Default TTL in seconds */\n defaultTTL?: number;\n /** Enable debug logging */\n enableLogging?: boolean;\n /** Maximum reconnection attempts (-1 for infinite) */\n maxReconnectAttempts?: number;\n /** Time to wait between reconnection attempts (ms) */\n reconnectTimeWait?: number;\n /** Connection timeout (ms) */\n connectionTimeout?: number;\n /** Client name/identifier */\n name?: string;\n}\n\n/**\n * Valkey-specific configuration\n * Compatible with Redis protocol (Valkey is a Redis fork)\n */\nexport interface ValkeyCacheConfig extends BaseCacheConfig {\n type: CacheProviderType.VALKEY | 'valkey' | 'redis';\n /** Valkey host */\n host?: string;\n /** Valkey port */\n port?: number;\n /** Valkey password */\n password?: string;\n /** Valkey database number */\n db?: number;\n /** Valkey username */\n username?: string;\n /** Use TLS for connection (simple boolean flag) */\n useTLS?: boolean;\n /** TLS configuration (detailed) */\n tls?: {\n enabled: boolean;\n cert?: string;\n key?: string;\n ca?: string;\n };\n /** Enable cluster mode */\n cluster?: boolean;\n /** Cluster nodes (if cluster mode enabled) */\n clusterNodes?: Array<{ host: string; port: number }>;\n /** Sentinel configuration */\n sentinel?: {\n enabled: boolean;\n sentinels: Array<{ host: string; port: number }>;\n name: string;\n };\n}\n\n/**\n * Memory cache-specific configuration\n */\nexport interface MemoryCacheConfig extends BaseCacheConfig {\n type: CacheProviderType.MEMORY | 'memory';\n /** Maximum number of items in cache */\n maxSize?: number;\n /** Eviction strategy */\n evictionStrategy?: 'lru' | 'lfu' | 'fifo';\n}\n\n/**\n * Memcached-specific configuration\n */\nexport interface MemcachedCacheConfig extends BaseCacheConfig {\n type: CacheProviderType.MEMCACHED | 'memcached';\n /** Memcached servers */\n servers?: string[];\n}\n\n/**\n * Union type for all cache configurations\n */\nexport type CacheConfig = ValkeyCacheConfig | MemoryCacheConfig | MemcachedCacheConfig;\n\n/**\n * Health check result\n */\nexport interface CacheHealthCheckResult {\n /** Overall health status */\n status: 'healthy' | 'unhealthy' | 'degraded';\n /** Timestamp of health check */\n timestamp: string;\n /** Connection status */\n connected?: boolean;\n /** Latency in milliseconds */\n latencyMs?: number;\n /** Additional details */\n details?: Record<string, unknown>;\n /** Error message if unhealthy */\n error?: string;\n}\n\n/**\n * Cache statistics\n */\nexport interface CacheStatistics {\n /** Total cache hits */\n hits?: number;\n /** Total cache misses */\n misses?: number;\n /** Hit rate (0-1) */\n hitRate?: number;\n /** Total number of keys */\n keyCount?: number;\n /** Total memory used (bytes) */\n memoryUsed?: number;\n /** Total cache operations */\n totalOperations?: number;\n /** Average operation time (ms) */\n avgOperationTimeMs?: number;\n /** Last activity timestamp */\n lastActivity?: string | null;\n /** Custom metrics */\n details?: Record<string, unknown>;\n}\n"]}
|