@zintrust/core 0.1.13 → 0.1.15
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/package.json +1 -1
- package/src/boot/Application.d.ts.map +1 -1
- package/src/boot/Application.js +110 -11
- package/src/cache/Cache.d.ts +13 -0
- package/src/cache/Cache.d.ts.map +1 -1
- package/src/cache/Cache.js +48 -6
- package/src/cache/CacheRuntimeRegistration.d.ts +11 -0
- package/src/cache/CacheRuntimeRegistration.d.ts.map +1 -0
- package/src/cache/CacheRuntimeRegistration.js +21 -0
- package/src/config/broadcast.d.ts +18 -4
- package/src/config/broadcast.d.ts.map +1 -1
- package/src/config/broadcast.js +62 -12
- package/src/config/cache.d.ts +1 -1
- package/src/config/cache.d.ts.map +1 -1
- package/src/config/cache.js +26 -9
- package/src/config/database.d.ts +1 -1
- package/src/config/database.d.ts.map +1 -1
- package/src/config/database.js +61 -43
- package/src/config/index.d.ts +23 -2
- package/src/config/index.d.ts.map +1 -1
- package/src/config/index.js +6 -0
- package/src/config/mail.d.ts +3 -3
- package/src/config/mail.d.ts.map +1 -1
- package/src/config/mail.js +31 -9
- package/src/config/notification.d.ts +25 -29
- package/src/config/notification.d.ts.map +1 -1
- package/src/config/notification.js +80 -20
- package/src/config/storage.d.ts +8 -0
- package/src/config/storage.d.ts.map +1 -1
- package/src/config/storage.js +29 -8
- package/src/config/type.d.ts +32 -31
- package/src/config/type.d.ts.map +1 -1
- package/src/index.d.ts +5 -0
- package/src/index.d.ts.map +1 -1
- package/src/index.js +5 -0
- package/src/node.d.ts +1 -3
- package/src/node.d.ts.map +1 -1
- package/src/node.js +1 -3
- package/src/orm/Database.d.ts.map +1 -1
- package/src/orm/Database.js +4 -0
- package/src/orm/DatabaseRuntimeRegistration.d.ts +17 -0
- package/src/orm/DatabaseRuntimeRegistration.d.ts.map +1 -0
- package/src/orm/DatabaseRuntimeRegistration.js +57 -0
- package/src/orm/Model.d.ts +3 -9
- package/src/orm/Model.d.ts.map +1 -1
- package/src/orm/Model.js +9 -7
- package/src/templates/project/basic/config/broadcast.ts.tpl +83 -13
- package/src/templates/project/basic/config/cache.ts.tpl +35 -11
- package/src/templates/project/basic/config/database.ts.tpl +70 -51
- package/src/templates/project/basic/config/index.ts.tpl +6 -0
- package/src/templates/project/basic/config/mail.ts.tpl +34 -11
- package/src/templates/project/basic/config/notification.ts.tpl +110 -25
- package/src/templates/project/basic/config/storage.ts.tpl +37 -19
- package/src/templates/project/basic/config/type.ts.tpl +46 -33
- package/src/templates/project/basic/routes/health.ts.tpl +21 -11
- package/src/tools/broadcast/Broadcast.d.ts +5 -3
- package/src/tools/broadcast/Broadcast.d.ts.map +1 -1
- package/src/tools/broadcast/Broadcast.js +48 -24
- package/src/tools/broadcast/BroadcastRegistry.d.ts +15 -0
- package/src/tools/broadcast/BroadcastRegistry.d.ts.map +1 -0
- package/src/tools/broadcast/BroadcastRegistry.js +29 -0
- package/src/tools/broadcast/BroadcastRuntimeRegistration.d.ts +11 -0
- package/src/tools/broadcast/BroadcastRuntimeRegistration.d.ts.map +1 -0
- package/src/tools/broadcast/BroadcastRuntimeRegistration.js +23 -0
- package/src/tools/broadcast/index.d.ts +2 -0
- package/src/tools/broadcast/index.d.ts.map +1 -1
- package/src/tools/broadcast/index.js +2 -0
- package/src/tools/mail/Mail.d.ts +8 -0
- package/src/tools/mail/Mail.d.ts.map +1 -1
- package/src/tools/mail/Mail.js +15 -2
- package/src/tools/mail/MailDriverRegistry.d.ts +2 -0
- package/src/tools/mail/MailDriverRegistry.d.ts.map +1 -1
- package/src/tools/mail/MailDriverRegistry.js +4 -0
- package/src/tools/notification/Notification.d.ts +3 -0
- package/src/tools/notification/Notification.d.ts.map +1 -1
- package/src/tools/notification/Notification.js +3 -0
- package/src/tools/notification/NotificationChannelRegistry.d.ts +15 -0
- package/src/tools/notification/NotificationChannelRegistry.d.ts.map +1 -0
- package/src/tools/notification/NotificationChannelRegistry.js +36 -0
- package/src/tools/notification/NotificationRuntimeRegistration.d.ts +13 -0
- package/src/tools/notification/NotificationRuntimeRegistration.d.ts.map +1 -0
- package/src/tools/notification/NotificationRuntimeRegistration.js +25 -0
- package/src/tools/notification/Registry.d.ts.map +1 -1
- package/src/tools/notification/Registry.js +4 -0
- package/src/tools/notification/Service.d.ts +1 -0
- package/src/tools/notification/Service.d.ts.map +1 -1
- package/src/tools/notification/Service.js +77 -4
- package/src/tools/notification/drivers/SlackNotification.d.ts +8 -0
- package/src/tools/notification/drivers/SlackNotification.d.ts.map +1 -0
- package/src/tools/notification/drivers/SlackNotification.js +13 -0
- package/src/tools/notification/drivers/TwilioNotification.d.ts +8 -0
- package/src/tools/notification/drivers/TwilioNotification.d.ts.map +1 -0
- package/src/tools/notification/drivers/TwilioNotification.js +13 -0
- package/src/tools/queue/Queue.d.ts +1 -0
- package/src/tools/queue/Queue.d.ts.map +1 -1
- package/src/tools/queue/Queue.js +7 -1
- package/src/tools/queue/QueueRuntimeRegistration.d.ts +11 -0
- package/src/tools/queue/QueueRuntimeRegistration.d.ts.map +1 -0
- package/src/tools/queue/QueueRuntimeRegistration.js +25 -0
- package/src/tools/storage/StorageDiskRegistry.d.ts +14 -0
- package/src/tools/storage/StorageDiskRegistry.d.ts.map +1 -0
- package/src/tools/storage/StorageDiskRegistry.js +36 -0
- package/src/tools/storage/StorageRuntimeRegistration.d.ts +10 -0
- package/src/tools/storage/StorageRuntimeRegistration.d.ts.map +1 -0
- package/src/tools/storage/StorageRuntimeRegistration.js +21 -0
- package/src/tools/storage/index.d.ts +1 -0
- package/src/tools/storage/index.d.ts.map +1 -1
- package/src/tools/storage/index.js +40 -6
package/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Application.d.ts","sourceRoot":"","sources":["../../../src/boot/Application.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,iBAAiB,EAAoB,MAAM,8BAA8B,CAAC;AAEnF,OAAO,EAAE,gBAAgB,EAAmB,MAAM,8BAA8B,CAAC;AACjF,OAAO,EAAE,KAAK,OAAO,EAAU,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"Application.d.ts","sourceRoot":"","sources":["../../../src/boot/Application.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,iBAAiB,EAAoB,MAAM,8BAA8B,CAAC;AAEnF,OAAO,EAAE,gBAAgB,EAAmB,MAAM,8BAA8B,CAAC;AACjF,OAAO,EAAE,KAAK,OAAO,EAAU,MAAM,kBAAkB,CAAC;AASxD,MAAM,WAAW,YAAY;IAC3B,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACtB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1B,QAAQ,IAAI,OAAO,CAAC;IACpB,aAAa,IAAI,OAAO,CAAC;IACzB,YAAY,IAAI,OAAO,CAAC;IACxB,SAAS,IAAI,OAAO,CAAC;IACrB,cAAc,IAAI,MAAM,CAAC;IACzB,SAAS,IAAI,OAAO,CAAC;IACrB,YAAY,IAAI,iBAAiB,CAAC;IAClC,kBAAkB,IAAI,gBAAgB,CAAC;IACvC,WAAW,IAAI,MAAM,CAAC;CACvB;AAsUD;;GAEG;AACH,eAAO,MAAM,WAAW;IACtB;;OAEG;sBACe,MAAM,GAAG,YAAY;EA0CvC,CAAC;AAEH,eAAe,WAAW,CAAC"}
|
package/src/boot/Application.js
CHANGED
|
@@ -2,13 +2,15 @@
|
|
|
2
2
|
* Application - Framework core entry point
|
|
3
3
|
* Handles application lifecycle, booting, and environment
|
|
4
4
|
*/
|
|
5
|
-
import { appConfig } from '../config/index.js';
|
|
5
|
+
import { appConfig, cacheConfig, databaseConfig, queueConfig, storageConfig } from '../config/index.js';
|
|
6
6
|
import { ServiceContainer } from '../container/ServiceContainer.js';
|
|
7
7
|
import { StartupHealthChecks } from '../health/StartupHealthChecks.js';
|
|
8
8
|
import { MiddlewareStack } from '../middleware/MiddlewareStack.js';
|
|
9
9
|
import { Router } from '../routing/Router.js';
|
|
10
|
+
import broadcastConfig from '../config/broadcast.js';
|
|
10
11
|
import { FeatureFlags } from '../config/features.js';
|
|
11
12
|
import { Logger } from '../config/logger.js';
|
|
13
|
+
import notificationConfig from '../config/notification.js';
|
|
12
14
|
import { StartupConfigValidator } from '../config/StartupConfigValidator.js';
|
|
13
15
|
import * as path from '../node-singletons/path.js';
|
|
14
16
|
import { pathToFileURL } from '../node-singletons/url.js';
|
|
@@ -55,6 +57,83 @@ const registerCoreInstances = (params) => {
|
|
|
55
57
|
params.container.singleton('container', params.container);
|
|
56
58
|
params.container.singleton('shutdownManager', params.shutdownManager);
|
|
57
59
|
};
|
|
60
|
+
const registerFrameworkShutdownHooks = (shutdownManager) => {
|
|
61
|
+
// Register framework-level shutdown hooks for long-lived resources
|
|
62
|
+
// ConnectionManager may not be initialized; shutdownIfInitialized is safe
|
|
63
|
+
// Use dynamic import without top-level await to avoid transforming the module into an async module
|
|
64
|
+
import('../orm/ConnectionManager.js')
|
|
65
|
+
.then((mod) => {
|
|
66
|
+
shutdownManager.add(async () => mod.ConnectionManager.shutdownIfInitialized());
|
|
67
|
+
})
|
|
68
|
+
/* c8 ignore start */
|
|
69
|
+
.catch(() => {
|
|
70
|
+
/* ignore import failures in restrictive runtimes */
|
|
71
|
+
});
|
|
72
|
+
/* c8 ignore stop */
|
|
73
|
+
import('../orm/Database.js')
|
|
74
|
+
.then((mod) => {
|
|
75
|
+
shutdownManager.add(() => mod.resetDatabase());
|
|
76
|
+
})
|
|
77
|
+
/* c8 ignore start */
|
|
78
|
+
.catch(() => {
|
|
79
|
+
/* ignore import failures in restrictive runtimes */
|
|
80
|
+
});
|
|
81
|
+
/* c8 ignore stop */
|
|
82
|
+
import('../cache/Cache.js')
|
|
83
|
+
.then((mod) => {
|
|
84
|
+
shutdownManager.add(() => mod.Cache.reset());
|
|
85
|
+
})
|
|
86
|
+
/* c8 ignore start */
|
|
87
|
+
.catch(() => {
|
|
88
|
+
/* ignore import failures in restrictive runtimes */
|
|
89
|
+
});
|
|
90
|
+
/* c8 ignore stop */
|
|
91
|
+
import('../tools/broadcast/BroadcastRegistry.js')
|
|
92
|
+
.then((mod) => {
|
|
93
|
+
shutdownManager.add(() => mod.BroadcastRegistry.reset());
|
|
94
|
+
})
|
|
95
|
+
/* c8 ignore start */
|
|
96
|
+
.catch(() => {
|
|
97
|
+
/* ignore import failures in restrictive runtimes */
|
|
98
|
+
});
|
|
99
|
+
/* c8 ignore stop */
|
|
100
|
+
import('../tools/storage/StorageDiskRegistry.js')
|
|
101
|
+
.then((mod) => {
|
|
102
|
+
shutdownManager.add(() => mod.StorageDiskRegistry.reset());
|
|
103
|
+
})
|
|
104
|
+
/* c8 ignore start */
|
|
105
|
+
.catch(() => {
|
|
106
|
+
/* ignore import failures in restrictive runtimes */
|
|
107
|
+
});
|
|
108
|
+
/* c8 ignore stop */
|
|
109
|
+
import('../tools/notification/NotificationChannelRegistry.js')
|
|
110
|
+
.then((mod) => {
|
|
111
|
+
shutdownManager.add(() => mod.NotificationChannelRegistry.reset());
|
|
112
|
+
})
|
|
113
|
+
/* c8 ignore start */
|
|
114
|
+
.catch(() => {
|
|
115
|
+
/* ignore import failures in restrictive runtimes */
|
|
116
|
+
});
|
|
117
|
+
/* c8 ignore stop */
|
|
118
|
+
import('../tools/mail/MailDriverRegistry.js')
|
|
119
|
+
.then((mod) => {
|
|
120
|
+
shutdownManager.add(() => mod.MailDriverRegistry.reset());
|
|
121
|
+
})
|
|
122
|
+
/* c8 ignore start */
|
|
123
|
+
.catch(() => {
|
|
124
|
+
/* ignore import failures in restrictive runtimes */
|
|
125
|
+
});
|
|
126
|
+
/* c8 ignore stop */
|
|
127
|
+
import('../tools/queue/Queue.js')
|
|
128
|
+
.then((mod) => {
|
|
129
|
+
shutdownManager.add(() => mod.Queue.reset());
|
|
130
|
+
})
|
|
131
|
+
/* c8 ignore start */
|
|
132
|
+
.catch(() => {
|
|
133
|
+
/* ignore import failures in restrictive runtimes */
|
|
134
|
+
});
|
|
135
|
+
/* c8 ignore stop */
|
|
136
|
+
};
|
|
58
137
|
const tryImportRoutesFromAppBase = async (resolvedBasePath) => {
|
|
59
138
|
if (resolvedBasePath === '')
|
|
60
139
|
return undefined;
|
|
@@ -118,6 +197,34 @@ const initializeArtifactDirectories = async (resolvedBasePath) => {
|
|
|
118
197
|
}
|
|
119
198
|
}
|
|
120
199
|
};
|
|
200
|
+
const tryImportOptional = async (modulePath) => {
|
|
201
|
+
try {
|
|
202
|
+
return (await import(modulePath));
|
|
203
|
+
}
|
|
204
|
+
catch {
|
|
205
|
+
return undefined;
|
|
206
|
+
}
|
|
207
|
+
};
|
|
208
|
+
const registerFromRuntimeConfig = async () => {
|
|
209
|
+
const db = await tryImportOptional('@orm/DatabaseRuntimeRegistration');
|
|
210
|
+
db?.registerDatabasesFromRuntimeConfig?.(databaseConfig);
|
|
211
|
+
const queues = await tryImportOptional('@tools/queue/QueueRuntimeRegistration');
|
|
212
|
+
queues?.registerQueuesFromRuntimeConfig?.(queueConfig);
|
|
213
|
+
const caches = await tryImportOptional('@cache/CacheRuntimeRegistration');
|
|
214
|
+
caches?.registerCachesFromRuntimeConfig?.(cacheConfig);
|
|
215
|
+
const broadcasters = await tryImportOptional('@broadcast/BroadcastRuntimeRegistration');
|
|
216
|
+
broadcasters?.registerBroadcastersFromRuntimeConfig?.({
|
|
217
|
+
default: broadcastConfig.default,
|
|
218
|
+
drivers: broadcastConfig.drivers,
|
|
219
|
+
});
|
|
220
|
+
const disks = await tryImportOptional('@storage/StorageRuntimeRegistration');
|
|
221
|
+
disks?.registerDisksFromRuntimeConfig?.(storageConfig);
|
|
222
|
+
const notifications = await tryImportOptional('@notification/NotificationRuntimeRegistration');
|
|
223
|
+
notifications?.registerNotificationChannelsFromRuntimeConfig?.({
|
|
224
|
+
default: notificationConfig.default,
|
|
225
|
+
drivers: notificationConfig.drivers,
|
|
226
|
+
});
|
|
227
|
+
};
|
|
121
228
|
const createLifecycle = (params) => {
|
|
122
229
|
const boot = async () => {
|
|
123
230
|
if (params.getBooted())
|
|
@@ -126,6 +233,7 @@ const createLifecycle = (params) => {
|
|
|
126
233
|
StartupConfigValidator.assertValid();
|
|
127
234
|
FeatureFlags.initialize();
|
|
128
235
|
await StartupHealthChecks.assertHealthy();
|
|
236
|
+
await registerFromRuntimeConfig();
|
|
129
237
|
await initializeArtifactDirectories(params.resolvedBasePath);
|
|
130
238
|
await registerRoutes(params.resolvedBasePath, params.router);
|
|
131
239
|
// Register service providers
|
|
@@ -164,16 +272,7 @@ export const Application = Object.freeze({
|
|
|
164
272
|
let booted = false;
|
|
165
273
|
registerCorePaths(container, resolvedBasePath, joinFromBase);
|
|
166
274
|
registerCoreInstances({ container, environment, router, middlewareStack, shutdownManager });
|
|
167
|
-
|
|
168
|
-
// ConnectionManager may not be initialized; shutdownIfInitialized is safe
|
|
169
|
-
// Use dynamic import without top-level await to avoid transforming the module into an async module
|
|
170
|
-
import('../orm/ConnectionManager.js')
|
|
171
|
-
.then(({ ConnectionManager }) => {
|
|
172
|
-
shutdownManager.add(async () => ConnectionManager.shutdownIfInitialized());
|
|
173
|
-
})
|
|
174
|
-
.catch(() => {
|
|
175
|
-
/* ignore import failures in restrictive runtimes */
|
|
176
|
-
});
|
|
275
|
+
registerFrameworkShutdownHooks(shutdownManager);
|
|
177
276
|
const { boot, shutdown } = createLifecycle({
|
|
178
277
|
environment,
|
|
179
278
|
resolvedBasePath,
|
package/src/cache/Cache.d.ts
CHANGED
|
@@ -4,6 +4,14 @@
|
|
|
4
4
|
* Sealed namespace pattern - all exports through Cache namespace
|
|
5
5
|
*/
|
|
6
6
|
import { CacheDriver } from './CacheDriver';
|
|
7
|
+
type CacheStore = Readonly<{
|
|
8
|
+
get: <T>(key: string) => Promise<T | null>;
|
|
9
|
+
set: <T>(key: string, value: T, ttl?: number) => Promise<void>;
|
|
10
|
+
delete: (key: string) => Promise<void>;
|
|
11
|
+
clear: () => Promise<void>;
|
|
12
|
+
has: (key: string) => Promise<boolean>;
|
|
13
|
+
getDriver: () => CacheDriver;
|
|
14
|
+
}>;
|
|
7
15
|
export declare const Cache: Readonly<{
|
|
8
16
|
get: <T>(key: string) => Promise<T | null>;
|
|
9
17
|
set: <T>(key: string, value: T, ttl?: number) => Promise<void>;
|
|
@@ -11,6 +19,8 @@ export declare const Cache: Readonly<{
|
|
|
11
19
|
clear: () => Promise<void>;
|
|
12
20
|
has: (key: string) => Promise<boolean>;
|
|
13
21
|
getDriver: () => CacheDriver;
|
|
22
|
+
store: (name?: string) => CacheStore;
|
|
23
|
+
reset: () => void;
|
|
14
24
|
}>;
|
|
15
25
|
/**
|
|
16
26
|
* Helper alias for cache
|
|
@@ -22,5 +32,8 @@ export declare const cache: Readonly<{
|
|
|
22
32
|
clear: () => Promise<void>;
|
|
23
33
|
has: (key: string) => Promise<boolean>;
|
|
24
34
|
getDriver: () => CacheDriver;
|
|
35
|
+
store: (name?: string) => CacheStore;
|
|
36
|
+
reset: () => void;
|
|
25
37
|
}>;
|
|
38
|
+
export {};
|
|
26
39
|
//# sourceMappingURL=Cache.d.ts.map
|
package/src/cache/Cache.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Cache.d.ts","sourceRoot":"","sources":["../../../src/cache/Cache.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"Cache.d.ts","sourceRoot":"","sources":["../../../src/cache/Cache.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAmHjD,KAAK,UAAU,GAAG,QAAQ,CAAC;IACzB,GAAG,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IAC3C,GAAG,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/D,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACvC,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3B,GAAG,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACvC,SAAS,EAAE,MAAM,WAAW,CAAC;CAC9B,CAAC,CAAC;AA0CH,eAAO,MAAM,KAAK;UA1FC,CAAC,OAAO,MAAM,KAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC;UAQlC,CAAC,OAAO,MAAM,SAAS,CAAC,QAAQ,MAAM,KAAG,OAAO,CAAC,IAAI,CAAC;kBAOjD,MAAM,KAAG,OAAO,CAAC,IAAI,CAAC;iBAOtB,OAAO,CAAC,IAAI,CAAC;eAOb,MAAM,KAAG,OAAO,CAAC,OAAO,CAAC;qBAQ3B,WAAW;mBAaX,MAAM,KAAG,UAAU;iBAmCvB,IAAI;EAcpB,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,KAAK;UAxGC,CAAC,OAAO,MAAM,KAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC;UAQlC,CAAC,OAAO,MAAM,SAAS,CAAC,QAAQ,MAAM,KAAG,OAAO,CAAC,IAAI,CAAC;kBAOjD,MAAM,KAAG,OAAO,CAAC,IAAI,CAAC;iBAOtB,OAAO,CAAC,IAAI,CAAC;eAOb,MAAM,KAAG,OAAO,CAAC,OAAO,CAAC;qBAQ3B,WAAW;mBAaX,MAAM,KAAG,UAAU;iBAmCvB,IAAI;EAmBI,CAAC"}
|
package/src/cache/Cache.js
CHANGED
|
@@ -11,7 +11,7 @@ import { MongoDriver } from './drivers/MongoDriver.js';
|
|
|
11
11
|
import { RedisDriver } from './drivers/RedisDriver.js';
|
|
12
12
|
import { cacheConfig } from '../config/cache.js';
|
|
13
13
|
import { ErrorFactory } from '../exceptions/ZintrustError.js';
|
|
14
|
-
|
|
14
|
+
const instances = new Map();
|
|
15
15
|
function buildDriver(driver) {
|
|
16
16
|
const maybeCreate = driver.create;
|
|
17
17
|
if (typeof maybeCreate === 'function') {
|
|
@@ -22,8 +22,8 @@ function buildDriver(driver) {
|
|
|
22
22
|
}
|
|
23
23
|
throw ErrorFactory.createGeneralError('Invalid cache driver export');
|
|
24
24
|
}
|
|
25
|
-
function resolveDriver() {
|
|
26
|
-
const driverConfig = cacheConfig.getDriver();
|
|
25
|
+
function resolveDriver(storeName) {
|
|
26
|
+
const driverConfig = cacheConfig.getDriver(storeName);
|
|
27
27
|
const externalFactory = CacheDriverRegistry.get(driverConfig.driver);
|
|
28
28
|
if (externalFactory !== undefined) {
|
|
29
29
|
return externalFactory(driverConfig);
|
|
@@ -43,9 +43,18 @@ function resolveDriver() {
|
|
|
43
43
|
return buildDriver(MemoryDriver);
|
|
44
44
|
}
|
|
45
45
|
}
|
|
46
|
-
function getDriverInstance() {
|
|
47
|
-
|
|
48
|
-
|
|
46
|
+
function getDriverInstance(storeName) {
|
|
47
|
+
const normalizedSelection = String(storeName ?? '')
|
|
48
|
+
.trim()
|
|
49
|
+
.toLowerCase();
|
|
50
|
+
const resolvedKey = normalizedSelection.length > 0 ? normalizedSelection : 'default';
|
|
51
|
+
const existing = instances.get(resolvedKey);
|
|
52
|
+
if (existing !== undefined)
|
|
53
|
+
return existing;
|
|
54
|
+
const selector = resolvedKey === 'default' ? undefined : resolvedKey;
|
|
55
|
+
const created = resolveDriver(selector);
|
|
56
|
+
instances.set(resolvedKey, created);
|
|
57
|
+
return created;
|
|
49
58
|
}
|
|
50
59
|
/**
|
|
51
60
|
* Get an item from the cache
|
|
@@ -85,6 +94,37 @@ const has = async (key) => {
|
|
|
85
94
|
const getDriver = () => {
|
|
86
95
|
return getDriverInstance();
|
|
87
96
|
};
|
|
97
|
+
const store = (name) => {
|
|
98
|
+
const getFromStore = async (key) => {
|
|
99
|
+
return getDriverInstance(name).get(key);
|
|
100
|
+
};
|
|
101
|
+
const setInStore = async (key, value, ttl) => {
|
|
102
|
+
await getDriverInstance(name).set(key, value, ttl);
|
|
103
|
+
};
|
|
104
|
+
const delFromStore = async (key) => {
|
|
105
|
+
await getDriverInstance(name).delete(key);
|
|
106
|
+
};
|
|
107
|
+
const clearStore = async () => {
|
|
108
|
+
await getDriverInstance(name).clear();
|
|
109
|
+
};
|
|
110
|
+
const hasInStore = async (key) => {
|
|
111
|
+
return getDriverInstance(name).has(key);
|
|
112
|
+
};
|
|
113
|
+
const getStoreDriver = () => {
|
|
114
|
+
return getDriverInstance(name);
|
|
115
|
+
};
|
|
116
|
+
return Object.freeze({
|
|
117
|
+
get: getFromStore,
|
|
118
|
+
set: setInStore,
|
|
119
|
+
delete: delFromStore,
|
|
120
|
+
clear: clearStore,
|
|
121
|
+
has: hasInStore,
|
|
122
|
+
getDriver: getStoreDriver,
|
|
123
|
+
});
|
|
124
|
+
};
|
|
125
|
+
const reset = () => {
|
|
126
|
+
instances.clear();
|
|
127
|
+
};
|
|
88
128
|
// Sealed namespace with cache functionality
|
|
89
129
|
export const Cache = Object.freeze({
|
|
90
130
|
get,
|
|
@@ -93,6 +133,8 @@ export const Cache = Object.freeze({
|
|
|
93
133
|
clear,
|
|
94
134
|
has,
|
|
95
135
|
getDriver,
|
|
136
|
+
store,
|
|
137
|
+
reset,
|
|
96
138
|
});
|
|
97
139
|
/**
|
|
98
140
|
* Helper alias for cache
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { CacheConfig } from '../config/cache';
|
|
2
|
+
/**
|
|
3
|
+
* Register cache drivers from runtime config.
|
|
4
|
+
*
|
|
5
|
+
* This follows the framework's config-driven availability pattern:
|
|
6
|
+
* - Built-in driver factories are registered so config entries can reference them.
|
|
7
|
+
* - Named cache stores are still resolved from `cacheConfig.drivers[storeName]`.
|
|
8
|
+
* - Unknown store names throw when explicitly selected via `cacheConfig.getDriver(name)`.
|
|
9
|
+
*/
|
|
10
|
+
export declare function registerCachesFromRuntimeConfig(_config: CacheConfig): void;
|
|
11
|
+
//# sourceMappingURL=CacheRuntimeRegistration.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CacheRuntimeRegistration.d.ts","sourceRoot":"","sources":["../../../src/cache/CacheRuntimeRegistration.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AASjD;;;;;;;GAOG;AACH,wBAAgB,+BAA+B,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI,CAM1E"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { CacheDriverRegistry } from './CacheDriverRegistry.js';
|
|
2
|
+
import { KVDriver } from './drivers/KVDriver.js';
|
|
3
|
+
import { KVRemoteDriver } from './drivers/KVRemoteDriver.js';
|
|
4
|
+
import { MemoryDriver } from './drivers/MemoryDriver.js';
|
|
5
|
+
import { MongoDriver } from './drivers/MongoDriver.js';
|
|
6
|
+
import { RedisDriver } from './drivers/RedisDriver.js';
|
|
7
|
+
/**
|
|
8
|
+
* Register cache drivers from runtime config.
|
|
9
|
+
*
|
|
10
|
+
* This follows the framework's config-driven availability pattern:
|
|
11
|
+
* - Built-in driver factories are registered so config entries can reference them.
|
|
12
|
+
* - Named cache stores are still resolved from `cacheConfig.drivers[storeName]`.
|
|
13
|
+
* - Unknown store names throw when explicitly selected via `cacheConfig.getDriver(name)`.
|
|
14
|
+
*/
|
|
15
|
+
export function registerCachesFromRuntimeConfig(_config) {
|
|
16
|
+
CacheDriverRegistry.register('memory', () => MemoryDriver.create());
|
|
17
|
+
CacheDriverRegistry.register('redis', () => RedisDriver.create());
|
|
18
|
+
CacheDriverRegistry.register('mongodb', () => MongoDriver.create());
|
|
19
|
+
CacheDriverRegistry.register('kv', () => KVDriver.create());
|
|
20
|
+
CacheDriverRegistry.register('kv-remote', () => KVRemoteDriver.create());
|
|
21
|
+
}
|
|
@@ -4,19 +4,33 @@
|
|
|
4
4
|
* Centralizes broadcast driver selection and provider env mappings.
|
|
5
5
|
* Driver selection must be dynamic (tests may mutate process.env).
|
|
6
6
|
*/
|
|
7
|
-
import { KnownBroadcastDriverConfig } from './type';
|
|
7
|
+
import { InMemoryBroadcastDriverConfig, KnownBroadcastDriverConfig, PusherBroadcastDriverConfig, RedisBroadcastDriverConfig, RedisHttpsBroadcastDriverConfig } from './type';
|
|
8
8
|
declare const _default: Readonly<{
|
|
9
9
|
/**
|
|
10
|
-
*
|
|
10
|
+
* Default broadcaster name (normalized).
|
|
11
|
+
*/
|
|
12
|
+
readonly default: string;
|
|
13
|
+
/**
|
|
14
|
+
* Broadcast drivers.
|
|
11
15
|
*
|
|
12
|
-
*
|
|
16
|
+
* You may add custom named broadcasters (e.g. `ops`, `billing`) that point to any
|
|
17
|
+
* known driver config.
|
|
18
|
+
*/
|
|
19
|
+
readonly drivers: {
|
|
20
|
+
readonly inmemory: InMemoryBroadcastDriverConfig;
|
|
21
|
+
readonly pusher: PusherBroadcastDriverConfig;
|
|
22
|
+
readonly redis: RedisBroadcastDriverConfig;
|
|
23
|
+
readonly redishttps: RedisHttpsBroadcastDriverConfig;
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* Normalized broadcast driver name for the default broadcaster.
|
|
13
27
|
*/
|
|
14
28
|
readonly getDriverName: () => string;
|
|
15
29
|
/**
|
|
16
30
|
* Get a config object for the currently selected driver.
|
|
17
31
|
* Defaults to inmemory for unknown/unsupported names.
|
|
18
32
|
*/
|
|
19
|
-
readonly getDriverConfig: () => KnownBroadcastDriverConfig;
|
|
33
|
+
readonly getDriverConfig: (name?: string) => KnownBroadcastDriverConfig;
|
|
20
34
|
}>;
|
|
21
35
|
export default _default;
|
|
22
36
|
//# sourceMappingURL=broadcast.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"broadcast.d.ts","sourceRoot":"","sources":["../../../src/config/broadcast.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,
|
|
1
|
+
{"version":3,"file":"broadcast.d.ts","sourceRoot":"","sources":["../../../src/config/broadcast.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAGL,6BAA6B,EAC7B,0BAA0B,EAC1B,2BAA2B,EAC3B,0BAA0B,EAC1B,+BAA+B,EAChC,MAAM,cAAc,CAAC;;IA4EpB;;OAEG;sBACY,MAAM;IAIrB;;;;;OAKG;;2BAEe,6BAA6B;;;;;IAc/C;;OAEG;kCACc,MAAM;IAIvB;;;OAGG;sCACoB,MAAM,KAAG,0BAA0B;;AAK5D,wBAAiD"}
|
package/src/config/broadcast.js
CHANGED
|
@@ -5,7 +5,21 @@
|
|
|
5
5
|
* Driver selection must be dynamic (tests may mutate process.env).
|
|
6
6
|
*/
|
|
7
7
|
import { Env } from './env.js';
|
|
8
|
+
import { ErrorFactory } from '../exceptions/ZintrustError.js';
|
|
8
9
|
const normalizeDriverName = (value) => value.trim().toLowerCase();
|
|
10
|
+
const hasOwn = (obj, key) => {
|
|
11
|
+
return Object.prototype.hasOwnProperty.call(obj, key);
|
|
12
|
+
};
|
|
13
|
+
const getDefaultBroadcaster = (drivers) => {
|
|
14
|
+
const envSelectedRaw = Env.get('BROADCAST_CONNECTION', Env.get('BROADCAST_DRIVER', 'inmemory'));
|
|
15
|
+
const value = normalizeDriverName(envSelectedRaw ?? 'inmemory');
|
|
16
|
+
if (value.length > 0 && hasOwn(drivers, value))
|
|
17
|
+
return value;
|
|
18
|
+
if (envSelectedRaw.trim().length > 0) {
|
|
19
|
+
throw ErrorFactory.createConfigError(`Broadcast driver not configured: ${value}`);
|
|
20
|
+
}
|
|
21
|
+
return hasOwn(drivers, 'inmemory') ? 'inmemory' : (Object.keys(drivers)[0] ?? 'inmemory');
|
|
22
|
+
};
|
|
9
23
|
const getPusherConfig = () => ({
|
|
10
24
|
driver: 'pusher',
|
|
11
25
|
appId: Env.get('PUSHER_APP_ID', ''),
|
|
@@ -27,28 +41,64 @@ const getRedisHttpsConfig = () => ({
|
|
|
27
41
|
token: Env.get('REDIS_HTTPS_TOKEN', ''),
|
|
28
42
|
channelPrefix: Env.get('BROADCAST_CHANNEL_PREFIX', 'broadcast:'),
|
|
29
43
|
});
|
|
44
|
+
const getBroadcastDriver = (config, name) => {
|
|
45
|
+
const selected = normalizeDriverName(String(name ?? config.default));
|
|
46
|
+
const broadcasterName = selected === 'default' ? normalizeDriverName(config.default) : selected;
|
|
47
|
+
const isExplicitSelection = name !== undefined &&
|
|
48
|
+
String(name).trim().length > 0 &&
|
|
49
|
+
normalizeDriverName(String(name)) !== 'default';
|
|
50
|
+
if (broadcasterName.length > 0 && hasOwn(config.drivers, broadcasterName)) {
|
|
51
|
+
const resolved = config.drivers[broadcasterName];
|
|
52
|
+
if (resolved !== undefined)
|
|
53
|
+
return resolved;
|
|
54
|
+
}
|
|
55
|
+
if (isExplicitSelection) {
|
|
56
|
+
throw ErrorFactory.createConfigError(`Broadcast driver not configured: ${broadcasterName}`);
|
|
57
|
+
}
|
|
58
|
+
const fallback = config.drivers['inmemory'] ?? Object.values(config.drivers)[0];
|
|
59
|
+
if (fallback !== undefined)
|
|
60
|
+
return fallback;
|
|
61
|
+
throw ErrorFactory.createConfigError('No broadcast drivers are configured');
|
|
62
|
+
};
|
|
30
63
|
const broadcastConfigObj = {
|
|
31
64
|
/**
|
|
32
|
-
*
|
|
65
|
+
* Default broadcaster name (normalized).
|
|
66
|
+
*/
|
|
67
|
+
get default() {
|
|
68
|
+
return getDefaultBroadcaster(this.drivers);
|
|
69
|
+
},
|
|
70
|
+
/**
|
|
71
|
+
* Broadcast drivers.
|
|
33
72
|
*
|
|
34
|
-
*
|
|
73
|
+
* You may add custom named broadcasters (e.g. `ops`, `billing`) that point to any
|
|
74
|
+
* known driver config.
|
|
75
|
+
*/
|
|
76
|
+
drivers: {
|
|
77
|
+
get inmemory() {
|
|
78
|
+
return { driver: 'inmemory' };
|
|
79
|
+
},
|
|
80
|
+
get pusher() {
|
|
81
|
+
return getPusherConfig();
|
|
82
|
+
},
|
|
83
|
+
get redis() {
|
|
84
|
+
return getRedisConfig();
|
|
85
|
+
},
|
|
86
|
+
get redishttps() {
|
|
87
|
+
return getRedisHttpsConfig();
|
|
88
|
+
},
|
|
89
|
+
},
|
|
90
|
+
/**
|
|
91
|
+
* Normalized broadcast driver name for the default broadcaster.
|
|
35
92
|
*/
|
|
36
93
|
getDriverName() {
|
|
37
|
-
return normalizeDriverName(
|
|
94
|
+
return normalizeDriverName(this.default);
|
|
38
95
|
},
|
|
39
96
|
/**
|
|
40
97
|
* Get a config object for the currently selected driver.
|
|
41
98
|
* Defaults to inmemory for unknown/unsupported names.
|
|
42
99
|
*/
|
|
43
|
-
getDriverConfig() {
|
|
44
|
-
|
|
45
|
-
if (driver === 'pusher')
|
|
46
|
-
return getPusherConfig();
|
|
47
|
-
if (driver === 'redis')
|
|
48
|
-
return getRedisConfig();
|
|
49
|
-
if (driver === 'redishttps')
|
|
50
|
-
return getRedisHttpsConfig();
|
|
51
|
-
return { driver: 'inmemory' };
|
|
100
|
+
getDriverConfig(name) {
|
|
101
|
+
return getBroadcastDriver(this, name);
|
|
52
102
|
},
|
|
53
103
|
};
|
|
54
104
|
export default Object.freeze(broadcastConfigObj);
|
package/src/config/cache.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../../../src/config/cache.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAoB,iBAAiB,
|
|
1
|
+
{"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../../../src/config/cache.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAoB,iBAAiB,EAAE,MAAM,cAAc,CAAC;AA2FnE,eAAO,MAAM,WAAW;IA/DtB;;OAEG;;IAaH;;OAEG;;;;;;;;;;;;;;;;;;;;;;;;;;;IA4BH;;OAEG;qBACc,MAAM,GAAG,iBAAiB;IAI3C;;OAEG;;IAGH;;OAEG;;EAImD,CAAC;AACzD,MAAM,MAAM,WAAW,GAAG,OAAO,WAAW,CAAC"}
|
package/src/config/cache.js
CHANGED
|
@@ -4,19 +4,36 @@
|
|
|
4
4
|
* Sealed namespace for immutability
|
|
5
5
|
*/
|
|
6
6
|
import { Env } from './env.js';
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
7
|
+
import { ErrorFactory } from '../exceptions/ZintrustError.js';
|
|
8
|
+
const getCacheDriver = (config, name) => {
|
|
9
|
+
const selected = String(name ?? config.default).trim();
|
|
10
|
+
const storeName = selected === 'default' ? String(config.default).trim() : selected;
|
|
11
|
+
const isExplicitSelection = name !== undefined && String(name).trim().length > 0 && String(name).trim() !== 'default';
|
|
12
|
+
if (storeName.length > 0 && Object.hasOwn(config.drivers, storeName)) {
|
|
13
|
+
const resolved = config.drivers[storeName];
|
|
14
|
+
if (resolved !== undefined)
|
|
15
|
+
return resolved;
|
|
12
16
|
}
|
|
13
|
-
|
|
17
|
+
if (isExplicitSelection) {
|
|
18
|
+
throw ErrorFactory.createConfigError(`Cache store not configured: ${storeName}`);
|
|
19
|
+
}
|
|
20
|
+
if (Object.keys(config.drivers ?? {}).length === 0) {
|
|
21
|
+
throw ErrorFactory.createConfigError('No cache stores are configured');
|
|
22
|
+
}
|
|
23
|
+
throw ErrorFactory.createConfigError(`Cache default store not configured: ${storeName || '<empty>'}`);
|
|
14
24
|
};
|
|
15
25
|
const cacheConfigObj = {
|
|
16
26
|
/**
|
|
17
27
|
* Default cache driver
|
|
18
28
|
*/
|
|
19
|
-
default:
|
|
29
|
+
default: (() => {
|
|
30
|
+
const envConnection = Env.get('CACHE_CONNECTION', '').trim();
|
|
31
|
+
const envDriver = typeof Env.CACHE_DRIVER === 'string'
|
|
32
|
+
? String(Env.CACHE_DRIVER)
|
|
33
|
+
: Env.get('CACHE_DRIVER', 'memory');
|
|
34
|
+
const selected = envConnection.length > 0 ? envConnection : String(envDriver ?? 'memory');
|
|
35
|
+
return selected.trim().toLowerCase();
|
|
36
|
+
})(),
|
|
20
37
|
/**
|
|
21
38
|
* Cache drivers
|
|
22
39
|
*/
|
|
@@ -49,8 +66,8 @@ const cacheConfigObj = {
|
|
|
49
66
|
/**
|
|
50
67
|
* Get cache driver config
|
|
51
68
|
*/
|
|
52
|
-
getDriver() {
|
|
53
|
-
return getCacheDriver(this);
|
|
69
|
+
getDriver(name) {
|
|
70
|
+
return getCacheDriver(this, name);
|
|
54
71
|
},
|
|
55
72
|
/**
|
|
56
73
|
* Key prefix for all cache keys
|
package/src/config/database.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../../../src/config/database.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,
|
|
1
|
+
{"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../../../src/config/database.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,mBAAmB,EAAE,wBAAwB,EAAuB,MAAM,cAAc,CAAC;AAoHlG,eAAO,MAAM,cAAc;IAzCzB;;OAEG;;IAGH;;OAEG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAGH;;OAEG;wBACiB,mBAAmB,GAAG,wBAAwB;IAIlE;;OAEG;;;;;IAMH;;OAEG;;;;;IAMH;;OAEG;;;;EAMyD,CAAC;AAC/D,MAAM,MAAM,cAAc,GAAG,OAAO,cAAc,CAAC"}
|