@studiosonrai/nestjs-migrations 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.
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
@@ -0,0 +1,242 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ const typeorm_1 = require("typeorm");
5
+ const path = require("path");
6
+ const migration_core_1 = require("../src/migration-core");
7
+ function printUsage() {
8
+ console.log(`
9
+ @studiosonrai/nestjs-migrations CLI
10
+
11
+ Usage:
12
+ nestjs-migrations run [options]
13
+ nestjs-migrations status [options]
14
+
15
+ Commands:
16
+ run Run all pending migrations
17
+ status Show migration status
18
+
19
+ Options:
20
+ --migrations-dir, -d Path to migrations directory (required)
21
+ --host, -h Database host (default: localhost)
22
+ --port, -p Database port (default: 1433)
23
+ --database, -D Database name (required)
24
+ --username, -u Database username
25
+ --password, -P Database password
26
+ --encrypt Enable encryption (default: false)
27
+ --trust-cert Trust server certificate (default: false)
28
+ --dry-run Show pending migrations without applying
29
+ --verbose, -v Verbose output (default: true)
30
+ --help Show this help message
31
+
32
+ Environment variables:
33
+ DB_HOST Database host
34
+ DB_PORT Database port
35
+ DB_DATABASE Database name
36
+ DB_USERNAME Database username
37
+ DB_PASSWORD Database password
38
+ DB_ENCRYPT Enable encryption
39
+ MIGRATIONS_DIR Path to migrations directory
40
+
41
+ Examples:
42
+ nestjs-migrations run -d ./migrations -D mydb -u sa -P password
43
+ nestjs-migrations status --migrations-dir ./migrations --database mydb
44
+ nestjs-migrations run --dry-run -d ./migrations -D mydb
45
+ `);
46
+ }
47
+ function parseArgs(args) {
48
+ const options = {
49
+ verbose: true,
50
+ };
51
+ let command = '';
52
+ for (let i = 0; i < args.length; i++) {
53
+ const arg = args[i];
54
+ const nextArg = args[i + 1];
55
+ switch (arg) {
56
+ case 'run':
57
+ case 'status':
58
+ command = arg;
59
+ break;
60
+ case '--migrations-dir':
61
+ case '-d':
62
+ options.migrationsDir = nextArg;
63
+ i++;
64
+ break;
65
+ case '--host':
66
+ case '-h':
67
+ options.host = nextArg;
68
+ i++;
69
+ break;
70
+ case '--port':
71
+ case '-p':
72
+ options.port = parseInt(nextArg, 10);
73
+ i++;
74
+ break;
75
+ case '--database':
76
+ case '-D':
77
+ options.database = nextArg;
78
+ i++;
79
+ break;
80
+ case '--username':
81
+ case '-u':
82
+ options.username = nextArg;
83
+ i++;
84
+ break;
85
+ case '--password':
86
+ case '-P':
87
+ options.password = nextArg;
88
+ i++;
89
+ break;
90
+ case '--encrypt':
91
+ options.encrypt = true;
92
+ break;
93
+ case '--trust-cert':
94
+ options.trustServerCertificate = true;
95
+ break;
96
+ case '--dry-run':
97
+ options.dryRun = true;
98
+ break;
99
+ case '--verbose':
100
+ case '-v':
101
+ options.verbose = true;
102
+ break;
103
+ case '--help':
104
+ printUsage();
105
+ process.exit(0);
106
+ }
107
+ }
108
+ return { command, options };
109
+ }
110
+ function resolveOptions(cliOptions) {
111
+ // Load environment variables
112
+ const dotenv = require('dotenv');
113
+ dotenv.config();
114
+ const options = {
115
+ migrationsDir: cliOptions.migrationsDir || process.env.MIGRATIONS_DIR || '',
116
+ host: cliOptions.host || process.env.DB_HOST || 'localhost',
117
+ port: cliOptions.port || parseInt(process.env.DB_PORT || '1433', 10),
118
+ database: cliOptions.database || process.env.DB_DATABASE || '',
119
+ username: cliOptions.username || process.env.DB_USERNAME,
120
+ password: cliOptions.password || process.env.DB_PASSWORD,
121
+ encrypt: cliOptions.encrypt || process.env.DB_ENCRYPT === 'true',
122
+ trustServerCertificate: cliOptions.trustServerCertificate || false,
123
+ dryRun: cliOptions.dryRun || false,
124
+ verbose: cliOptions.verbose ?? true,
125
+ };
126
+ // Resolve relative paths
127
+ if (options.migrationsDir && !path.isAbsolute(options.migrationsDir)) {
128
+ options.migrationsDir = path.resolve(process.cwd(), options.migrationsDir);
129
+ }
130
+ return options;
131
+ }
132
+ function validateOptions(options) {
133
+ if (!options.migrationsDir) {
134
+ console.error('Error: --migrations-dir is required');
135
+ process.exit(1);
136
+ }
137
+ if (!options.database) {
138
+ console.error('Error: --database is required');
139
+ process.exit(1);
140
+ }
141
+ }
142
+ async function createDataSource(options) {
143
+ const dataSource = new typeorm_1.DataSource({
144
+ type: 'mssql',
145
+ host: options.host,
146
+ port: options.port,
147
+ database: options.database,
148
+ username: options.username,
149
+ password: options.password,
150
+ options: {
151
+ encrypt: options.encrypt || false,
152
+ trustServerCertificate: options.trustServerCertificate || false,
153
+ },
154
+ });
155
+ await dataSource.initialize();
156
+ return dataSource;
157
+ }
158
+ async function runCommand(options) {
159
+ console.log('Starting migration runner...');
160
+ console.log(`Migrations directory: ${options.migrationsDir}`);
161
+ console.log(`Database: ${options.database}`);
162
+ console.log(`Host: ${options.host}:${options.port}`);
163
+ console.log('');
164
+ const dataSource = await createDataSource(options);
165
+ console.log('Database connection established');
166
+ try {
167
+ const migrationCore = new migration_core_1.MigrationCore(dataSource, {
168
+ migrationsDir: options.migrationsDir,
169
+ });
170
+ const result = await migrationCore.runMigrations({
171
+ dryRun: options.dryRun,
172
+ verbose: options.verbose,
173
+ });
174
+ if (result.success) {
175
+ console.log('');
176
+ console.log('Migration completed successfully!');
177
+ }
178
+ }
179
+ finally {
180
+ await dataSource.destroy();
181
+ console.log('Database connection closed');
182
+ }
183
+ }
184
+ async function statusCommand(options) {
185
+ console.log('Checking migration status...');
186
+ console.log(`Migrations directory: ${options.migrationsDir}`);
187
+ console.log(`Database: ${options.database}`);
188
+ console.log('');
189
+ const dataSource = await createDataSource(options);
190
+ try {
191
+ const migrationCore = new migration_core_1.MigrationCore(dataSource, {
192
+ migrationsDir: options.migrationsDir,
193
+ });
194
+ const status = await migrationCore.getStatus();
195
+ console.log(`Total migrations: ${status.total}`);
196
+ console.log(`Applied: ${status.applied}`);
197
+ console.log(`Pending: ${status.pending}`);
198
+ if (status.pendingFiles.length > 0) {
199
+ console.log('');
200
+ console.log('Pending migrations:');
201
+ status.pendingFiles.forEach((file) => console.log(` - ${file}`));
202
+ }
203
+ }
204
+ finally {
205
+ await dataSource.destroy();
206
+ }
207
+ }
208
+ async function main() {
209
+ const args = process.argv.slice(2);
210
+ if (args.length === 0 || args.includes('--help')) {
211
+ printUsage();
212
+ process.exit(0);
213
+ }
214
+ const { command, options: cliOptions } = parseArgs(args);
215
+ const options = resolveOptions(cliOptions);
216
+ if (!command) {
217
+ console.error('Error: No command specified. Use "run" or "status".');
218
+ printUsage();
219
+ process.exit(1);
220
+ }
221
+ validateOptions(options);
222
+ try {
223
+ switch (command) {
224
+ case 'run':
225
+ await runCommand(options);
226
+ break;
227
+ case 'status':
228
+ await statusCommand(options);
229
+ break;
230
+ default:
231
+ console.error(`Unknown command: ${command}`);
232
+ printUsage();
233
+ process.exit(1);
234
+ }
235
+ }
236
+ catch (error) {
237
+ console.error('Migration failed:', error);
238
+ process.exit(1);
239
+ }
240
+ }
241
+ main();
242
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xpLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vYmluL2NsaS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFFQSxxQ0FBcUM7QUFDckMsNkJBQTZCO0FBQzdCLDBEQUFzRDtBQWV0RCxTQUFTLFVBQVU7SUFDakIsT0FBTyxDQUFDLEdBQUcsQ0FBQzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztDQXFDYixDQUFDLENBQUM7QUFDSCxDQUFDO0FBRUQsU0FBUyxTQUFTLENBQUMsSUFBYztJQUMvQixNQUFNLE9BQU8sR0FBd0I7UUFDbkMsT0FBTyxFQUFFLElBQUk7S0FDZCxDQUFDO0lBQ0YsSUFBSSxPQUFPLEdBQUcsRUFBRSxDQUFDO0lBRWpCLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUM7UUFDckMsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3BCLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7UUFFNUIsUUFBUSxHQUFHLEVBQUUsQ0FBQztZQUNaLEtBQUssS0FBSyxDQUFDO1lBQ1gsS0FBSyxRQUFRO2dCQUNYLE9BQU8sR0FBRyxHQUFHLENBQUM7Z0JBQ2QsTUFBTTtZQUNSLEtBQUssa0JBQWtCLENBQUM7WUFDeEIsS0FBSyxJQUFJO2dCQUNQLE9BQU8sQ0FBQyxhQUFhLEdBQUcsT0FBTyxDQUFDO2dCQUNoQyxDQUFDLEVBQUUsQ0FBQztnQkFDSixNQUFNO1lBQ1IsS0FBSyxRQUFRLENBQUM7WUFDZCxLQUFLLElBQUk7Z0JBQ1AsT0FBTyxDQUFDLElBQUksR0FBRyxPQUFPLENBQUM7Z0JBQ3ZCLENBQUMsRUFBRSxDQUFDO2dCQUNKLE1BQU07WUFDUixLQUFLLFFBQVEsQ0FBQztZQUNkLEtBQUssSUFBSTtnQkFDUCxPQUFPLENBQUMs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LENBQUM7SUFDbEIsQ0FBQztBQUNILENBQUM7QUFFRCxJQUFJLEVBQUUsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIiMhL3Vzci9iaW4vZW52IG5vZGVcblxuaW1wb3J0IHsgRGF0YVNvdXJjZSB9IGZyb20gJ3R5cGVvcm0nO1xuaW1wb3J0ICogYXMgcGF0aCBmcm9tICdwYXRoJztcbmltcG9ydCB7IE1pZ3JhdGlvbkNvcmUgfSBmcm9tICcuLi9zcmMvbWlncmF0aW9uLWNvcmUnO1xuXG5pbnRlcmZhY2UgQ2xpT3B0aW9ucyB7XG4gIG1pZ3JhdGlvbnNEaXI6IHN0cmluZztcbiAgaG9zdDogc3RyaW5nO1xuICBwb3J0OiBudW1iZXI7XG4gIGRhdGFiYXNlOiBzdHJpbmc7XG4gIHVzZXJuYW1lPzogc3RyaW5nO1xuICBwYXNzd29yZD86IHN0cmluZztcbiAgZW5jcnlwdD86IGJvb2xlYW47XG4gIHRydXN0U2VydmVyQ2VydGlmaWNhdGU/OiBib29sZWFuO1xuICBkcnlSdW4/OiBib29sZWFuO1xuICB2ZXJib3NlPzogYm9vbGVhbjtcbn1cblxuZnVuY3Rpb24gcHJpbnRVc2FnZSgpOiB2b2lkIHtcbiAgY29uc29sZS5sb2coYFxuQHN0dWRpb3NvbnJhaS9uZXN0anMtbWlncmF0aW9ucyBDTElcblxuVXNhZ2U6XG4gIG5lc3Rqcy1taWdyYXRpb25zIHJ1biBbb3B0aW9uc11cbiAgbmVzdGpzLW1pZ3JhdGlvbnMgc3RhdHVzIFtvcHRpb25zXVxuXG5Db21tYW5kczpcbiAgcnVuICAgICAgIFJ1biBhbGwgcGVuZGluZyBtaWdyYXRpb25zXG4gIHN0YXR1cyAgICBTaG93IG1pZ3JhdGlvbiBzdGF0dXNcblxuT3B0aW9uczpcbiAgLS1taWdyYXRpb25zLWRpciwgLWQgICAgUGF0aCB0byBtaWdyYXRpb25zIGRpcmVjdG9yeSAocmVxdWlyZWQpXG4gIC0taG9zdCwgLWggICAgICAgICAgICAgIERhdGFiYXNlIGhvc3QgKGRlZmF1bHQ6IGxvY2FsaG9zdClcbiAgLS1wb3J0LCAtcCAgICAgICAgICAgICAgRGF0YWJhc2UgcG9ydCAoZGVmYXVsdDogMTQzMylcbiAgLS1kYXRhYmFzZSwgLUQgICAgICAgICAgRGF0YWJhc2UgbmFtZSAocmVxdWlyZWQpXG4gIC0tdXNlcm5hbWUsIC11ICAgICAgICAgIERhdGFiYXNlIHVzZXJuYW1lXG4gIC0tcGFzc3dvcmQsIC1QICAgICAgICAgIERhdGFiYXNlIHBhc3N3b3JkXG4gIC0tZW5jcnlwdCAgICAgICAgICAgICAgIEVuYWJsZSBlbmNyeXB0aW9uIChkZWZhdWx0OiBmYWxzZSlcbiAgLS10cnVzdC1jZXJ0ICAgICAgICAgICAgVHJ1c3Qgc2VydmVyIGNlcnRpZmljYXRlIChkZWZhdWx0OiBmYWxzZSlcbiAgLS1kcnktcnVuICAgICAgICAgICAgICAgU2hvdyBwZW5kaW5nIG1pZ3JhdGlvbnMgd2l0aG91dCBhcHBseWluZ1xuICAtLXZlcmJvc2UsIC12ICAgICAgICAgICBWZXJib3NlIG91dHB1dCAoZGVmYXVsdDogdHJ1ZSlcbiAgLS1oZWxwICAgICAgICAgICAgICAgICAgU2hvdyB0aGlzIGhlbHAgbWVzc2FnZVxuXG5FbnZpcm9ubWVudCB2YXJpYWJsZXM6XG4gIERCX0hPU1QgICAgICAgICAgICAgICAgIERhdGFiYXNlIGhvc3RcbiAgREJfUE9SVCAgICAgICAgICAgICAgICAgRGF0YWJhc2UgcG9ydFxuICBEQl9EQVRBQkFTRSAgICAgICAgICAgICBEYXRhYmFzZSBuYW1lXG4gIERCX1VTRVJOQU1FICAgICAgICAgICAgIERhdGFiYXNlIHVzZXJuYW1lXG4gIERCX1BBU1NXT1JEICAgICAgICAgICAgIERhdGFiYXNlIHBhc3N3b3JkXG4gIERCX0VOQ1JZUFQgICAgICAgICAgICAgIEVuYWJsZSBlbmNyeXB0aW9uXG4gIE1JR1JBVElPTlNfRElSICAgICAgICAgIFBhdGggdG8gbWlncmF0aW9ucyBkaXJlY3RvcnlcblxuRXhhbXBsZXM6XG4gIG5lc3Rqcy1taWdyYXRpb25zIHJ1biAtZCAuL21pZ3JhdGlvbnMgLUQgbXlkYiAtdSBzYSAtUCBwYXNzd29yZFxuICBuZXN0anMtbWlncmF0aW9ucyBzdGF0dXMgLS1taWdyYXRpb25zLWRpciAuL21pZ3JhdGlvbnMgLS1kYXRhYmFzZSBteWRiXG4gIG5lc3Rqcy1taWdyYXRpb25zIHJ1biAtLWRyeS1ydW4gLWQgLi9taWdyYXRpb25zIC1EIG15ZGJcbmApO1xufVxuXG5mdW5jdGlvbiBwYXJzZUFyZ3MoYXJnczogc3RyaW5nW10pOiB7IGNvbW1hbmQ6IHN0cmluZzsgb3B0aW9uczogUGFydGlhbDxDbGlPcHRpb25zPiB9IHtcbiAgY29uc3Qgb3B0aW9uczogUGFydGlhbDxDbGlPcHRpb25zPiA9IHtcbiAgICB2ZXJib3NlOiB0cnVlLFxuICB9O1xuICBsZXQgY29tbWFuZCA9ICcnO1xuXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgYXJncy5sZW5ndGg7IGkrKykge1xuICAgIGNvbnN0IGFyZyA9IGFyZ3NbaV07XG4gICAgY29uc3QgbmV4dEFyZyA9IGFyZ3NbaSArIDFdO1xuXG4gICAgc3dpdGNoIChhcmcpIHtcbiAgICAgIGNhc2UgJ3J1bic6XG4gICAgICBjYXNlICdzdGF0dXMnOlxuICAgICAgICBjb21tYW5kID0gYXJnO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJy0tbWlncmF0aW9ucy1kaXInOlxuICAgICAgY2FzZSAnLWQnOlxuICAgICAgICBvcHRpb25zLm1pZ3JhdGlvbnNEaXIgPSBuZXh0QXJnO1xuICAgICAgICBpKys7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnLS1ob3N0JzpcbiAgICAgIGNhc2UgJy1oJzpcbiAgICAgICAgb3B0aW9ucy5ob3N0ID0gbmV4dEFyZztcbiAgICAgICAgaSsrO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJy0tcG9ydCc6XG4gICAgICBjYXNlICctcCc6XG4gICAgICAgIG9wdGlvbnMucG9ydCA9IHBhcnNlSW50KG5leHRBcmcsIDEwKTtcbiAgICAgICAgaSsrO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJy0tZGF0YWJhc2UnOlxuICAgICAgY2FzZSAnLUQnOlxuICAgICAgICBvcHRpb25zLmRhdGFiYXNlID0gbmV4dEFyZztcbiAgICAgICAgaSsrO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJy0tdXNlcm5hbWUnOlxuICAgICAgY2FzZSAnLXUnOlxuICAgICAgICBvcHRpb25zLnVzZXJuYW1lID0gbmV4dEFyZztcbiAgICAgICAgaSsrO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJy0tcGFzc3dvcmQnOlxuICAgICAgY2FzZSAnLVAnOlxuICAgICAgICBvcHRpb25zLnBhc3N3b3JkID0gbmV4dEFyZztcbiAgICAgICAgaSsrO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJy0tZW5jcnlwdCc6XG4gICAgICAgIG9wdGlvbnMuZW5jcnlwdCA9IHRydWU7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnLS10cnVzdC1jZXJ0JzpcbiAgICAgICAgb3B0aW9ucy50cnVzdFNlcnZlckNlcnRpZmljYXRlID0gdHJ1ZTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICctLWRyeS1ydW4nOlxuICAgICAgICBvcHRpb25zLmRyeVJ1biA9IHRydWU7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnLS12ZXJib3NlJzpcbiAgICAgIGNhc2UgJy12JzpcbiAgICAgICAgb3B0aW9ucy52ZXJib3NlID0gdHJ1ZTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICctLWhlbHAnOlxuICAgICAgICBwcmludFVzYWdlKCk7XG4gICAgICAgIHByb2Nlc3MuZXhpdCgwKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4geyBjb21tYW5kLCBvcHRpb25zIH07XG59XG5cbmZ1bmN0aW9uIHJlc29sdmVPcHRpb25zKGNsaU9wdGlvbnM6IFBhcnRpYWw8Q2xpT3B0aW9ucz4pOiBDbGlPcHRpb25zIHtcbiAgLy8gTG9hZCBlbnZpcm9ubWVudCB2YXJpYWJsZXNcbiAgY29uc3QgZG90ZW52ID0gcmVxdWlyZSgnZG90ZW52Jyk7XG4gIGRvdGVudi5jb25maWcoKTtcblxuICBjb25zdCBvcHRpb25zOiBDbGlPcHRpb25zID0ge1xuICAgIG1pZ3JhdGlvbnNEaXI6IGNsaU9wdGlvbnMubWlncmF0aW9uc0RpciB8fCBwcm9jZXNzLmVudi5NSUdSQVRJT05TX0RJUiB8fCAnJyxcbiAgICBob3N0OiBjbGlPcHRpb25zLmhvc3QgfHwgcHJvY2Vzcy5lbnYuREJfSE9TVCB8fCAnbG9jYWxob3N0JyxcbiAgICBwb3J0OiBjbGlPcHRpb25zLnBvcnQgfHwgcGFyc2VJbnQocHJvY2Vzcy5lbnYuREJfUE9SVCB8fCAnMTQzMycsIDEwKSxcbiAgICBkYXRhYmFzZTogY2xpT3B0aW9ucy5kYXRhYmFzZSB8fCBwcm9jZXNzLmVudi5EQl9EQVRBQkFTRSB8fCAnJyxcbiAgICB1c2VybmFtZTogY2xpT3B0aW9ucy51c2VybmFtZSB8fCBwcm9jZXNzLmVudi5EQl9VU0VSTkFNRSxcbiAgICBwYXNzd29yZDogY2xpT3B0aW9ucy5wYXNzd29yZCB8fCBwcm9jZXNzLmVudi5EQl9QQVNTV09SRCxcbiAgICBlbmNyeXB0OiBjbGlPcHRpb25zLmVuY3J5cHQgfHwgcHJvY2Vzcy5lbnYuREJfRU5DUllQVCA9PT0gJ3RydWUnLFxuICAgIHRydXN0U2VydmVyQ2VydGlmaWNhdGU6IGNsaU9wdGlvbnMudHJ1c3RTZXJ2ZXJDZXJ0aWZpY2F0ZSB8fCBmYWxzZSxcbiAgICBkcnlSdW46IGNsaU9wdGlvbnMuZHJ5UnVuIHx8IGZhbHNlLFxuICAgIHZlcmJvc2U6IGNsaU9wdGlvbnMudmVyYm9zZSA/PyB0cnVlLFxuICB9O1xuXG4gIC8vIFJlc29sdmUgcmVsYXRpdmUgcGF0aHNcbiAgaWYgKG9wdGlvbnMubWlncmF0aW9uc0RpciAmJiAhcGF0aC5pc0Fic29sdXRlKG9wdGlvbnMubWlncmF0aW9uc0RpcikpIHtcbiAgICBvcHRpb25zLm1pZ3JhdGlvbnNEaXIgPSBwYXRoLnJlc29sdmUocHJvY2Vzcy5jd2QoKSwgb3B0aW9ucy5taWdyYXRpb25zRGlyKTtcbiAgfVxuXG4gIHJldHVybiBvcHRpb25zO1xufVxuXG5mdW5jdGlvbiB2YWxpZGF0ZU9wdGlvbnMob3B0aW9uczogQ2xpT3B0aW9ucyk6IHZvaWQge1xuICBpZiAoIW9wdGlvbnMubWlncmF0aW9uc0Rpcikge1xuICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yOiAtLW1pZ3JhdGlvbnMtZGlyIGlzIHJlcXVpcmVkJyk7XG4gICAgcHJvY2Vzcy5leGl0KDEpO1xuICB9XG5cbiAgaWYgKCFvcHRpb25zLmRhdGFiYXNlKSB7XG4gICAgY29uc29sZS5lcnJvcignRXJyb3I6IC0tZGF0YWJhc2UgaXMgcmVxdWlyZWQnKTtcbiAgICBwcm9jZXNzLmV4aXQoMSk7XG4gIH1cbn1cblxuYXN5bmMgZnVuY3Rpb24gY3JlYXRlRGF0YVNvdXJjZShvcHRpb25zOiBDbGlPcHRpb25zKTogUHJvbWlzZTxEYXRhU291cmNlPiB7XG4gIGNvbnN0IGRhdGFTb3VyY2UgPSBuZXcgRGF0YVNvdXJjZSh7XG4gICAgdHlwZTogJ21zc3FsJyxcbiAgICBob3N0OiBvcHRpb25zLmhvc3QsXG4gICAgcG9ydDogb3B0aW9ucy5wb3J0LFxuICAgIGRhdGFiYXNlOiBvcHRpb25zLmRhdGFiYXNlLFxuICAgIHVzZXJuYW1lOiBvcHRpb25zLnVzZXJuYW1lLFxuICAgIHBhc3N3b3JkOiBvcHRpb25zLnBhc3N3b3JkLFxuICAgIG9wdGlvbnM6IHtcbiAgICAgIGVuY3J5cHQ6IG9wdGlvbnMuZW5jcnlwdCB8fCBmYWxzZSxcbiAgICAgIHRydXN0U2VydmVyQ2VydGlmaWNhdGU6IG9wdGlvbnMudHJ1c3RTZXJ2ZXJDZXJ0aWZpY2F0ZSB8fCBmYWxzZSxcbiAgICB9LFxuICB9KTtcblxuICBhd2FpdCBkYXRhU291cmNlLmluaXRpYWxpemUoKTtcbiAgcmV0dXJuIGRhdGFTb3VyY2U7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIHJ1bkNvbW1hbmQob3B0aW9uczogQ2xpT3B0aW9ucyk6IFByb21pc2U8dm9pZD4ge1xuICBjb25zb2xlLmxvZygnU3RhcnRpbmcgbWlncmF0aW9uIHJ1bm5lci4uLicpO1xuICBjb25zb2xlLmxvZyhgTWlncmF0aW9ucyBkaXJlY3Rvcnk6ICR7b3B0aW9ucy5taWdyYXRpb25zRGlyfWApO1xuICBjb25zb2xlLmxvZyhgRGF0YWJhc2U6ICR7b3B0aW9ucy5kYXRhYmFzZX1gKTtcbiAgY29uc29sZS5sb2coYEhvc3Q6ICR7b3B0aW9ucy5ob3N0fToke29wdGlvbnMucG9ydH1gKTtcbiAgY29uc29sZS5sb2coJycpO1xuXG4gIGNvbnN0IGRhdGFTb3VyY2UgPSBhd2FpdCBjcmVhdGVEYXRhU291cmNlKG9wdGlvbnMpO1xuICBjb25zb2xlLmxvZygnRGF0YWJhc2UgY29ubmVjdGlvbiBlc3RhYmxpc2hlZCcpO1xuXG4gIHRyeSB7XG4gICAgY29uc3QgbWlncmF0aW9uQ29yZSA9IG5ldyBNaWdyYXRpb25Db3JlKGRhdGFTb3VyY2UsIHtcbiAgICAgIG1pZ3JhdGlvbnNEaXI6IG9wdGlvbnMubWlncmF0aW9uc0RpcixcbiAgICB9KTtcblxuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IG1pZ3JhdGlvbkNvcmUucnVuTWlncmF0aW9ucyh7XG4gICAgICBkcnlSdW46IG9wdGlvbnMuZHJ5UnVuLFxuICAgICAgdmVyYm9zZTogb3B0aW9ucy52ZXJib3NlLFxuICAgIH0pO1xuXG4gICAgaWYgKHJlc3VsdC5zdWNjZXNzKSB7XG4gICAgICBjb25zb2xlLmxvZygnJyk7XG4gICAgICBjb25zb2xlLmxvZygnTWlncmF0aW9uIGNvbXBsZXRlZCBzdWNjZXNzZnVsbHkhJyk7XG4gICAgfVxuICB9IGZpbmFsbHkge1xuICAgIGF3YWl0IGRhdGFTb3VyY2UuZGVzdHJveSgpO1xuICAgIGNvbnNvbGUubG9nKCdEYXRhYmFzZSBjb25uZWN0aW9uIGNsb3NlZCcpO1xuICB9XG59XG5cbmFzeW5jIGZ1bmN0aW9uIHN0YXR1c0NvbW1hbmQob3B0aW9uczogQ2xpT3B0aW9ucyk6IFByb21pc2U8dm9pZD4ge1xuICBjb25zb2xlLmxvZygnQ2hlY2tpbmcgbWlncmF0aW9uIHN0YXR1cy4uLicpO1xuICBjb25zb2xlLmxvZyhgTWlncmF0aW9ucyBkaXJlY3Rvcnk6ICR7b3B0aW9ucy5taWdyYXRpb25zRGlyfWApO1xuICBjb25zb2xlLmxvZyhgRGF0YWJhc2U6ICR7b3B0aW9ucy5kYXRhYmFzZX1gKTtcbiAgY29uc29sZS5sb2coJycpO1xuXG4gIGNvbnN0IGRhdGFTb3VyY2UgPSBhd2FpdCBjcmVhdGVEYXRhU291cmNlKG9wdGlvbnMpO1xuXG4gIHRyeSB7XG4gICAgY29uc3QgbWlncmF0aW9uQ29yZSA9IG5ldyBNaWdyYXRpb25Db3JlKGRhdGFTb3VyY2UsIHtcbiAgICAgIG1pZ3JhdGlvbnNEaXI6IG9wdGlvbnMubWlncmF0aW9uc0RpcixcbiAgICB9KTtcblxuICAgIGNvbnN0IHN0YXR1cyA9IGF3YWl0IG1pZ3JhdGlvbkNvcmUuZ2V0U3RhdHVzKCk7XG5cbiAgICBjb25zb2xlLmxvZyhgVG90YWwgbWlncmF0aW9uczogJHtzdGF0dXMudG90YWx9YCk7XG4gICAgY29uc29sZS5sb2coYEFwcGxpZWQ6ICR7c3RhdHVzLmFwcGxpZWR9YCk7XG4gICAgY29uc29sZS5sb2coYFBlbmRpbmc6ICR7c3RhdHVzLnBlbmRpbmd9YCk7XG5cbiAgICBpZiAoc3RhdHVzLnBlbmRpbmdGaWxlcy5sZW5ndGggPiAwKSB7XG4gICAgICBjb25zb2xlLmxvZygnJyk7XG4gICAgICBjb25zb2xlLmxvZygnUGVuZGluZyBtaWdyYXRpb25zOicpO1xuICAgICAgc3RhdHVzLnBlbmRpbmdGaWxlcy5mb3JFYWNoKChmaWxlKSA9PiBjb25zb2xlLmxvZyhgICAtICR7ZmlsZX1gKSk7XG4gICAgfVxuICB9IGZpbmFsbHkge1xuICAgIGF3YWl0IGRhdGFTb3VyY2UuZGVzdHJveSgpO1xuICB9XG59XG5cbmFzeW5jIGZ1bmN0aW9uIG1haW4oKTogUHJvbWlzZTx2b2lkPiB7XG4gIGNvbnN0IGFyZ3MgPSBwcm9jZXNzLmFyZ3Yuc2xpY2UoMik7XG5cbiAgaWYgKGFyZ3MubGVuZ3RoID09PSAwIHx8IGFyZ3MuaW5jbHVkZXMoJy0taGVscCcpKSB7XG4gICAgcHJpbnRVc2FnZSgpO1xuICAgIHByb2Nlc3MuZXhpdCgwKTtcbiAgfVxuXG4gIGNvbnN0IHsgY29tbWFuZCwgb3B0aW9uczogY2xpT3B0aW9ucyB9ID0gcGFyc2VBcmdzKGFyZ3MpO1xuICBjb25zdCBvcHRpb25zID0gcmVzb2x2ZU9wdGlvbnMoY2xpT3B0aW9ucyk7XG5cbiAgaWYgKCFjb21tYW5kKSB7XG4gICAgY29uc29sZS5lcnJvcignRXJyb3I6IE5vIGNvbW1hbmQgc3BlY2lmaWVkLiBVc2UgXCJydW5cIiBvciBcInN0YXR1c1wiLicpO1xuICAgIHByaW50VXNhZ2UoKTtcbiAgICBwcm9jZXNzLmV4aXQoMSk7XG4gIH1cblxuICB2YWxpZGF0ZU9wdGlvbnMob3B0aW9ucyk7XG5cbiAgdHJ5IHtcbiAgICBzd2l0Y2ggKGNvbW1hbmQpIHtcbiAgICAgIGNhc2UgJ3J1bic6XG4gICAgICAgIGF3YWl0IHJ1bkNvbW1hbmQob3B0aW9ucyk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnc3RhdHVzJzpcbiAgICAgICAgYXdhaXQgc3RhdHVzQ29tbWFuZChvcHRpb25zKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICBjb25zb2xlLmVycm9yKGBVbmtub3duIGNvbW1hbmQ6ICR7Y29tbWFuZH1gKTtcbiAgICAgICAgcHJpbnRVc2FnZSgpO1xuICAgICAgICBwcm9jZXNzLmV4aXQoMSk7XG4gICAgfVxuICB9IGNhdGNoIChlcnJvcikge1xuICAgIGNvbnNvbGUuZXJyb3IoJ01pZ3JhdGlvbiBmYWlsZWQ6JywgZXJyb3IpO1xuICAgIHByb2Nlc3MuZXhpdCgxKTtcbiAgfVxufVxuXG5tYWluKCk7XG4iXX0=
@@ -0,0 +1,4 @@
1
+ export { MigrationModule } from './migration.module';
2
+ export { MigrationService } from './migration.service';
3
+ export { MigrationCore } from './migration-core';
4
+ export { MigrationModuleOptions, MigrationModuleAsyncOptions, MigrationModuleOptionsFactory, MigrationResult, MigrationRunOptions, MigrationCoreOptions, MIGRATION_MODULE_OPTIONS, } from './types';
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MIGRATION_MODULE_OPTIONS = exports.MigrationCore = exports.MigrationService = exports.MigrationModule = void 0;
4
+ // Module
5
+ var migration_module_1 = require("./migration.module");
6
+ Object.defineProperty(exports, "MigrationModule", { enumerable: true, get: function () { return migration_module_1.MigrationModule; } });
7
+ // Service
8
+ var migration_service_1 = require("./migration.service");
9
+ Object.defineProperty(exports, "MigrationService", { enumerable: true, get: function () { return migration_service_1.MigrationService; } });
10
+ // Core (for standalone/CLI usage)
11
+ var migration_core_1 = require("./migration-core");
12
+ Object.defineProperty(exports, "MigrationCore", { enumerable: true, get: function () { return migration_core_1.MigrationCore; } });
13
+ // Types
14
+ var types_1 = require("./types");
15
+ Object.defineProperty(exports, "MIGRATION_MODULE_OPTIONS", { enumerable: true, get: function () { return types_1.MIGRATION_MODULE_OPTIONS; } });
16
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsU0FBUztBQUNULHVEQUFxRDtBQUE1QyxtSEFBQSxlQUFlLE9BQUE7QUFFeEIsVUFBVTtBQUNWLHlEQUF1RDtBQUE5QyxxSEFBQSxnQkFBZ0IsT0FBQTtBQUV6QixrQ0FBa0M7QUFDbEMsbURBQWlEO0FBQXhDLCtHQUFBLGFBQWEsT0FBQTtBQUV0QixRQUFRO0FBQ1IsaUNBUWlCO0FBRGYsaUhBQUEsd0JBQXdCLE9BQUEiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBNb2R1bGVcbmV4cG9ydCB7IE1pZ3JhdGlvbk1vZHVsZSB9IGZyb20gJy4vbWlncmF0aW9uLm1vZHVsZSc7XG5cbi8vIFNlcnZpY2VcbmV4cG9ydCB7IE1pZ3JhdGlvblNlcnZpY2UgfSBmcm9tICcuL21pZ3JhdGlvbi5zZXJ2aWNlJztcblxuLy8gQ29yZSAoZm9yIHN0YW5kYWxvbmUvQ0xJIHVzYWdlKVxuZXhwb3J0IHsgTWlncmF0aW9uQ29yZSB9IGZyb20gJy4vbWlncmF0aW9uLWNvcmUnO1xuXG4vLyBUeXBlc1xuZXhwb3J0IHtcbiAgTWlncmF0aW9uTW9kdWxlT3B0aW9ucyxcbiAgTWlncmF0aW9uTW9kdWxlQXN5bmNPcHRpb25zLFxuICBNaWdyYXRpb25Nb2R1bGVPcHRpb25zRmFjdG9yeSxcbiAgTWlncmF0aW9uUmVzdWx0LFxuICBNaWdyYXRpb25SdW5PcHRpb25zLFxuICBNaWdyYXRpb25Db3JlT3B0aW9ucyxcbiAgTUlHUkFUSU9OX01PRFVMRV9PUFRJT05TLFxufSBmcm9tICcuL3R5cGVzJztcbiJdfQ==
@@ -0,0 +1,49 @@
1
+ import { DataSource, QueryRunner } from 'typeorm';
2
+ import { MigrationCoreOptions, MigrationResult, MigrationRunOptions } from './types';
3
+ /**
4
+ * Core migration runner for SQL Server databases.
5
+ * Handles reading SQL migration files, tracking applied migrations,
6
+ * and executing pending migrations within transactions.
7
+ */
8
+ export declare class MigrationCore {
9
+ private readonly dataSource;
10
+ private readonly migrationsDir;
11
+ constructor(dataSource: DataSource, options: MigrationCoreOptions);
12
+ /**
13
+ * Ensures the migrations tracking table exists in the database.
14
+ * Creates it if it doesn't exist.
15
+ */
16
+ ensureMigrationsTable(): Promise<void>;
17
+ /**
18
+ * Gets the list of migrations that have already been applied.
19
+ */
20
+ getAppliedMigrations(): Promise<string[]>;
21
+ /**
22
+ * Gets all SQL migration files from the migrations directory.
23
+ * Files are sorted alphabetically (by convention, use numeric prefixes).
24
+ */
25
+ getMigrationFiles(): Promise<string[]>;
26
+ /**
27
+ * Runs a single migration file within the provided query runner.
28
+ * Handles SQL Server's GO batch separator.
29
+ */
30
+ runSingleMigration(file: string, queryRunner: QueryRunner): Promise<void>;
31
+ /**
32
+ * Runs all pending migrations.
33
+ * Each migration runs in its own transaction for isolation.
34
+ */
35
+ runMigrations(options?: MigrationRunOptions): Promise<MigrationResult>;
36
+ /**
37
+ * Gets the list of pending migrations without applying them.
38
+ */
39
+ getPendingMigrations(): Promise<string[]>;
40
+ /**
41
+ * Gets migration status information.
42
+ */
43
+ getStatus(): Promise<{
44
+ total: number;
45
+ applied: number;
46
+ pending: number;
47
+ pendingFiles: string[];
48
+ }>;
49
+ }
@@ -0,0 +1,184 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MigrationCore = void 0;
4
+ const fs = require("fs");
5
+ const path = require("path");
6
+ const MIGRATION_TABLE = 'migrations';
7
+ /**
8
+ * Core migration runner for SQL Server databases.
9
+ * Handles reading SQL migration files, tracking applied migrations,
10
+ * and executing pending migrations within transactions.
11
+ */
12
+ class MigrationCore {
13
+ dataSource;
14
+ migrationsDir;
15
+ constructor(dataSource, options) {
16
+ this.dataSource = dataSource;
17
+ this.migrationsDir = options.migrationsDir;
18
+ }
19
+ /**
20
+ * Ensures the migrations tracking table exists in the database.
21
+ * Creates it if it doesn't exist.
22
+ */
23
+ async ensureMigrationsTable() {
24
+ const tableExists = await this.dataSource.query(`
25
+ SELECT COUNT(*) as count FROM sysobjects WHERE name='${MIGRATION_TABLE}' AND xtype='U'
26
+ `);
27
+ if (tableExists[0].count === 0) {
28
+ await this.dataSource.query(`
29
+ CREATE TABLE ${MIGRATION_TABLE} (
30
+ id INT IDENTITY(1,1) PRIMARY KEY,
31
+ name NVARCHAR(255) UNIQUE NOT NULL,
32
+ run_on DATETIME DEFAULT GETDATE() NOT NULL
33
+ )
34
+ `);
35
+ }
36
+ }
37
+ /**
38
+ * Gets the list of migrations that have already been applied.
39
+ */
40
+ async getAppliedMigrations() {
41
+ const rows = await this.dataSource.query(`SELECT name FROM ${MIGRATION_TABLE}`);
42
+ return rows.map((row) => row.name);
43
+ }
44
+ /**
45
+ * Gets all SQL migration files from the migrations directory.
46
+ * Files are sorted alphabetically (by convention, use numeric prefixes).
47
+ */
48
+ async getMigrationFiles() {
49
+ if (!fs.existsSync(this.migrationsDir)) {
50
+ throw new Error(`Migrations directory not found: ${this.migrationsDir}`);
51
+ }
52
+ return fs
53
+ .readdirSync(this.migrationsDir)
54
+ .filter((f) => f.endsWith('.sql'))
55
+ .sort();
56
+ }
57
+ /**
58
+ * Runs a single migration file within the provided query runner.
59
+ * Handles SQL Server's GO batch separator.
60
+ */
61
+ async runSingleMigration(file, queryRunner) {
62
+ const sql = fs.readFileSync(path.join(this.migrationsDir, file), 'utf8');
63
+ // Split SQL by GO statements (batch separator for SQL Server)
64
+ // GO is not part of T-SQL and must be handled by the client
65
+ const batches = sql
66
+ .split(/^\s*GO\s*$/im)
67
+ .map((batch) => batch.trim())
68
+ .filter((batch) => batch.length > 0);
69
+ // Run each batch separately
70
+ for (const batch of batches) {
71
+ await queryRunner.query(batch);
72
+ }
73
+ // Track the migration
74
+ await queryRunner.query(`INSERT INTO ${MIGRATION_TABLE} (name, run_on) VALUES (@0, GETDATE())`, [file]);
75
+ }
76
+ /**
77
+ * Runs all pending migrations.
78
+ * Each migration runs in its own transaction for isolation.
79
+ */
80
+ async runMigrations(options) {
81
+ const result = {
82
+ success: false,
83
+ totalMigrations: 0,
84
+ appliedMigrations: 0,
85
+ pendingMigrations: 0,
86
+ };
87
+ try {
88
+ await this.ensureMigrationsTable();
89
+ const files = await this.getMigrationFiles();
90
+ const applied = await this.getAppliedMigrations();
91
+ result.totalMigrations = files.length;
92
+ result.appliedMigrations = applied.length;
93
+ if (options?.verbose) {
94
+ console.log(`Found ${files.length} migration files`);
95
+ console.log(`${applied.length} migrations already applied`);
96
+ }
97
+ const pendingMigrations = files.filter((file) => !applied.includes(file));
98
+ result.pendingMigrations = pendingMigrations.length;
99
+ if (pendingMigrations.length === 0) {
100
+ if (options?.verbose) {
101
+ console.log('No pending migrations to apply');
102
+ }
103
+ result.success = true;
104
+ return result;
105
+ }
106
+ if (options?.dryRun) {
107
+ console.log('Dry run mode - would apply:');
108
+ pendingMigrations.forEach((file) => console.log(` - ${file}`));
109
+ result.success = true;
110
+ return result;
111
+ }
112
+ if (options?.verbose) {
113
+ console.log(`Running ${pendingMigrations.length} pending migrations...`);
114
+ }
115
+ for (const file of pendingMigrations) {
116
+ if (options?.verbose) {
117
+ console.log(`Applying migration: ${file}`);
118
+ }
119
+ // Use a transaction for each migration
120
+ const queryRunner = this.dataSource.createQueryRunner();
121
+ await queryRunner.connect();
122
+ await queryRunner.startTransaction();
123
+ try {
124
+ await this.runSingleMigration(file, queryRunner);
125
+ await queryRunner.commitTransaction();
126
+ if (options?.verbose) {
127
+ console.log(`✓ Applied migration: ${file}`);
128
+ }
129
+ }
130
+ catch (error) {
131
+ await queryRunner.rollbackTransaction();
132
+ if (options?.verbose) {
133
+ console.error(`Failed to apply migration ${file}:`, error);
134
+ }
135
+ result.failedMigration = file;
136
+ result.error = error;
137
+ throw error;
138
+ }
139
+ finally {
140
+ await queryRunner.release();
141
+ }
142
+ }
143
+ result.success = true;
144
+ result.appliedMigrations += pendingMigrations.length;
145
+ if (options?.verbose) {
146
+ console.log('All migrations completed successfully!');
147
+ }
148
+ return result;
149
+ }
150
+ catch (error) {
151
+ result.error = error;
152
+ if (options?.verbose) {
153
+ console.error('Migration failed:', error);
154
+ }
155
+ throw error;
156
+ }
157
+ }
158
+ /**
159
+ * Gets the list of pending migrations without applying them.
160
+ */
161
+ async getPendingMigrations() {
162
+ await this.ensureMigrationsTable();
163
+ const files = await this.getMigrationFiles();
164
+ const applied = await this.getAppliedMigrations();
165
+ return files.filter((file) => !applied.includes(file));
166
+ }
167
+ /**
168
+ * Gets migration status information.
169
+ */
170
+ async getStatus() {
171
+ await this.ensureMigrationsTable();
172
+ const files = await this.getMigrationFiles();
173
+ const applied = await this.getAppliedMigrations();
174
+ const pendingFiles = files.filter((file) => !applied.includes(file));
175
+ return {
176
+ total: files.length,
177
+ applied: applied.length,
178
+ pending: pendingFiles.length,
179
+ pendingFiles,
180
+ };
181
+ }
182
+ }
183
+ exports.MigrationCore = MigrationCore;
184
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWlncmF0aW9uLWNvcmUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvbWlncmF0aW9uLWNvcmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQ0EseUJBQXlCO0FBQ3pCLDZCQUE2QjtBQUc3QixNQUFNLGVBQWUsR0FBRyxZQUFZLENBQUM7QUFFckM7Ozs7R0FJRztBQUNILE1BQWEsYUFBYTtJQUlMO0lBSEYsYUFBYSxDQUFTO0lBRXZDLFlBQ21CLFVBQXNCLEVBQ3ZDLE9BQTZCO1FBRFosZUFBVSxHQUFWLFVBQVUsQ0FBWTtRQUd2QyxJQUFJLENBQUMsYUFBYSxHQUFHLE9BQU8sQ0FBQyxhQUFhLENBQUM7SUFDN0MsQ0FBQztJQUVEOzs7T0FHRztJQUNILEtBQUssQ0FBQyxxQkFBcUI7UUFDekIsTUFBTSxXQUFXLEdBQUcsTUFBTSxJQUFJLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQzs2REFDUyxlQUFlO0tBQ3ZFLENBQUMsQ0FBQztRQUVILElBQUksV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUMvQixNQUFNLElBQUksQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDO3VCQUNYLGVBQWU7Ozs7O09BSy9CLENBQUMsQ0FBQztRQUNMLENBQUM7SUFDSCxDQUFDO0lBRUQ7O09BRUc7SUFDSCxLQUFLLENBQUMsb0JBQW9CO1FBQ3hCLE1BQU0sSUFBSSxHQUFHLE1BQU0sSUFBSSxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQ3RDLG9CQUFvQixlQUFlLEVBQUUsQ0FDdEMsQ0FBQztRQUNGLE9BQU8sSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ3JDLENBQUM7SUFFRDs7O09BR0c7SUFDSCxLQUFLLENBQUMsaUJBQWlCO1FBQ3JCLElBQUksQ0FBQyxFQUFFLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxh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QUcsTUFBTSxJQUFJLENBQUMsb0JBQW9CLEVBQUUsQ0FBQztRQUNsRCxPQUFPLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO0lBQ3pELENBQUM7SUFFRDs7T0FFRztJQUNILEtBQUssQ0FBQyxTQUFTO1FBTWIsTUFBTSxJQUFJLENBQUMscUJBQXFCLEVBQUUsQ0FBQztRQUNuQyxNQUFNLEtBQUssR0FBRyxNQUFNLElBQUksQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO1FBQzdDLE1BQU0sT0FBTyxHQUFHLE1BQU0sSUFBSSxDQUFDLG9CQUFvQixFQUFFLENBQUM7UUFDbEQsTUFBTSxZQUFZLEdBQUcsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7UUFFckUsT0FBTztZQUNMLEtBQUssRUFBRSxLQUFLLENBQUMsTUFBTTtZQUNuQixPQUFPLEVBQUUsT0FBTyxDQUFDLE1BQU07WUFDdkIsT0FBTyxFQUFFLFlBQVksQ0FBQyxNQUFNO1lBQzVCLFlBQVk7U0FDYixDQUFDO0lBQ0osQ0FBQztDQUNGO0FBeE5ELHNDQXdOQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IERhdGFTb3VyY2UsIFF1ZXJ5UnVubmVyIH0gZnJvbSAndHlwZW9ybSc7XG5pbXBvcnQgKiBhcyBmcyBmcm9tICdmcyc7XG5pbXBvcnQgKiBhcyBwYXRoIGZyb20gJ3BhdGgnO1xuaW1wb3J0IHsgTWlncmF0aW9uQ29yZU9wdGlvbnMsIE1pZ3JhdGlvblJlc3VsdCwgTWlncmF0aW9uUnVuT3B0aW9ucyB9IGZyb20gJy4vdHlwZXMnO1xuXG5jb25zdCBNSUdSQVRJT05fVEFCTEUgPSAnbWlncmF0aW9ucyc7XG5cbi8qKlxuICogQ29yZSBtaWdyYXRpb24gcnVubmVyIGZvciBTUUwgU2VydmVyIGRhdGFiYXNlcy5cbiAqIEhhbmRsZXMgcmVhZGluZyBTUUwgbWlncmF0aW9uIGZpbGVzLCB0cmFja2luZyBhcHBsaWVkIG1pZ3JhdGlvbnMsXG4gKiBhbmQgZXhlY3V0aW5nIHBlbmRpbmcgbWlncmF0aW9ucyB3aXRoaW4gdHJhbnNhY3Rpb25zLlxuICovXG5leHBvcnQgY2xhc3MgTWlncmF0aW9uQ29yZSB7XG4gIHByaXZhdGUgcmVhZG9ubHkgbWlncmF0aW9uc0Rpcjogc3RyaW5nO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgcmVhZG9ubHkgZGF0YVNvdXJjZTogRGF0YVNvdXJjZSxcbiAgICBvcHRpb25zOiBNaWdyYXRpb25Db3JlT3B0aW9ucyxcbiAgKSB7XG4gICAgdGhpcy5taWdyYXRpb25zRGlyID0gb3B0aW9ucy5taWdyYXRpb25zRGlyO1xuICB9XG5cbiAgLyoqXG4gICAqIEVuc3VyZXMgdGhlIG1pZ3JhdGlvbnMgdHJhY2tpbmcgdGFibGUgZXhpc3RzIGluIHRoZSBkYXRhYmFzZS5cbiAgICogQ3JlYXRlcyBpdCBpZiBpdCBkb2Vzbid0IGV4aXN0LlxuICAgKi9cbiAgYXN5bmMgZW5zdXJlTWlncmF0aW9uc1RhYmxlKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IHRhYmxlRXhpc3RzID0gYXdhaXQgdGhpcy5kYXRhU291cmNlLnF1ZXJ5KGBcbiAgICAgIFNFTEVDVCBDT1VOVCgqKSBhcyBjb3VudCBGUk9NIHN5c29iamVjdHMgV0hFUkUgbmFtZT0nJHtNSUdSQVRJT05fVEFCTEV9JyBBTkQgeHR5cGU9J1UnXG4gICAgYCk7XG5cbiAgICBpZiAodGFibGVFeGlzdHNbMF0uY291bnQgPT09IDApIHtcbiAgICAgIGF3YWl0IHRoaXMuZGF0YVNvdXJjZS5xdWVyeShgXG4gICAgICAgIENSRUFURSBUQUJMRSAke01JR1JBVElPTl9UQUJMRX0gKFxuICAgICAgICAgIGlkIElOVCBJREVOVElUWSgxLDEpIFBSSU1BUlkgS0VZLFxuICAgICAgICAgIG5hbWUgTlZBUkNIQVIoMjU1KSBVTklRVUUgTk9UIE5VTEwsXG4gICAgICAgICAgcnVuX29uIERBVEVUSU1FIERFRkFVTFQgR0VUREFURSgpIE5PVCBOVUxMXG4gICAgICAgIClcbiAgICAgIGApO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBHZXRzIHRoZSBsaXN0IG9mIG1pZ3JhdGlvbnMgdGhhdCBoYXZlIGFscmVhZHkgYmVlbiBhcHBsaWVkLlxuICAgKi9cbiAgYXN5bmMgZ2V0QXBwbGllZE1pZ3JhdGlvbnMoKTogUHJvbWlzZTxzdHJpbmdbXT4ge1xuICAgIGNvbnN0IHJvd3MgPSBhd2FpdCB0aGlzLmRhdGFTb3VyY2UucXVlcnk8eyBuYW1lOiBzdHJpbmcgfVtdPihcbiAgICAgIGBTRUxFQ1QgbmFtZSBGUk9NICR7TUlHUkFUSU9OX1RBQkxFfWAsXG4gICAgKTtcbiAgICByZXR1cm4gcm93cy5tYXAoKHJvdykgPT4gcm93Lm5hbWUpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldHMgYWxsIFNRTCBtaWdyYXRpb24gZmlsZXMgZnJvbSB0aGUgbWlncmF0aW9ucyBkaXJlY3RvcnkuXG4gICAqIEZpbGVzIGFyZSBzb3J0ZWQgYWxwaGFiZXRpY2FsbHkgKGJ5IGNvbnZlbnRpb24sIHVzZSBudW1lcmljIHByZWZpeGVzKS5cbiAgICovXG4gIGFzeW5jIGdldE1pZ3JhdGlvbkZpbGVzKCk6IFByb21pc2U8c3RyaW5nW10+IHtcbiAgICBpZiAoIWZzLmV4aXN0c1N5bmModGhpcy5taWdyYXRpb25zRGlyKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBNaWdyYXRpb25zIGRpcmVjdG9yeSBub3QgZm91bmQ6ICR7dGhpcy5taWdyYXRpb25zRGlyfWApO1xuICAgIH1cblxuICAgIHJldHVybiBmc1xuICAgICAgLnJlYWRkaXJTeW5jKHRoaXMubWlncmF0aW9uc0RpcilcbiAgICAgIC5maWx0ZXIoKGYpID0+IGYuZW5kc1dpdGgoJy5zcWwnKSlcbiAgICAgIC5zb3J0KCk7XG4gIH1cblxuICAvKipcbiAgICogUnVucyBhIHNpbmdsZSBtaWdyYXRpb24gZmlsZSB3aXRoaW4gdGhlIHByb3ZpZGVkIHF1ZXJ5IHJ1bm5lci5cbiAgICogSGFuZGxlcyBTUUwgU2VydmVyJ3MgR08gYmF0Y2ggc2VwYXJhdG9yLlxuICAgKi9cbiAgYXN5bmMgcnVuU2luZ2xlTWlncmF0aW9uKFxuICAgIGZpbGU6IHN0cmluZyxcbiAgICBxdWVyeVJ1bm5lcjogUXVlcnlSdW5uZXIsXG4gICk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IHNxbCA9IGZzLnJlYWRGaWxlU3luYyhwYXRoLmpvaW4odGhpcy5taWdyYXRpb25zRGlyLCBmaWxlKSwgJ3V0ZjgnKTtcblxuICAgIC8vIFNwbGl0IFNRTCBieSBHTyBzdGF0ZW1lbnRzIChiYXRjaCBzZXBhcmF0b3IgZm9yIFNRTCBTZXJ2ZXIpXG4gICAgLy8gR08gaXMgbm90IHBhcnQgb2YgVC1TUUwgYW5kIG11c3QgYmUgaGFuZGxlZCBieSB0aGUgY2xpZW50XG4gICAgY29uc3QgYmF0Y2hlcyA9IHNxbFxuICAgICAgLnNwbGl0KC9eXFxzKkdPXFxzKiQvaW0pXG4gICAgICAubWFwKChiYXRjaCkgPT4gYmF0Y2gudHJpbSgpKVxuICAgICAgLmZpbHRlcigoYmF0Y2gpID0+IGJhdGNoLmxlbmd0aCA+IDApO1xuXG4gICAgLy8gUnVuIGVhY2ggYmF0Y2ggc2VwYXJhdGVseVxuICAgIGZvciAoY29uc3QgYmF0Y2ggb2YgYmF0Y2hlcykge1xuICAgICAgYXdhaXQgcXVlcnlSdW5uZXIucXVlcnkoYmF0Y2gpO1xuICAgIH1cblxuICAgIC8vIFRyYWNrIHRoZSBtaWdyYXRpb25cbiAgICBhd2FpdCBxdWVyeVJ1bm5lci5xdWVyeShcbiAgICAgIGBJTlNFUlQgSU5UTyAke01JR1JBVElPTl9UQUJMRX0gKG5hbWUsIHJ1bl9vbikgVkFMVUVTIChAMCwgR0VUREFURSgpKWAsXG4gICAgICBbZmlsZV0sXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGFsbCBwZW5kaW5nIG1pZ3JhdGlvbnMuXG4gICAqIEVhY2ggbWlncmF0aW9uIHJ1bnMgaW4gaXRzIG93biB0cmFuc2FjdGlvbiBmb3IgaXNvbGF0aW9uLlxuICAgKi9cbiAgYXN5bmMgcnVuTWlncmF0aW9ucyhvcHRpb25zPzogTWlncmF0aW9uUnVuT3B0aW9ucyk6IFByb21pc2U8TWlncmF0aW9uUmVzdWx0PiB7XG4gICAgY29uc3QgcmVzdWx0OiBNaWdyYXRpb25SZXN1bHQgPSB7XG4gICAgICBzdWNjZXNzOiBmYWxzZSxcbiAgICAgIHRvdGFsTWlncmF0aW9uczogMCxcbiAgICAgIGFwcGxpZWRNaWdyYXRpb25zOiAwLFxuICAgICAgcGVuZGluZ01pZ3JhdGlvbnM6IDAsXG4gICAgfTtcblxuICAgIHRyeSB7XG4gICAgICBhd2FpdCB0aGlzLmVuc3VyZU1pZ3JhdGlvbnNUYWJsZSgpO1xuXG4gICAgICBjb25zdCBmaWxlcyA9IGF3YWl0IHRoaXMuZ2V0TWlncmF0aW9uRmlsZXMoKTtcbiAgICAgIGNvbnN0IGFwcGxpZWQgPSBhd2FpdCB0aGlzLmdldEFwcGxpZWRNaWdyYXRpb25zKCk7XG5cbiAgICAgIHJlc3VsdC50b3RhbE1pZ3JhdGlvbnMgPSBmaWxlcy5sZW5ndGg7XG4gICAgICByZXN1bHQuYXBwbGllZE1pZ3JhdGlvbnMgPSBhcHBsaWVkLmxlbmd0aDtcblxuICAgICAgaWYgKG9wdGlvbnM/LnZlcmJvc2UpIHtcbiAgICAgICAgY29uc29sZS5sb2coYEZvdW5kICR7ZmlsZXMubGVuZ3RofSBtaWdyYXRpb24gZmlsZXNgKTtcbiAgICAgICAgY29uc29sZS5sb2coYCR7YXBwbGllZC5sZW5ndGh9IG1pZ3JhdGlvbnMgYWxyZWFkeSBhcHBsaWVkYCk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHBlbmRpbmdNaWdyYXRpb25zID0gZmlsZXMuZmlsdGVyKChmaWxlKSA9PiAhYXBwbGllZC5pbmNsdWRlcyhmaWxlKSk7XG4gICAgICByZXN1bHQucGVuZGluZ01pZ3JhdGlvbnMgPSBwZW5kaW5nTWlncmF0aW9ucy5sZW5ndGg7XG5cbiAgICAgIGlmIChwZW5kaW5nTWlncmF0aW9ucy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgaWYgKG9wdGlvbnM/LnZlcmJvc2UpIHtcbiAgICAgICAgICBjb25zb2xlLmxvZygnTm8gcGVuZGluZyBtaWdyYXRpb25zIHRvIGFwcGx5Jyk7XG4gICAgICAgIH1cbiAgICAgICAgcmVzdWx0LnN1Y2Nlc3MgPSB0cnVlO1xuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgfVxuXG4gICAgICBpZiAob3B0aW9ucz8uZHJ5UnVuKSB7XG4gICAgICAgIGNvbnNvbGUubG9nKCdEcnkgcnVuIG1vZGUgLSB3b3VsZCBhcHBseTonKTtcbiAgICAgICAgcGVuZGluZ01pZ3JhdGlvbnMuZm9yRWFjaCgoZmlsZSkgPT4gY29uc29sZS5sb2coYCAgLSAke2ZpbGV9YCkpO1xuICAgICAgICByZXN1bHQuc3VjY2VzcyA9IHRydWU7XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9XG5cbiAgICAgIGlmIChvcHRpb25zPy52ZXJib3NlKSB7XG4gICAgICAgIGNvbnNvbGUubG9nKFxuICAgICAgICAgIGBSdW5uaW5nICR7cGVuZGluZ01pZ3JhdGlvbnMubGVuZ3RofSBwZW5kaW5nIG1pZ3JhdGlvbnMuLi5gLFxuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICBmb3IgKGNvbnN0IGZpbGUgb2YgcGVuZGluZ01pZ3JhdGlvbnMpIHtcbiAgICAgICAgaWYgKG9wdGlvbnM/LnZlcmJvc2UpIHtcbiAgICAgICAgICBjb25zb2xlLmxvZyhgQXBwbHlpbmcgbWlncmF0aW9uOiAke2ZpbGV9YCk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBVc2UgYSB0cmFuc2FjdGlvbiBmb3IgZWFjaCBtaWdyYXRpb25cbiAgICAgICAgY29uc3QgcXVlcnlSdW5uZXIgPSB0aGlzLmRhdGFTb3VyY2UuY3JlYXRlUXVlcnlSdW5uZXIoKTtcbiAgICAgICAgYXdhaXQgcXVlcnlSdW5uZXIuY29ubmVjdCgpO1xuICAgICAgICBhd2FpdCBxdWVyeVJ1bm5lci5zdGFydFRyYW5zYWN0aW9uKCk7XG5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBhd2FpdCB0aGlzLnJ1blNpbmdsZU1pZ3JhdGlvbihmaWxlLCBxdWVyeVJ1bm5lcik7XG4gICAgICAgICAgYXdhaXQgcXVlcnlSdW5uZXIuY29tbWl0VHJhbnNhY3Rpb24oKTtcblxuICAgICAgICAgIGlmIChvcHRpb25zPy52ZXJib3NlKSB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZyhg4pyTIEFwcGxpZWQgbWlncmF0aW9uOiAke2ZpbGV9YCk7XG4gICAgICAgICAgfVxuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgIGF3YWl0IHF1ZXJ5UnVubmVyLnJvbGxiYWNrVHJhbnNhY3Rpb24oKTtcblxuICAgICAgICAgIGlmIChvcHRpb25zPy52ZXJib3NlKSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKGBGYWlsZWQgdG8gYXBwbHkgbWlncmF0aW9uICR7ZmlsZX06YCwgZXJyb3IpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHJlc3VsdC5mYWlsZWRNaWdyYXRpb24gPSBmaWxlO1xuICAgICAgICAgIHJlc3VsdC5lcnJvciA9IGVycm9yO1xuICAgICAgICAgIHRocm93IGVycm9yO1xuICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgIGF3YWl0IHF1ZXJ5UnVubmVyLnJlbGVhc2UoKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZXN1bHQuc3VjY2VzcyA9IHRydWU7XG4gICAgICByZXN1bHQuYXBwbGllZE1pZ3JhdGlvbnMgKz0gcGVuZGluZ01pZ3JhdGlvbnMubGVuZ3RoO1xuXG4gICAgICBpZiAob3B0aW9ucz8udmVyYm9zZSkge1xuICAgICAgICBjb25zb2xlLmxvZygnQWxsIG1pZ3JhdGlvbnMgY29tcGxldGVkIHN1Y2Nlc3NmdWxseSEnKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgcmVzdWx0LmVycm9yID0gZXJyb3I7XG5cbiAgICAgIGlmIChvcHRpb25zPy52ZXJib3NlKSB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoJ01pZ3JhdGlvbiBmYWlsZWQ6JywgZXJyb3IpO1xuICAgICAgfVxuXG4gICAgICB0aHJvdyBlcnJvcjtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogR2V0cyB0aGUgbGlzdCBvZiBwZW5kaW5nIG1pZ3JhdGlvbnMgd2l0aG91dCBhcHBseWluZyB0aGVtLlxuICAgKi9cbiAgYXN5bmMgZ2V0UGVuZGluZ01pZ3JhdGlvbnMoKTogUHJvbWlzZTxzdHJpbmdbXT4ge1xuICAgIGF3YWl0IHRoaXMuZW5zdXJlTWlncmF0aW9uc1RhYmxlKCk7XG4gICAgY29uc3QgZmlsZXMgPSBhd2FpdCB0aGlzLmdldE1pZ3JhdGlvbkZpbGVzKCk7XG4gICAgY29uc3QgYXBwbGllZCA9IGF3YWl0IHRoaXMuZ2V0QXBwbGllZE1pZ3JhdGlvbnMoKTtcbiAgICByZXR1cm4gZmlsZXMuZmlsdGVyKChmaWxlKSA9PiAhYXBwbGllZC5pbmNsdWRlcyhmaWxlKSk7XG4gIH1cblxuICAvKipcbiAgICogR2V0cyBtaWdyYXRpb24gc3RhdHVzIGluZm9ybWF0aW9uLlxuICAgKi9cbiAgYXN5bmMgZ2V0U3RhdHVzKCk6IFByb21pc2U8e1xuICAgIHRvdGFsOiBudW1iZXI7XG4gICAgYXBwbGllZDogbnVtYmVyO1xuICAgIHBlbmRpbmc6IG51bWJlcjtcbiAgICBwZW5kaW5nRmlsZXM6IHN0cmluZ1tdO1xuICB9PiB7XG4gICAgYXdhaXQgdGhpcy5lbnN1cmVNaWdyYXRpb25zVGFibGUoKTtcbiAgICBjb25zdCBmaWxlcyA9IGF3YWl0IHRoaXMuZ2V0TWlncmF0aW9uRmlsZXMoKTtcbiAgICBjb25zdCBhcHBsaWVkID0gYXdhaXQgdGhpcy5nZXRBcHBsaWVkTWlncmF0aW9ucygpO1xuICAgIGNvbnN0IHBlbmRpbmdGaWxlcyA9IGZpbGVzLmZpbHRlcigoZmlsZSkgPT4gIWFwcGxpZWQuaW5jbHVkZXMoZmlsZSkpO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIHRvdGFsOiBmaWxlcy5sZW5ndGgsXG4gICAgICBhcHBsaWVkOiBhcHBsaWVkLmxlbmd0aCxcbiAgICAgIHBlbmRpbmc6IHBlbmRpbmdGaWxlcy5sZW5ndGgsXG4gICAgICBwZW5kaW5nRmlsZXMsXG4gICAgfTtcbiAgfVxufVxuIl19
@@ -0,0 +1,37 @@
1
+ import { DynamicModule } from '@nestjs/common';
2
+ import { MigrationModuleAsyncOptions, MigrationModuleOptions } from './types';
3
+ /**
4
+ * NestJS module for SQL Server migrations.
5
+ *
6
+ * @example
7
+ * // Synchronous configuration
8
+ * MigrationModule.forRoot({
9
+ * migrationsDir: path.join(__dirname, '../migrations'),
10
+ * autoRun: true,
11
+ * verbose: true,
12
+ * })
13
+ *
14
+ * @example
15
+ * // Asynchronous configuration with ConfigService
16
+ * MigrationModule.forRootAsync({
17
+ * imports: [ConfigModule],
18
+ * inject: [ConfigService],
19
+ * useFactory: (configService: ConfigService) => ({
20
+ * migrationsDir: path.join(__dirname, '../migrations'),
21
+ * autoRun: configService.get<boolean>('AUTO_RUN_MIGRATIONS', false),
22
+ * verbose: true,
23
+ * }),
24
+ * })
25
+ */
26
+ export declare class MigrationModule {
27
+ /**
28
+ * Configure the migration module with static options.
29
+ */
30
+ static forRoot(options: MigrationModuleOptions): DynamicModule;
31
+ /**
32
+ * Configure the migration module with async options.
33
+ * Useful when options depend on ConfigService or other async providers.
34
+ */
35
+ static forRootAsync(options: MigrationModuleAsyncOptions): DynamicModule;
36
+ private static createAsyncProviders;
37
+ }
@@ -0,0 +1,108 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var MigrationModule_1;
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.MigrationModule = void 0;
11
+ const common_1 = require("@nestjs/common");
12
+ const migration_service_1 = require("./migration.service");
13
+ const types_1 = require("./types");
14
+ /**
15
+ * NestJS module for SQL Server migrations.
16
+ *
17
+ * @example
18
+ * // Synchronous configuration
19
+ * MigrationModule.forRoot({
20
+ * migrationsDir: path.join(__dirname, '../migrations'),
21
+ * autoRun: true,
22
+ * verbose: true,
23
+ * })
24
+ *
25
+ * @example
26
+ * // Asynchronous configuration with ConfigService
27
+ * MigrationModule.forRootAsync({
28
+ * imports: [ConfigModule],
29
+ * inject: [ConfigService],
30
+ * useFactory: (configService: ConfigService) => ({
31
+ * migrationsDir: path.join(__dirname, '../migrations'),
32
+ * autoRun: configService.get<boolean>('AUTO_RUN_MIGRATIONS', false),
33
+ * verbose: true,
34
+ * }),
35
+ * })
36
+ */
37
+ let MigrationModule = MigrationModule_1 = class MigrationModule {
38
+ /**
39
+ * Configure the migration module with static options.
40
+ */
41
+ static forRoot(options) {
42
+ return {
43
+ module: MigrationModule_1,
44
+ providers: [
45
+ {
46
+ provide: types_1.MIGRATION_MODULE_OPTIONS,
47
+ useValue: options,
48
+ },
49
+ migration_service_1.MigrationService,
50
+ ],
51
+ exports: [migration_service_1.MigrationService],
52
+ };
53
+ }
54
+ /**
55
+ * Configure the migration module with async options.
56
+ * Useful when options depend on ConfigService or other async providers.
57
+ */
58
+ static forRootAsync(options) {
59
+ return {
60
+ module: MigrationModule_1,
61
+ imports: options.imports || [],
62
+ providers: [
63
+ ...this.createAsyncProviders(options),
64
+ migration_service_1.MigrationService,
65
+ ],
66
+ exports: [migration_service_1.MigrationService],
67
+ };
68
+ }
69
+ static createAsyncProviders(options) {
70
+ if (options.useFactory) {
71
+ return [
72
+ {
73
+ provide: types_1.MIGRATION_MODULE_OPTIONS,
74
+ useFactory: options.useFactory,
75
+ inject: options.inject || [],
76
+ },
77
+ ];
78
+ }
79
+ if (options.useClass) {
80
+ return [
81
+ {
82
+ provide: options.useClass,
83
+ useClass: options.useClass,
84
+ },
85
+ {
86
+ provide: types_1.MIGRATION_MODULE_OPTIONS,
87
+ useFactory: async (optionsFactory) => optionsFactory.createMigrationOptions(),
88
+ inject: [options.useClass],
89
+ },
90
+ ];
91
+ }
92
+ if (options.useExisting) {
93
+ return [
94
+ {
95
+ provide: types_1.MIGRATION_MODULE_OPTIONS,
96
+ useFactory: async (optionsFactory) => optionsFactory.createMigrationOptions(),
97
+ inject: [options.useExisting],
98
+ },
99
+ ];
100
+ }
101
+ return [];
102
+ }
103
+ };
104
+ exports.MigrationModule = MigrationModule;
105
+ exports.MigrationModule = MigrationModule = MigrationModule_1 = __decorate([
106
+ (0, common_1.Module)({})
107
+ ], MigrationModule);
108
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWlncmF0aW9uLm1vZHVsZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9taWdyYXRpb24ubW9kdWxlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7QUFBQSwyQ0FBaUU7QUFDakUsMkRBQXVEO0FBQ3ZELG1DQUtpQjtBQUVqQjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQXNCRztBQUVJLElBQU0sZUFBZSx1QkFBckIsTUFBTSxlQUFlO0lBQzFCOztPQUVHO0lBQ0gsTUFBTSxDQUFDLE9BQU8sQ0FBQyxPQUErQjtRQUM1QyxPQUFPO1lBQ0wsTUFBTSxFQUFFLGlCQUFlO1lBQ3ZCLFNBQVMsRUFBRTtnQkFDVDtvQkFDRSxPQUFPLEVBQUUsZ0NBQXdCO29CQUNqQyxRQUFRLEVBQUUsT0FBTztpQkFDbEI7Z0JBQ0Qsb0NBQWdCO2FBQ2pCO1lBQ0QsT0FBTyxFQUFFLENBQUMsb0NBQWdCLENBQUM7U0FDNUIsQ0FBQztJQUNKLENBQUM7SUFFRDs7O09BR0c7SUFDSCxNQUFNLENBQUMsWUFBWSxDQUFDLE9BQW9DO1FBQ3RELE9BQU87WUFDTCxNQUFNLEVBQUUsaUJBQWU7WUFDdkIsT0FBTyxFQUFFLE9BQU8sQ0FBQyxPQUFPLElBQUksRUFBRTtZQUM5QixTQUFTLEVBQUU7Z0JBQ1QsR0FBRyxJQUFJLENBQUMsb0JBQW9CLENBQUMsT0FBTyxDQUFDO2dCQUNyQyxvQ0FBZ0I7YUFDakI7WUFDRCxPQUFPLEVBQUUsQ0FBQyxvQ0FBZ0IsQ0FBQztTQUM1QixDQUFDO0lBQ0osQ0FBQztJQUVPLE1BQU0sQ0FBQyxvQkFBb0IsQ0FDakMsT0FBb0M7UUFFcEMsSUFBSSxPQUFPLENBQUMsVUFBVSxFQUFFLENBQUM7WUFDdkIsT0FBTztnQkFDTDtvQkFDRSxPQUFPLEVBQUUsZ0NBQXdCO29CQUNqQyxVQUFVLEVBQUUsT0FBTyxDQUFDLFVBQVU7b0JBQzlCLE1BQU0sRUFBRSxPQUFPLENBQUMsTUFBTSxJQUFJLEVBQUU7aUJBQzdCO2FBQ0YsQ0FBQztRQUNKLENBQUM7UUFFRCxJQUFJLE9BQU8sQ0FBQyxRQUFRLEVBQUUsQ0FBQztZQUNyQixPQUFPO2dCQUNMO29CQUNFLE9BQU8sRUFBRSxPQUFPLENBQUMsUUFBUTtvQkFDekIsUUFBUSxFQUFFLE9BQU8sQ0FBQyxRQUFRO2lCQUMzQjtnQkFDRDtvQkFDRSxPQUFPLEVBQUUsZ0NBQXdCO29CQUNqQyxVQUFVLEVBQUUsS0FBSyxFQUFFLGNBQTZDLEVBQUUsRUFBRSxDQUNsRSxjQUFjLENBQUMsc0JBQXNCLEVBQUU7b0JBQ3pDLE1BQU0sRUFBRSxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUM7aUJBQzNCO2FBQ0YsQ0FBQztRQUNKLENBQUM7UUFFRCxJQUFJLE9BQU8sQ0FBQyxXQUFXLEVBQUUsQ0FBQztZQUN4QixPQUFPO2dCQUNMO29CQUNFLE9BQU8sRUFBRSxnQ0FBd0I7b0JBQ2pDLFVBQVUsRUFBRSxLQUFLLEVBQUUsY0FBNkMsRUFBRSxFQUFFLENBQ2xFLGNBQWMsQ0FBQyxzQkFBc0IsRUFBRTtvQkFDekMsTUFBTSxFQUFFLENBQUMsT0FBTyxDQUFDLFdBQVcsQ0FBQztpQkFDOUI7YUFDRixDQUFDO1FBQ0osQ0FBQztRQUVELE9BQU8sRUFBRSxDQUFDO0lBQ1osQ0FBQztDQUNGLENBQUE7QUEzRVksMENBQWU7MEJBQWYsZUFBZTtJQUQzQixJQUFBLGVBQU0sRUFBQyxFQUFFLENBQUM7R0FDRSxlQUFlLENBMkUzQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IER5bmFtaWNNb2R1bGUsIE1vZHVsZSwgUHJvdmlkZXIgfSBmcm9tICdAbmVzdGpzL2NvbW1vbic7XG5pbXBvcnQgeyBNaWdyYXRpb25TZXJ2aWNlIH0gZnJvbSAnLi9taWdyYXRpb24uc2VydmljZSc7XG5pbXBvcnQge1xuICBNSUdSQVRJT05fTU9EVUxFX09QVElPTlMsXG4gIE1pZ3JhdGlvbk1vZHVsZUFzeW5jT3B0aW9ucyxcbiAgTWlncmF0aW9uTW9kdWxlT3B0aW9ucyxcbiAgTWlncmF0aW9uTW9kdWxlT3B0aW9uc0ZhY3RvcnksXG59IGZyb20gJy4vdHlwZXMnO1xuXG4vKipcbiAqIE5lc3RKUyBtb2R1bGUgZm9yIFNRTCBTZXJ2ZXIgbWlncmF0aW9ucy5cbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gU3luY2hyb25vdXMgY29uZmlndXJhdGlvblxuICogTWlncmF0aW9uTW9kdWxlLmZvclJvb3Qoe1xuICogICBtaWdyYXRpb25zRGlyOiBwYXRoLmpvaW4oX19kaXJuYW1lLCAnLi4vbWlncmF0aW9ucycpLFxuICogICBhdXRvUnVuOiB0cnVlLFxuICogICB2ZXJib3NlOiB0cnVlLFxuICogfSlcbiAqXG4gKiBAZXhhbXBsZVxuICogLy8gQXN5bmNocm9ub3VzIGNvbmZpZ3VyYXRpb24gd2l0aCBDb25maWdTZXJ2aWNlXG4gKiBNaWdyYXRpb25Nb2R1bGUuZm9yUm9vdEFzeW5jKHtcbiAqICAgaW1wb3J0czogW0NvbmZpZ01vZHVsZV0sXG4gKiAgIGluamVjdDogW0NvbmZpZ1NlcnZpY2VdLFxuICogICB1c2VGYWN0b3J5OiAoY29uZmlnU2VydmljZTogQ29uZmlnU2VydmljZSkgPT4gKHtcbiAqICAgICBtaWdyYXRpb25zRGlyOiBwYXRoLmpvaW4oX19kaXJuYW1lLCAnLi4vbWlncmF0aW9ucycpLFxuICogICAgIGF1dG9SdW46IGNvbmZpZ1NlcnZpY2UuZ2V0PGJvb2xlYW4+KCdBVVRPX1JVTl9NSUdSQVRJT05TJywgZmFsc2UpLFxuICogICAgIHZlcmJvc2U6IHRydWUsXG4gKiAgIH0pLFxuICogfSlcbiAqL1xuQE1vZHVsZSh7fSlcbmV4cG9ydCBjbGFzcyBNaWdyYXRpb25Nb2R1bGUge1xuICAvKipcbiAgICogQ29uZmlndXJlIHRoZSBtaWdyYXRpb24gbW9kdWxlIHdpdGggc3RhdGljIG9wdGlvbnMuXG4gICAqL1xuICBzdGF0aWMgZm9yUm9vdChvcHRpb25zOiBNaWdyYXRpb25Nb2R1bGVPcHRpb25zKTogRHluYW1pY01vZHVsZSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIG1vZHVsZTogTWlncmF0aW9uTW9kdWxlLFxuICAgICAgcHJvdmlkZXJzOiBbXG4gICAgICAgIHtcbiAgICAgICAgICBwcm92aWRlOiBNSUdSQVRJT05fTU9EVUxFX09QVElPTlMsXG4gICAgICAgICAgdXNlVmFsdWU6IG9wdGlvbnMsXG4gICAgICAgIH0sXG4gICAgICAgIE1pZ3JhdGlvblNlcnZpY2UsXG4gICAgICBdLFxuICAgICAgZXhwb3J0czogW01pZ3JhdGlvblNlcnZpY2VdLFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogQ29uZmlndXJlIHRoZSBtaWdyYXRpb24gbW9kdWxlIHdpdGggYXN5bmMgb3B0aW9ucy5cbiAgICogVXNlZnVsIHdoZW4gb3B0aW9ucyBkZXBlbmQgb24gQ29uZmlnU2VydmljZSBvciBvdGhlciBhc3luYyBwcm92aWRlcnMuXG4gICAqL1xuICBzdGF0aWMgZm9yUm9vdEFzeW5jKG9wdGlvbnM6IE1pZ3JhdGlvbk1vZHVsZUFzeW5jT3B0aW9ucyk6IER5bmFtaWNNb2R1bGUge1xuICAgIHJldHVybiB7XG4gICAgICBtb2R1bGU6IE1pZ3JhdGlvbk1vZHVsZSxcbiAgICAgIGltcG9ydHM6IG9wdGlvbnMuaW1wb3J0cyB8fCBbXSxcbiAgICAgIHByb3ZpZGVyczogW1xuICAgICAgICAuLi50aGlzLmNyZWF0ZUFzeW5jUHJvdmlkZXJzKG9wdGlvbnMpLFxuICAgICAgICBNaWdyYXRpb25TZXJ2aWNlLFxuICAgICAgXSxcbiAgICAgIGV4cG9ydHM6IFtNaWdyYXRpb25TZXJ2aWNlXSxcbiAgICB9O1xuICB9XG5cbiAgcHJpdmF0ZSBzdGF0aWMgY3JlYXRlQXN5bmNQcm92aWRlcnMoXG4gICAgb3B0aW9uczogTWlncmF0aW9uTW9kdWxlQXN5bmNPcHRpb25zLFxuICApOiBQcm92aWRlcltdIHtcbiAgICBpZiAob3B0aW9ucy51c2VGYWN0b3J5KSB7XG4gICAgICByZXR1cm4gW1xuICAgICAgICB7XG4gICAgICAgICAgcHJvdmlkZTogTUlHUkFUSU9OX01PRFVMRV9PUFRJT05TLFxuICAgICAgICAgIHVzZUZhY3Rvcnk6IG9wdGlvbnMudXNlRmFjdG9yeSxcbiAgICAgICAgICBpbmplY3Q6IG9wdGlvbnMuaW5qZWN0IHx8IFtdLFxuICAgICAgICB9LFxuICAgICAgXTtcbiAgICB9XG5cbiAgICBpZiAob3B0aW9ucy51c2VDbGFzcykge1xuICAgICAgcmV0dXJuIFtcbiAgICAgICAge1xuICAgICAgICAgIHByb3ZpZGU6IG9wdGlvbnMudXNlQ2xhc3MsXG4gICAgICAgICAgdXNlQ2xhc3M6IG9wdGlvbnMudXNlQ2xhc3MsXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICBwcm92aWRlOiBNSUdSQVRJT05fTU9EVUxFX09QVElPTlMsXG4gICAgICAgICAgdXNlRmFjdG9yeTogYXN5bmMgKG9wdGlvbnNGYWN0b3J5OiBNaWdyYXRpb25Nb2R1bGVPcHRpb25zRmFjdG9yeSkgPT5cbiAgICAgICAgICAgIG9wdGlvbnNGYWN0b3J5LmNyZWF0ZU1pZ3JhdGlvbk9wdGlvbnMoKSxcbiAgICAgICAgICBpbmplY3Q6IFtvcHRpb25zLnVzZUNsYXNzXSxcbiAgICAgICAgfSxcbiAgICAgIF07XG4gICAgfVxuXG4gICAgaWYgKG9wdGlvbnMudXNlRXhpc3RpbmcpIHtcbiAgICAgIHJldHVybiBbXG4gICAgICAgIHtcbiAgICAgICAgICBwcm92aWRlOiBNSUdSQVRJT05fTU9EVUxFX09QVElPTlMsXG4gICAgICAgICAgdXNlRmFjdG9yeTogYXN5bmMgKG9wdGlvbnNGYWN0b3J5OiBNaWdyYXRpb25Nb2R1bGVPcHRpb25zRmFjdG9yeSkgPT5cbiAgICAgICAgICAgIG9wdGlvbnNGYWN0b3J5LmNyZWF0ZU1pZ3JhdGlvbk9wdGlvbnMoKSxcbiAgICAgICAgICBpbmplY3Q6IFtvcHRpb25zLnVzZUV4aXN0aW5nXSxcbiAgICAgICAgfSxcbiAgICAgIF07XG4gICAgfVxuXG4gICAgcmV0dXJuIFtdO1xuICB9XG59XG4iXX0=
@@ -0,0 +1,32 @@
1
+ import { OnModuleInit } from '@nestjs/common';
2
+ import { DataSource } from 'typeorm';
3
+ import { MigrationModuleOptions, MigrationResult, MigrationRunOptions } from './types';
4
+ /**
5
+ * NestJS service for running SQL Server migrations.
6
+ * Automatically runs migrations on module initialization if autoRun is enabled.
7
+ */
8
+ export declare class MigrationService implements OnModuleInit {
9
+ private readonly options;
10
+ private readonly migrationCore;
11
+ private readonly autoRun;
12
+ private readonly verbose;
13
+ constructor(options: MigrationModuleOptions, dataSource: DataSource);
14
+ onModuleInit(): Promise<void>;
15
+ /**
16
+ * Run all pending migrations.
17
+ */
18
+ runMigrations(options?: MigrationRunOptions): Promise<MigrationResult>;
19
+ /**
20
+ * Get list of pending migration files.
21
+ */
22
+ getPendingMigrations(): Promise<string[]>;
23
+ /**
24
+ * Get migration status information.
25
+ */
26
+ getStatus(): Promise<{
27
+ total: number;
28
+ applied: number;
29
+ pending: number;
30
+ pendingFiles: string[];
31
+ }>;
32
+ }
@@ -0,0 +1,77 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
12
+ return function (target, key) { decorator(target, key, paramIndex); }
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.MigrationService = void 0;
16
+ const common_1 = require("@nestjs/common");
17
+ const typeorm_1 = require("typeorm");
18
+ const migration_core_1 = require("./migration-core");
19
+ const types_1 = require("./types");
20
+ /**
21
+ * NestJS service for running SQL Server migrations.
22
+ * Automatically runs migrations on module initialization if autoRun is enabled.
23
+ */
24
+ let MigrationService = class MigrationService {
25
+ options;
26
+ migrationCore;
27
+ autoRun;
28
+ verbose;
29
+ constructor(options, dataSource) {
30
+ this.options = options;
31
+ this.migrationCore = new migration_core_1.MigrationCore(dataSource, {
32
+ migrationsDir: options.migrationsDir,
33
+ });
34
+ this.autoRun = options.autoRun ?? false;
35
+ this.verbose = options.verbose ?? true;
36
+ }
37
+ async onModuleInit() {
38
+ if (!this.autoRun) {
39
+ if (this.verbose) {
40
+ console.log('Auto migrations are disabled');
41
+ }
42
+ return;
43
+ }
44
+ if (this.verbose) {
45
+ console.log('Auto-running migrations...');
46
+ }
47
+ await this.runMigrations();
48
+ }
49
+ /**
50
+ * Run all pending migrations.
51
+ */
52
+ async runMigrations(options) {
53
+ return this.migrationCore.runMigrations({
54
+ verbose: this.verbose,
55
+ ...options,
56
+ });
57
+ }
58
+ /**
59
+ * Get list of pending migration files.
60
+ */
61
+ async getPendingMigrations() {
62
+ return this.migrationCore.getPendingMigrations();
63
+ }
64
+ /**
65
+ * Get migration status information.
66
+ */
67
+ async getStatus() {
68
+ return this.migrationCore.getStatus();
69
+ }
70
+ };
71
+ exports.MigrationService = MigrationService;
72
+ exports.MigrationService = MigrationService = __decorate([
73
+ (0, common_1.Injectable)(),
74
+ __param(0, (0, common_1.Inject)(types_1.MIGRATION_MODULE_OPTIONS)),
75
+ __metadata("design:paramtypes", [Object, typeorm_1.DataSource])
76
+ ], MigrationService);
77
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWlncmF0aW9uLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvbWlncmF0aW9uLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsMkNBQWtFO0FBQ2xFLHFDQUFxQztBQUNyQyxxREFBaUQ7QUFDakQsbUNBS2lCO0FBRWpCOzs7R0FHRztBQUVJLElBQU0sZ0JBQWdCLEdBQXRCLE1BQU0sZ0JBQWdCO0lBT1I7SUFORixhQUFhLENBQWdCO0lBQzdCLE9BQU8sQ0FBVTtJQUNqQixPQUFPLENBQVU7SUFFbEMsWUFFbUIsT0FBK0IsRUFDaEQsVUFBc0I7UUFETCxZQUFPLEdBQVAsT0FBTyxDQUF3QjtRQUdoRCxJQUFJLENBQUMsYUFBYSxHQUFHLElBQUksOEJBQWEsQ0FBQyxVQUFVLEVBQUU7WUFDakQsYUFBYSxFQUFFLE9BQU8sQ0FBQyxhQUFhO1NBQ3JDLENBQUMsQ0FBQztRQUNILElBQUksQ0FBQyxPQUFPLEdBQUcsT0FBTyxDQUFDLE9BQU8sSUFBSSxLQUFLLENBQUM7UUFDeEMsSUFBSSxDQUFDLE9BQU8sR0FBRyxPQUFPLENBQUMsT0FBTyxJQUFJLElBQUksQ0FBQztJQUN6QyxDQUFDO0lBRUQsS0FBSyxDQUFDLFlBQVk7UUFDaEIsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztZQUNsQixJQUFJLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztnQkFDakIsT0FBTyxDQUFDLEdBQUcsQ0FBQyw4QkFBOEIsQ0FBQyxDQUFDO1lBQzlDLENBQUM7WUFDRCxPQUFPO1FBQ1QsQ0FBQztRQUVELElBQUksSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO1lBQ2pCLE9BQU8sQ0FBQyxHQUFHLENBQUMsNEJBQTRCLENBQUMsQ0FBQztRQUM1QyxDQUFDO1FBRUQsTUFBTSxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7SUFDN0IsQ0FBQztJQUVEOztPQUVHO0lBQ0gsS0FBSyxDQUFDLGFBQWEsQ0FBQyxPQUE2QjtRQUMvQyxPQUFPLElBQUksQ0FBQyxhQUFhLENBQUMsYUFBYSxDQUFDO1lBQ3RDLE9BQU8sRUFBRSxJQUFJLENBQUMsT0FBTztZQUNyQixHQUFHLE9BQU87U0FDWCxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQ7O09BRUc7SUFDSCxLQUFLLENBQUMsb0JBQW9CO1FBQ3hCLE9BQU8sSUFBSSxDQUFDLGFBQWEsQ0FBQyxvQkFBb0IsRUFBRSxDQUFDO0lBQ25ELENBQUM7SUFFRDs7T0FFRztJQUNILEtBQUssQ0FBQyxTQUFTO1FBTWIsT0FBTyxJQUFJLENBQUMsYUFBYSxDQUFDLFNBQVMsRUFBRSxDQUFDO0lBQ3hDLENBQUM7Q0FDRixDQUFBO0FBNURZLDRDQUFnQjsyQkFBaEIsZ0JBQWdCO0lBRDVCLElBQUEsbUJBQVUsR0FBRTtJQU9SLFdBQUEsSUFBQSxlQUFNLEVBQUMsZ0NBQXdCLENBQUMsQ0FBQTs2Q0FFckIsb0JBQVU7R0FSYixnQkFBZ0IsQ0E0RDVCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0LCBJbmplY3RhYmxlLCBPbk1vZHVsZUluaXQgfSBmcm9tICdAbmVzdGpzL2NvbW1vbic7XG5pbXBvcnQgeyBEYXRhU291cmNlIH0gZnJvbSAndHlwZW9ybSc7XG5pbXBvcnQgeyBNaWdyYXRpb25Db3JlIH0gZnJvbSAnLi9taWdyYXRpb24tY29yZSc7XG5pbXBvcnQge1xuICBNSUdSQVRJT05fTU9EVUxFX09QVElPTlMsXG4gIE1pZ3JhdGlvbk1vZHVsZU9wdGlvbnMsXG4gIE1pZ3JhdGlvblJlc3VsdCxcbiAgTWlncmF0aW9uUnVuT3B0aW9ucyxcbn0gZnJvbSAnLi90eXBlcyc7XG5cbi8qKlxuICogTmVzdEpTIHNlcnZpY2UgZm9yIHJ1bm5pbmcgU1FMIFNlcnZlciBtaWdyYXRpb25zLlxuICogQXV0b21hdGljYWxseSBydW5zIG1pZ3JhdGlvbnMgb24gbW9kdWxlIGluaXRpYWxpemF0aW9uIGlmIGF1dG9SdW4gaXMgZW5hYmxlZC5cbiAqL1xuQEluamVjdGFibGUoKVxuZXhwb3J0IGNsYXNzIE1pZ3JhdGlvblNlcnZpY2UgaW1wbGVtZW50cyBPbk1vZHVsZUluaXQge1xuICBwcml2YXRlIHJlYWRvbmx5IG1pZ3JhdGlvbkNvcmU6IE1pZ3JhdGlvbkNvcmU7XG4gIHByaXZhdGUgcmVhZG9ubHkgYXV0b1J1bjogYm9vbGVhbjtcbiAgcHJpdmF0ZSByZWFkb25seSB2ZXJib3NlOiBib29sZWFuO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIEBJbmplY3QoTUlHUkFUSU9OX01PRFVMRV9PUFRJT05TKVxuICAgIHByaXZhdGUgcmVhZG9ubHkgb3B0aW9uczogTWlncmF0aW9uTW9kdWxlT3B0aW9ucyxcbiAgICBkYXRhU291cmNlOiBEYXRhU291cmNlLFxuICApIHtcbiAgICB0aGlzLm1pZ3JhdGlvbkNvcmUgPSBuZXcgTWlncmF0aW9uQ29yZShkYXRhU291cmNlLCB7XG4gICAgICBtaWdyYXRpb25zRGlyOiBvcHRpb25zLm1pZ3JhdGlvbnNEaXIsXG4gICAgfSk7XG4gICAgdGhpcy5hdXRvUnVuID0gb3B0aW9ucy5hdXRvUnVuID8/IGZhbHNlO1xuICAgIHRoaXMudmVyYm9zZSA9IG9wdGlvbnMudmVyYm9zZSA/PyB0cnVlO1xuICB9XG5cbiAgYXN5bmMgb25Nb2R1bGVJbml0KCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGlmICghdGhpcy5hdXRvUnVuKSB7XG4gICAgICBpZiAodGhpcy52ZXJib3NlKSB7XG4gICAgICAgIGNvbnNvbGUubG9nKCdBdXRvIG1pZ3JhdGlvbnMgYXJlIGRpc2FibGVkJyk7XG4gICAgICB9XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKHRoaXMudmVyYm9zZSkge1xuICAgICAgY29uc29sZS5sb2coJ0F1dG8tcnVubmluZyBtaWdyYXRpb25zLi4uJyk7XG4gICAgfVxuXG4gICAgYXdhaXQgdGhpcy5ydW5NaWdyYXRpb25zKCk7XG4gIH1cblxuICAvKipcbiAgICogUnVuIGFsbCBwZW5kaW5nIG1pZ3JhdGlvbnMuXG4gICAqL1xuICBhc3luYyBydW5NaWdyYXRpb25zKG9wdGlvbnM/OiBNaWdyYXRpb25SdW5PcHRpb25zKTogUHJvbWlzZTxNaWdyYXRpb25SZXN1bHQ+IHtcbiAgICByZXR1cm4gdGhpcy5taWdyYXRpb25Db3JlLnJ1bk1pZ3JhdGlvbnMoe1xuICAgICAgdmVyYm9zZTogdGhpcy52ZXJib3NlLFxuICAgICAgLi4ub3B0aW9ucyxcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgbGlzdCBvZiBwZW5kaW5nIG1pZ3JhdGlvbiBmaWxlcy5cbiAgICovXG4gIGFzeW5jIGdldFBlbmRpbmdNaWdyYXRpb25zKCk6IFByb21pc2U8c3RyaW5nW10+IHtcbiAgICByZXR1cm4gdGhpcy5taWdyYXRpb25Db3JlLmdldFBlbmRpbmdNaWdyYXRpb25zKCk7XG4gIH1cblxuICAvKipcbiAgICogR2V0IG1pZ3JhdGlvbiBzdGF0dXMgaW5mb3JtYXRpb24uXG4gICAqL1xuICBhc3luYyBnZXRTdGF0dXMoKTogUHJvbWlzZTx7XG4gICAgdG90YWw6IG51bWJlcjtcbiAgICBhcHBsaWVkOiBudW1iZXI7XG4gICAgcGVuZGluZzogbnVtYmVyO1xuICAgIHBlbmRpbmdGaWxlczogc3RyaW5nW107XG4gIH0+IHtcbiAgICByZXR1cm4gdGhpcy5taWdyYXRpb25Db3JlLmdldFN0YXR1cygpO1xuICB9XG59XG4iXX0=
@@ -0,0 +1,83 @@
1
+ import { ModuleMetadata, Type } from '@nestjs/common';
2
+ export interface MigrationModuleOptions {
3
+ /**
4
+ * Path to the directory containing SQL migration files
5
+ */
6
+ migrationsDir: string;
7
+ /**
8
+ * Whether to automatically run migrations on module initialization
9
+ * @default false
10
+ */
11
+ autoRun?: boolean;
12
+ /**
13
+ * Whether to log verbose output during migration execution
14
+ * @default true
15
+ */
16
+ verbose?: boolean;
17
+ }
18
+ export interface MigrationModuleAsyncOptions extends Pick<ModuleMetadata, 'imports'> {
19
+ /**
20
+ * Factory function to create MigrationModuleOptions
21
+ */
22
+ useFactory: (...args: any[]) => Promise<MigrationModuleOptions> | MigrationModuleOptions;
23
+ /**
24
+ * Dependencies to inject into the factory function
25
+ */
26
+ inject?: any[];
27
+ /**
28
+ * Optional class to use for creating options
29
+ */
30
+ useClass?: Type<MigrationModuleOptionsFactory>;
31
+ /**
32
+ * Optional existing instance to use for options
33
+ */
34
+ useExisting?: Type<MigrationModuleOptionsFactory>;
35
+ }
36
+ export interface MigrationModuleOptionsFactory {
37
+ createMigrationOptions(): Promise<MigrationModuleOptions> | MigrationModuleOptions;
38
+ }
39
+ export interface MigrationResult {
40
+ /**
41
+ * Whether the migration run was successful
42
+ */
43
+ success: boolean;
44
+ /**
45
+ * Total number of migration files found
46
+ */
47
+ totalMigrations: number;
48
+ /**
49
+ * Number of migrations already applied
50
+ */
51
+ appliedMigrations: number;
52
+ /**
53
+ * Number of pending migrations to apply
54
+ */
55
+ pendingMigrations: number;
56
+ /**
57
+ * Name of the failed migration file (if any)
58
+ */
59
+ failedMigration?: string;
60
+ /**
61
+ * Error object if migration failed
62
+ */
63
+ error?: any;
64
+ }
65
+ export interface MigrationRunOptions {
66
+ /**
67
+ * If true, only list pending migrations without applying them
68
+ * @default false
69
+ */
70
+ dryRun?: boolean;
71
+ /**
72
+ * Whether to log verbose output
73
+ * @default false
74
+ */
75
+ verbose?: boolean;
76
+ }
77
+ export interface MigrationCoreOptions {
78
+ /**
79
+ * Path to the directory containing SQL migration files
80
+ */
81
+ migrationsDir: string;
82
+ }
83
+ export declare const MIGRATION_MODULE_OPTIONS: unique symbol;
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MIGRATION_MODULE_OPTIONS = void 0;
4
+ exports.MIGRATION_MODULE_OPTIONS = Symbol('MIGRATION_MODULE_OPTIONS');
5
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdHlwZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBeUdhLFFBQUEsd0JBQXdCLEdBQUcsTUFBTSxDQUFDLDBCQUEwQixDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBNb2R1bGVNZXRhZGF0YSwgVHlwZSB9IGZyb20gJ0BuZXN0anMvY29tbW9uJztcblxuZXhwb3J0IGludGVyZmFjZSBNaWdyYXRpb25Nb2R1bGVPcHRpb25zIHtcbiAgLyoqXG4gICAqIFBhdGggdG8gdGhlIGRpcmVjdG9yeSBjb250YWluaW5nIFNRTCBtaWdyYXRpb24gZmlsZXNcbiAgICovXG4gIG1pZ3JhdGlvbnNEaXI6IHN0cmluZztcblxuICAvKipcbiAgICogV2hldGhlciB0byBhdXRvbWF0aWNhbGx5IHJ1biBtaWdyYXRpb25zIG9uIG1vZHVsZSBpbml0aWFsaXphdGlvblxuICAgKiBAZGVmYXVsdCBmYWxzZVxuICAgKi9cbiAgYXV0b1J1bj86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgdG8gbG9nIHZlcmJvc2Ugb3V0cHV0IGR1cmluZyBtaWdyYXRpb24gZXhlY3V0aW9uXG4gICAqIEBkZWZhdWx0IHRydWVcbiAgICovXG4gIHZlcmJvc2U/OiBib29sZWFuO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIE1pZ3JhdGlvbk1vZHVsZUFzeW5jT3B0aW9uc1xuICBleHRlbmRzIFBpY2s8TW9kdWxlTWV0YWRhdGEsICdpbXBvcnRzJz4ge1xuICAvKipcbiAgICogRmFjdG9yeSBmdW5jdGlvbiB0byBjcmVhdGUgTWlncmF0aW9uTW9kdWxlT3B0aW9uc1xuICAgKi9cbiAgdXNlRmFjdG9yeTogKFxuICAgIC4uLmFyZ3M6IGFueVtdXG4gICkgPT4gUHJvbWlzZTxNaWdyYXRpb25Nb2R1bGVPcHRpb25zPiB8IE1pZ3JhdGlvbk1vZHVsZU9wdGlvbnM7XG5cbiAgLyoqXG4gICAqIERlcGVuZGVuY2llcyB0byBpbmplY3QgaW50byB0aGUgZmFjdG9yeSBmdW5jdGlvblxuICAgKi9cbiAgaW5qZWN0PzogYW55W107XG5cbiAgLyoqXG4gICAqIE9wdGlvbmFsIGNsYXNzIHRvIHVzZSBmb3IgY3JlYXRpbmcgb3B0aW9uc1xuICAgKi9cbiAgdXNlQ2xhc3M/OiBUeXBlPE1pZ3JhdGlvbk1vZHVsZU9wdGlvbnNGYWN0b3J5PjtcblxuICAvKipcbiAgICogT3B0aW9uYWwgZXhpc3RpbmcgaW5zdGFuY2UgdG8gdXNlIGZvciBvcHRpb25zXG4gICAqL1xuICB1c2VFeGlzdGluZz86IFR5cGU8TWlncmF0aW9uTW9kdWxlT3B0aW9uc0ZhY3Rvcnk+O1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIE1pZ3JhdGlvbk1vZHVsZU9wdGlvbnNGYWN0b3J5IHtcbiAgY3JlYXRlTWlncmF0aW9uT3B0aW9ucygpOlxuICAgIHwgUHJvbWlzZTxNaWdyYXRpb25Nb2R1bGVPcHRpb25zPlxuICAgIHwgTWlncmF0aW9uTW9kdWxlT3B0aW9ucztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBNaWdyYXRpb25SZXN1bHQge1xuICAvKipcbiAgICogV2hldGhlciB0aGUgbWlncmF0aW9uIHJ1biB3YXMgc3VjY2Vzc2Z1bFxuICAgKi9cbiAgc3VjY2VzczogYm9vbGVhbjtcblxuICAvKipcbiAgICogVG90YWwgbnVtYmVyIG9mIG1pZ3JhdGlvbiBmaWxlcyBmb3VuZFxuICAgKi9cbiAgdG90YWxNaWdyYXRpb25zOiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIE51bWJlciBvZiBtaWdyYXRpb25zIGFscmVhZHkgYXBwbGllZFxuICAgKi9cbiAgYXBwbGllZE1pZ3JhdGlvbnM6IG51bWJlcjtcblxuICAvKipcbiAgICogTnVtYmVyIG9mIHBlbmRpbmcgbWlncmF0aW9ucyB0byBhcHBseVxuICAgKi9cbiAgcGVuZGluZ01pZ3JhdGlvbnM6IG51bWJlcjtcblxuICAvKipcbiAgICogTmFtZSBvZiB0aGUgZmFpbGVkIG1pZ3JhdGlvbiBmaWxlIChpZiBhbnkpXG4gICAqL1xuICBmYWlsZWRNaWdyYXRpb24/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIEVycm9yIG9iamVjdCBpZiBtaWdyYXRpb24gZmFpbGVkXG4gICAqL1xuICBlcnJvcj86IGFueTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBNaWdyYXRpb25SdW5PcHRpb25zIHtcbiAgLyoqXG4gICAqIElmIHRydWUsIG9ubHkgbGlzdCBwZW5kaW5nIG1pZ3JhdGlvbnMgd2l0aG91dCBhcHBseWluZyB0aGVtXG4gICAqIEBkZWZhdWx0IGZhbHNlXG4gICAqL1xuICBkcnlSdW4/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRvIGxvZyB2ZXJib3NlIG91dHB1dFxuICAgKiBAZGVmYXVsdCBmYWxzZVxuICAgKi9cbiAgdmVyYm9zZT86IGJvb2xlYW47XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgTWlncmF0aW9uQ29yZU9wdGlvbnMge1xuICAvKipcbiAgICogUGF0aCB0byB0aGUgZGlyZWN0b3J5IGNvbnRhaW5pbmcgU1FMIG1pZ3JhdGlvbiBmaWxlc1xuICAgKi9cbiAgbWlncmF0aW9uc0Rpcjogc3RyaW5nO1xufVxuXG5leHBvcnQgY29uc3QgTUlHUkFUSU9OX01PRFVMRV9PUFRJT05TID0gU3ltYm9sKCdNSUdSQVRJT05fTU9EVUxFX09QVElPTlMnKTtcbiJdfQ==
package/package.json ADDED
@@ -0,0 +1,49 @@
1
+ {
2
+ "name": "@studiosonrai/nestjs-migrations",
3
+ "version": "1.0.0",
4
+ "description": "SQL Server migrations module for NestJS applications",
5
+ "main": "dist/src/index.js",
6
+ "types": "dist/src/index.d.ts",
7
+ "bin": {
8
+ "nestjs-migrations": "./dist/bin/cli.js"
9
+ },
10
+ "files": [
11
+ "dist"
12
+ ],
13
+ "scripts": {
14
+ "build": "rm -rf dist && tsc",
15
+ "prepublishOnly": "npm run build",
16
+ "clean": "rm -rf dist"
17
+ },
18
+ "keywords": [
19
+ "nestjs",
20
+ "migrations",
21
+ "sql-server",
22
+ "mssql",
23
+ "typeorm"
24
+ ],
25
+ "author": "",
26
+ "license": "UNLICENSED",
27
+ "peerDependencies": {
28
+ "@nestjs/common": "^11.0.0",
29
+ "@nestjs/config": "^4.0.0",
30
+ "@nestjs/core": "^11.0.0",
31
+ "typeorm": "^0.3.0"
32
+ },
33
+ "dependencies": {
34
+ "dotenv": "^17.2.1"
35
+ },
36
+ "devDependencies": {
37
+ "@nestjs/common": "^11.0.1",
38
+ "@nestjs/config": "^4.0.2",
39
+ "@nestjs/core": "^11.0.1",
40
+ "@types/node": "^22.10.7",
41
+ "reflect-metadata": "^0.2.2",
42
+ "rxjs": "^7.8.1",
43
+ "typeorm": "^0.3.25",
44
+ "typescript": "^5.7.3"
45
+ },
46
+ "publishConfig": {
47
+ "access": "public"
48
+ }
49
+ }