@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/src/config/database.js
CHANGED
|
@@ -4,61 +4,79 @@
|
|
|
4
4
|
* Sealed namespace for immutability
|
|
5
5
|
*/
|
|
6
6
|
import { Env } from './env.js';
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
import { ErrorFactory } from '../exceptions/ZintrustError.js';
|
|
8
|
+
const hasOwn = (obj, key) => {
|
|
9
|
+
return Object.prototype.hasOwnProperty.call(obj, key);
|
|
9
10
|
};
|
|
10
|
-
const getDefaultConnection = () => {
|
|
11
|
-
const
|
|
12
|
-
|
|
11
|
+
const getDefaultConnection = (connections) => {
|
|
12
|
+
const envSelectedRaw = Env.get('DB_CONNECTION', '');
|
|
13
|
+
const value = String(envSelectedRaw ?? '').trim();
|
|
14
|
+
if (value.length > 0 && hasOwn(connections, value))
|
|
15
|
+
return value;
|
|
16
|
+
if (envSelectedRaw.trim().length > 0) {
|
|
17
|
+
throw ErrorFactory.createConfigError(`Database connection not configured: ${value}`);
|
|
18
|
+
}
|
|
19
|
+
return hasOwn(connections, 'sqlite') ? 'sqlite' : (Object.keys(connections)[0] ?? 'sqlite');
|
|
13
20
|
};
|
|
14
21
|
const getDatabaseConnection = (config) => {
|
|
15
22
|
const connName = config.default;
|
|
16
|
-
|
|
23
|
+
const resolved = config.connections[connName];
|
|
24
|
+
if (resolved !== undefined)
|
|
25
|
+
return resolved;
|
|
26
|
+
// Backwards-compatible fallback.
|
|
27
|
+
const sqliteFallback = config.connections['sqlite'];
|
|
28
|
+
if (sqliteFallback !== undefined)
|
|
29
|
+
return sqliteFallback;
|
|
30
|
+
const first = Object.values(config.connections)[0];
|
|
31
|
+
if (first !== undefined)
|
|
32
|
+
return first;
|
|
33
|
+
throw ErrorFactory.createConfigError(`No database connections are configured (default='${connName}').`);
|
|
34
|
+
};
|
|
35
|
+
const connections = {
|
|
36
|
+
sqlite: {
|
|
37
|
+
driver: 'sqlite',
|
|
38
|
+
database: Env.DB_DATABASE,
|
|
39
|
+
migrations: 'database/migrations',
|
|
40
|
+
},
|
|
41
|
+
postgresql: {
|
|
42
|
+
driver: 'postgresql',
|
|
43
|
+
host: Env.DB_HOST,
|
|
44
|
+
port: Env.DB_PORT,
|
|
45
|
+
database: Env.DB_DATABASE,
|
|
46
|
+
username: Env.DB_USERNAME,
|
|
47
|
+
password: Env.DB_PASSWORD,
|
|
48
|
+
ssl: Env.getBool('DB_SSL', false),
|
|
49
|
+
pooling: {
|
|
50
|
+
enabled: Env.getBool('DB_POOLING', true),
|
|
51
|
+
min: Env.getInt('DB_POOL_MIN', 5),
|
|
52
|
+
max: Env.getInt('DB_POOL_MAX', 20),
|
|
53
|
+
idleTimeout: Env.getInt('DB_IDLE_TIMEOUT', 30000),
|
|
54
|
+
connectionTimeout: Env.getInt('DB_CONNECTION_TIMEOUT', 10000),
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
mysql: {
|
|
58
|
+
driver: 'mysql',
|
|
59
|
+
host: Env.DB_HOST,
|
|
60
|
+
port: Env.DB_PORT,
|
|
61
|
+
database: Env.DB_DATABASE,
|
|
62
|
+
username: Env.DB_USERNAME,
|
|
63
|
+
password: Env.DB_PASSWORD,
|
|
64
|
+
pooling: {
|
|
65
|
+
enabled: Env.getBool('DB_POOLING', true),
|
|
66
|
+
min: Env.getInt('DB_POOL_MIN', 5),
|
|
67
|
+
max: Env.getInt('DB_POOL_MAX', 20),
|
|
68
|
+
},
|
|
69
|
+
},
|
|
17
70
|
};
|
|
18
71
|
const databaseConfigObj = {
|
|
19
72
|
/**
|
|
20
73
|
* Default database connection
|
|
21
74
|
*/
|
|
22
|
-
default: getDefaultConnection(),
|
|
75
|
+
default: getDefaultConnection(connections),
|
|
23
76
|
/**
|
|
24
77
|
* Database connections
|
|
25
78
|
*/
|
|
26
|
-
connections
|
|
27
|
-
sqlite: {
|
|
28
|
-
driver: 'sqlite',
|
|
29
|
-
database: Env.DB_DATABASE,
|
|
30
|
-
migrations: 'database/migrations',
|
|
31
|
-
},
|
|
32
|
-
postgresql: {
|
|
33
|
-
driver: 'postgresql',
|
|
34
|
-
host: Env.DB_HOST,
|
|
35
|
-
port: Env.DB_PORT,
|
|
36
|
-
database: Env.DB_DATABASE,
|
|
37
|
-
username: Env.DB_USERNAME,
|
|
38
|
-
password: Env.DB_PASSWORD,
|
|
39
|
-
ssl: Env.getBool('DB_SSL', false),
|
|
40
|
-
pooling: {
|
|
41
|
-
enabled: Env.getBool('DB_POOLING', true),
|
|
42
|
-
min: Env.getInt('DB_POOL_MIN', 5),
|
|
43
|
-
max: Env.getInt('DB_POOL_MAX', 20),
|
|
44
|
-
idleTimeout: Env.getInt('DB_IDLE_TIMEOUT', 30000),
|
|
45
|
-
connectionTimeout: Env.getInt('DB_CONNECTION_TIMEOUT', 10000),
|
|
46
|
-
},
|
|
47
|
-
},
|
|
48
|
-
mysql: {
|
|
49
|
-
driver: 'mysql',
|
|
50
|
-
host: Env.DB_HOST,
|
|
51
|
-
port: Env.DB_PORT,
|
|
52
|
-
database: Env.DB_DATABASE,
|
|
53
|
-
username: Env.DB_USERNAME,
|
|
54
|
-
password: Env.DB_PASSWORD,
|
|
55
|
-
pooling: {
|
|
56
|
-
enabled: Env.getBool('DB_POOLING', true),
|
|
57
|
-
min: Env.getInt('DB_POOL_MIN', 5),
|
|
58
|
-
max: Env.getInt('DB_POOL_MAX', 20),
|
|
59
|
-
},
|
|
60
|
-
},
|
|
61
|
-
},
|
|
79
|
+
connections,
|
|
62
80
|
/**
|
|
63
81
|
* Get current connection config
|
|
64
82
|
*/
|
package/src/config/index.d.ts
CHANGED
|
@@ -3,10 +3,12 @@
|
|
|
3
3
|
* Central export point for all configuration
|
|
4
4
|
*/
|
|
5
5
|
export { appConfig, type AppConfig } from './app';
|
|
6
|
+
export { default as broadcastConfig } from './broadcast';
|
|
6
7
|
export { cacheConfig, type CacheConfig } from './cache';
|
|
7
8
|
export { databaseConfig, type DatabaseConfig } from './database';
|
|
8
9
|
export { microservicesConfig, type MicroservicesConfig } from './microservices';
|
|
9
10
|
export { middlewareConfig } from './middleware';
|
|
11
|
+
export { notificationConfig, type NotificationConfig } from './notification';
|
|
10
12
|
export { queueConfig, type QueueConfig } from './queue';
|
|
11
13
|
export { securityConfig } from './security';
|
|
12
14
|
export { storageConfig, type StorageConfig } from './storage';
|
|
@@ -29,8 +31,19 @@ export declare const config: Readonly<{
|
|
|
29
31
|
readonly maxBodySize: string;
|
|
30
32
|
readonly getSafeEnv: () => NodeJS.ProcessEnv;
|
|
31
33
|
}>;
|
|
34
|
+
readonly broadcast: Readonly<{
|
|
35
|
+
readonly default: string;
|
|
36
|
+
readonly drivers: {
|
|
37
|
+
readonly inmemory: import("./type").InMemoryBroadcastDriverConfig;
|
|
38
|
+
readonly pusher: import("./type").PusherBroadcastDriverConfig;
|
|
39
|
+
readonly redis: import("./type").RedisBroadcastDriverConfig;
|
|
40
|
+
readonly redishttps: import("./type").RedisHttpsBroadcastDriverConfig;
|
|
41
|
+
};
|
|
42
|
+
readonly getDriverName: () => string;
|
|
43
|
+
readonly getDriverConfig: (name?: string) => import("./type").KnownBroadcastDriverConfig;
|
|
44
|
+
}>;
|
|
32
45
|
readonly database: Readonly<{
|
|
33
|
-
default:
|
|
46
|
+
default: string;
|
|
34
47
|
connections: {
|
|
35
48
|
sqlite: {
|
|
36
49
|
driver: "sqlite";
|
|
@@ -84,6 +97,7 @@ export declare const config: Readonly<{
|
|
|
84
97
|
readonly default: string;
|
|
85
98
|
readonly drivers: import("./type").StorageDrivers;
|
|
86
99
|
getDriver(this: import("./type").StorageConfigRuntime): import("./type").StorageDriverConfig;
|
|
100
|
+
getDriverConfig(this: import("./type").StorageConfigRuntime, name?: string): import("./type").StorageDriverConfig;
|
|
87
101
|
readonly temp: {
|
|
88
102
|
path: string;
|
|
89
103
|
maxAge: number;
|
|
@@ -98,6 +112,13 @@ export declare const config: Readonly<{
|
|
|
98
112
|
driver: string;
|
|
99
113
|
};
|
|
100
114
|
}>;
|
|
115
|
+
readonly notification: Readonly<{
|
|
116
|
+
readonly default: string;
|
|
117
|
+
readonly drivers: import("./type").NotificationDrivers;
|
|
118
|
+
readonly providers: import("./type").NotificationProviders;
|
|
119
|
+
readonly getDriverName: () => string;
|
|
120
|
+
readonly getDriverConfig: (name?: string) => import("./type").KnownNotificationDriverConfig;
|
|
121
|
+
}>;
|
|
101
122
|
readonly security: Readonly<{
|
|
102
123
|
readonly jwt: {
|
|
103
124
|
readonly enabled: boolean;
|
|
@@ -250,7 +271,7 @@ export declare const config: Readonly<{
|
|
|
250
271
|
ttl: number;
|
|
251
272
|
};
|
|
252
273
|
};
|
|
253
|
-
getDriver(): import("./type").CacheDriverConfig;
|
|
274
|
+
getDriver(name?: string): import("./type").CacheDriverConfig;
|
|
254
275
|
keyPrefix: string;
|
|
255
276
|
ttl: number;
|
|
256
277
|
}>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/config/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/config/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAaH,OAAO,EAAE,SAAS,EAAE,KAAK,SAAS,EAAE,MAAM,aAAa,CAAC;AACxD,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAC/D,OAAO,EAAE,WAAW,EAAE,KAAK,WAAW,EAAE,MAAM,eAAe,CAAC;AAC9D,OAAO,EAAE,cAAc,EAAE,KAAK,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACvE,OAAO,EAAE,mBAAmB,EAAE,KAAK,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AACtF,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,kBAAkB,EAAE,KAAK,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AACnF,OAAO,EAAE,WAAW,EAAE,KAAK,WAAW,EAAE,MAAM,eAAe,CAAC;AAC9D,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,KAAK,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAEpE;;;GAGG;AACH,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAWR,CAAC;AAEZ,MAAM,MAAM,MAAM,GAAG,OAAO,MAAM,CAAC"}
|
package/src/config/index.js
CHANGED
|
@@ -3,18 +3,22 @@
|
|
|
3
3
|
* Central export point for all configuration
|
|
4
4
|
*/
|
|
5
5
|
import { appConfig } from './app.js';
|
|
6
|
+
import broadcastConfig from './broadcast.js';
|
|
6
7
|
import { cacheConfig } from './cache.js';
|
|
7
8
|
import { databaseConfig } from './database.js';
|
|
8
9
|
import { microservicesConfig } from './microservices.js';
|
|
9
10
|
import { middlewareConfig } from './middleware.js';
|
|
11
|
+
import notificationConfig from './notification.js';
|
|
10
12
|
import { queueConfig } from './queue.js';
|
|
11
13
|
import { securityConfig } from './security.js';
|
|
12
14
|
import { storageConfig } from './storage.js';
|
|
13
15
|
export { appConfig } from './app.js';
|
|
16
|
+
export { default as broadcastConfig } from './broadcast.js';
|
|
14
17
|
export { cacheConfig } from './cache.js';
|
|
15
18
|
export { databaseConfig } from './database.js';
|
|
16
19
|
export { microservicesConfig } from './microservices.js';
|
|
17
20
|
export { middlewareConfig } from './middleware.js';
|
|
21
|
+
export { notificationConfig } from './notification.js';
|
|
18
22
|
export { queueConfig } from './queue.js';
|
|
19
23
|
export { securityConfig } from './security.js';
|
|
20
24
|
export { storageConfig } from './storage.js';
|
|
@@ -24,8 +28,10 @@ export { storageConfig } from './storage.js';
|
|
|
24
28
|
*/
|
|
25
29
|
export const config = Object.freeze({
|
|
26
30
|
app: appConfig,
|
|
31
|
+
broadcast: broadcastConfig,
|
|
27
32
|
database: databaseConfig,
|
|
28
33
|
storage: storageConfig,
|
|
34
|
+
notification: notificationConfig,
|
|
29
35
|
security: securityConfig,
|
|
30
36
|
middleware: middlewareConfig,
|
|
31
37
|
microservices: microservicesConfig,
|
package/src/config/mail.d.ts
CHANGED
|
@@ -3,12 +3,12 @@
|
|
|
3
3
|
* Runtime mail drivers and settings
|
|
4
4
|
* Sealed namespace for immutability
|
|
5
5
|
*/
|
|
6
|
-
import type { MailDriverConfig
|
|
6
|
+
import type { MailDriverConfig } from './type';
|
|
7
7
|
export declare const mailConfig: Readonly<{
|
|
8
8
|
/**
|
|
9
9
|
* Default mail driver
|
|
10
10
|
*/
|
|
11
|
-
readonly default:
|
|
11
|
+
readonly default: string;
|
|
12
12
|
/**
|
|
13
13
|
* Default "From" identity
|
|
14
14
|
*/
|
|
@@ -57,7 +57,7 @@ export declare const mailConfig: Readonly<{
|
|
|
57
57
|
/**
|
|
58
58
|
* Get selected driver config
|
|
59
59
|
*/
|
|
60
|
-
readonly getDriver: () => MailDriverConfig;
|
|
60
|
+
readonly getDriver: (name?: string) => MailDriverConfig;
|
|
61
61
|
}>;
|
|
62
62
|
export type MailConfig = typeof mailConfig;
|
|
63
63
|
//# sourceMappingURL=mail.d.ts.map
|
package/src/config/mail.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mail.d.ts","sourceRoot":"","sources":["../../../src/config/mail.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAmB,gBAAgB,EAAE,
|
|
1
|
+
{"version":3,"file":"mail.d.ts","sourceRoot":"","sources":["../../../src/config/mail.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAmB,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAkHtE,eAAO,MAAM,UAAU;IA7ErB;;OAEG;;IAGH;;OAEG;;;;;IAMH;;OAEG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAsDH;;OAEG;gCACc,MAAM,KAAG,gBAAgB;EAKU,CAAC;AACvD,MAAM,MAAM,UAAU,GAAG,OAAO,UAAU,CAAC"}
|
package/src/config/mail.js
CHANGED
|
@@ -4,19 +4,41 @@
|
|
|
4
4
|
* Sealed namespace for immutability
|
|
5
5
|
*/
|
|
6
6
|
import { Env } from './env.js';
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
if (
|
|
10
|
-
|
|
11
|
-
|
|
7
|
+
import { ErrorFactory } from '../exceptions/ZintrustError.js';
|
|
8
|
+
const isMailDriverConfig = (value) => {
|
|
9
|
+
if (typeof value !== 'object' || value === null)
|
|
10
|
+
return false;
|
|
11
|
+
if (!('driver' in value))
|
|
12
|
+
return false;
|
|
13
|
+
const driver = value.driver;
|
|
14
|
+
return typeof driver === 'string' && driver.trim().length > 0;
|
|
15
|
+
};
|
|
16
|
+
const getMailDriver = (config, name) => {
|
|
17
|
+
const drivers = config.drivers;
|
|
18
|
+
const envSelectedRaw = Env.get('MAIL_CONNECTION', Env.get('MAIL_DRIVER', '')).trim();
|
|
19
|
+
const selected = (name ??
|
|
20
|
+
(envSelectedRaw.length > 0 ? envSelectedRaw : undefined) ??
|
|
21
|
+
config.default)
|
|
22
|
+
.toString()
|
|
23
|
+
.trim();
|
|
24
|
+
if (selected.length === 0) {
|
|
25
|
+
const disabled = drivers['disabled'];
|
|
26
|
+
if (isMailDriverConfig(disabled))
|
|
27
|
+
return disabled;
|
|
28
|
+
throw ErrorFactory.createConfigError('Mail driver not configured: disabled');
|
|
29
|
+
}
|
|
30
|
+
if (Object.hasOwn(drivers, selected)) {
|
|
31
|
+
const resolved = drivers[selected];
|
|
32
|
+
if (isMailDriverConfig(resolved))
|
|
33
|
+
return resolved;
|
|
12
34
|
}
|
|
13
|
-
|
|
35
|
+
throw ErrorFactory.createConfigError(`Mail driver not configured: ${selected}`);
|
|
14
36
|
};
|
|
15
37
|
const mailConfigObj = {
|
|
16
38
|
/**
|
|
17
39
|
* Default mail driver
|
|
18
40
|
*/
|
|
19
|
-
default: Env.get('
|
|
41
|
+
default: Env.get('MAIL_CONNECTION', Env.get('MAIL_DRIVER', 'disabled')).trim().toLowerCase(),
|
|
20
42
|
/**
|
|
21
43
|
* Default "From" identity
|
|
22
44
|
*/
|
|
@@ -83,8 +105,8 @@ const mailConfigObj = {
|
|
|
83
105
|
/**
|
|
84
106
|
* Get selected driver config
|
|
85
107
|
*/
|
|
86
|
-
getDriver() {
|
|
87
|
-
return getMailDriver(this);
|
|
108
|
+
getDriver(name) {
|
|
109
|
+
return getMailDriver(this, name);
|
|
88
110
|
},
|
|
89
111
|
};
|
|
90
112
|
export const mailConfig = Object.freeze(mailConfigObj);
|
|
@@ -1,41 +1,37 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Notification Configuration
|
|
3
3
|
*
|
|
4
|
-
* Config-first mapping of notification providers.
|
|
5
|
-
*
|
|
4
|
+
* Config-first mapping of notification providers/channels.
|
|
5
|
+
* Driver selection must be dynamic (tests may mutate process.env).
|
|
6
6
|
*/
|
|
7
|
-
|
|
7
|
+
import type { KnownNotificationDriverConfig, NotificationDrivers, NotificationProviders } from './type';
|
|
8
|
+
export declare const notificationConfig: Readonly<{
|
|
8
9
|
/**
|
|
9
|
-
*
|
|
10
|
+
* Default notification channel name (normalized).
|
|
11
|
+
*/
|
|
12
|
+
readonly default: string;
|
|
13
|
+
/**
|
|
14
|
+
* Notification channels.
|
|
10
15
|
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
16
|
+
* You may add custom named channels (e.g. `opsSlack`, `smsMarketing`) that
|
|
17
|
+
* point to any known driver config.
|
|
18
|
+
*/
|
|
19
|
+
readonly drivers: NotificationDrivers;
|
|
20
|
+
/**
|
|
21
|
+
* Legacy provider configs (kept for backwards compatibility with wrappers).
|
|
22
|
+
*/
|
|
23
|
+
readonly providers: NotificationProviders;
|
|
24
|
+
/**
|
|
25
|
+
* Normalized notification channel name.
|
|
13
26
|
*/
|
|
14
27
|
readonly getDriverName: () => string;
|
|
15
28
|
/**
|
|
16
|
-
*
|
|
29
|
+
* Resolve a channel config.
|
|
30
|
+
* - Unknown names throw when explicitly selected.
|
|
31
|
+
* - `default` is a reserved alias of the configured default.
|
|
17
32
|
*/
|
|
18
|
-
readonly
|
|
19
|
-
console: {
|
|
20
|
-
driver: "console";
|
|
21
|
-
};
|
|
22
|
-
termii: {
|
|
23
|
-
driver: "termii";
|
|
24
|
-
apiKey: string;
|
|
25
|
-
sender: string;
|
|
26
|
-
endpoint: string;
|
|
27
|
-
};
|
|
28
|
-
twilio: {
|
|
29
|
-
driver: "twilio";
|
|
30
|
-
accountSid: string;
|
|
31
|
-
authToken: string;
|
|
32
|
-
fromNumber: string;
|
|
33
|
-
};
|
|
34
|
-
slack: {
|
|
35
|
-
driver: "slack";
|
|
36
|
-
webhookUrl: string;
|
|
37
|
-
};
|
|
38
|
-
};
|
|
33
|
+
readonly getDriverConfig: (name?: string) => KnownNotificationDriverConfig;
|
|
39
34
|
}>;
|
|
40
|
-
export
|
|
35
|
+
export type NotificationConfig = typeof notificationConfig;
|
|
36
|
+
export default notificationConfig;
|
|
41
37
|
//# sourceMappingURL=notification.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"notification.d.ts","sourceRoot":"","sources":["../../../src/config/notification.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;;
|
|
1
|
+
{"version":3,"file":"notification.d.ts","sourceRoot":"","sources":["../../../src/config/notification.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EACV,6BAA6B,EAE7B,mBAAmB,EACnB,qBAAqB,EACtB,MAAM,cAAc,CAAC;AAuHtB,eAAO,MAAM,kBAAkB;IA1C7B;;OAEG;sBACY,MAAM;IAIrB;;;;;OAKG;sBACY,mBAAmB;IAKlC;;OAEG;wBACc,qBAAqB;IAItC;;OAEG;kCACc,MAAM;IAIvB;;;;OAIG;sCACoB,MAAM,KAAG,6BAA6B;EAKO,CAAC;AACvE,MAAM,MAAM,kBAAkB,GAAG,OAAO,kBAAkB,CAAC;AAE3D,eAAe,kBAAkB,CAAC"}
|
|
@@ -1,27 +1,48 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Notification Configuration
|
|
3
3
|
*
|
|
4
|
-
* Config-first mapping of notification providers.
|
|
5
|
-
*
|
|
4
|
+
* Config-first mapping of notification providers/channels.
|
|
5
|
+
* Driver selection must be dynamic (tests may mutate process.env).
|
|
6
6
|
*/
|
|
7
7
|
import { Env } from './env.js';
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
8
|
+
import { ErrorFactory } from '../exceptions/ZintrustError.js';
|
|
9
|
+
const normalizeName = (value) => value.trim().toLowerCase();
|
|
10
|
+
const hasOwn = (obj, key) => {
|
|
11
|
+
return Object.prototype.hasOwnProperty.call(obj, key);
|
|
12
|
+
};
|
|
13
|
+
const getDefaultChannel = (drivers) => {
|
|
14
|
+
const envSelectedRaw = Env.get('NOTIFICATION_CONNECTION', Env.get('NOTIFICATION_DRIVER', 'console'));
|
|
15
|
+
const value = normalizeName(envSelectedRaw ?? 'console');
|
|
16
|
+
if (value.length > 0 && hasOwn(drivers, value))
|
|
17
|
+
return value;
|
|
18
|
+
if (envSelectedRaw.trim().length > 0) {
|
|
19
|
+
throw ErrorFactory.createConfigError(`Notification channel not configured: ${value}`);
|
|
20
|
+
}
|
|
21
|
+
return hasOwn(drivers, 'console') ? 'console' : (Object.keys(drivers)[0] ?? 'console');
|
|
22
|
+
};
|
|
23
|
+
const getNotificationDriver = (config, name) => {
|
|
24
|
+
const selected = normalizeName(String(name ?? config.default));
|
|
25
|
+
const channelName = selected === 'default' ? normalizeName(config.default) : selected;
|
|
26
|
+
const isExplicitSelection = name !== undefined &&
|
|
27
|
+
String(name).trim().length > 0 &&
|
|
28
|
+
normalizeName(String(name)) !== 'default';
|
|
29
|
+
if (channelName.length > 0 && hasOwn(config.drivers, channelName)) {
|
|
30
|
+
const resolved = config.drivers[channelName];
|
|
31
|
+
if (resolved !== undefined)
|
|
32
|
+
return resolved;
|
|
33
|
+
}
|
|
34
|
+
if (Object.keys(config.drivers ?? {}).length === 0) {
|
|
35
|
+
throw ErrorFactory.createConfigError('No notification channels are configured');
|
|
36
|
+
}
|
|
37
|
+
if (isExplicitSelection) {
|
|
38
|
+
throw ErrorFactory.createConfigError(`Notification channel not configured: ${channelName}`);
|
|
39
|
+
}
|
|
40
|
+
// Default selection is strict: if `default` points at an unconfigured channel, throw.
|
|
41
|
+
throw ErrorFactory.createConfigError(`Notification channel not configured: ${channelName}`);
|
|
42
|
+
};
|
|
43
|
+
const getBaseProviders = () => {
|
|
44
|
+
return {
|
|
45
|
+
console: { driver: 'console' },
|
|
25
46
|
termii: {
|
|
26
47
|
driver: 'termii',
|
|
27
48
|
apiKey: Env.get('TERMII_API_KEY', ''),
|
|
@@ -38,6 +59,45 @@ const notificationConfigObj = {
|
|
|
38
59
|
driver: 'slack',
|
|
39
60
|
webhookUrl: Env.get('SLACK_WEBHOOK_URL', ''),
|
|
40
61
|
},
|
|
62
|
+
};
|
|
63
|
+
};
|
|
64
|
+
const notificationConfigObj = {
|
|
65
|
+
/**
|
|
66
|
+
* Default notification channel name (normalized).
|
|
67
|
+
*/
|
|
68
|
+
get default() {
|
|
69
|
+
return getDefaultChannel(this.drivers);
|
|
70
|
+
},
|
|
71
|
+
/**
|
|
72
|
+
* Notification channels.
|
|
73
|
+
*
|
|
74
|
+
* You may add custom named channels (e.g. `opsSlack`, `smsMarketing`) that
|
|
75
|
+
* point to any known driver config.
|
|
76
|
+
*/
|
|
77
|
+
get drivers() {
|
|
78
|
+
// Return a record of channels; can be extended by app-level config.
|
|
79
|
+
return getBaseProviders();
|
|
80
|
+
},
|
|
81
|
+
/**
|
|
82
|
+
* Legacy provider configs (kept for backwards compatibility with wrappers).
|
|
83
|
+
*/
|
|
84
|
+
get providers() {
|
|
85
|
+
return getBaseProviders();
|
|
86
|
+
},
|
|
87
|
+
/**
|
|
88
|
+
* Normalized notification channel name.
|
|
89
|
+
*/
|
|
90
|
+
getDriverName() {
|
|
91
|
+
return normalizeName(this.default);
|
|
92
|
+
},
|
|
93
|
+
/**
|
|
94
|
+
* Resolve a channel config.
|
|
95
|
+
* - Unknown names throw when explicitly selected.
|
|
96
|
+
* - `default` is a reserved alias of the configured default.
|
|
97
|
+
*/
|
|
98
|
+
getDriverConfig(name) {
|
|
99
|
+
return getNotificationDriver(this, name);
|
|
41
100
|
},
|
|
42
101
|
};
|
|
43
|
-
export
|
|
102
|
+
export const notificationConfig = Object.freeze(notificationConfigObj);
|
|
103
|
+
export default notificationConfig;
|
package/src/config/storage.d.ts
CHANGED
|
@@ -17,6 +17,14 @@ export declare const storageConfig: Readonly<{
|
|
|
17
17
|
* Get storage driver config
|
|
18
18
|
*/
|
|
19
19
|
getDriver(this: StorageConfigRuntime): StorageDriverConfig;
|
|
20
|
+
/**
|
|
21
|
+
* Get a storage disk configuration by name.
|
|
22
|
+
*
|
|
23
|
+
* - When `name` is provided and not configured, this throws.
|
|
24
|
+
* - When `name` is omitted, it resolves the configured default with a backwards-compatible fallback.
|
|
25
|
+
* - Reserved name `default` aliases the configured default.
|
|
26
|
+
*/
|
|
27
|
+
getDriverConfig(this: StorageConfigRuntime, name?: string): StorageDriverConfig;
|
|
20
28
|
/**
|
|
21
29
|
* Temporary file settings
|
|
22
30
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../../src/config/storage.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../../src/config/storage.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAmI9F,eAAO,MAAM,aAAa;IAhExB;;OAEG;sBACY,MAAM;IAIrB;;OAEG;sBACY,cAAc;IAI7B;;OAEG;oBACa,oBAAoB,GAAG,mBAAmB;IAI1D;;;;;;OAMG;0BACmB,oBAAoB,SAAS,MAAM,GAAG,mBAAmB;IAI/E;;OAEG;mBACS;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE;IAO5C;;OAEG;sBACY;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE;IAQtE;;OAEG;sBACY;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE;EAQW,CAAC;AAE7D,MAAM,MAAM,aAAa,GAAG,OAAO,aAAa,CAAC"}
|
package/src/config/storage.js
CHANGED
|
@@ -4,15 +4,26 @@
|
|
|
4
4
|
* Sealed namespace for immutability
|
|
5
5
|
*/
|
|
6
6
|
import { Env } from './env.js';
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
import { ErrorFactory } from '../exceptions/ZintrustError.js';
|
|
8
|
+
const hasOwn = (obj, key) => {
|
|
9
|
+
return Object.prototype.hasOwnProperty.call(obj, key);
|
|
9
10
|
};
|
|
10
|
-
const getStorageDriver = (config) => {
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
const getStorageDriver = (config, name) => {
|
|
12
|
+
const selected = String(name ?? config.default).trim();
|
|
13
|
+
const diskName = selected === 'default' ? String(config.default).trim() : selected;
|
|
14
|
+
const isExplicitSelection = name !== undefined && String(name).trim().length > 0 && String(name).trim() !== 'default';
|
|
15
|
+
if (diskName !== '' && hasOwn(config.drivers, diskName)) {
|
|
16
|
+
const resolved = config.drivers[diskName];
|
|
17
|
+
if (resolved !== undefined)
|
|
18
|
+
return resolved;
|
|
14
19
|
}
|
|
15
|
-
|
|
20
|
+
if (isExplicitSelection) {
|
|
21
|
+
throw ErrorFactory.createConfigError(`Storage disk not configured: ${diskName}`);
|
|
22
|
+
}
|
|
23
|
+
if (Object.keys(config.drivers ?? {}).length === 0) {
|
|
24
|
+
throw ErrorFactory.createConfigError('No storage disks are configured');
|
|
25
|
+
}
|
|
26
|
+
throw ErrorFactory.createConfigError(`Storage default disk not configured: ${diskName || '<empty>'}`);
|
|
16
27
|
};
|
|
17
28
|
const getDrivers = () => ({
|
|
18
29
|
local: {
|
|
@@ -53,7 +64,7 @@ const storageConfigObj = {
|
|
|
53
64
|
* Default storage driver (dynamic; tests may mutate process.env)
|
|
54
65
|
*/
|
|
55
66
|
get default() {
|
|
56
|
-
return Env.get('STORAGE_DRIVER', 'local');
|
|
67
|
+
return Env.get('STORAGE_CONNECTION', Env.get('STORAGE_DRIVER', 'local')).trim().toLowerCase();
|
|
57
68
|
},
|
|
58
69
|
/**
|
|
59
70
|
* Storage drivers configuration (dynamic; tests may mutate process.env)
|
|
@@ -67,6 +78,16 @@ const storageConfigObj = {
|
|
|
67
78
|
getDriver() {
|
|
68
79
|
return getStorageDriver(this);
|
|
69
80
|
},
|
|
81
|
+
/**
|
|
82
|
+
* Get a storage disk configuration by name.
|
|
83
|
+
*
|
|
84
|
+
* - When `name` is provided and not configured, this throws.
|
|
85
|
+
* - When `name` is omitted, it resolves the configured default with a backwards-compatible fallback.
|
|
86
|
+
* - Reserved name `default` aliases the configured default.
|
|
87
|
+
*/
|
|
88
|
+
getDriverConfig(name) {
|
|
89
|
+
return getStorageDriver(this, name);
|
|
90
|
+
},
|
|
70
91
|
/**
|
|
71
92
|
* Temporary file settings
|
|
72
93
|
*/
|