@flusys/nestjs-core 7.1.0 ā 8.0.0-beta.1
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/README.md +2 -2
- package/config/index.d.ts +1 -1
- package/constants/index.d.ts +1 -1
- package/docs/docs.config.d.ts +1 -1
- package/docs/index.d.ts +1 -1
- package/fesm/229.js +729 -0
- package/fesm/config/index.js +126 -1
- package/fesm/constants/index.js +29 -1
- package/fesm/docs/index.js +288 -1
- package/fesm/index.js +124 -5
- package/fesm/interfaces/index.js +18 -4
- package/fesm/migration/cli.js +19 -2
- package/fesm/migration/index.js +45 -3
- package/fesm/runtime.js +85 -0
- package/fesm/utils/index.js +131 -1
- package/index.d.ts +5 -5
- package/interfaces/app-config.interfaces.d.ts +1 -1
- package/interfaces/index.d.ts +4 -4
- package/interfaces/migration.interface.d.ts +2 -2
- package/migration/cli.d.ts +0 -1
- package/migration/datasource.factory.d.ts +1 -1
- package/migration/index.d.ts +3 -3
- package/migration/migration.cli.d.ts +1 -1
- package/migration/migration.runner.d.ts +1 -1
- package/package.json +24 -32
- package/utils/datasource-config.builder.d.ts +2 -2
- package/utils/index.d.ts +1 -1
- package/cjs/config/env-config.service.js +0 -162
- package/cjs/config/env-config.service.spec.js +0 -325
- package/cjs/config/index.js +0 -18
- package/cjs/constants/database.constants.js +0 -20
- package/cjs/constants/index.js +0 -18
- package/cjs/docs/docs.config.js +0 -276
- package/cjs/docs/docs.config.spec.js +0 -923
- package/cjs/docs/index.js +0 -18
- package/cjs/index.js +0 -23
- package/cjs/interfaces/app-config.interfaces.js +0 -4
- package/cjs/interfaces/base-entity.interface.js +0 -9
- package/cjs/interfaces/database.interface.js +0 -4
- package/cjs/interfaces/index.js +0 -21
- package/cjs/interfaces/migration.interface.js +0 -4
- package/cjs/migration/cli.js +0 -10
- package/cjs/migration/datasource.factory.js +0 -43
- package/cjs/migration/datasource.factory.spec.js +0 -113
- package/cjs/migration/index.js +0 -45
- package/cjs/migration/migration.cli.js +0 -231
- package/cjs/migration/migration.cli.spec.js +0 -293
- package/cjs/migration/migration.runner.js +0 -276
- package/cjs/migration/migration.runner.spec.js +0 -268
- package/cjs/utils/datasource-config.builder.js +0 -103
- package/cjs/utils/datasource-config.builder.spec.js +0 -232
- package/cjs/utils/index.js +0 -18
- package/fesm/config/env-config.service.js +0 -112
- package/fesm/config/env-config.service.spec.js +0 -321
- package/fesm/constants/database.constants.js +0 -2
- package/fesm/docs/docs.config.js +0 -258
- package/fesm/docs/docs.config.spec.js +0 -919
- package/fesm/interfaces/app-config.interfaces.js +0 -1
- package/fesm/interfaces/base-entity.interface.js +0 -6
- package/fesm/interfaces/database.interface.js +0 -1
- package/fesm/interfaces/migration.interface.js +0 -1
- package/fesm/migration/datasource.factory.js +0 -25
- package/fesm/migration/datasource.factory.spec.js +0 -109
- package/fesm/migration/migration.cli.js +0 -180
- package/fesm/migration/migration.cli.spec.js +0 -289
- package/fesm/migration/migration.runner.js +0 -202
- package/fesm/migration/migration.runner.spec.js +0 -264
- package/fesm/utils/datasource-config.builder.js +0 -84
- package/fesm/utils/datasource-config.builder.spec.js +0 -228
package/fesm/229.js
ADDED
|
@@ -0,0 +1,729 @@
|
|
|
1
|
+
import * as __rspack_external_path from "path";
|
|
2
|
+
import * as __rspack_external_typeorm from "typeorm";
|
|
3
|
+
import * as __rspack_external_typeorm_naming_strategies_48a68f8e from "typeorm-naming-strategies";
|
|
4
|
+
import * as __rspack_external_url from "url";
|
|
5
|
+
import * as __rspack_external_dotenv from "dotenv";
|
|
6
|
+
import * as __rspack_external_child_process from "child_process";
|
|
7
|
+
import * as __rspack_external_fs from "fs";
|
|
8
|
+
export const __rspack_esm_id = 229;
|
|
9
|
+
export const __rspack_esm_ids = [229];
|
|
10
|
+
export const __webpack_modules__ = {
|
|
11
|
+
398(module) {
|
|
12
|
+
function __rspack_empty_async_context(req) {
|
|
13
|
+
// Here Promise.resolve().then() is used instead of new Promise() to prevent
|
|
14
|
+
// uncaught exception popping up in devtools
|
|
15
|
+
return Promise.resolve().then(function() {
|
|
16
|
+
var e = new Error("Cannot find module '" + req + "'");
|
|
17
|
+
e.code = 'MODULE_NOT_FOUND';
|
|
18
|
+
throw e;
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
__rspack_empty_async_context.keys = () => ([]);
|
|
22
|
+
__rspack_empty_async_context.resolve = __rspack_empty_async_context;
|
|
23
|
+
__rspack_empty_async_context.id = 398;
|
|
24
|
+
module.exports = __rspack_empty_async_context;
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
},
|
|
28
|
+
892(__unused_rspack_module, __webpack_exports__, __webpack_require__) {
|
|
29
|
+
|
|
30
|
+
// EXPORTS
|
|
31
|
+
__webpack_require__.d(__webpack_exports__, {
|
|
32
|
+
K: () => (/* reexport */ envConfig)
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
;// CONCATENATED MODULE: external "dotenv"
|
|
36
|
+
|
|
37
|
+
;// CONCATENATED MODULE: ./projects/nestjs-core/src/config/env-config.service.ts
|
|
38
|
+
|
|
39
|
+
__rspack_external_dotenv.config();
|
|
40
|
+
let EnvConfigService = class EnvConfigService {
|
|
41
|
+
env;
|
|
42
|
+
restrictedKeys = {
|
|
43
|
+
FRONTEND_URL: 'getFrontendUrl',
|
|
44
|
+
ALLOW_ORIGINS: 'getOrigins',
|
|
45
|
+
PORT: 'getPort',
|
|
46
|
+
MODE: 'isProduction',
|
|
47
|
+
DB_TYPE: 'getTypeOrmConfig',
|
|
48
|
+
DB_HOST: 'getTypeOrmConfig',
|
|
49
|
+
DB_PORT: 'getTypeOrmConfig',
|
|
50
|
+
DB_USER: 'getTypeOrmConfig',
|
|
51
|
+
DB_PASSWORD: 'getTypeOrmConfig',
|
|
52
|
+
DB_NAME: 'getTypeOrmConfig'
|
|
53
|
+
};
|
|
54
|
+
constructor(env){
|
|
55
|
+
this.env = env;
|
|
56
|
+
}
|
|
57
|
+
getValue(key, throwOnMissing = true) {
|
|
58
|
+
const value = this.env[key];
|
|
59
|
+
if (!value && throwOnMissing) {
|
|
60
|
+
throw new Error(`Config error - missing env.${key}`);
|
|
61
|
+
}
|
|
62
|
+
return value ?? '';
|
|
63
|
+
}
|
|
64
|
+
tryGetValue(key, throwOnMissing = false) {
|
|
65
|
+
if (this.restrictedKeys[key]) {
|
|
66
|
+
throw new Error(`Access denied for env key "${key}". Use the method \`${this.restrictedKeys[key]}()\` instead.`);
|
|
67
|
+
}
|
|
68
|
+
return this.getValue(key, throwOnMissing);
|
|
69
|
+
}
|
|
70
|
+
getNumber(key, throwOnMissing = true) {
|
|
71
|
+
return Number(this.getValue(key, throwOnMissing));
|
|
72
|
+
}
|
|
73
|
+
getBoolean(key, throwOnMissing = true) {
|
|
74
|
+
return this.getValue(key, throwOnMissing).toLowerCase() === 'true';
|
|
75
|
+
}
|
|
76
|
+
getPort() {
|
|
77
|
+
return this.getNumber('PORT', false) || 3000;
|
|
78
|
+
}
|
|
79
|
+
isProduction() {
|
|
80
|
+
return this.getValue('MODE', false).toUpperCase() !== 'DEV';
|
|
81
|
+
}
|
|
82
|
+
getOrigins() {
|
|
83
|
+
const origins = this.getValue('ALLOW_ORIGINS');
|
|
84
|
+
return origins ? origins.split(',').map((o)=>o.trim()) : [];
|
|
85
|
+
}
|
|
86
|
+
getTypeOrmConfig() {
|
|
87
|
+
const type = this.getValue('DB_TYPE', false) || 'mysql';
|
|
88
|
+
const defaultPort = type === 'postgres' ? 5432 : 3306;
|
|
89
|
+
return {
|
|
90
|
+
type,
|
|
91
|
+
host: this.getValue('DB_HOST', false) || 'localhost',
|
|
92
|
+
port: this.getNumber('DB_PORT', false) || defaultPort,
|
|
93
|
+
username: this.getValue('DB_USER', false) || 'root',
|
|
94
|
+
password: this.getValue('DB_PASSWORD', false) || '',
|
|
95
|
+
database: this.getValue('DB_NAME', false) || 'flusys_main'
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
getJwtConfig() {
|
|
99
|
+
return {
|
|
100
|
+
secret: this.getValue('JWT_SECRET'),
|
|
101
|
+
expiration: this.getValue('JWT_EXPIRATION', false) || '1h',
|
|
102
|
+
refreshSecret: this.getValue('REFRESH_TOKEN_SECRET'),
|
|
103
|
+
refreshExpiration: this.getValue('REFRESH_TOKEN_EXPIRATION', false) || '7d'
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
getRedisUrl() {
|
|
107
|
+
return this.getValue('REDIS_URL', false) || 'redis://localhost:6379';
|
|
108
|
+
}
|
|
109
|
+
getMailConfig() {
|
|
110
|
+
return {
|
|
111
|
+
MAIL_FROM: this.getValue('MAIL_FROM', false) || '',
|
|
112
|
+
MAIL_APP_PASSWORD: this.getValue('MAIL_APP_PASSWORD', false) || ''
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
getTenantId() {
|
|
116
|
+
return this.getValue('TENANT_ID', false) || null;
|
|
117
|
+
}
|
|
118
|
+
useTenantMode() {
|
|
119
|
+
return this.getValue('USE_TENANT_MODE', false).toLowerCase() === 'true';
|
|
120
|
+
}
|
|
121
|
+
getLogConfig() {
|
|
122
|
+
return {
|
|
123
|
+
dir: this.getValue('LOG_DIR', false) || 'logs',
|
|
124
|
+
level: this.getValue('LOG_LEVEL', false) || (this.isProduction() ? 'info' : 'debug'),
|
|
125
|
+
maxSize: this.getValue('LOG_MAX_SIZE', false) || '20m',
|
|
126
|
+
maxFiles: this.getValue('LOG_MAX_FILES', false) || '14d',
|
|
127
|
+
disableHttpLogging: this.getValue('DISABLE_HTTP_LOGGING', false).toLowerCase() === 'true'
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
getEnv() {
|
|
131
|
+
return process.env;
|
|
132
|
+
}
|
|
133
|
+
};
|
|
134
|
+
const envConfig = new EnvConfigService(process.env);
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
;// CONCATENATED MODULE: ./projects/nestjs-core/src/config/index.ts
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
},
|
|
142
|
+
193(__unused_rspack_module, __webpack_exports__, __webpack_require__) {
|
|
143
|
+
|
|
144
|
+
// EXPORTS
|
|
145
|
+
__webpack_require__.d(__webpack_exports__, {
|
|
146
|
+
O: () => (/* binding */ createMigrationDataSource),
|
|
147
|
+
w: () => (/* binding */ initializeDataSource)
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
// EXTERNAL MODULE: external "typeorm"
|
|
151
|
+
var external_typeorm_ = __webpack_require__(158);
|
|
152
|
+
;// CONCATENATED MODULE: external "typeorm-naming-strategies"
|
|
153
|
+
|
|
154
|
+
// EXTERNAL MODULE: ./projects/nestjs-core/src/utils/datasource-config.builder.ts
|
|
155
|
+
var datasource_config_builder = __webpack_require__(722);
|
|
156
|
+
;// CONCATENATED MODULE: ./projects/nestjs-core/src/migration/datasource.factory.ts
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
function createMigrationDataSource(options) {
|
|
161
|
+
const { config, tenantId } = options;
|
|
162
|
+
const { database, tenant, tenantConfig } = (0,datasource_config_builder/* .getDatabaseForTenant */.LH)(config, tenantId);
|
|
163
|
+
console.log(`\nš¦ Database: ${database}${tenant ? ` [${tenant.name}]` : ' [default]'}`);
|
|
164
|
+
console.log(`š Migrations: migrations/${tenantId || 'default'}/`);
|
|
165
|
+
if (config.bootstrapAppConfig?.databaseMode === 'multi-tenant' && !tenantId && config.tenants && config.tenants.length > 0) {
|
|
166
|
+
console.log(`\nš” Multi-tenant mode. Available tenants:`);
|
|
167
|
+
config.tenants.forEach((t)=>console.log(` - TENANT_ID=${t.id} ā ${t.database}`));
|
|
168
|
+
}
|
|
169
|
+
const dbConfig = (0,datasource_config_builder/* .resolveDatabaseConnection */.ul)(config, tenantId);
|
|
170
|
+
const entities = (0,datasource_config_builder/* .resolveEntities */.Md)(config, tenantConfig);
|
|
171
|
+
const dsOptions = (0,datasource_config_builder/* .buildDataSourceOptions */.QP)(dbConfig, entities, (0,datasource_config_builder/* .getMigrationsGlobPattern */.Q0)(config.migrationsPath, tenantId), config.migrationsTableName);
|
|
172
|
+
return new external_typeorm_.DataSource({
|
|
173
|
+
...dsOptions,
|
|
174
|
+
namingStrategy: new __rspack_external_typeorm_naming_strategies_48a68f8e.SnakeNamingStrategy()
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
async function initializeDataSource(options) {
|
|
178
|
+
const ds = createMigrationDataSource(options);
|
|
179
|
+
await ds.initialize();
|
|
180
|
+
return ds;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
},
|
|
185
|
+
164(__unused_rspack_module, __webpack_exports__, __webpack_require__) {
|
|
186
|
+
|
|
187
|
+
// EXPORTS
|
|
188
|
+
__webpack_require__.d(__webpack_exports__, {
|
|
189
|
+
w: () => (/* binding */ runMigrationCli)
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
// EXTERNAL MODULE: external "path"
|
|
193
|
+
var external_path_ = __webpack_require__(521);
|
|
194
|
+
;// CONCATENATED MODULE: external "url"
|
|
195
|
+
|
|
196
|
+
// EXTERNAL MODULE: ./projects/nestjs-core/src/config/index.ts + 2 modules
|
|
197
|
+
var src_config = __webpack_require__(892);
|
|
198
|
+
// EXTERNAL MODULE: ./projects/nestjs-core/src/utils/datasource-config.builder.ts
|
|
199
|
+
var datasource_config_builder = __webpack_require__(722);
|
|
200
|
+
// EXTERNAL MODULE: ./projects/nestjs-core/src/migration/migration.runner.ts + 2 modules
|
|
201
|
+
var migration_runner = __webpack_require__(654);
|
|
202
|
+
;// CONCATENATED MODULE: ./projects/nestjs-core/src/migration/migration.cli.ts
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
function showHelp() {
|
|
209
|
+
console.log(`
|
|
210
|
+
Migration CLI
|
|
211
|
+
|
|
212
|
+
Usage:
|
|
213
|
+
npm run migration <command> [options]
|
|
214
|
+
|
|
215
|
+
Commands:
|
|
216
|
+
generate --name=<Name> Generate migration
|
|
217
|
+
run Run pending migrations
|
|
218
|
+
revert Revert last migration
|
|
219
|
+
reset Drop db, wipe migration files, recreate db, generate + run initial migration (dev only)
|
|
220
|
+
status Show migration status
|
|
221
|
+
run:all Run for all tenants
|
|
222
|
+
revert:all Revert for all tenants
|
|
223
|
+
status:all Status for all tenants
|
|
224
|
+
|
|
225
|
+
Options:
|
|
226
|
+
--config=<path> Migration config file (default: src/persistence/migration.config.ts)
|
|
227
|
+
--name=<Name> Migration name (for generate command)
|
|
228
|
+
--force Required to run 'reset' when MODE is not 'dev'
|
|
229
|
+
|
|
230
|
+
Environment:
|
|
231
|
+
TENANT_ID Target tenant (default: uses default database)
|
|
232
|
+
MIGRATION_CONFIG Default config path (overrides auto-detection)
|
|
233
|
+
|
|
234
|
+
Examples:
|
|
235
|
+
npm run migration generate --name=CreateUsers
|
|
236
|
+
npm run migration -- generate --name=CreateUsers --config=src/persistence/migration.config.ts
|
|
237
|
+
TENANT_ID=tenant1 npm run migration run
|
|
238
|
+
npm run migration run:all
|
|
239
|
+
npm run migration reset
|
|
240
|
+
`);
|
|
241
|
+
}
|
|
242
|
+
function parseArgs() {
|
|
243
|
+
const args = process.argv.slice(2);
|
|
244
|
+
let command;
|
|
245
|
+
let name;
|
|
246
|
+
let configPath;
|
|
247
|
+
let datasourcePath;
|
|
248
|
+
let force = false;
|
|
249
|
+
for(let i = 0; i < args.length; i++){
|
|
250
|
+
const arg = args[i];
|
|
251
|
+
if (arg.startsWith('--name=')) {
|
|
252
|
+
name = arg.split('=')[1];
|
|
253
|
+
} else if (arg.startsWith('--config=')) {
|
|
254
|
+
configPath = arg.split('=')[1];
|
|
255
|
+
} else if (arg.startsWith('--datasource=')) {
|
|
256
|
+
datasourcePath = arg.split('=')[1];
|
|
257
|
+
} else if (arg === '--force') {
|
|
258
|
+
force = true;
|
|
259
|
+
} else if (!arg.startsWith('-') && !command) {
|
|
260
|
+
command = arg;
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
return {
|
|
264
|
+
command,
|
|
265
|
+
name,
|
|
266
|
+
configPath,
|
|
267
|
+
datasourcePath,
|
|
268
|
+
force
|
|
269
|
+
};
|
|
270
|
+
}
|
|
271
|
+
async function loadConfig(configPath) {
|
|
272
|
+
const absolutePath = external_path_.isAbsolute(configPath) ? configPath : external_path_.resolve(process.cwd(), configPath);
|
|
273
|
+
const module = await __webpack_require__(398)((0,__rspack_external_url.pathToFileURL)(absolutePath).href);
|
|
274
|
+
return module.migrationConfig || module.default?.migrationConfig || module;
|
|
275
|
+
}
|
|
276
|
+
async function runMigrationCli(configOrPath) {
|
|
277
|
+
const { command, name, configPath: argConfigPath, datasourcePath, force } = parseArgs();
|
|
278
|
+
const tenantId = src_config/* .envConfig.getTenantId */.K.getTenantId() ?? undefined;
|
|
279
|
+
// npm passes --name=X as npm_config_name
|
|
280
|
+
const migrationName = src_config/* .envConfig.tryGetValue */.K.tryGetValue('npm_config_name') || src_config/* .envConfig.tryGetValue */.K.tryGetValue('MIGRATION_NAME') || name;
|
|
281
|
+
// Resolve config
|
|
282
|
+
let config;
|
|
283
|
+
let dsPath = datasourcePath;
|
|
284
|
+
if (typeof configOrPath === 'string') {
|
|
285
|
+
config = await loadConfig(configOrPath);
|
|
286
|
+
dsPath = dsPath || configOrPath;
|
|
287
|
+
} else if (configOrPath) {
|
|
288
|
+
config = configOrPath;
|
|
289
|
+
} else if (argConfigPath) {
|
|
290
|
+
config = await loadConfig(argConfigPath);
|
|
291
|
+
dsPath = dsPath || argConfigPath;
|
|
292
|
+
} else {
|
|
293
|
+
// Try paths in order: env var, then common defaults
|
|
294
|
+
const envConfigPath = src_config/* .envConfig.tryGetValue */.K.tryGetValue('MIGRATION_CONFIG');
|
|
295
|
+
const defaultPaths = [
|
|
296
|
+
envConfigPath,
|
|
297
|
+
'src/persistence/migration.config.ts',
|
|
298
|
+
'src/persistence/migration.config.js',
|
|
299
|
+
'persistence/migration.config.ts',
|
|
300
|
+
'persistence/migration.config.js'
|
|
301
|
+
].filter(Boolean);
|
|
302
|
+
let loaded = false;
|
|
303
|
+
for (const tryPath of defaultPaths){
|
|
304
|
+
try {
|
|
305
|
+
config = await loadConfig(tryPath);
|
|
306
|
+
dsPath = dsPath || tryPath;
|
|
307
|
+
loaded = true;
|
|
308
|
+
break;
|
|
309
|
+
} catch {
|
|
310
|
+
// Try next path
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
if (!loaded) {
|
|
314
|
+
console.error('ā Config not found. Use --config=<path> or set MIGRATION_CONFIG env var');
|
|
315
|
+
console.error(' Tried paths:', defaultPaths.join(', '));
|
|
316
|
+
showHelp();
|
|
317
|
+
process.exit(1);
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
if (!command) {
|
|
321
|
+
showHelp();
|
|
322
|
+
return;
|
|
323
|
+
}
|
|
324
|
+
// Multi-tenant batch commands
|
|
325
|
+
if (command.endsWith(':all')) {
|
|
326
|
+
if (config.bootstrapAppConfig?.databaseMode === 'single') {
|
|
327
|
+
console.error('ā Multi-tenant mode not enabled');
|
|
328
|
+
process.exit(1);
|
|
329
|
+
}
|
|
330
|
+
const action = command.split(':')[0];
|
|
331
|
+
const results = await (0,migration_runner/* .runForAllTenants */.XR)(config, action);
|
|
332
|
+
if (results.some((r)=>!r.success)) process.exit(1);
|
|
333
|
+
return;
|
|
334
|
+
}
|
|
335
|
+
// Show target info
|
|
336
|
+
const { database } = (0,datasource_config_builder/* .getDatabaseForTenant */.LH)(config, tenantId);
|
|
337
|
+
const folder = (0,datasource_config_builder/* .getMigrationsFolderPath */.jr)(config.migrationsPath, tenantId);
|
|
338
|
+
console.log(`\nš¦ Database: ${database}`);
|
|
339
|
+
console.log(`š Migrations: ${external_path_.relative(process.cwd(), folder)}`);
|
|
340
|
+
switch(command){
|
|
341
|
+
case 'generate':
|
|
342
|
+
if (!migrationName) {
|
|
343
|
+
console.error('ā Migration name required. Use --name=<Name>');
|
|
344
|
+
process.exit(1);
|
|
345
|
+
}
|
|
346
|
+
await (0,migration_runner/* .generateMigration */.iL)(config, migrationName, tenantId, dsPath);
|
|
347
|
+
break;
|
|
348
|
+
case 'run':
|
|
349
|
+
{
|
|
350
|
+
const result = await (0,migration_runner/* .runMigrations */.vI)(config, tenantId);
|
|
351
|
+
if (!result.success) process.exit(1);
|
|
352
|
+
break;
|
|
353
|
+
}
|
|
354
|
+
case 'revert':
|
|
355
|
+
{
|
|
356
|
+
const result = await (0,migration_runner/* .revertMigration */.$N)(config, tenantId);
|
|
357
|
+
if (!result.success) process.exit(1);
|
|
358
|
+
break;
|
|
359
|
+
}
|
|
360
|
+
case 'reset':
|
|
361
|
+
{
|
|
362
|
+
if (src_config/* .envConfig.isProduction */.K.isProduction() && !force) {
|
|
363
|
+
console.error('ā Refusing to reset database outside dev mode. Pass --force to override.');
|
|
364
|
+
process.exit(1);
|
|
365
|
+
}
|
|
366
|
+
const result = await (0,migration_runner/* .resetDatabase */.$7)(config, tenantId);
|
|
367
|
+
if (!result.success) process.exit(1);
|
|
368
|
+
await (0,migration_runner/* .generateMigration */.iL)(config, migrationName || 'Init', tenantId, dsPath);
|
|
369
|
+
const runResult = await (0,migration_runner/* .runMigrations */.vI)(config, tenantId);
|
|
370
|
+
if (!runResult.success) process.exit(1);
|
|
371
|
+
break;
|
|
372
|
+
}
|
|
373
|
+
case 'status':
|
|
374
|
+
await (0,migration_runner/* .migrationStatus */.vd)(config, tenantId);
|
|
375
|
+
break;
|
|
376
|
+
default:
|
|
377
|
+
console.error(`ā Unknown command: ${command}`);
|
|
378
|
+
showHelp();
|
|
379
|
+
process.exit(1);
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
|
|
384
|
+
},
|
|
385
|
+
654(__unused_rspack_module, __webpack_exports__, __webpack_require__) {
|
|
386
|
+
|
|
387
|
+
// EXPORTS
|
|
388
|
+
__webpack_require__.d(__webpack_exports__, {
|
|
389
|
+
Mg: () => (/* binding */ ensureMigrationsFolder),
|
|
390
|
+
iL: () => (/* binding */ generateMigration),
|
|
391
|
+
vd: () => (/* binding */ migrationStatus),
|
|
392
|
+
$7: () => (/* binding */ resetDatabase),
|
|
393
|
+
$N: () => (/* binding */ revertMigration),
|
|
394
|
+
XR: () => (/* binding */ runForAllTenants),
|
|
395
|
+
vI: () => (/* binding */ runMigrations)
|
|
396
|
+
});
|
|
397
|
+
|
|
398
|
+
;// CONCATENATED MODULE: external "child_process"
|
|
399
|
+
|
|
400
|
+
;// CONCATENATED MODULE: external "fs"
|
|
401
|
+
|
|
402
|
+
// EXTERNAL MODULE: external "path"
|
|
403
|
+
var external_path_ = __webpack_require__(521);
|
|
404
|
+
// EXTERNAL MODULE: external "typeorm"
|
|
405
|
+
var external_typeorm_ = __webpack_require__(158);
|
|
406
|
+
// EXTERNAL MODULE: ./projects/nestjs-core/src/config/index.ts + 2 modules
|
|
407
|
+
var src_config = __webpack_require__(892);
|
|
408
|
+
// EXTERNAL MODULE: ./projects/nestjs-core/src/utils/datasource-config.builder.ts
|
|
409
|
+
var datasource_config_builder = __webpack_require__(722);
|
|
410
|
+
// EXTERNAL MODULE: ./projects/nestjs-core/src/migration/datasource.factory.ts + 1 modules
|
|
411
|
+
var datasource_factory = __webpack_require__(193);
|
|
412
|
+
;// CONCATENATED MODULE: ./projects/nestjs-core/src/migration/migration.runner.ts
|
|
413
|
+
|
|
414
|
+
|
|
415
|
+
|
|
416
|
+
|
|
417
|
+
|
|
418
|
+
|
|
419
|
+
|
|
420
|
+
function getLabel(tenantId) {
|
|
421
|
+
return tenantId ? `[${tenantId}]` : '[default]';
|
|
422
|
+
}
|
|
423
|
+
async function withDataSource(config, tenantId, operation) {
|
|
424
|
+
const { database } = (0,datasource_config_builder/* .getDatabaseForTenant */.LH)(config, tenantId);
|
|
425
|
+
const label = getLabel(tenantId);
|
|
426
|
+
try {
|
|
427
|
+
const ds = await (0,datasource_factory/* .initializeDataSource */.w)({
|
|
428
|
+
config,
|
|
429
|
+
tenantId
|
|
430
|
+
});
|
|
431
|
+
const partial = await operation(ds, label);
|
|
432
|
+
await ds.destroy();
|
|
433
|
+
return {
|
|
434
|
+
tenantId,
|
|
435
|
+
database,
|
|
436
|
+
success: true,
|
|
437
|
+
...partial
|
|
438
|
+
};
|
|
439
|
+
} catch (error) {
|
|
440
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
441
|
+
console.error(`${label} ā Failed: ${errorMessage}`);
|
|
442
|
+
return {
|
|
443
|
+
tenantId,
|
|
444
|
+
database,
|
|
445
|
+
success: false,
|
|
446
|
+
error: errorMessage
|
|
447
|
+
};
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
function ensureMigrationsFolder(basePath, tenantId) {
|
|
451
|
+
const folder = (0,datasource_config_builder/* .getMigrationsFolderPath */.jr)(basePath, tenantId);
|
|
452
|
+
if (!__rspack_external_fs.existsSync(folder)) {
|
|
453
|
+
__rspack_external_fs.mkdirSync(folder, {
|
|
454
|
+
recursive: true
|
|
455
|
+
});
|
|
456
|
+
console.log(`š Created: ${folder}`);
|
|
457
|
+
}
|
|
458
|
+
return folder;
|
|
459
|
+
}
|
|
460
|
+
async function generateMigration(config, name, tenantId, datasourcePath) {
|
|
461
|
+
const label = tenantId ? `[${tenantId}]` : '[default]';
|
|
462
|
+
const folder = ensureMigrationsFolder(config.migrationsPath, tenantId);
|
|
463
|
+
console.log(`${label} Generating migration: ${name}`);
|
|
464
|
+
console.log(`${label} Target folder: ${folder}`);
|
|
465
|
+
const dsPath = datasourcePath || findDatasourcePath();
|
|
466
|
+
const migrationFile = external_path_.join(folder, name);
|
|
467
|
+
const command = `tsx ./node_modules/typeorm/cli.js migration:generate "${migrationFile}" -d "${dsPath}"`;
|
|
468
|
+
(0,__rspack_external_child_process.execSync)(command, {
|
|
469
|
+
stdio: 'inherit',
|
|
470
|
+
env: {
|
|
471
|
+
...src_config/* .envConfig.getEnv */.K.getEnv(),
|
|
472
|
+
TENANT_ID: tenantId || ''
|
|
473
|
+
},
|
|
474
|
+
cwd: process.cwd()
|
|
475
|
+
});
|
|
476
|
+
console.log(`${label} ā Generated!`);
|
|
477
|
+
}
|
|
478
|
+
function findDatasourcePath() {
|
|
479
|
+
const possiblePaths = [
|
|
480
|
+
'src/persistence/migration.config.ts',
|
|
481
|
+
'projects/flusysnest/src/persistence/migration.config.ts'
|
|
482
|
+
];
|
|
483
|
+
for (const p of possiblePaths){
|
|
484
|
+
if (__rspack_external_fs.existsSync(external_path_.join(process.cwd(), p))) {
|
|
485
|
+
return p;
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
throw new Error('Could not find datasource file. Specify with --datasource=<path>');
|
|
489
|
+
}
|
|
490
|
+
async function runMigrations(config, tenantId) {
|
|
491
|
+
return withDataSource(config, tenantId, async (ds, label)=>{
|
|
492
|
+
const migrations = await ds.runMigrations();
|
|
493
|
+
if (migrations.length === 0) {
|
|
494
|
+
console.log(`${label} No pending migrations.`);
|
|
495
|
+
} else {
|
|
496
|
+
console.log(`${label} ā Executed ${migrations.length} migration(s):`);
|
|
497
|
+
migrations.forEach((m)=>console.log(` - ${m.name}`));
|
|
498
|
+
}
|
|
499
|
+
return {
|
|
500
|
+
migrationsRun: migrations.map((m)=>m.name)
|
|
501
|
+
};
|
|
502
|
+
});
|
|
503
|
+
}
|
|
504
|
+
async function revertMigration(config, tenantId) {
|
|
505
|
+
return withDataSource(config, tenantId, async (ds, label)=>{
|
|
506
|
+
await ds.undoLastMigration();
|
|
507
|
+
console.log(`${label} ā Reverted!`);
|
|
508
|
+
return {};
|
|
509
|
+
});
|
|
510
|
+
}
|
|
511
|
+
function clearMigrationFiles(basePath, tenantId, label) {
|
|
512
|
+
const folder = (0,datasource_config_builder/* .getMigrationsFolderPath */.jr)(basePath, tenantId);
|
|
513
|
+
if (!__rspack_external_fs.existsSync(folder)) return;
|
|
514
|
+
const files = __rspack_external_fs.readdirSync(folder).filter((f)=>f.endsWith('.ts') || f.endsWith('.js'));
|
|
515
|
+
files.forEach((file)=>__rspack_external_fs.rmSync(external_path_.join(folder, file)));
|
|
516
|
+
console.log(`${label} ā Removed ${files.length} migration file(s) from ${folder}`);
|
|
517
|
+
}
|
|
518
|
+
async function dropAndRecreateDatabase(dbConfig, label) {
|
|
519
|
+
const { type, database } = dbConfig;
|
|
520
|
+
if (type === 'sqlite') {
|
|
521
|
+
if (database && __rspack_external_fs.existsSync(database)) __rspack_external_fs.rmSync(database);
|
|
522
|
+
console.log(`${label} ā Deleted sqlite file`);
|
|
523
|
+
return;
|
|
524
|
+
}
|
|
525
|
+
if (type !== 'mysql' && type !== 'mariadb' && type !== 'postgres') {
|
|
526
|
+
throw new Error(`Database reset is not supported for type '${type}'`);
|
|
527
|
+
}
|
|
528
|
+
const adminDs = new external_typeorm_.DataSource({
|
|
529
|
+
type,
|
|
530
|
+
host: dbConfig.host,
|
|
531
|
+
port: dbConfig.port,
|
|
532
|
+
username: dbConfig.username,
|
|
533
|
+
password: dbConfig.password,
|
|
534
|
+
database: type === 'postgres' ? 'postgres' : undefined
|
|
535
|
+
});
|
|
536
|
+
await adminDs.initialize();
|
|
537
|
+
try {
|
|
538
|
+
if (type === 'postgres') {
|
|
539
|
+
await adminDs.query(`SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE datname = $1 AND pid <> pg_backend_pid()`, [
|
|
540
|
+
database
|
|
541
|
+
]);
|
|
542
|
+
await adminDs.query(`DROP DATABASE IF EXISTS "${database}"`);
|
|
543
|
+
await adminDs.query(`CREATE DATABASE "${database}"`);
|
|
544
|
+
} else {
|
|
545
|
+
await adminDs.query(`DROP DATABASE IF EXISTS \`${database}\``);
|
|
546
|
+
await adminDs.query(`CREATE DATABASE \`${database}\` CHARACTER SET utf8mb4`);
|
|
547
|
+
}
|
|
548
|
+
console.log(`${label} ā Database '${database}' dropped and recreated`);
|
|
549
|
+
} finally{
|
|
550
|
+
await adminDs.destroy();
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
async function resetDatabase(config, tenantId) {
|
|
554
|
+
const { database } = (0,datasource_config_builder/* .getDatabaseForTenant */.LH)(config, tenantId);
|
|
555
|
+
const label = getLabel(tenantId);
|
|
556
|
+
try {
|
|
557
|
+
clearMigrationFiles(config.migrationsPath, tenantId, label);
|
|
558
|
+
const dbConfig = (0,datasource_config_builder/* .resolveDatabaseConnection */.ul)(config, tenantId);
|
|
559
|
+
await dropAndRecreateDatabase(dbConfig, label);
|
|
560
|
+
return {
|
|
561
|
+
tenantId,
|
|
562
|
+
database,
|
|
563
|
+
success: true
|
|
564
|
+
};
|
|
565
|
+
} catch (error) {
|
|
566
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
567
|
+
console.error(`${label} ā Failed: ${errorMessage}`);
|
|
568
|
+
return {
|
|
569
|
+
tenantId,
|
|
570
|
+
database,
|
|
571
|
+
success: false,
|
|
572
|
+
error: errorMessage
|
|
573
|
+
};
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
async function migrationStatus(config, tenantId) {
|
|
577
|
+
return withDataSource(config, tenantId, async (ds, label)=>{
|
|
578
|
+
const hasPending = await ds.showMigrations();
|
|
579
|
+
console.log(`${label} Pending: ${hasPending ? 'Yes' : 'No'}`);
|
|
580
|
+
return {
|
|
581
|
+
migrationsRun: [
|
|
582
|
+
hasPending ? 'Has pending' : 'Up to date'
|
|
583
|
+
]
|
|
584
|
+
};
|
|
585
|
+
});
|
|
586
|
+
}
|
|
587
|
+
async function runForAllTenants(config, command) {
|
|
588
|
+
const tenants = (0,datasource_config_builder/* .getActiveTenants */.SP)(config);
|
|
589
|
+
console.log(`\nš Running '${command}' for ${tenants.length} tenant(s)...\n`);
|
|
590
|
+
const results = [];
|
|
591
|
+
for (const tenant of tenants){
|
|
592
|
+
let result;
|
|
593
|
+
switch(command){
|
|
594
|
+
case 'run':
|
|
595
|
+
result = await runMigrations(config, tenant.id);
|
|
596
|
+
break;
|
|
597
|
+
case 'revert':
|
|
598
|
+
result = await revertMigration(config, tenant.id);
|
|
599
|
+
break;
|
|
600
|
+
case 'status':
|
|
601
|
+
result = await migrationStatus(config, tenant.id);
|
|
602
|
+
break;
|
|
603
|
+
}
|
|
604
|
+
results.push(result);
|
|
605
|
+
console.log('');
|
|
606
|
+
}
|
|
607
|
+
console.log('\n=== Summary ===');
|
|
608
|
+
results.forEach((r)=>{
|
|
609
|
+
const icon = r.success ? 'ā' : 'ā';
|
|
610
|
+
const msg = r.error ? ` - ${r.error}` : '';
|
|
611
|
+
console.log(`${icon} ${r.tenantId || 'default'}${msg}`);
|
|
612
|
+
});
|
|
613
|
+
return results;
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
|
|
617
|
+
},
|
|
618
|
+
722(__unused_rspack_module, __webpack_exports__, __webpack_require__) {
|
|
619
|
+
/**
|
|
620
|
+
* Build DataSource options from database config
|
|
621
|
+
*/ function buildDataSourceOptions(config, entities, migrationsPath, migrationsTableName = 'migrations') {
|
|
622
|
+
return {
|
|
623
|
+
type: config.type,
|
|
624
|
+
host: config.host,
|
|
625
|
+
port: config.port,
|
|
626
|
+
username: config.username,
|
|
627
|
+
password: config.password,
|
|
628
|
+
database: config.database || '',
|
|
629
|
+
entities,
|
|
630
|
+
migrations: [
|
|
631
|
+
migrationsPath
|
|
632
|
+
],
|
|
633
|
+
migrationsTableName,
|
|
634
|
+
synchronize: false
|
|
635
|
+
};
|
|
636
|
+
}
|
|
637
|
+
/**
|
|
638
|
+
* Get migration folder path for a tenant
|
|
639
|
+
*/ function getMigrationsFolderPath(basePath, tenantId) {
|
|
640
|
+
const folder = tenantId || 'default';
|
|
641
|
+
return `${basePath}/${folder}`;
|
|
642
|
+
}
|
|
643
|
+
/**
|
|
644
|
+
* Get migrations glob pattern for a tenant
|
|
645
|
+
*/ function getMigrationsGlobPattern(basePath, tenantId) {
|
|
646
|
+
return `${getMigrationsFolderPath(basePath, tenantId)}/*{.ts,.js}`;
|
|
647
|
+
}
|
|
648
|
+
/**
|
|
649
|
+
* Get database and config for a tenant (or default)
|
|
650
|
+
*/ function getDatabaseForTenant(config, tenantId) {
|
|
651
|
+
if (tenantId && config.tenants) {
|
|
652
|
+
const tenant = config.tenants.find((t)=>t.id === tenantId);
|
|
653
|
+
if (!tenant) {
|
|
654
|
+
throw new Error(`Tenant '${tenantId}' not found. Available: ${config.tenants.map((t)=>t.id).join(', ')}`);
|
|
655
|
+
}
|
|
656
|
+
return {
|
|
657
|
+
database: tenant.database,
|
|
658
|
+
tenant,
|
|
659
|
+
tenantConfig: tenant
|
|
660
|
+
};
|
|
661
|
+
}
|
|
662
|
+
// Default config - use bootstrapAppConfig for feature flags
|
|
663
|
+
const defaultTenantConfig = {
|
|
664
|
+
id: 'default',
|
|
665
|
+
database: config.defaultDatabaseConfig.database || 'default',
|
|
666
|
+
enableCompanyFeature: config.bootstrapAppConfig?.enableCompanyFeature ?? false,
|
|
667
|
+
permissionMode: config.bootstrapAppConfig?.permissionMode ?? 'FULL'
|
|
668
|
+
};
|
|
669
|
+
return {
|
|
670
|
+
database: defaultTenantConfig.database,
|
|
671
|
+
tenantConfig: defaultTenantConfig
|
|
672
|
+
};
|
|
673
|
+
}
|
|
674
|
+
/**
|
|
675
|
+
* Resolve full connection details for a tenant.
|
|
676
|
+
*/ function resolveDatabaseConnection(config, tenantId) {
|
|
677
|
+
const { database, tenant } = getDatabaseForTenant(config, tenantId);
|
|
678
|
+
return tenant ? {
|
|
679
|
+
...config.defaultDatabaseConfig,
|
|
680
|
+
host: tenant.host ?? config.defaultDatabaseConfig.host,
|
|
681
|
+
port: tenant.port ?? config.defaultDatabaseConfig.port,
|
|
682
|
+
username: tenant.username ?? config.defaultDatabaseConfig.username,
|
|
683
|
+
password: tenant.password ?? config.defaultDatabaseConfig.password,
|
|
684
|
+
database: tenant.database
|
|
685
|
+
} : {
|
|
686
|
+
...config.defaultDatabaseConfig,
|
|
687
|
+
database
|
|
688
|
+
};
|
|
689
|
+
}
|
|
690
|
+
/**
|
|
691
|
+
* Resolve entities based on tenant config
|
|
692
|
+
*/ function resolveEntities(config, tenantConfig) {
|
|
693
|
+
if (typeof config.entities === 'function') {
|
|
694
|
+
return config.entities(tenantConfig);
|
|
695
|
+
}
|
|
696
|
+
return config.entities;
|
|
697
|
+
}
|
|
698
|
+
/**
|
|
699
|
+
* Get active tenants from config
|
|
700
|
+
*/ function getActiveTenants(config) {
|
|
701
|
+
return config.tenants || [];
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
__webpack_require__.d(__webpack_exports__, {
|
|
705
|
+
LH: () => (getDatabaseForTenant),
|
|
706
|
+
Md: () => (resolveEntities),
|
|
707
|
+
Q0: () => (getMigrationsGlobPattern),
|
|
708
|
+
QP: () => (buildDataSourceOptions),
|
|
709
|
+
SP: () => (getActiveTenants),
|
|
710
|
+
jr: () => (getMigrationsFolderPath),
|
|
711
|
+
ul: () => (resolveDatabaseConnection)
|
|
712
|
+
});
|
|
713
|
+
|
|
714
|
+
|
|
715
|
+
},
|
|
716
|
+
521(module) {
|
|
717
|
+
|
|
718
|
+
module.exports = __rspack_external_path;
|
|
719
|
+
|
|
720
|
+
|
|
721
|
+
},
|
|
722
|
+
158(module) {
|
|
723
|
+
|
|
724
|
+
module.exports = __rspack_external_typeorm;
|
|
725
|
+
|
|
726
|
+
|
|
727
|
+
},
|
|
728
|
+
|
|
729
|
+
};
|