@common-stack/server-stack 8.0.1-alpha.2 → 8.2.1-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (152) hide show
  1. package/LICENSE +34 -21
  2. package/lib/MainStackServer.cjs +126 -143
  3. package/lib/MainStackServer.cjs.map +1 -1
  4. package/lib/MainStackServer.d.ts +12 -6
  5. package/lib/MainStackServer.mjs +126 -143
  6. package/lib/MainStackServer.mjs.map +1 -1
  7. package/lib/StackServer.cjs +23 -66
  8. package/lib/StackServer.cjs.map +1 -1
  9. package/lib/StackServer.d.ts +4 -5
  10. package/lib/StackServer.mjs +23 -66
  11. package/lib/StackServer.mjs.map +1 -1
  12. package/lib/api/schema-builder.cjs +13 -12
  13. package/lib/api/schema-builder.cjs.map +1 -1
  14. package/lib/api/schema-builder.mjs +13 -12
  15. package/lib/api/schema-builder.mjs.map +1 -1
  16. package/lib/api/sub-graph-schema-builder.cjs +147 -0
  17. package/lib/api/sub-graph-schema-builder.cjs.map +1 -0
  18. package/lib/api/sub-graph-schema-builder.d.ts +24 -0
  19. package/lib/api/sub-graph-schema-builder.mjs +147 -0
  20. package/lib/api/sub-graph-schema-builder.mjs.map +1 -0
  21. package/lib/config/env-config.cjs +6 -0
  22. package/lib/config/env-config.cjs.map +1 -1
  23. package/lib/config/env-config.d.ts +6 -0
  24. package/lib/config/env-config.mjs +6 -0
  25. package/lib/config/env-config.mjs.map +1 -1
  26. package/lib/examples/tenant-feature-example.d.ts +13 -0
  27. package/lib/examples/tenant-feature-integration.d.ts +14 -0
  28. package/lib/features/multi-module-example.d.ts +17 -0
  29. package/lib/index.cjs +1 -1
  30. package/lib/index.d.ts +1 -0
  31. package/lib/index.mjs +1 -1
  32. package/lib/infrastructure/container-module.cjs +27 -0
  33. package/lib/infrastructure/container-module.cjs.map +1 -0
  34. package/lib/infrastructure/container-module.d.ts +3 -0
  35. package/lib/infrastructure/container-module.mjs +27 -0
  36. package/lib/infrastructure/container-module.mjs.map +1 -0
  37. package/lib/infrastructure/example-workflows.d.ts +16 -0
  38. package/lib/infrastructure/index.d.ts +5 -0
  39. package/lib/infrastructure/infrastructure-factory.cjs +172 -0
  40. package/lib/infrastructure/infrastructure-factory.cjs.map +1 -0
  41. package/lib/infrastructure/infrastructure-factory.d.ts +36 -0
  42. package/lib/infrastructure/infrastructure-factory.mjs +172 -0
  43. package/lib/infrastructure/infrastructure-factory.mjs.map +1 -0
  44. package/lib/infrastructure/inngest-factory.cjs +47 -0
  45. package/lib/infrastructure/inngest-factory.cjs.map +1 -0
  46. package/lib/infrastructure/inngest-factory.d.ts +8 -0
  47. package/lib/infrastructure/inngest-factory.mjs +47 -0
  48. package/lib/infrastructure/inngest-factory.mjs.map +1 -0
  49. package/lib/infrastructure/types.d.ts +28 -0
  50. package/lib/infrastructure/usage-examples.d.ts +9 -0
  51. package/lib/infrastructure/workflow-orchestrator.cjs +59 -0
  52. package/lib/infrastructure/workflow-orchestrator.cjs.map +1 -0
  53. package/lib/infrastructure/workflow-orchestrator.d.ts +10 -0
  54. package/lib/infrastructure/workflow-orchestrator.mjs +59 -0
  55. package/lib/infrastructure/workflow-orchestrator.mjs.map +1 -0
  56. package/lib/inngest/client-id-generator.d.ts +29 -0
  57. package/lib/inngest/handler-factory.d.ts +24 -0
  58. package/lib/inngest/middleware/auto-resolve-invoke.middleware.cjs +275 -0
  59. package/lib/inngest/middleware/auto-resolve-invoke.middleware.cjs.map +1 -0
  60. package/lib/inngest/middleware/auto-resolve-invoke.middleware.d.ts +111 -0
  61. package/lib/inngest/middleware/auto-resolve-invoke.middleware.mjs +275 -0
  62. package/lib/inngest/middleware/auto-resolve-invoke.middleware.mjs.map +1 -0
  63. package/lib/inngest/middleware/function-reference-helper.cjs +363 -0
  64. package/lib/inngest/middleware/function-reference-helper.cjs.map +1 -0
  65. package/lib/inngest/middleware/function-reference-helper.d.ts +211 -0
  66. package/lib/inngest/middleware/function-reference-helper.mjs +363 -0
  67. package/lib/inngest/middleware/function-reference-helper.mjs.map +1 -0
  68. package/lib/inngest/middleware/index.d.ts +31 -0
  69. package/lib/inngest/middleware/types.d.ts +162 -0
  70. package/lib/inngest/multi-module-functions.d.ts +133 -0
  71. package/lib/inngest/setup.cjs +55 -0
  72. package/lib/inngest/setup.cjs.map +1 -0
  73. package/lib/inngest/setup.d.ts +10 -0
  74. package/lib/inngest/setup.mjs +55 -0
  75. package/lib/inngest/setup.mjs.map +1 -0
  76. package/lib/interfaces/graphql-request-context.d.ts +20 -0
  77. package/lib/interfaces/index.d.ts +1 -0
  78. package/lib/middleware/index.d.ts +5 -0
  79. package/lib/middleware/redis-client.cjs +18 -0
  80. package/lib/middleware/redis-client.cjs.map +1 -0
  81. package/lib/middleware/redis-client.d.ts +16 -0
  82. package/lib/middleware/redis-client.mjs +18 -0
  83. package/lib/middleware/redis-client.mjs.map +1 -0
  84. package/lib/plugins/index.d.ts +1 -0
  85. package/lib/plugins/invalidateCachePlugin.cjs +33 -10
  86. package/lib/plugins/invalidateCachePlugin.cjs.map +1 -1
  87. package/lib/plugins/invalidateCachePlugin.mjs +33 -10
  88. package/lib/plugins/invalidateCachePlugin.mjs.map +1 -1
  89. package/lib/plugins/responseCachePlugin.cjs +63 -0
  90. package/lib/plugins/responseCachePlugin.cjs.map +1 -0
  91. package/lib/plugins/responseCachePlugin.d.ts +12 -0
  92. package/lib/plugins/responseCachePlugin.mjs +63 -0
  93. package/lib/plugins/responseCachePlugin.mjs.map +1 -0
  94. package/lib/servers/ExpressApp.cjs +8 -3
  95. package/lib/servers/ExpressApp.cjs.map +1 -1
  96. package/lib/servers/ExpressApp.d.ts +1 -1
  97. package/lib/servers/ExpressApp.mjs +8 -3
  98. package/lib/servers/ExpressApp.mjs.map +1 -1
  99. package/lib/servers/GraphqlServer.cjs +10 -36
  100. package/lib/servers/GraphqlServer.cjs.map +1 -1
  101. package/lib/servers/GraphqlServer.d.ts +8 -6
  102. package/lib/servers/GraphqlServer.mjs +10 -36
  103. package/lib/servers/GraphqlServer.mjs.map +1 -1
  104. package/lib/servers/GraphqlWs.cjs +3 -44
  105. package/lib/servers/GraphqlWs.cjs.map +1 -1
  106. package/lib/servers/GraphqlWs.mjs +3 -44
  107. package/lib/servers/GraphqlWs.mjs.map +1 -1
  108. package/lib/servers/WebsocketMultipathUpdate.cjs +4 -2
  109. package/lib/servers/WebsocketMultipathUpdate.cjs.map +1 -1
  110. package/lib/servers/WebsocketMultipathUpdate.mjs +4 -2
  111. package/lib/servers/WebsocketMultipathUpdate.mjs.map +1 -1
  112. package/lib/servers/mongodb-migration-update.d.ts +1 -1
  113. package/lib/servers/websocket-context.cjs +70 -0
  114. package/lib/servers/websocket-context.cjs.map +1 -0
  115. package/lib/servers/websocket-context.d.ts +30 -0
  116. package/lib/servers/websocket-context.mjs +70 -0
  117. package/lib/servers/websocket-context.mjs.map +1 -0
  118. package/lib/utils/add-shareable-directive-to-schema.cjs +44 -0
  119. package/lib/utils/add-shareable-directive-to-schema.cjs.map +1 -0
  120. package/lib/utils/add-shareable-directive-to-schema.d.ts +1 -0
  121. package/lib/utils/add-shareable-directive-to-schema.mjs +44 -0
  122. package/lib/utils/add-shareable-directive-to-schema.mjs.map +1 -0
  123. package/lib/utils/index.d.ts +3 -0
  124. package/lib/utils/safe-model-factory.d.ts +18 -0
  125. package/package.json +15 -11
  126. package/lib/api/resolver.cjs +0 -12
  127. package/lib/api/resolver.cjs.map +0 -1
  128. package/lib/api/resolver.mjs +0 -12
  129. package/lib/api/resolver.mjs.map +0 -1
  130. package/lib/api/root-schema.graphqls.cjs +0 -2
  131. package/lib/api/root-schema.graphqls.cjs.map +0 -1
  132. package/lib/api/root-schema.graphqls.mjs +0 -2
  133. package/lib/api/root-schema.graphqls.mjs.map +0 -1
  134. package/lib/api/scalar.cjs +0 -16
  135. package/lib/api/scalar.cjs.map +0 -1
  136. package/lib/api/scalar.mjs +0 -16
  137. package/lib/api/scalar.mjs.map +0 -1
  138. package/lib/graphql/directives/index.cjs +0 -10
  139. package/lib/graphql/directives/index.cjs.map +0 -1
  140. package/lib/graphql/directives/index.d.ts +0 -7
  141. package/lib/graphql/directives/index.mjs +0 -10
  142. package/lib/graphql/directives/index.mjs.map +0 -1
  143. package/lib/graphql/index.d.ts +0 -2
  144. package/lib/graphql/schema/directives.graphql.cjs +0 -1
  145. package/lib/graphql/schema/directives.graphql.cjs.map +0 -1
  146. package/lib/graphql/schema/directives.graphql.mjs +0 -1
  147. package/lib/graphql/schema/directives.graphql.mjs.map +0 -1
  148. package/lib/graphql/schema/index.cjs +0 -1
  149. package/lib/graphql/schema/index.cjs.map +0 -1
  150. package/lib/graphql/schema/index.d.ts +0 -1
  151. package/lib/graphql/schema/index.mjs +0 -1
  152. package/lib/graphql/schema/index.mjs.map +0 -1
@@ -0,0 +1,133 @@
1
+ import { Container } from 'inversify';
2
+ /**
3
+ * User management Inngest functions that depend on container services
4
+ */
5
+ export declare const userInngestFunctions: ({ container, inngest, settings, }: {
6
+ container: Container;
7
+ inngest: any;
8
+ settings?: any;
9
+ }) => {
10
+ createUserFunction: {
11
+ id: string;
12
+ _type: string;
13
+ };
14
+ updateUserProfileFunction: {
15
+ id: string;
16
+ _type: string;
17
+ };
18
+ };
19
+ /**
20
+ * Email campaign Inngest functions that depend on container services
21
+ */
22
+ export declare const emailCampaignInngestFunctions: ({ container, inngest, settings, }: {
23
+ container: Container;
24
+ inngest: any;
25
+ settings?: any;
26
+ }) => {
27
+ sendCampaignFunction: {
28
+ id: string;
29
+ _type: string;
30
+ };
31
+ trackEmailOpenFunction: {
32
+ id: string;
33
+ _type: string;
34
+ };
35
+ };
36
+ /**
37
+ * Analytics Inngest functions that depend on container services
38
+ */
39
+ export declare const analyticsInngestFunctions: ({ container, inngest, settings, }: {
40
+ container: Container;
41
+ inngest: any;
42
+ settings?: any;
43
+ }) => {
44
+ generateReportFunction: {
45
+ id: string;
46
+ _type: string;
47
+ };
48
+ trackUserEventFunction: {
49
+ id: string;
50
+ _type: string;
51
+ };
52
+ };
53
+ /**
54
+ * AI Page Creator functions that depend on container services
55
+ */
56
+ export declare const aiPageCreatorInngestFunctions: ({ container, inngest, settings, }: {
57
+ container: Container;
58
+ inngest: any;
59
+ settings?: any;
60
+ }) => {
61
+ codeAgentFunction: {
62
+ id: string;
63
+ _type: string;
64
+ };
65
+ sendMessageFunction: {
66
+ id: string;
67
+ _type: string;
68
+ };
69
+ processPageFunction: {
70
+ id: string;
71
+ _type: string;
72
+ };
73
+ };
74
+ /**
75
+ * Export array of all function factories for easy registration
76
+ */
77
+ export declare const allInngestFunctionFactories: ((({ container, inngest, settings, }: {
78
+ container: Container;
79
+ inngest: any;
80
+ settings?: any;
81
+ }) => {
82
+ createUserFunction: {
83
+ id: string;
84
+ _type: string;
85
+ };
86
+ updateUserProfileFunction: {
87
+ id: string;
88
+ _type: string;
89
+ };
90
+ }) | (({ container, inngest, settings, }: {
91
+ container: Container;
92
+ inngest: any;
93
+ settings?: any;
94
+ }) => {
95
+ sendCampaignFunction: {
96
+ id: string;
97
+ _type: string;
98
+ };
99
+ trackEmailOpenFunction: {
100
+ id: string;
101
+ _type: string;
102
+ };
103
+ }) | (({ container, inngest, settings, }: {
104
+ container: Container;
105
+ inngest: any;
106
+ settings?: any;
107
+ }) => {
108
+ generateReportFunction: {
109
+ id: string;
110
+ _type: string;
111
+ };
112
+ trackUserEventFunction: {
113
+ id: string;
114
+ _type: string;
115
+ };
116
+ }) | (({ container, inngest, settings, }: {
117
+ container: Container;
118
+ inngest: any;
119
+ settings?: any;
120
+ }) => {
121
+ codeAgentFunction: {
122
+ id: string;
123
+ _type: string;
124
+ };
125
+ sendMessageFunction: {
126
+ id: string;
127
+ _type: string;
128
+ };
129
+ processPageFunction: {
130
+ id: string;
131
+ _type: string;
132
+ };
133
+ }))[];
@@ -0,0 +1,55 @@
1
+ 'use strict';var express=require('inngest/express'),functionReferenceHelper=require('./middleware/function-reference-helper.cjs');/**
2
+ * Sets up Inngest functions from the Feature system and registers the handler
3
+ */
4
+ async function setupInngestFunctions(modules, app, serviceContainer, logger) {
5
+ try {
6
+ // Get Inngest client from the container (already bound in infraModule)
7
+ const inngestClient = serviceContainer.get('INNGEST_CLIENT');
8
+ logger.info('✅ Retrieved Inngest client from service container');
9
+ // Load Inngest functions from all modules
10
+ // The improved loadInngestFunctions now handles both array and object returns
11
+ const inngestFunctions = await modules.loadInngestFunctions({
12
+ container: serviceContainer,
13
+ inngest: inngestClient,
14
+ settings: {},
15
+ });
16
+ if (inngestFunctions.length > 0) {
17
+ logger.info(`✅ Loaded ${inngestFunctions.length} Inngest functions from Feature system`);
18
+ // Log function IDs for debugging
19
+ const functionIds = inngestFunctions
20
+ .filter((fn) => fn && fn.id)
21
+ .map((fn) => (typeof fn.id === 'function' ? fn.id() : fn.id))
22
+ .join(', ');
23
+ logger.debug(`Registering Inngest functions: ${functionIds}`);
24
+ // ✨ Register functions with global registry for referenceFunction() helper
25
+ logger.info('📝 Registering functions with global function registry...');
26
+ try {
27
+ functionReferenceHelper.globalFunctionRegistry.register(inngestFunctions);
28
+ logger.info(`✅ Registered ${functionReferenceHelper.globalFunctionRegistry.count} functions for referenceFunction() helper`);
29
+ logger.info('💡 You can now use: referenceFunction("function-id") or auto-invoke in step.invoke()');
30
+ }
31
+ catch (registryError) {
32
+ logger.error('❌ Error registering functions with global registry:', registryError);
33
+ }
34
+ // Register Inngest handler
35
+ logger.info('📞 Calling serve() to register Inngest handler...');
36
+ const inngestHandler = express.serve({
37
+ client: inngestClient,
38
+ functions: inngestFunctions,
39
+ });
40
+ logger.info('✅ serve() completed successfully');
41
+ app.use('/api/inngest', inngestHandler);
42
+ logger.info(`✅ Inngest handler registered at /api/inngest with ${inngestFunctions.length} functions`);
43
+ }
44
+ else {
45
+ logger.info('No Inngest functions found - handler not registered');
46
+ }
47
+ }
48
+ catch (error) {
49
+ logger.warn('Inngest handler registration failed:', error?.message || String(error));
50
+ logger.debug('Full error stack:', error?.stack || error);
51
+ if (error && typeof error === 'object') {
52
+ logger.debug('Error keys:', Object.keys(error));
53
+ }
54
+ }
55
+ }exports.setupInngestFunctions=setupInngestFunctions;//# sourceMappingURL=setup.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup.cjs","sources":["../../src/inngest/setup.ts"],"sourcesContent":[null],"names":["globalFunctionRegistry","serve"],"mappings":"kIAWA;;AAEG;AACI,eAAe,qBAAqB,CACvC,OAAgB,EAChB,GAAY,EACZ,gBAA2B,EAC3B,MAAe,EAAA;AAEf,IAAA,IAAI;;QAEA,MAAM,aAAa,GAAG,gBAAgB,CAAC,GAAG,CAAU,gBAAgB,CAAC,CAAC;AACtE,QAAA,MAAM,CAAC,IAAI,CAAC,mDAAmD,CAAC,CAAC;;;AAIjE,QAAA,MAAM,gBAAgB,GAAG,MAAM,OAAO,CAAC,oBAAoB,CAAC;AACxD,YAAA,SAAS,EAAE,gBAAgB;AAC3B,YAAA,OAAO,EAAE,aAAa;AACtB,YAAA,QAAQ,EAAE,EAAE;AACf,SAAA,CAAC,CAAC;AAEH,QAAA,IAAI,gBAAgB,CAAC,MAAM,GAAG,CAAC,EAAE;YAC7B,MAAM,CAAC,IAAI,CAAC,CAAA,SAAA,EAAY,gBAAgB,CAAC,MAAM,CAAwC,sCAAA,CAAA,CAAC,CAAC;;YAGzF,MAAM,WAAW,GAAG,gBAAgB;iBAC/B,MAAM,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;iBAC3B,GAAG,CAAC,CAAC,EAAE,MAAM,OAAO,EAAE,CAAC,EAAE,KAAK,UAAU,GAAG,EAAE,CAAC,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;iBAC5D,IAAI,CAAC,IAAI,CAAC,CAAC;AAChB,YAAA,MAAM,CAAC,KAAK,CAAC,kCAAkC,WAAW,CAAA,CAAE,CAAC,CAAC;;AAG9D,YAAA,MAAM,CAAC,IAAI,CAAC,2DAA2D,CAAC,CAAC;AACzE,YAAA,IAAI;AACA,gBAAAA,8CAAsB,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAC;gBAClD,MAAM,CAAC,IAAI,CAAC,CAAA,aAAA,EAAgBA,8CAAsB,CAAC,KAAK,CAA2C,yCAAA,CAAA,CAAC,CAAC;AACrG,gBAAA,MAAM,CAAC,IAAI,CAAC,sFAAsF,CAAC,CAAC;aACvG;YAAC,OAAO,aAAa,EAAE;AACpB,gBAAA,MAAM,CAAC,KAAK,CAAC,qDAAqD,EAAE,aAAa,CAAC,CAAC;aACtF;;AAGD,YAAA,MAAM,CAAC,IAAI,CAAC,mDAAmD,CAAC,CAAC;YACjE,MAAM,cAAc,GAAGC,aAAK,CAAC;AACzB,gBAAA,MAAM,EAAE,aAAa;AACrB,gBAAA,SAAS,EAAE,gBAAgB;AAC9B,aAAA,CAAC,CAAC;AACH,YAAA,MAAM,CAAC,IAAI,CAAC,kCAAkC,CAAC,CAAC;AAEhD,YAAA,GAAG,CAAC,GAAG,CAAC,cAAc,EAAE,cAAc,CAAC,CAAC;YACxC,MAAM,CAAC,IAAI,CAAC,CAAA,kDAAA,EAAqD,gBAAgB,CAAC,MAAM,CAAY,UAAA,CAAA,CAAC,CAAC;SACzG;aAAM;AACH,YAAA,MAAM,CAAC,IAAI,CAAC,qDAAqD,CAAC,CAAC;SACtE;KACJ;IAAC,OAAO,KAAK,EAAE;AACZ,QAAA,MAAM,CAAC,IAAI,CAAC,sCAAsC,EAAE,KAAK,EAAE,OAAO,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;QACrF,MAAM,CAAC,KAAK,CAAC,mBAAmB,EAAE,KAAK,EAAE,KAAK,IAAI,KAAK,CAAC,CAAC;AACzD,QAAA,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE;AACpC,YAAA,MAAM,CAAC,KAAK,CAAC,aAAa,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;SACnD;KACJ;AACL"}
@@ -0,0 +1,10 @@
1
+ import { Express } from 'express';
2
+ import { Container } from 'inversify';
3
+ import { CdmLogger } from '@cdm-logger/core';
4
+ import { Feature } from '@common-stack/server-core';
5
+ type ILogger = CdmLogger.ILogger;
6
+ /**
7
+ * Sets up Inngest functions from the Feature system and registers the handler
8
+ */
9
+ export declare function setupInngestFunctions(modules: Feature, app: Express, serviceContainer: Container, logger: ILogger): Promise<void>;
10
+ export {};
@@ -0,0 +1,55 @@
1
+ import {serve}from'inngest/express';import {globalFunctionRegistry}from'./middleware/function-reference-helper.mjs';/**
2
+ * Sets up Inngest functions from the Feature system and registers the handler
3
+ */
4
+ async function setupInngestFunctions(modules, app, serviceContainer, logger) {
5
+ try {
6
+ // Get Inngest client from the container (already bound in infraModule)
7
+ const inngestClient = serviceContainer.get('INNGEST_CLIENT');
8
+ logger.info('✅ Retrieved Inngest client from service container');
9
+ // Load Inngest functions from all modules
10
+ // The improved loadInngestFunctions now handles both array and object returns
11
+ const inngestFunctions = await modules.loadInngestFunctions({
12
+ container: serviceContainer,
13
+ inngest: inngestClient,
14
+ settings: {},
15
+ });
16
+ if (inngestFunctions.length > 0) {
17
+ logger.info(`✅ Loaded ${inngestFunctions.length} Inngest functions from Feature system`);
18
+ // Log function IDs for debugging
19
+ const functionIds = inngestFunctions
20
+ .filter((fn) => fn && fn.id)
21
+ .map((fn) => (typeof fn.id === 'function' ? fn.id() : fn.id))
22
+ .join(', ');
23
+ logger.debug(`Registering Inngest functions: ${functionIds}`);
24
+ // ✨ Register functions with global registry for referenceFunction() helper
25
+ logger.info('📝 Registering functions with global function registry...');
26
+ try {
27
+ globalFunctionRegistry.register(inngestFunctions);
28
+ logger.info(`✅ Registered ${globalFunctionRegistry.count} functions for referenceFunction() helper`);
29
+ logger.info('💡 You can now use: referenceFunction("function-id") or auto-invoke in step.invoke()');
30
+ }
31
+ catch (registryError) {
32
+ logger.error('❌ Error registering functions with global registry:', registryError);
33
+ }
34
+ // Register Inngest handler
35
+ logger.info('📞 Calling serve() to register Inngest handler...');
36
+ const inngestHandler = serve({
37
+ client: inngestClient,
38
+ functions: inngestFunctions,
39
+ });
40
+ logger.info('✅ serve() completed successfully');
41
+ app.use('/api/inngest', inngestHandler);
42
+ logger.info(`✅ Inngest handler registered at /api/inngest with ${inngestFunctions.length} functions`);
43
+ }
44
+ else {
45
+ logger.info('No Inngest functions found - handler not registered');
46
+ }
47
+ }
48
+ catch (error) {
49
+ logger.warn('Inngest handler registration failed:', error?.message || String(error));
50
+ logger.debug('Full error stack:', error?.stack || error);
51
+ if (error && typeof error === 'object') {
52
+ logger.debug('Error keys:', Object.keys(error));
53
+ }
54
+ }
55
+ }export{setupInngestFunctions};//# sourceMappingURL=setup.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup.mjs","sources":["../../src/inngest/setup.ts"],"sourcesContent":[null],"names":[],"mappings":"oHAWA;;AAEG;AACI,eAAe,qBAAqB,CACvC,OAAgB,EAChB,GAAY,EACZ,gBAA2B,EAC3B,MAAe,EAAA;AAEf,IAAA,IAAI;;QAEA,MAAM,aAAa,GAAG,gBAAgB,CAAC,GAAG,CAAU,gBAAgB,CAAC,CAAC;AACtE,QAAA,MAAM,CAAC,IAAI,CAAC,mDAAmD,CAAC,CAAC;;;AAIjE,QAAA,MAAM,gBAAgB,GAAG,MAAM,OAAO,CAAC,oBAAoB,CAAC;AACxD,YAAA,SAAS,EAAE,gBAAgB;AAC3B,YAAA,OAAO,EAAE,aAAa;AACtB,YAAA,QAAQ,EAAE,EAAE;AACf,SAAA,CAAC,CAAC;AAEH,QAAA,IAAI,gBAAgB,CAAC,MAAM,GAAG,CAAC,EAAE;YAC7B,MAAM,CAAC,IAAI,CAAC,CAAA,SAAA,EAAY,gBAAgB,CAAC,MAAM,CAAwC,sCAAA,CAAA,CAAC,CAAC;;YAGzF,MAAM,WAAW,GAAG,gBAAgB;iBAC/B,MAAM,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;iBAC3B,GAAG,CAAC,CAAC,EAAE,MAAM,OAAO,EAAE,CAAC,EAAE,KAAK,UAAU,GAAG,EAAE,CAAC,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;iBAC5D,IAAI,CAAC,IAAI,CAAC,CAAC;AAChB,YAAA,MAAM,CAAC,KAAK,CAAC,kCAAkC,WAAW,CAAA,CAAE,CAAC,CAAC;;AAG9D,YAAA,MAAM,CAAC,IAAI,CAAC,2DAA2D,CAAC,CAAC;AACzE,YAAA,IAAI;AACA,gBAAA,sBAAsB,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAC;gBAClD,MAAM,CAAC,IAAI,CAAC,CAAA,aAAA,EAAgB,sBAAsB,CAAC,KAAK,CAA2C,yCAAA,CAAA,CAAC,CAAC;AACrG,gBAAA,MAAM,CAAC,IAAI,CAAC,sFAAsF,CAAC,CAAC;aACvG;YAAC,OAAO,aAAa,EAAE;AACpB,gBAAA,MAAM,CAAC,KAAK,CAAC,qDAAqD,EAAE,aAAa,CAAC,CAAC;aACtF;;AAGD,YAAA,MAAM,CAAC,IAAI,CAAC,mDAAmD,CAAC,CAAC;YACjE,MAAM,cAAc,GAAG,KAAK,CAAC;AACzB,gBAAA,MAAM,EAAE,aAAa;AACrB,gBAAA,SAAS,EAAE,gBAAgB;AAC9B,aAAA,CAAC,CAAC;AACH,YAAA,MAAM,CAAC,IAAI,CAAC,kCAAkC,CAAC,CAAC;AAEhD,YAAA,GAAG,CAAC,GAAG,CAAC,cAAc,EAAE,cAAc,CAAC,CAAC;YACxC,MAAM,CAAC,IAAI,CAAC,CAAA,kDAAA,EAAqD,gBAAgB,CAAC,MAAM,CAAY,UAAA,CAAA,CAAC,CAAC;SACzG;aAAM;AACH,YAAA,MAAM,CAAC,IAAI,CAAC,qDAAqD,CAAC,CAAC;SACtE;KACJ;IAAC,OAAO,KAAK,EAAE;AACZ,QAAA,MAAM,CAAC,IAAI,CAAC,sCAAsC,EAAE,KAAK,EAAE,OAAO,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;QACrF,MAAM,CAAC,KAAK,CAAC,mBAAmB,EAAE,KAAK,EAAE,KAAK,IAAI,KAAK,CAAC,CAAC;AACzD,QAAA,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE;AACpC,YAAA,MAAM,CAAC,KAAK,CAAC,aAAa,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;SACnD;KACJ;AACL"}
@@ -0,0 +1,20 @@
1
+ import type { ServiceBroker } from 'moleculer';
2
+ export type GraphqlRequestContext = {
3
+ overallCachePolicy: {
4
+ scope: string;
5
+ maxAge: number;
6
+ };
7
+ user: {
8
+ sub: string;
9
+ };
10
+ req: {
11
+ currentPageUriSegments: {
12
+ authority: string;
13
+ };
14
+ tenant?: string;
15
+ };
16
+ queriesToInvalidate: string[];
17
+ tenantId?: string;
18
+ accountId?: string;
19
+ moleculerBroker?: ServiceBroker;
20
+ };
@@ -1,3 +1,4 @@
1
1
  export * from './moleculer';
2
2
  export * from './module-interface';
3
3
  export * from './dbMigration';
4
+ export * from './graphql-request-context';
@@ -0,0 +1,5 @@
1
+ export { redisClientMiddleware } from './redis-client';
2
+ export { contextServicesMiddleware } from './services';
3
+ export { corsMiddleware } from './cors';
4
+ export { errorMiddleware } from './error';
5
+ export { sentryMiddleware, sentryErrorHandlerMiddleware } from './sentry';
@@ -0,0 +1,18 @@
1
+ 'use strict';/**
2
+ * Redis Client Middleware
3
+ *
4
+ * This middleware attaches the Redis client to the request object,
5
+ * making it available for session storage and other Redis operations.
6
+ */
7
+ /**
8
+ * Creates middleware that attaches Redis client to request object
9
+ * @param redisClient - The Redis client instance
10
+ * @returns Express middleware function
11
+ */
12
+ function redisClientMiddleware(redisClient) {
13
+ return (req, res, next) => {
14
+ // Attach Redis client to request object
15
+ req.redisClient = redisClient;
16
+ next();
17
+ };
18
+ }exports.redisClientMiddleware=redisClientMiddleware;//# sourceMappingURL=redis-client.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redis-client.cjs","sources":["../../src/middleware/redis-client.ts"],"sourcesContent":[null],"names":[],"mappings":"aAAA;;;;;AAKG;AAQH;;;;AAIG;AACG,SAAU,qBAAqB,CAAC,WAAgB,EAAA;AAClD,IAAA,OAAO,CAAC,GAAuB,EAAE,GAAa,EAAE,IAAkB,KAAI;;AAElE,QAAA,GAAG,CAAC,WAAW,GAAG,WAAW,CAAC;AAC9B,QAAA,IAAI,EAAE,CAAC;AACX,KAAC,CAAC;AACN"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Redis Client Middleware
3
+ *
4
+ * This middleware attaches the Redis client to the request object,
5
+ * making it available for session storage and other Redis operations.
6
+ */
7
+ import { Request, Response, NextFunction } from 'express';
8
+ export interface RedisClientRequest extends Request {
9
+ redisClient?: any;
10
+ }
11
+ /**
12
+ * Creates middleware that attaches Redis client to request object
13
+ * @param redisClient - The Redis client instance
14
+ * @returns Express middleware function
15
+ */
16
+ export declare function redisClientMiddleware(redisClient: any): (req: RedisClientRequest, res: Response, next: NextFunction) => void;
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Redis Client Middleware
3
+ *
4
+ * This middleware attaches the Redis client to the request object,
5
+ * making it available for session storage and other Redis operations.
6
+ */
7
+ /**
8
+ * Creates middleware that attaches Redis client to request object
9
+ * @param redisClient - The Redis client instance
10
+ * @returns Express middleware function
11
+ */
12
+ function redisClientMiddleware(redisClient) {
13
+ return (req, res, next) => {
14
+ // Attach Redis client to request object
15
+ req.redisClient = redisClient;
16
+ next();
17
+ };
18
+ }export{redisClientMiddleware};//# sourceMappingURL=redis-client.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redis-client.mjs","sources":["../../src/middleware/redis-client.ts"],"sourcesContent":[null],"names":[],"mappings":"AAAA;;;;;AAKG;AAQH;;;;AAIG;AACG,SAAU,qBAAqB,CAAC,WAAgB,EAAA;AAClD,IAAA,OAAO,CAAC,GAAuB,EAAE,GAAa,EAAE,IAAkB,KAAI;;AAElE,QAAA,GAAG,CAAC,WAAW,GAAG,WAAW,CAAC;AAC9B,QAAA,IAAI,EAAE,CAAC;AACX,KAAC,CAAC;AACN"}
@@ -1 +1,2 @@
1
1
  export * from './invalidateCachePlugin';
2
+ export { responseCachePlugin } from './responseCachePlugin';
@@ -1,4 +1,4 @@
1
- 'use strict';var envConfig=require('../config/env-config.cjs');const invalidateCachePlugin = ({ cache: redisClient, invalidateCacheKeyGenerator, }) => ({
1
+ 'use strict';var _=require('lodash-es'),serverCore=require('@common-stack/server-core'),envConfig=require('../config/env-config.cjs');const invalidateCachePlugin = ({ cache: redisClient, invalidateCacheKeyGenerator, }) => ({
2
2
  requestDidStart(requestContext) {
3
3
  return {
4
4
  willSendResponse: async (responseContext) => {
@@ -8,26 +8,49 @@
8
8
  }
9
9
  try {
10
10
  const hasErrors = !!requestContext.errors?.length;
11
- const { queriesToInvalidate } = requestContext.contextValue;
11
+ const { schema } = requestContext;
12
+ const { queriesToInvalidate, user, req } = requestContext.contextValue;
13
+ const tenantId = serverCore.extractTenantId(req?.currentPageUriSegments?.authority);
12
14
  const [{ operation }] = responseContext.document.definitions;
13
15
  const isMutation = operation === 'mutation';
14
16
  if (hasErrors || !queriesToInvalidate?.length || !isMutation) {
15
17
  return;
16
18
  }
17
- // this to get the
18
19
  const nestedKeys = await Promise.all(queriesToInvalidate.map(async (query) => {
19
- let defaultKey = `${envConfig.config.APP_NAME}:${query}:*`;
20
- if (typeof invalidateCacheKeyGenerator === 'function') {
21
- const generatedKey = invalidateCacheKeyGenerator(requestContext, responseContext, defaultKey);
22
- if (generatedKey) {
23
- defaultKey = generatedKey;
20
+ // Build keys in order of specificity
21
+ let keys = [];
22
+ const cachePolicy = serverCore.getDirectiveArgsFromSchema({
23
+ schema,
24
+ queryName: query,
25
+ directiveName: serverCore.CACHE_CONTROL_DIRECTIVE,
26
+ });
27
+ const isPrivate = cachePolicy.scope?.toLowerCase() === 'private';
28
+ // Add tenant-specific key if tenant exists
29
+ if (tenantId) {
30
+ keys.push(`${envConfig.config.APP_NAME}:${tenantId}:${query}:*`);
31
+ // Add user-specific key if user exists
32
+ if (user?.sub && isPrivate) {
33
+ keys.push(`${envConfig.config.APP_NAME}:${tenantId}:${user.sub}:${query}:*`);
24
34
  }
25
35
  }
26
- return redisClient.keys(defaultKey);
36
+ // Add global key as fallback
37
+ keys.push(`${envConfig.config.APP_NAME}:${query}:*`);
38
+ // Allow custom key generation if provided
39
+ if (typeof invalidateCacheKeyGenerator === 'function') {
40
+ keys = keys.map((key) => invalidateCacheKeyGenerator(requestContext, responseContext, key));
41
+ }
42
+ const matchedKeys = await Promise.all(keys.map(async (key) => {
43
+ const matchingKeys = await redisClient.keys(key);
44
+ if (matchingKeys.length) {
45
+ return matchingKeys;
46
+ }
47
+ return [];
48
+ }));
49
+ return matchedKeys.flat();
27
50
  }));
28
51
  const keys = nestedKeys.flat();
29
52
  if (keys?.length) {
30
- await redisClient.del(keys);
53
+ await redisClient.del(_.uniq(keys));
31
54
  }
32
55
  }
33
56
  catch (e) {
@@ -1 +1 @@
1
- {"version":3,"file":"invalidateCachePlugin.cjs","sources":["../../src/plugins/invalidateCachePlugin.ts"],"sourcesContent":[null],"names":["config"],"mappings":"+DAWO,MAAM,qBAAqB,GAAG,CAAC,EAClC,KAAK,EAAE,WAAW,EAClB,2BAA2B,GAI9B,MACI;AACG,IAAA,eAAe,CAAC,cAA8C,EAAA;QAC1D,OAAO;AACH,YAAA,gBAAgB,EAAE,OAAO,eAA+D,KAAI;;gBAExF,IAAI,CAAC,cAAc,EAAE;oBACjB,OAAO;iBACV;AACD,gBAAA,IAAI;oBACA,MAAM,SAAS,GAAG,CAAC,CAAC,cAAc,CAAC,MAAM,EAAE,MAAM,CAAC;AAClD,oBAAA,MAAM,EAAE,mBAAmB,EAAE,GAAG,cAAc,CAAC,YAE9C,CAAC;oBACF,MAAM,CAAC,EAAE,SAAS,EAAE,CAAC,GAAG,eAAe,CAAC,QAAQ,CAAC,WAAwC,CAAC;AAC1F,oBAAA,MAAM,UAAU,GAAG,SAAS,KAAK,UAAU,CAAC;oBAC5C,IAAI,SAAS,IAAI,CAAC,mBAAmB,EAAE,MAAM,IAAI,CAAC,UAAU,EAAE;wBAC1D,OAAO;qBACV;;AAED,oBAAA,MAAM,UAAU,GAAG,MAAM,OAAO,CAAC,GAAG,CAChC,mBAAmB,CAAC,GAAG,CAAC,OAAO,KAAa,KAAI;wBAC5C,IAAI,UAAU,GAAG,CAAG,EAAAA,gBAAM,CAAC,QAAQ,CAAA,CAAA,EAAI,KAAK,CAAA,EAAA,CAAI,CAAC;AACjD,wBAAA,IAAI,OAAO,2BAA2B,KAAK,UAAU,EAAE;4BACnD,MAAM,YAAY,GAAG,2BAA2B,CAC5C,cAAc,EACd,eAAe,EACf,UAAU,CACb,CAAC;4BACF,IAAI,YAAY,EAAE;gCACd,UAAU,GAAG,YAAY,CAAC;6BAC7B;yBACJ;AACD,wBAAA,OAAO,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;qBACvC,CAAC,CACL,CAAC;AACF,oBAAA,MAAM,IAAI,GAAG,UAAU,CAAC,IAAI,EAAE,CAAC;AAC/B,oBAAA,IAAI,IAAI,EAAE,MAAM,EAAE;AACd,wBAAA,MAAM,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;qBAC/B;iBACJ;gBAAC,OAAO,CAAC,EAAE;AACR,oBAAA,cAAc,CAAC,MAAM,CAAC,KAAK,CAAC,yCAAyC,CAAC,CAAC;AACvE,oBAAA,cAAc,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;iBAClC;aACJ;SACJ,CAAC;KACL;AACJ,CAAA"}
1
+ {"version":3,"file":"invalidateCachePlugin.cjs","sources":["../../src/plugins/invalidateCachePlugin.ts"],"sourcesContent":[null],"names":["extractTenantId","getDirectiveArgsFromSchema","CACHE_CONTROL_DIRECTIVE","config","uniq"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import {config}from'../config/env-config.mjs';const invalidateCachePlugin = ({ cache: redisClient, invalidateCacheKeyGenerator, }) => ({
1
+ import {uniq}from'lodash-es';import {extractTenantId,getDirectiveArgsFromSchema,CACHE_CONTROL_DIRECTIVE}from'@common-stack/server-core';import {config}from'../config/env-config.mjs';const invalidateCachePlugin = ({ cache: redisClient, invalidateCacheKeyGenerator, }) => ({
2
2
  requestDidStart(requestContext) {
3
3
  return {
4
4
  willSendResponse: async (responseContext) => {
@@ -8,26 +8,49 @@ import {config}from'../config/env-config.mjs';const invalidateCachePlugin = ({ c
8
8
  }
9
9
  try {
10
10
  const hasErrors = !!requestContext.errors?.length;
11
- const { queriesToInvalidate } = requestContext.contextValue;
11
+ const { schema } = requestContext;
12
+ const { queriesToInvalidate, user, req } = requestContext.contextValue;
13
+ const tenantId = extractTenantId(req?.currentPageUriSegments?.authority);
12
14
  const [{ operation }] = responseContext.document.definitions;
13
15
  const isMutation = operation === 'mutation';
14
16
  if (hasErrors || !queriesToInvalidate?.length || !isMutation) {
15
17
  return;
16
18
  }
17
- // this to get the
18
19
  const nestedKeys = await Promise.all(queriesToInvalidate.map(async (query) => {
19
- let defaultKey = `${config.APP_NAME}:${query}:*`;
20
- if (typeof invalidateCacheKeyGenerator === 'function') {
21
- const generatedKey = invalidateCacheKeyGenerator(requestContext, responseContext, defaultKey);
22
- if (generatedKey) {
23
- defaultKey = generatedKey;
20
+ // Build keys in order of specificity
21
+ let keys = [];
22
+ const cachePolicy = getDirectiveArgsFromSchema({
23
+ schema,
24
+ queryName: query,
25
+ directiveName: CACHE_CONTROL_DIRECTIVE,
26
+ });
27
+ const isPrivate = cachePolicy.scope?.toLowerCase() === 'private';
28
+ // Add tenant-specific key if tenant exists
29
+ if (tenantId) {
30
+ keys.push(`${config.APP_NAME}:${tenantId}:${query}:*`);
31
+ // Add user-specific key if user exists
32
+ if (user?.sub && isPrivate) {
33
+ keys.push(`${config.APP_NAME}:${tenantId}:${user.sub}:${query}:*`);
24
34
  }
25
35
  }
26
- return redisClient.keys(defaultKey);
36
+ // Add global key as fallback
37
+ keys.push(`${config.APP_NAME}:${query}:*`);
38
+ // Allow custom key generation if provided
39
+ if (typeof invalidateCacheKeyGenerator === 'function') {
40
+ keys = keys.map((key) => invalidateCacheKeyGenerator(requestContext, responseContext, key));
41
+ }
42
+ const matchedKeys = await Promise.all(keys.map(async (key) => {
43
+ const matchingKeys = await redisClient.keys(key);
44
+ if (matchingKeys.length) {
45
+ return matchingKeys;
46
+ }
47
+ return [];
48
+ }));
49
+ return matchedKeys.flat();
27
50
  }));
28
51
  const keys = nestedKeys.flat();
29
52
  if (keys?.length) {
30
- await redisClient.del(keys);
53
+ await redisClient.del(uniq(keys));
31
54
  }
32
55
  }
33
56
  catch (e) {
@@ -1 +1 @@
1
- {"version":3,"file":"invalidateCachePlugin.mjs","sources":["../../src/plugins/invalidateCachePlugin.ts"],"sourcesContent":[null],"names":[],"mappings":"8CAWO,MAAM,qBAAqB,GAAG,CAAC,EAClC,KAAK,EAAE,WAAW,EAClB,2BAA2B,GAI9B,MACI;AACG,IAAA,eAAe,CAAC,cAA8C,EAAA;QAC1D,OAAO;AACH,YAAA,gBAAgB,EAAE,OAAO,eAA+D,KAAI;;gBAExF,IAAI,CAAC,cAAc,EAAE;oBACjB,OAAO;iBACV;AACD,gBAAA,IAAI;oBACA,MAAM,SAAS,GAAG,CAAC,CAAC,cAAc,CAAC,MAAM,EAAE,MAAM,CAAC;AAClD,oBAAA,MAAM,EAAE,mBAAmB,EAAE,GAAG,cAAc,CAAC,YAE9C,CAAC;oBACF,MAAM,CAAC,EAAE,SAAS,EAAE,CAAC,GAAG,eAAe,CAAC,QAAQ,CAAC,WAAwC,CAAC;AAC1F,oBAAA,MAAM,UAAU,GAAG,SAAS,KAAK,UAAU,CAAC;oBAC5C,IAAI,SAAS,IAAI,CAAC,mBAAmB,EAAE,MAAM,IAAI,CAAC,UAAU,EAAE;wBAC1D,OAAO;qBACV;;AAED,oBAAA,MAAM,UAAU,GAAG,MAAM,OAAO,CAAC,GAAG,CAChC,mBAAmB,CAAC,GAAG,CAAC,OAAO,KAAa,KAAI;wBAC5C,IAAI,UAAU,GAAG,CAAG,EAAA,MAAM,CAAC,QAAQ,CAAA,CAAA,EAAI,KAAK,CAAA,EAAA,CAAI,CAAC;AACjD,wBAAA,IAAI,OAAO,2BAA2B,KAAK,UAAU,EAAE;4BACnD,MAAM,YAAY,GAAG,2BAA2B,CAC5C,cAAc,EACd,eAAe,EACf,UAAU,CACb,CAAC;4BACF,IAAI,YAAY,EAAE;gCACd,UAAU,GAAG,YAAY,CAAC;6BAC7B;yBACJ;AACD,wBAAA,OAAO,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;qBACvC,CAAC,CACL,CAAC;AACF,oBAAA,MAAM,IAAI,GAAG,UAAU,CAAC,IAAI,EAAE,CAAC;AAC/B,oBAAA,IAAI,IAAI,EAAE,MAAM,EAAE;AACd,wBAAA,MAAM,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;qBAC/B;iBACJ;gBAAC,OAAO,CAAC,EAAE;AACR,oBAAA,cAAc,CAAC,MAAM,CAAC,KAAK,CAAC,yCAAyC,CAAC,CAAC;AACvE,oBAAA,cAAc,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;iBAClC;aACJ;SACJ,CAAC;KACL;AACJ,CAAA"}
1
+ {"version":3,"file":"invalidateCachePlugin.mjs","sources":["../../src/plugins/invalidateCachePlugin.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}
@@ -0,0 +1,63 @@
1
+ 'use strict';var serverCore=require('@common-stack/server-core'),_=require('lodash-es'),apolloCachePlugin=require('@apollo/server-plugin-response-cache');const cachePlugin = apolloCachePlugin.default ?? apolloCachePlugin;
2
+ const isCacheable = (requestContext) => {
3
+ const { document, schema } = requestContext;
4
+ const cache = serverCore.getDirectiveArgsFromSchema({
5
+ schema,
6
+ document,
7
+ directiveName: serverCore.CACHE_CONTROL_DIRECTIVE,
8
+ });
9
+ if (!cache)
10
+ return false;
11
+ if (cache.scope && !cache.maxAge) {
12
+ cache.maxAge = 86400;
13
+ }
14
+ if (!requestContext.overallCachePolicy) {
15
+ // eslint-disable-next-line no-param-reassign
16
+ // to support test cases
17
+ requestContext.overallCachePolicy = {};
18
+ }
19
+ // eslint-disable-next-line no-param-reassign
20
+ requestContext.overallCachePolicy.maxAge = cache.maxAge;
21
+ return cache.maxAge > 0;
22
+ };
23
+ const generateCacheKey = ({ logger, cacheKeyGenerator }) => (requestContext) => {
24
+ if (!isCacheable(requestContext)) {
25
+ return null;
26
+ }
27
+ const { request, contextValue, document, schema } = requestContext;
28
+ const { user, req } = contextValue ?? {};
29
+ const { query, variables } = request;
30
+ const cacheControlDirective = serverCore.getDirectiveArgsFromSchema({
31
+ schema,
32
+ document,
33
+ directiveName: serverCore.CACHE_CONTROL_DIRECTIVE,
34
+ });
35
+ const { scope } = cacheControlDirective ?? {};
36
+ const isPrivate = scope?.toLowerCase() === 'private';
37
+ const tenantId = req.tenant ?? serverCore.extractTenantId(req?.currentPageUriSegments?.authority);
38
+ const cacheKey = serverCore.generateQueryCacheKey({
39
+ query,
40
+ variables,
41
+ logger,
42
+ userId: isPrivate ? user?.sub || null : null,
43
+ tenantId,
44
+ });
45
+ try {
46
+ if (typeof cacheKeyGenerator === 'function') {
47
+ const generatedKey = cacheKeyGenerator(requestContext, cacheKey);
48
+ return generatedKey || cacheKey;
49
+ }
50
+ return cacheKey;
51
+ }
52
+ catch (e) {
53
+ console.warn('GenerateCacheKey Failed %s', e.message);
54
+ return cacheKey;
55
+ }
56
+ };
57
+ const responseCachePlugin = ({ logger, cacheKeyGenerator }) => cachePlugin({
58
+ sessionId: ({ contextValue }) => Promise.resolve(contextValue?.user?.sub ?? null),
59
+ generateCacheKey: generateCacheKey({ logger, cacheKeyGenerator }),
60
+ shouldWriteToCache: (ctx) =>
61
+ // Cache only successful responses
62
+ isCacheable(ctx) && _.isEmpty(ctx?.response?.body?.singleResult.errors),
63
+ });exports.generateCacheKey=generateCacheKey;exports.isCacheable=isCacheable;exports.responseCachePlugin=responseCachePlugin;//# sourceMappingURL=responseCachePlugin.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"responseCachePlugin.cjs","sources":["../../src/plugins/responseCachePlugin.ts"],"sourcesContent":[null],"names":["getDirectiveArgsFromSchema","CACHE_CONTROL_DIRECTIVE","extractTenantId","generateQueryCacheKey","isEmpty"],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import { GraphQLRequestContext } from '@apollo/server';
2
+ import { ILogger } from '@cdm-logger/core/lib/interface';
3
+ import { GraphqlRequestContext } from '../interfaces';
4
+ import { KeyGenerator } from '../servers/GraphqlServer';
5
+ type ApolloCachePluginOptions = {
6
+ logger: ILogger;
7
+ cacheKeyGenerator: KeyGenerator;
8
+ };
9
+ export declare const isCacheable: (requestContext: GraphQLRequestContext<GraphqlRequestContext>) => boolean;
10
+ export declare const generateCacheKey: ({ logger, cacheKeyGenerator }: ApolloCachePluginOptions) => (requestContext: GraphQLRequestContext<GraphqlRequestContext>) => string;
11
+ export declare const responseCachePlugin: ({ logger, cacheKeyGenerator }: ApolloCachePluginOptions) => any;
12
+ export {};