@ambiten/core 1.0.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.
- package/LICENSE +21 -0
- package/README.md +247 -0
- package/bin/bootstrap.js +26 -0
- package/dist/ambiten-cache/ambitenCache.d.ts +64 -0
- package/dist/ambiten-cache/ambitenCache.d.ts.map +1 -0
- package/dist/ambiten-cache/ambitenCache.js +127 -0
- package/dist/ambiten-cache/index.d.ts +2 -0
- package/dist/ambiten-cache/index.d.ts.map +1 -0
- package/dist/ambiten-cache/index.js +4 -0
- package/dist/browser.d.ts +32 -0
- package/dist/browser.d.ts.map +1 -0
- package/dist/browser.js +37 -0
- package/dist/cli/ambiten-core-cli.d.ts +4 -0
- package/dist/cli/ambiten-core-cli.d.ts.map +1 -0
- package/dist/cli/ambiten-core-cli.js +41 -0
- package/dist/cli/buildInteractiveConfig.d.ts +4 -0
- package/dist/cli/buildInteractiveConfig.d.ts.map +1 -0
- package/dist/cli/buildInteractiveConfig.js +198 -0
- package/dist/cli/index.d.ts +5 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +7 -0
- package/dist/cli/prompt.d.ts +10 -0
- package/dist/cli/prompt.d.ts.map +1 -0
- package/dist/cli/prompt.js +48 -0
- package/dist/cli/types.d.ts +11 -0
- package/dist/cli/types.d.ts.map +1 -0
- package/dist/cli/types.js +2 -0
- package/dist/config/ambiten.config.schema.json +278 -0
- package/dist/config/index.d.ts +2 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +4 -0
- package/dist/config/loadAmbitenConfig.d.ts +3 -0
- package/dist/config/loadAmbitenConfig.d.ts.map +1 -0
- package/dist/config/loadAmbitenConfig.js +131 -0
- package/dist/context/ambitenContext.d.ts +35 -0
- package/dist/context/ambitenContext.d.ts.map +1 -0
- package/dist/context/ambitenContext.js +147 -0
- package/dist/context/helpers/runManualTransaction.d.ts +3 -0
- package/dist/context/helpers/runManualTransaction.d.ts.map +1 -0
- package/dist/context/helpers/runManualTransaction.js +22 -0
- package/dist/context/helpers/transactionSession.d.ts +9 -0
- package/dist/context/helpers/transactionSession.d.ts.map +1 -0
- package/dist/context/helpers/transactionSession.js +8 -0
- package/dist/context/index.d.ts +4 -0
- package/dist/context/index.d.ts.map +1 -0
- package/dist/context/index.js +6 -0
- package/dist/debug/debugLog.d.ts +2 -0
- package/dist/debug/debugLog.d.ts.map +1 -0
- package/dist/debug/debugLog.js +23 -0
- package/dist/debug/index.d.ts +2 -0
- package/dist/debug/index.d.ts.map +1 -0
- package/dist/debug/index.js +4 -0
- package/dist/gc/ambitenGC.d.ts +49 -0
- package/dist/gc/ambitenGC.d.ts.map +1 -0
- package/dist/gc/ambitenGC.js +138 -0
- package/dist/gc/gcCron.browser.d.ts +2 -0
- package/dist/gc/gcCron.browser.d.ts.map +1 -0
- package/dist/gc/gcCron.browser.js +9 -0
- package/dist/gc/gcCron.node.d.ts +19 -0
- package/dist/gc/gcCron.node.d.ts.map +1 -0
- package/dist/gc/gcCron.node.js +47 -0
- package/dist/gc/gcManager.d.ts +37 -0
- package/dist/gc/gcManager.d.ts.map +1 -0
- package/dist/gc/gcManager.js +62 -0
- package/dist/gc/index.d.ts +5 -0
- package/dist/gc/index.d.ts.map +1 -0
- package/dist/gc/index.js +7 -0
- package/dist/graphql/ambitenGraphQL.d.ts +24 -0
- package/dist/graphql/ambitenGraphQL.d.ts.map +1 -0
- package/dist/graphql/ambitenGraphQL.js +215 -0
- package/dist/graphql/index.d.ts +2 -0
- package/dist/graphql/index.d.ts.map +1 -0
- package/dist/graphql/index.js +4 -0
- package/dist/index-browser.js +25 -0
- package/dist/index-browser.js.map +1 -0
- package/dist/index-cli.js +26 -0
- package/dist/index-cli.js.map +1 -0
- package/dist/index.d.ts +30 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +25 -0
- package/dist/index.js.map +1 -0
- package/dist/init-cli/generate.project.d.ts +9 -0
- package/dist/init-cli/generate.project.d.ts.map +1 -0
- package/dist/init-cli/generate.project.js +38 -0
- package/dist/instrumentation/index.d.ts +3 -0
- package/dist/instrumentation/index.d.ts.map +1 -0
- package/dist/instrumentation/index.js +5 -0
- package/dist/instrumentation/measureQuery.browser.d.ts +3 -0
- package/dist/instrumentation/measureQuery.browser.d.ts.map +1 -0
- package/dist/instrumentation/measureQuery.browser.js +6 -0
- package/dist/instrumentation/measureQueryWithErrors.d.ts +11 -0
- package/dist/instrumentation/measureQueryWithErrors.d.ts.map +1 -0
- package/dist/instrumentation/measureQueryWithErrors.js +90 -0
- package/dist/lib-core/ambitenClient.d.ts +115 -0
- package/dist/lib-core/ambitenClient.d.ts.map +1 -0
- package/dist/lib-core/ambitenClient.js +537 -0
- package/dist/lib-core/ambitenModelFactory.d.ts +979 -0
- package/dist/lib-core/ambitenModelFactory.d.ts.map +1 -0
- package/dist/lib-core/ambitenModelFactory.js +3984 -0
- package/dist/lib-core/ambitenSchema.d.ts +126 -0
- package/dist/lib-core/ambitenSchema.d.ts.map +1 -0
- package/dist/lib-core/ambitenSchema.js +247 -0
- package/dist/lib-core/bootstrap/ambitenBootstrap.d.ts +38 -0
- package/dist/lib-core/bootstrap/ambitenBootstrap.d.ts.map +1 -0
- package/dist/lib-core/bootstrap/ambitenBootstrap.js +381 -0
- package/dist/lib-core/bootstrap/index.d.ts +2 -0
- package/dist/lib-core/bootstrap/index.d.ts.map +1 -0
- package/dist/lib-core/bootstrap/index.js +4 -0
- package/dist/lib-core/index.d.ts +5 -0
- package/dist/lib-core/index.d.ts.map +1 -0
- package/dist/lib-core/index.js +7 -0
- package/dist/middleware/authorization/auth.d.ts +22 -0
- package/dist/middleware/authorization/auth.d.ts.map +1 -0
- package/dist/middleware/authorization/auth.js +37 -0
- package/dist/middleware/index.d.ts +4 -0
- package/dist/middleware/index.d.ts.map +1 -0
- package/dist/middleware/index.js +6 -0
- package/dist/middleware/rbac/rbacMiddleware.d.ts +103 -0
- package/dist/middleware/rbac/rbacMiddleware.d.ts.map +1 -0
- package/dist/middleware/rbac/rbacMiddleware.js +246 -0
- package/dist/middleware/rbac/rbacTypes.d.ts +4 -0
- package/dist/middleware/rbac/rbacTypes.d.ts.map +1 -0
- package/dist/middleware/rbac/rbacTypes.js +8 -0
- package/dist/plugins/index.d.ts +3 -0
- package/dist/plugins/index.d.ts.map +1 -0
- package/dist/plugins/index.js +5 -0
- package/dist/plugins/softDelete/applySoftDelete.d.ts +5 -0
- package/dist/plugins/softDelete/applySoftDelete.d.ts.map +1 -0
- package/dist/plugins/softDelete/applySoftDelete.js +139 -0
- package/dist/plugins/softDelete/types.d.ts +14 -0
- package/dist/plugins/softDelete/types.d.ts.map +1 -0
- package/dist/plugins/softDelete/types.js +2 -0
- package/dist/redis-manager/index.d.ts +2 -0
- package/dist/redis-manager/index.d.ts.map +1 -0
- package/dist/redis-manager/index.js +4 -0
- package/dist/redis-manager/redisClient.d.ts +32 -0
- package/dist/redis-manager/redisClient.d.ts.map +1 -0
- package/dist/redis-manager/redisClient.js +146 -0
- package/dist/tanancy/MultiTenantManager.d.ts +98 -0
- package/dist/tanancy/MultiTenantManager.d.ts.map +1 -0
- package/dist/tanancy/MultiTenantManager.js +190 -0
- package/dist/tanancy/TenantContext.d.ts +31 -0
- package/dist/tanancy/TenantContext.d.ts.map +1 -0
- package/dist/tanancy/TenantContext.js +59 -0
- package/dist/tanancy/TenantModelResolver.d.ts +10 -0
- package/dist/tanancy/TenantModelResolver.d.ts.map +1 -0
- package/dist/tanancy/TenantModelResolver.js +114 -0
- package/dist/tanancy/index.d.ts +5 -0
- package/dist/tanancy/index.d.ts.map +1 -0
- package/dist/tanancy/index.js +7 -0
- package/dist/tanancy/init/initMultiTenancy.d.ts +29 -0
- package/dist/tanancy/init/initMultiTenancy.d.ts.map +1 -0
- package/dist/tanancy/init/initMultiTenancy.js +62 -0
- package/dist/templates/generateDefaultConfigContent.d.ts +10 -0
- package/dist/templates/generateDefaultConfigContent.d.ts.map +1 -0
- package/dist/templates/generateDefaultConfigContent.js +108 -0
- package/dist/templates/generateGCManagerFile.d.ts +2 -0
- package/dist/templates/generateGCManagerFile.d.ts.map +1 -0
- package/dist/templates/generateGCManagerFile.js +39 -0
- package/dist/templates/generateGCRunnerFile.d.ts +2 -0
- package/dist/templates/generateGCRunnerFile.d.ts.map +1 -0
- package/dist/templates/generateGCRunnerFile.js +25 -0
- package/dist/templates/generateMainEntry.d.ts +3 -0
- package/dist/templates/generateMainEntry.d.ts.map +1 -0
- package/dist/templates/generateMainEntry.js +24 -0
- package/dist/templates/index.d.ts +6 -0
- package/dist/templates/index.d.ts.map +1 -0
- package/dist/templates/index.js +8 -0
- package/dist/templates/scaffold/structureGenerator.d.ts +4 -0
- package/dist/templates/scaffold/structureGenerator.d.ts.map +1 -0
- package/dist/templates/scaffold/structureGenerator.js +193 -0
- package/dist/types/GCConfig.d.ts +7 -0
- package/dist/types/GCConfig.d.ts.map +1 -0
- package/dist/types/GCConfig.js +2 -0
- package/dist/types/ambiten-runtime-type.d.ts +24 -0
- package/dist/types/ambiten-runtime-type.d.ts.map +1 -0
- package/dist/types/ambiten-runtime-type.js +2 -0
- package/dist/types/ambiten.client.type.d.ts +136 -0
- package/dist/types/ambiten.client.type.d.ts.map +1 -0
- package/dist/types/ambiten.client.type.js +3 -0
- package/dist/types/ambiten.model.type.d.ts +135 -0
- package/dist/types/ambiten.model.type.d.ts.map +1 -0
- package/dist/types/ambiten.model.type.js +4 -0
- package/dist/types/ambitenConfig.d.ts +103 -0
- package/dist/types/ambitenConfig.d.ts.map +1 -0
- package/dist/types/ambitenConfig.js +3 -0
- package/dist/types/bootstrapClient.type.d.ts +11 -0
- package/dist/types/bootstrapClient.type.d.ts.map +1 -0
- package/dist/types/bootstrapClient.type.js +2 -0
- package/dist/types/db.provider.d.ts +66 -0
- package/dist/types/db.provider.d.ts.map +1 -0
- package/dist/types/db.provider.js +2 -0
- package/dist/types/document.d.ts +7 -0
- package/dist/types/document.d.ts.map +1 -0
- package/dist/types/document.js +2 -0
- package/dist/types/event.type.d.ts +6 -0
- package/dist/types/event.type.d.ts.map +1 -0
- package/dist/types/event.type.js +27 -0
- package/dist/types/graphql.type.d.ts +22 -0
- package/dist/types/graphql.type.d.ts.map +1 -0
- package/dist/types/graphql.type.js +2 -0
- package/dist/types/index.d.ts +15 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +17 -0
- package/dist/types/logger.types.d.ts +15 -0
- package/dist/types/logger.types.d.ts.map +1 -0
- package/dist/types/logger.types.js +3 -0
- package/dist/types/middleware/types.d.ts +28 -0
- package/dist/types/middleware/types.d.ts.map +1 -0
- package/dist/types/middleware/types.js +2 -0
- package/dist/types/result.utils.types.d.ts +7 -0
- package/dist/types/result.utils.types.d.ts.map +1 -0
- package/dist/types/result.utils.types.js +2 -0
- package/dist/types/schema.type.d.ts +23 -0
- package/dist/types/schema.type.d.ts.map +1 -0
- package/dist/types/schema.type.js +10 -0
- package/dist/types/user.type.d.ts +11 -0
- package/dist/types/user.type.d.ts.map +1 -0
- package/dist/types/user.type.js +2 -0
- package/dist/utils/AuthUtils.d.ts +15 -0
- package/dist/utils/AuthUtils.d.ts.map +1 -0
- package/dist/utils/AuthUtils.js +26 -0
- package/dist/utils/ModelRegistry.d.ts +15 -0
- package/dist/utils/ModelRegistry.d.ts.map +1 -0
- package/dist/utils/ModelRegistry.js +35 -0
- package/dist/utils/banner.d.ts +2 -0
- package/dist/utils/banner.d.ts.map +1 -0
- package/dist/utils/banner.js +20 -0
- package/dist/utils/builders/createModel.d.ts +37 -0
- package/dist/utils/builders/createModel.d.ts.map +1 -0
- package/dist/utils/builders/createModel.js +38 -0
- package/dist/utils/builders/getTenantDb.d.ts +12 -0
- package/dist/utils/builders/getTenantDb.d.ts.map +1 -0
- package/dist/utils/builders/getTenantDb.js +25 -0
- package/dist/utils/builders/index.d.ts +4 -0
- package/dist/utils/builders/index.d.ts.map +1 -0
- package/dist/utils/builders/index.js +6 -0
- package/dist/utils/builders/schema.d.ts +22 -0
- package/dist/utils/builders/schema.d.ts.map +1 -0
- package/dist/utils/builders/schema.js +26 -0
- package/dist/utils/cacheWithRedis.d.ts +27 -0
- package/dist/utils/cacheWithRedis.d.ts.map +1 -0
- package/dist/utils/cacheWithRedis.js +22 -0
- package/dist/utils/castId.d.ts +5 -0
- package/dist/utils/castId.d.ts.map +1 -0
- package/dist/utils/castId.js +52 -0
- package/dist/utils/color-palatte.d.ts +4 -0
- package/dist/utils/color-palatte.d.ts.map +1 -0
- package/dist/utils/color-palatte.js +24 -0
- package/dist/utils/configureAmbitenContext.d.ts +13 -0
- package/dist/utils/configureAmbitenContext.d.ts.map +1 -0
- package/dist/utils/configureAmbitenContext.js +35 -0
- package/dist/utils/detect-package-manager.d.ts +5 -0
- package/dist/utils/detect-package-manager.d.ts.map +1 -0
- package/dist/utils/detect-package-manager.js +59 -0
- package/dist/utils/ensureModelNameSafe.d.ts +12 -0
- package/dist/utils/ensureModelNameSafe.d.ts.map +1 -0
- package/dist/utils/ensureModelNameSafe.js +28 -0
- package/dist/utils/ensureRedis.d.ts +7 -0
- package/dist/utils/ensureRedis.d.ts.map +1 -0
- package/dist/utils/ensureRedis.js +40 -0
- package/dist/utils/error/ambitenError-handler.d.ts +24 -0
- package/dist/utils/error/ambitenError-handler.d.ts.map +1 -0
- package/dist/utils/error/ambitenError-handler.js +39 -0
- package/dist/utils/error/errorTypes.d.ts +27 -0
- package/dist/utils/error/errorTypes.d.ts.map +1 -0
- package/dist/utils/error/errorTypes.js +30 -0
- package/dist/utils/error/index.d.ts +3 -0
- package/dist/utils/error/index.d.ts.map +1 -0
- package/dist/utils/error/index.js +5 -0
- package/dist/utils/eventOptions.d.ts +38 -0
- package/dist/utils/eventOptions.d.ts.map +1 -0
- package/dist/utils/eventOptions.js +130 -0
- package/dist/utils/events.d.ts +5 -0
- package/dist/utils/events.d.ts.map +1 -0
- package/dist/utils/events.js +7 -0
- package/dist/utils/index.d.ts +23 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +25 -0
- package/dist/utils/invalidateTenantCache.d.ts +18 -0
- package/dist/utils/invalidateTenantCache.d.ts.map +1 -0
- package/dist/utils/invalidateTenantCache.js +27 -0
- package/dist/utils/logger.d.ts +3 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +27 -0
- package/dist/utils/modelLoader.d.ts +3 -0
- package/dist/utils/modelLoader.d.ts.map +1 -0
- package/dist/utils/modelLoader.js +41 -0
- package/dist/utils/resolveAmbitenOption.d.ts +2 -0
- package/dist/utils/resolveAmbitenOption.d.ts.map +1 -0
- package/dist/utils/resolveAmbitenOption.js +10 -0
- package/dist/utils/resolveRuntimeConfig.d.ts +22 -0
- package/dist/utils/resolveRuntimeConfig.d.ts.map +1 -0
- package/dist/utils/resolveRuntimeConfig.js +33 -0
- package/dist/utils/scaffoldLoger.d.ts +11 -0
- package/dist/utils/scaffoldLoger.d.ts.map +1 -0
- package/dist/utils/scaffoldLoger.js +68 -0
- package/dist/utils/symbols.d.ts +4 -0
- package/dist/utils/symbols.d.ts.map +1 -0
- package/dist/utils/symbols.js +6 -0
- package/dist/utils/time.d.ts +5 -0
- package/dist/utils/time.d.ts.map +1 -0
- package/dist/utils/time.js +39 -0
- package/package.json +180 -0
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { MongoClient } from 'mongodb';
|
|
2
|
+
export interface TenantConfig {
|
|
3
|
+
tenantId: string;
|
|
4
|
+
uri: string;
|
|
5
|
+
dbName: string;
|
|
6
|
+
client?: MongoClient;
|
|
7
|
+
lazy: boolean;
|
|
8
|
+
metadata?: Record<string, unknown>;
|
|
9
|
+
}
|
|
10
|
+
export interface RegisterTenantOptions {
|
|
11
|
+
dbName?: string;
|
|
12
|
+
client?: MongoClient;
|
|
13
|
+
lazy?: boolean;
|
|
14
|
+
metadata?: Record<string, unknown>;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* MultiTenantManager is responsible for managing tenant configurations and MongoDB client connections in a multi-tenant application.
|
|
18
|
+
* It supports both lazy and immediate tenant registration, allowing for flexible connection management based on application needs.
|
|
19
|
+
*/
|
|
20
|
+
export declare class MultiTenantManager {
|
|
21
|
+
private static tenants;
|
|
22
|
+
constructor();
|
|
23
|
+
/**
|
|
24
|
+
* Checks if a tenant is already registered.
|
|
25
|
+
* @param {string} tenantId - The ID of the tenant to check.
|
|
26
|
+
* @returns {boolean} `true` if the tenant is registered, `false` otherwise.
|
|
27
|
+
*/
|
|
28
|
+
static hasTenant(tenantId: string): boolean;
|
|
29
|
+
/**
|
|
30
|
+
* Registers a tenant for lazy connection.
|
|
31
|
+
* Connection is established only when the tenant is accessed for the first time.
|
|
32
|
+
*
|
|
33
|
+
* @param {string} tenantId - The tenant ID.
|
|
34
|
+
* @param {string} uri - The MongoDB URI.
|
|
35
|
+
* @param {RegisterTenantOptions} [options] - Optional tenant registration settings.
|
|
36
|
+
*/
|
|
37
|
+
static registerLazyTenant(tenantId: string, uri: string, options?: Omit<RegisterTenantOptions, 'lazy' | 'client'>): TenantConfig;
|
|
38
|
+
/**
|
|
39
|
+
* Registers a tenant and establishes a connection immediately.
|
|
40
|
+
*
|
|
41
|
+
* @param {string} tenantId - The tenant ID.
|
|
42
|
+
* @param {string} uri - The MongoDB URI.
|
|
43
|
+
* @param {RegisterTenantOptions} [options] - Optional tenant registration settings.
|
|
44
|
+
* @returns {Promise<MongoClient>} The connected MongoClient instance.
|
|
45
|
+
*/
|
|
46
|
+
static registerTenant(tenantId: string, uri: string, options?: Omit<RegisterTenantOptions, 'lazy'>): Promise<MongoClient>;
|
|
47
|
+
/**
|
|
48
|
+
* Retrieves the MongoClient instance for a specific tenant.
|
|
49
|
+
* If the tenant was registered lazily, connection is established on first access.
|
|
50
|
+
*
|
|
51
|
+
* @param {string} tenantId - The tenant ID.
|
|
52
|
+
* @returns {Promise<MongoClient | null>} The MongoClient or null if not registered.
|
|
53
|
+
*/
|
|
54
|
+
static getClient(tenantId: string): Promise<MongoClient | null>;
|
|
55
|
+
/**
|
|
56
|
+
* Retrieves the full tenant configuration.
|
|
57
|
+
*
|
|
58
|
+
* @param {string} tenantId - The tenant ID.
|
|
59
|
+
* @returns {TenantConfig | undefined} The tenant configuration if found.
|
|
60
|
+
*/
|
|
61
|
+
static getTenant(tenantId: string): TenantConfig | undefined;
|
|
62
|
+
/**
|
|
63
|
+
* Retrieves the configured database name for a tenant.
|
|
64
|
+
*
|
|
65
|
+
* @param {string} tenantId - The tenant ID.
|
|
66
|
+
* @returns {string | undefined} The database name if found.
|
|
67
|
+
*/
|
|
68
|
+
static getTenantDbName(tenantId: string): string | undefined;
|
|
69
|
+
/**
|
|
70
|
+
* Returns the first connected tenant ID.
|
|
71
|
+
* Useful for backward compatibility, though not ideal in multi-tenant flows.
|
|
72
|
+
*/
|
|
73
|
+
static getConnectedTenant(): string;
|
|
74
|
+
/**
|
|
75
|
+
* Returns all currently connected tenant IDs.
|
|
76
|
+
*/
|
|
77
|
+
static getAllConnectedTenants(): string[];
|
|
78
|
+
/**
|
|
79
|
+
* Returns all registered tenant configs.
|
|
80
|
+
*/
|
|
81
|
+
static getAllTenants(): TenantConfig[];
|
|
82
|
+
/**
|
|
83
|
+
* Returns true if at least one tenant is registered.
|
|
84
|
+
*/
|
|
85
|
+
static isEnabled(): boolean;
|
|
86
|
+
/**
|
|
87
|
+
* Removes a tenant from the registry.
|
|
88
|
+
*/
|
|
89
|
+
static removeTenant(tenantId: string): boolean;
|
|
90
|
+
/**
|
|
91
|
+
* Clears all tenants from the registry.
|
|
92
|
+
*/
|
|
93
|
+
static clearTenants(): void;
|
|
94
|
+
private static validateTenantId;
|
|
95
|
+
private static validateUri;
|
|
96
|
+
private static extractDbNameFromUri;
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=MultiTenantManager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MultiTenantManager.d.ts","sourceRoot":"","sources":["../../src/tanancy/MultiTenantManager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAEtC,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,IAAI,EAAE,OAAO,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED,MAAM,WAAW,qBAAqB;IACpC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED;;;GAGG;AACH,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,MAAM,CAAC,OAAO,CAAwC;;IAI9D;;;;OAIG;IACH,MAAM,CAAC,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;IAI3C;;;;;;;OAOG;IACH,MAAM,CAAC,kBAAkB,CACvB,QAAQ,EAAE,MAAM,EAChB,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,IAAI,CAAC,qBAAqB,EAAE,MAAM,GAAG,QAAQ,CAAM,GAC3D,YAAY;IAoBf;;;;;;;OAOG;WACU,cAAc,CACzB,QAAQ,EAAE,MAAM,EAChB,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,IAAI,CAAC,qBAAqB,EAAE,MAAM,CAAM,GAChD,OAAO,CAAC,WAAW,CAAC;IA6BvB;;;;;;OAMG;WACU,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;IA4BrE;;;;;OAKG;IACH,MAAM,CAAC,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS;IAK5D;;;;;OAKG;IACH,MAAM,CAAC,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAI5D;;;OAGG;IACH,MAAM,CAAC,kBAAkB,IAAI,MAAM;IAKnC;;OAEG;IACH,MAAM,CAAC,sBAAsB,IAAI,MAAM,EAAE;IAMzC;;OAEG;IACH,MAAM,CAAC,aAAa,IAAI,YAAY,EAAE;IAItC;;OAEG;IACH,MAAM,CAAC,SAAS,IAAI,OAAO;IAI3B;;OAEG;IACH,MAAM,CAAC,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;IAK9C;;OAEG;IACH,MAAM,CAAC,YAAY,IAAI,IAAI;IAI3B,OAAO,CAAC,MAAM,CAAC,gBAAgB;IAM/B,OAAO,CAAC,MAAM,CAAC,WAAW;IAU1B,OAAO,CAAC,MAAM,CAAC,oBAAoB;CAepC"}
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MultiTenantManager = void 0;
|
|
4
|
+
const mongodb_1 = require("mongodb");
|
|
5
|
+
/**
|
|
6
|
+
* MultiTenantManager is responsible for managing tenant configurations and MongoDB client connections in a multi-tenant application.
|
|
7
|
+
* It supports both lazy and immediate tenant registration, allowing for flexible connection management based on application needs.
|
|
8
|
+
*/
|
|
9
|
+
class MultiTenantManager {
|
|
10
|
+
static tenants = new Map();
|
|
11
|
+
constructor() { }
|
|
12
|
+
/**
|
|
13
|
+
* Checks if a tenant is already registered.
|
|
14
|
+
* @param {string} tenantId - The ID of the tenant to check.
|
|
15
|
+
* @returns {boolean} `true` if the tenant is registered, `false` otherwise.
|
|
16
|
+
*/
|
|
17
|
+
static hasTenant(tenantId) {
|
|
18
|
+
return this.tenants.has(tenantId);
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Registers a tenant for lazy connection.
|
|
22
|
+
* Connection is established only when the tenant is accessed for the first time.
|
|
23
|
+
*
|
|
24
|
+
* @param {string} tenantId - The tenant ID.
|
|
25
|
+
* @param {string} uri - The MongoDB URI.
|
|
26
|
+
* @param {RegisterTenantOptions} [options] - Optional tenant registration settings.
|
|
27
|
+
*/
|
|
28
|
+
static registerLazyTenant(tenantId, uri, options = {}) {
|
|
29
|
+
this.validateTenantId(tenantId);
|
|
30
|
+
this.validateUri(uri);
|
|
31
|
+
const normalizedTenantId = tenantId.trim();
|
|
32
|
+
const tenantConfig = {
|
|
33
|
+
tenantId: normalizedTenantId,
|
|
34
|
+
uri: uri.trim(),
|
|
35
|
+
dbName: options.dbName?.trim() || this.extractDbNameFromUri(uri) || normalizedTenantId,
|
|
36
|
+
client: undefined,
|
|
37
|
+
lazy: true,
|
|
38
|
+
metadata: options.metadata
|
|
39
|
+
};
|
|
40
|
+
this.tenants.set(normalizedTenantId, tenantConfig);
|
|
41
|
+
return tenantConfig;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Registers a tenant and establishes a connection immediately.
|
|
45
|
+
*
|
|
46
|
+
* @param {string} tenantId - The tenant ID.
|
|
47
|
+
* @param {string} uri - The MongoDB URI.
|
|
48
|
+
* @param {RegisterTenantOptions} [options] - Optional tenant registration settings.
|
|
49
|
+
* @returns {Promise<MongoClient>} The connected MongoClient instance.
|
|
50
|
+
*/
|
|
51
|
+
static async registerTenant(tenantId, uri, options = {}) {
|
|
52
|
+
this.validateTenantId(tenantId);
|
|
53
|
+
this.validateUri(uri);
|
|
54
|
+
const normalizedTenantId = tenantId.trim();
|
|
55
|
+
const existing = this.tenants.get(normalizedTenantId);
|
|
56
|
+
if (existing?.client) {
|
|
57
|
+
return existing.client;
|
|
58
|
+
}
|
|
59
|
+
const client = options.client ?? new mongodb_1.MongoClient(uri);
|
|
60
|
+
if (!options.client) {
|
|
61
|
+
await client.connect();
|
|
62
|
+
}
|
|
63
|
+
const tenantConfig = {
|
|
64
|
+
tenantId: normalizedTenantId,
|
|
65
|
+
uri: uri.trim(),
|
|
66
|
+
dbName: options.dbName?.trim() || this.extractDbNameFromUri(uri) || normalizedTenantId,
|
|
67
|
+
client,
|
|
68
|
+
lazy: false,
|
|
69
|
+
metadata: options.metadata
|
|
70
|
+
};
|
|
71
|
+
this.tenants.set(normalizedTenantId, tenantConfig);
|
|
72
|
+
return client;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Retrieves the MongoClient instance for a specific tenant.
|
|
76
|
+
* If the tenant was registered lazily, connection is established on first access.
|
|
77
|
+
*
|
|
78
|
+
* @param {string} tenantId - The tenant ID.
|
|
79
|
+
* @returns {Promise<MongoClient | null>} The MongoClient or null if not registered.
|
|
80
|
+
*/
|
|
81
|
+
static async getClient(tenantId) {
|
|
82
|
+
this.validateTenantId(tenantId);
|
|
83
|
+
const normalizedTenantId = tenantId.trim();
|
|
84
|
+
const tenant = this.tenants.get(normalizedTenantId);
|
|
85
|
+
if (!tenant)
|
|
86
|
+
return null;
|
|
87
|
+
if (tenant.client) {
|
|
88
|
+
return tenant.client;
|
|
89
|
+
}
|
|
90
|
+
if (tenant.lazy) {
|
|
91
|
+
const client = new mongodb_1.MongoClient(tenant.uri);
|
|
92
|
+
await client.connect();
|
|
93
|
+
this.tenants.set(normalizedTenantId, {
|
|
94
|
+
...tenant,
|
|
95
|
+
client,
|
|
96
|
+
lazy: false
|
|
97
|
+
});
|
|
98
|
+
return client;
|
|
99
|
+
}
|
|
100
|
+
return null;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Retrieves the full tenant configuration.
|
|
104
|
+
*
|
|
105
|
+
* @param {string} tenantId - The tenant ID.
|
|
106
|
+
* @returns {TenantConfig | undefined} The tenant configuration if found.
|
|
107
|
+
*/
|
|
108
|
+
static getTenant(tenantId) {
|
|
109
|
+
this.validateTenantId(tenantId);
|
|
110
|
+
return this.tenants.get(tenantId.trim());
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Retrieves the configured database name for a tenant.
|
|
114
|
+
*
|
|
115
|
+
* @param {string} tenantId - The tenant ID.
|
|
116
|
+
* @returns {string | undefined} The database name if found.
|
|
117
|
+
*/
|
|
118
|
+
static getTenantDbName(tenantId) {
|
|
119
|
+
return this.getTenant(tenantId)?.dbName;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Returns the first connected tenant ID.
|
|
123
|
+
* Useful for backward compatibility, though not ideal in multi-tenant flows.
|
|
124
|
+
*/
|
|
125
|
+
static getConnectedTenant() {
|
|
126
|
+
const connected = Array.from(this.tenants.values()).find(tenant => !!tenant.client);
|
|
127
|
+
return connected?.tenantId || '';
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Returns all currently connected tenant IDs.
|
|
131
|
+
*/
|
|
132
|
+
static getAllConnectedTenants() {
|
|
133
|
+
return Array.from(this.tenants.values())
|
|
134
|
+
.filter(tenant => !!tenant.client)
|
|
135
|
+
.map(tenant => tenant.tenantId);
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Returns all registered tenant configs.
|
|
139
|
+
*/
|
|
140
|
+
static getAllTenants() {
|
|
141
|
+
return Array.from(this.tenants.values());
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Returns true if at least one tenant is registered.
|
|
145
|
+
*/
|
|
146
|
+
static isEnabled() {
|
|
147
|
+
return this.tenants.size > 0;
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Removes a tenant from the registry.
|
|
151
|
+
*/
|
|
152
|
+
static removeTenant(tenantId) {
|
|
153
|
+
this.validateTenantId(tenantId);
|
|
154
|
+
return this.tenants.delete(tenantId.trim());
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Clears all tenants from the registry.
|
|
158
|
+
*/
|
|
159
|
+
static clearTenants() {
|
|
160
|
+
this.tenants.clear();
|
|
161
|
+
}
|
|
162
|
+
static validateTenantId(tenantId) {
|
|
163
|
+
if (!tenantId || typeof tenantId !== 'string' || !tenantId.trim()) {
|
|
164
|
+
throw new Error('Tenant ID is required.');
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
static validateUri(uri) {
|
|
168
|
+
if (!uri || typeof uri !== 'string' || !uri.trim()) {
|
|
169
|
+
throw new Error('MongoDB URI is required.');
|
|
170
|
+
}
|
|
171
|
+
if (!uri.startsWith('mongodb://') && !uri.startsWith('mongodb+srv://')) {
|
|
172
|
+
throw new Error(`Invalid MongoDB URI: ${uri}`);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
static extractDbNameFromUri(uri) {
|
|
176
|
+
try {
|
|
177
|
+
const withoutQuery = uri.split('?')[0];
|
|
178
|
+
const parts = withoutQuery.split('/');
|
|
179
|
+
const lastPart = parts[parts.length - 1];
|
|
180
|
+
if (!lastPart || lastPart.includes(':')) {
|
|
181
|
+
return undefined;
|
|
182
|
+
}
|
|
183
|
+
return lastPart.trim() || undefined;
|
|
184
|
+
}
|
|
185
|
+
catch {
|
|
186
|
+
return undefined;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
exports.MultiTenantManager = MultiTenantManager;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @deprecated
|
|
3
|
+
* @internal
|
|
4
|
+
*
|
|
5
|
+
* This is legacy code and is not intended for public use. It may be removed in future versions without warning.
|
|
6
|
+
* Provides a thread-safe context for managing tenant-specific data using `AsyncLocalStorage`.
|
|
7
|
+
* This is useful for multi-tenant applications where the current tenant needs to be tracked across asynchronous operations.
|
|
8
|
+
*/
|
|
9
|
+
export declare class TenantContext {
|
|
10
|
+
/**
|
|
11
|
+
* Runs a callback function within a specific tenant context.
|
|
12
|
+
* @param {string} tenantId - The ID of the tenant to set in the context.
|
|
13
|
+
* @param {() => void} callback - The callback function to execute within the tenant context.
|
|
14
|
+
*/
|
|
15
|
+
static run(tenantId: string, callback: () => void): void;
|
|
16
|
+
/**
|
|
17
|
+
* Sets the tenant ID in the current context.
|
|
18
|
+
* @param {string} tenantId - The ID of the tenant to set.
|
|
19
|
+
*/
|
|
20
|
+
static setTenantId(tenantId: string): void;
|
|
21
|
+
/**
|
|
22
|
+
* Retrieves the tenant ID from the current context.
|
|
23
|
+
* @returns {string | undefined} The tenant ID, or `undefined` if no tenant ID is set.
|
|
24
|
+
*/
|
|
25
|
+
static getTenantId(): string | undefined;
|
|
26
|
+
/**
|
|
27
|
+
* Clears the tenant ID from the current context.
|
|
28
|
+
*/
|
|
29
|
+
static clear(): void;
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=TenantContext.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TenantContext.d.ts","sourceRoot":"","sources":["../../src/tanancy/TenantContext.ts"],"names":[],"mappings":"AAWA;;;;;;;GAOG;AACH,qBAAa,aAAa;IACxB;;;;OAIG;IACH,MAAM,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,IAAI,GAAG,IAAI;IAOxD;;;OAGG;IACH,MAAM,CAAC,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAK1C;;;OAGG;IACH,MAAM,CAAC,WAAW,IAAI,MAAM,GAAG,SAAS;IAIxC;;OAEG;IACH,MAAM,CAAC,KAAK,IAAI,IAAI;CAIrB"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TenantContext = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* This is legacy code and is not intended for public use. It may be removed in future versions without warning.
|
|
6
|
+
* @deprecated
|
|
7
|
+
* @internal
|
|
8
|
+
* TenantContext provides a thread-safe way to manage tenant-specific data using AsyncLocalStorage.
|
|
9
|
+
* This is particularly useful in multi-tenant applications where you need to track the current tenant across asynchronous operations.
|
|
10
|
+
*/
|
|
11
|
+
const node_async_hooks_1 = require("node:async_hooks");
|
|
12
|
+
const tenantStorage = new node_async_hooks_1.AsyncLocalStorage();
|
|
13
|
+
/**
|
|
14
|
+
* @deprecated
|
|
15
|
+
* @internal
|
|
16
|
+
*
|
|
17
|
+
* This is legacy code and is not intended for public use. It may be removed in future versions without warning.
|
|
18
|
+
* Provides a thread-safe context for managing tenant-specific data using `AsyncLocalStorage`.
|
|
19
|
+
* This is useful for multi-tenant applications where the current tenant needs to be tracked across asynchronous operations.
|
|
20
|
+
*/
|
|
21
|
+
class TenantContext {
|
|
22
|
+
/**
|
|
23
|
+
* Runs a callback function within a specific tenant context.
|
|
24
|
+
* @param {string} tenantId - The ID of the tenant to set in the context.
|
|
25
|
+
* @param {() => void} callback - The callback function to execute within the tenant context.
|
|
26
|
+
*/
|
|
27
|
+
static run(tenantId, callback) {
|
|
28
|
+
if (!tenantId) {
|
|
29
|
+
throw new Error('tenantId is required to run tenant context');
|
|
30
|
+
}
|
|
31
|
+
tenantStorage.run({ tenantId: tenantId }, callback);
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Sets the tenant ID in the current context.
|
|
35
|
+
* @param {string} tenantId - The ID of the tenant to set.
|
|
36
|
+
*/
|
|
37
|
+
static setTenantId(tenantId) {
|
|
38
|
+
const store = tenantStorage.getStore();
|
|
39
|
+
if (store)
|
|
40
|
+
store.tenantId = tenantId;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Retrieves the tenant ID from the current context.
|
|
44
|
+
* @returns {string | undefined} The tenant ID, or `undefined` if no tenant ID is set.
|
|
45
|
+
*/
|
|
46
|
+
static getTenantId() {
|
|
47
|
+
return tenantStorage.getStore()?.tenantId;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Clears the tenant ID from the current context.
|
|
51
|
+
*/
|
|
52
|
+
static clear() {
|
|
53
|
+
const store = tenantStorage.getStore();
|
|
54
|
+
if (store)
|
|
55
|
+
store.tenantId = undefined;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
exports.TenantContext = TenantContext;
|
|
59
|
+
;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Document } from "mongodb";
|
|
2
|
+
import type { AmbitenSchema } from "../lib-core";
|
|
3
|
+
export type GetTenantModelParams<T extends Document> = {
|
|
4
|
+
collectionName: string;
|
|
5
|
+
schema: AmbitenSchema<T>;
|
|
6
|
+
tenantId?: string;
|
|
7
|
+
dbName?: string;
|
|
8
|
+
};
|
|
9
|
+
export declare const getTenantModel: <T extends Document>(params: GetTenantModelParams<T>) => Promise<any>;
|
|
10
|
+
//# sourceMappingURL=TenantModelResolver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TenantModelResolver.d.ts","sourceRoot":"","sources":["../../src/tanancy/TenantModelResolver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAM,QAAQ,EAAE,MAAM,SAAS,CAAC;AAG5C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAMjD,MAAM,MAAM,oBAAoB,CAAC,CAAC,SAAS,QAAQ,IAAI;IACrD,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAqBF,eAAO,MAAM,cAAc,GAAU,CAAC,SAAS,QAAQ,EACrD,QAAQ,oBAAoB,CAAC,CAAC,CAAC,KAC9B,OAAO,CAAC,GAAG,CAqCb,CAAC"}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getTenantModel = void 0;
|
|
4
|
+
const builders_1 = require("../utils/builders");
|
|
5
|
+
const MultiTenantManager_1 = require("./MultiTenantManager");
|
|
6
|
+
const context_1 = require("../context");
|
|
7
|
+
const tenantModelsCache = new Map();
|
|
8
|
+
function createTenantProvider(tenantId, dbName) {
|
|
9
|
+
return {
|
|
10
|
+
async db(ctx) {
|
|
11
|
+
const client = await MultiTenantManager_1.MultiTenantManager.getClient(tenantId);
|
|
12
|
+
if (!client) {
|
|
13
|
+
throw new Error(`Tenant "${tenantId}" not registered.`);
|
|
14
|
+
}
|
|
15
|
+
const resolvedDbName = ctx?.dbName ?? dbName;
|
|
16
|
+
return resolvedDbName ? client.db(resolvedDbName) : client.db();
|
|
17
|
+
},
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
const getTenantModel = async (params) => {
|
|
21
|
+
const collectionName = params?.collectionName?.trim();
|
|
22
|
+
const tenantId = params?.tenantId ?? context_1.AmbitenContext.getTenantId();
|
|
23
|
+
if (!collectionName) {
|
|
24
|
+
throw new Error("collectionName is required.");
|
|
25
|
+
}
|
|
26
|
+
if (!tenantId) {
|
|
27
|
+
throw new Error("tenantId is required to run tenant context");
|
|
28
|
+
}
|
|
29
|
+
if (!tenantModelsCache.has(tenantId)) {
|
|
30
|
+
tenantModelsCache.set(tenantId, new Map());
|
|
31
|
+
}
|
|
32
|
+
const tenantCache = tenantModelsCache.get(tenantId);
|
|
33
|
+
const cacheKey = params.dbName
|
|
34
|
+
? `${collectionName}::${params.dbName}`
|
|
35
|
+
: collectionName;
|
|
36
|
+
if (tenantCache.has(cacheKey)) {
|
|
37
|
+
return tenantCache.get(cacheKey);
|
|
38
|
+
}
|
|
39
|
+
const provider = createTenantProvider(tenantId, params.dbName);
|
|
40
|
+
const model = (0, builders_1.Model)({
|
|
41
|
+
collectionName,
|
|
42
|
+
schema: params.schema,
|
|
43
|
+
provider,
|
|
44
|
+
});
|
|
45
|
+
tenantCache.set(cacheKey, model);
|
|
46
|
+
return model;
|
|
47
|
+
};
|
|
48
|
+
exports.getTenantModel = getTenantModel;
|
|
49
|
+
// import { AmbitenSchema } from '../lib-core';
|
|
50
|
+
// import { MultiTenantManager } from './MultiTenantManager';
|
|
51
|
+
// import { TenantContext } from './TenantContext';
|
|
52
|
+
// import { Model } from '../utils/builders/createModel';
|
|
53
|
+
// import { ensureModelNameSafe } from '../utils/ensureModelNameSafe'; // <- wherever you put it
|
|
54
|
+
// import { Document } from '../types';
|
|
55
|
+
// import { Db } from 'mongodb';
|
|
56
|
+
// type DbProvider = { db(ctx?: { dbName?: string }): Promise<Db> };
|
|
57
|
+
// /**
|
|
58
|
+
// * Parameters required to resolve a tenant-specific model.
|
|
59
|
+
// * @template T - The type of the document in the model.
|
|
60
|
+
// */
|
|
61
|
+
// export type GetTanantModelParams<T extends Document> = {
|
|
62
|
+
// collectionName: string;
|
|
63
|
+
// tenantId: string;
|
|
64
|
+
// schema?: AmbitenSchema<T>;
|
|
65
|
+
// };
|
|
66
|
+
// const tenantModelsCache: Map<string, Map<string, ReturnType<typeof Model>>> = new Map();
|
|
67
|
+
// /**
|
|
68
|
+
// * Resolves a tenant-specific model by creating or retrieving it from the cache.
|
|
69
|
+
// * Ensures that each tenant has its own isolated model instance.
|
|
70
|
+
// *
|
|
71
|
+
// * @template T - The type of the document in the model.
|
|
72
|
+
// * @param {GetTanantModelParams<T>} param - The parameters required to resolve the model.
|
|
73
|
+
// * @param {string} param.modelName - The name of the model to resolve.
|
|
74
|
+
// * @param {AmbitenSchema<T>} [param.schema] - The schema definition for the model (optional).
|
|
75
|
+
// * @param {string} param.tenantId - The ID of the tenant for which the model is being resolved.
|
|
76
|
+
// * @returns {Promise<any>} A promise that resolves to the tenant-specific model instance.
|
|
77
|
+
// * @throws {Error} If no tenant context is found or the tenant is not registered.
|
|
78
|
+
// * @example
|
|
79
|
+
// * const userModel = await getTenantModel({
|
|
80
|
+
// * modelName: 'User',
|
|
81
|
+
// * schema: UserSchema,
|
|
82
|
+
// * tenantId: 'tenant123'
|
|
83
|
+
// * });
|
|
84
|
+
// * // userModel is now a tenant-specific model for the 'User' collection in 'tenant123'
|
|
85
|
+
// * @example
|
|
86
|
+
// * const productModel = await getTenantModel({
|
|
87
|
+
// * modelName: 'Product',
|
|
88
|
+
// * schema: ProductSchema,
|
|
89
|
+
// * tenantId: 'tenant456'
|
|
90
|
+
// * });
|
|
91
|
+
// */
|
|
92
|
+
// export const getTenantModel = async <T extends Document>
|
|
93
|
+
// (param: GetTanantModelParams<T>): Promise<any> => {
|
|
94
|
+
// const safeCollectionName = ensureModelNameSafe(param.collectionName);
|
|
95
|
+
// const schema = param.schema;
|
|
96
|
+
// // const client = await MultiTenantManager.getClient(param.tenantId);
|
|
97
|
+
// const tenantId = param.tenantId ?? TenantContext.getTenantId();
|
|
98
|
+
// if (!tenantId) throw new Error('No tenant context found');
|
|
99
|
+
// if (!tenantModelsCache.has(tenantId)) {
|
|
100
|
+
// tenantModelsCache.set(tenantId, new Map());
|
|
101
|
+
// }
|
|
102
|
+
// const clientCache = tenantModelsCache.get(tenantId)!;
|
|
103
|
+
// if (clientCache.has(safeCollectionName)) {
|
|
104
|
+
// return clientCache.get(safeCollectionName);
|
|
105
|
+
// }
|
|
106
|
+
// const provider = tenantDbProvider(tenantId);
|
|
107
|
+
// const model = Model({
|
|
108
|
+
// collectionName: safeCollectionName,
|
|
109
|
+
// schema,
|
|
110
|
+
// provider: provider
|
|
111
|
+
// });
|
|
112
|
+
// clientCache.set(safeCollectionName, model as unknown as ReturnType<typeof Model>);
|
|
113
|
+
// return model;
|
|
114
|
+
// };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tanancy/index.ts"],"names":[],"mappings":"AAAA,cAAc,sBAAsB,CAAC;AACrC,cAAc,iBAAiB,CAAC;AAChC,cAAc,uBAAuB,CAAC;AACtC,cAAc,yBAAyB,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const tslib_1 = require("tslib");
|
|
4
|
+
tslib_1.__exportStar(require("./MultiTenantManager"), exports);
|
|
5
|
+
tslib_1.__exportStar(require("./TenantContext"), exports);
|
|
6
|
+
tslib_1.__exportStar(require("./TenantModelResolver"), exports);
|
|
7
|
+
tslib_1.__exportStar(require("./init/initMultiTenancy"), exports);
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { AmbitenConfig } from '../../types/index';
|
|
2
|
+
export interface InitMultiTenancyOptions {
|
|
3
|
+
lazy?: boolean;
|
|
4
|
+
config?: AmbitenConfig['logger'];
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Initializes multi-tenancy by registering tenants with their respective MongoDB URIs.
|
|
8
|
+
* Supports both lazy (on-demand) and eager connection strategies.
|
|
9
|
+
*
|
|
10
|
+
* @param {Record<string, string>} tenants - A record of tenant IDs mapped to their MongoDB URIs.
|
|
11
|
+
* @param {InitMultiTenancyOptions} [options={}] - Optional configuration for multi-tenancy initialization.
|
|
12
|
+
* @param {boolean} [options.lazy=false] - If `true`, tenants are registered lazily (connected on-demand).
|
|
13
|
+
* @param {AmbitenConfig} [options.config] - Optional configuration, including a logger for logging messages.
|
|
14
|
+
* @returns {Promise<void>} A promise that resolves when all tenants are registered.
|
|
15
|
+
* @throws {Error} If a tenant's MongoDB URI is invalid or missing.
|
|
16
|
+
* @throws {Error} If a tenant is already registered and `lazy` is `false`.
|
|
17
|
+
* @example
|
|
18
|
+
* // Initialize multi-tenancy with eager connection. Practically, you should use applyMultiTenancy instead.
|
|
19
|
+
* that implements this function.
|
|
20
|
+
* await initMultiTenancy({
|
|
21
|
+
* 'tenant-a': 'mongodb://localhost:27017/tenant-a',
|
|
22
|
+
* 'tenant-b': 'mongodb://localhost:27017/tenant-b'
|
|
23
|
+
* }, {
|
|
24
|
+
* lazy: false,
|
|
25
|
+
* config: {}
|
|
26
|
+
*/
|
|
27
|
+
export declare const initMultiTenancy: (tenants: Record<string, string>, // tenantId => MongoDB URI
|
|
28
|
+
options?: InitMultiTenancyOptions) => Promise<void>;
|
|
29
|
+
//# sourceMappingURL=initMultiTenancy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"initMultiTenancy.d.ts","sourceRoot":"","sources":["../../../src/tanancy/init/initMultiTenancy.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAGlD,MAAM,WAAW,uBAAuB;IACtC,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,aAAa,CAAC,QAAQ,CAAC,CAAA;CACjC;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,gBAAgB,GAC3B,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,0BAA0B;AAC3D,UAAS,uBAA4B,KACpC,OAAO,CAAC,IAAI,CA2Bd,CAAC"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.initMultiTenancy = void 0;
|
|
4
|
+
const MultiTenantManager_1 = require("../MultiTenantManager");
|
|
5
|
+
/**
|
|
6
|
+
* Initializes multi-tenancy by registering tenants with their respective MongoDB URIs.
|
|
7
|
+
* Supports both lazy (on-demand) and eager connection strategies.
|
|
8
|
+
*
|
|
9
|
+
* @param {Record<string, string>} tenants - A record of tenant IDs mapped to their MongoDB URIs.
|
|
10
|
+
* @param {InitMultiTenancyOptions} [options={}] - Optional configuration for multi-tenancy initialization.
|
|
11
|
+
* @param {boolean} [options.lazy=false] - If `true`, tenants are registered lazily (connected on-demand).
|
|
12
|
+
* @param {AmbitenConfig} [options.config] - Optional configuration, including a logger for logging messages.
|
|
13
|
+
* @returns {Promise<void>} A promise that resolves when all tenants are registered.
|
|
14
|
+
* @throws {Error} If a tenant's MongoDB URI is invalid or missing.
|
|
15
|
+
* @throws {Error} If a tenant is already registered and `lazy` is `false`.
|
|
16
|
+
* @example
|
|
17
|
+
* // Initialize multi-tenancy with eager connection. Practically, you should use applyMultiTenancy instead.
|
|
18
|
+
* that implements this function.
|
|
19
|
+
* await initMultiTenancy({
|
|
20
|
+
* 'tenant-a': 'mongodb://localhost:27017/tenant-a',
|
|
21
|
+
* 'tenant-b': 'mongodb://localhost:27017/tenant-b'
|
|
22
|
+
* }, {
|
|
23
|
+
* lazy: false,
|
|
24
|
+
* config: {}
|
|
25
|
+
*/
|
|
26
|
+
const initMultiTenancy = async (tenants, // tenantId => MongoDB URI
|
|
27
|
+
options = {}) => {
|
|
28
|
+
const { lazy = false, config } = options;
|
|
29
|
+
for (const [tenantId, uri] of Object.entries(tenants)) {
|
|
30
|
+
if (!uri || typeof uri !== 'string' || !uri.startsWith('mongodb')) {
|
|
31
|
+
throw new Error(`Invalid MongoDB URI for tenant "${tenantId}": ${uri}`);
|
|
32
|
+
}
|
|
33
|
+
if (MultiTenantManager_1.MultiTenantManager.hasTenant(tenantId)) {
|
|
34
|
+
config?.logger?.warn?.(`Tenant "${tenantId}" is already registered. Skipping.`);
|
|
35
|
+
continue;
|
|
36
|
+
}
|
|
37
|
+
if (lazy) {
|
|
38
|
+
// Ensure logger implements all required methods for core/src/types/logger.types.ts
|
|
39
|
+
if (config?.enabled && config.logger) {
|
|
40
|
+
const logger = config.logger;
|
|
41
|
+
return logger;
|
|
42
|
+
}
|
|
43
|
+
MultiTenantManager_1.MultiTenantManager.registerLazyTenant(tenantId, uri);
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
// Eagerly connect
|
|
48
|
+
await MultiTenantManager_1.MultiTenantManager.registerTenant(tenantId, uri);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
exports.initMultiTenancy = initMultiTenancy;
|
|
53
|
+
function impl_Logger(logger) {
|
|
54
|
+
const { info, warn, error, fatal, debug } = logger;
|
|
55
|
+
return {
|
|
56
|
+
info: info?.bind(logger) ?? (() => { }),
|
|
57
|
+
warn: warn?.bind(logger) ?? (() => { }),
|
|
58
|
+
error: error?.bind(logger) ?? (() => { }),
|
|
59
|
+
fatal: fatal?.bind(logger) ?? (() => { }),
|
|
60
|
+
debug: debug?.bind(logger) ?? (() => { }),
|
|
61
|
+
};
|
|
62
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { AmbitenConfig } from "../types";
|
|
2
|
+
export interface LoggerFormatOptions {
|
|
3
|
+
timestamp?: boolean | (() => string);
|
|
4
|
+
colorize?: boolean;
|
|
5
|
+
source?: string;
|
|
6
|
+
json?: boolean;
|
|
7
|
+
prefix?: string;
|
|
8
|
+
}
|
|
9
|
+
export declare function DEFAULT_CONFIG_CONTENT(options: AmbitenConfig): string;
|
|
10
|
+
//# sourceMappingURL=generateDefaultConfigContent.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generateDefaultConfigContent.d.ts","sourceRoot":"","sources":["../../src/templates/generateDefaultConfigContent.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAE9C,MAAM,WAAW,mBAAmB;IAClC,SAAS,CAAC,EAAE,OAAO,GAAG,CAAC,MAAM,MAAM,CAAC,CAAC;IACrC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAGD,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,aAAa,GAAG,MAAM,CA+GrE"}
|