@depup/typeorm-extension 3.9.0-depup.0 → 4.0.0-depup.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.MD +268 -134
- package/README.md +4 -6
- package/bin/cli.mjs +538 -267
- package/bin/cli.mjs.map +1 -0
- package/changes.json +3 -11
- package/dist/index.d.mts +1456 -0
- package/dist/index.mjs +3123 -2972
- package/dist/index.mjs.map +1 -1
- package/package.json +50 -56
- package/bin/cli.cjs +0 -275
- package/dist/cli/commands/database/create.d.ts +0 -27
- package/dist/cli/commands/database/drop.d.ts +0 -23
- package/dist/cli/commands/database/index.d.ts +0 -2
- package/dist/cli/commands/index.d.ts +0 -2
- package/dist/cli/commands/seed/create.d.ts +0 -21
- package/dist/cli/commands/seed/index.d.ts +0 -2
- package/dist/cli/commands/seed/run.d.ts +0 -24
- package/dist/cli/index.d.ts +0 -2
- package/dist/data-source/find/index.d.ts +0 -2
- package/dist/data-source/find/module.d.ts +0 -3
- package/dist/data-source/find/type.d.ts +0 -22
- package/dist/data-source/index.d.ts +0 -4
- package/dist/data-source/options/index.d.ts +0 -4
- package/dist/data-source/options/module.d.ts +0 -8
- package/dist/data-source/options/singleton.d.ts +0 -4
- package/dist/data-source/options/type.d.ts +0 -26
- package/dist/data-source/options/utils/env.d.ts +0 -4
- package/dist/data-source/options/utils/index.d.ts +0 -2
- package/dist/data-source/options/utils/merge.d.ts +0 -2
- package/dist/data-source/singleton.d.ts +0 -5
- package/dist/data-source/type.d.ts +0 -2
- package/dist/database/driver/cockroachdb.d.ts +0 -4
- package/dist/database/driver/index.d.ts +0 -9
- package/dist/database/driver/mongodb.d.ts +0 -6
- package/dist/database/driver/mssql.d.ts +0 -6
- package/dist/database/driver/mysql.d.ts +0 -7
- package/dist/database/driver/oracle.d.ts +0 -6
- package/dist/database/driver/postgres.d.ts +0 -8
- package/dist/database/driver/sqlite.d.ts +0 -3
- package/dist/database/driver/types.d.ts +0 -20
- package/dist/database/driver/utils/build.d.ts +0 -3
- package/dist/database/driver/utils/character-set.d.ts +0 -2
- package/dist/database/driver/utils/charset.d.ts +0 -2
- package/dist/database/driver/utils/create.d.ts +0 -2
- package/dist/database/driver/utils/index.d.ts +0 -4
- package/dist/database/index.d.ts +0 -3
- package/dist/database/methods/check/index.d.ts +0 -2
- package/dist/database/methods/check/module.d.ts +0 -7
- package/dist/database/methods/check/types.d.ts +0 -51
- package/dist/database/methods/create/index.d.ts +0 -1
- package/dist/database/methods/create/module.d.ts +0 -10
- package/dist/database/methods/drop/index.d.ts +0 -1
- package/dist/database/methods/drop/module.d.ts +0 -10
- package/dist/database/methods/index.d.ts +0 -4
- package/dist/database/methods/type.d.ts +0 -43
- package/dist/database/utils/context.d.ts +0 -3
- package/dist/database/utils/index.d.ts +0 -5
- package/dist/database/utils/migration.d.ts +0 -2
- package/dist/database/utils/query.d.ts +0 -3
- package/dist/database/utils/schema.d.ts +0 -3
- package/dist/database/utils/type.d.ts +0 -32
- package/dist/env/constants.d.ts +0 -68
- package/dist/env/index.d.ts +0 -3
- package/dist/env/module.d.ts +0 -4
- package/dist/env/type.d.ts +0 -36
- package/dist/env/utils.d.ts +0 -3
- package/dist/errors/base.d.ts +0 -2
- package/dist/errors/driver.d.ts +0 -6
- package/dist/errors/index.d.ts +0 -3
- package/dist/errors/options.d.ts +0 -7
- package/dist/helpers/entity/error.d.ts +0 -20
- package/dist/helpers/entity/index.d.ts +0 -5
- package/dist/helpers/entity/join-columns.d.ts +0 -16
- package/dist/helpers/entity/metadata.d.ts +0 -10
- package/dist/helpers/entity/property-names.d.ts +0 -11
- package/dist/helpers/entity/uniqueness.d.ts +0 -28
- package/dist/helpers/index.d.ts +0 -1
- package/dist/index.cjs +0 -3258
- package/dist/index.cjs.map +0 -1
- package/dist/index.d.ts +0 -9
- package/dist/query/index.d.ts +0 -4
- package/dist/query/module.d.ts +0 -5
- package/dist/query/parameter/fields/index.d.ts +0 -2
- package/dist/query/parameter/fields/module.d.ts +0 -25
- package/dist/query/parameter/fields/type.d.ts +0 -6
- package/dist/query/parameter/filters/index.d.ts +0 -2
- package/dist/query/parameter/filters/module.d.ts +0 -35
- package/dist/query/parameter/filters/type.d.ts +0 -12
- package/dist/query/parameter/index.d.ts +0 -5
- package/dist/query/parameter/pagination/index.d.ts +0 -2
- package/dist/query/parameter/pagination/module.d.ts +0 -26
- package/dist/query/parameter/pagination/type.d.ts +0 -3
- package/dist/query/parameter/relations/index.d.ts +0 -2
- package/dist/query/parameter/relations/module.d.ts +0 -27
- package/dist/query/parameter/relations/type.d.ts +0 -8
- package/dist/query/parameter/sort/index.d.ts +0 -2
- package/dist/query/parameter/sort/module.d.ts +0 -26
- package/dist/query/parameter/sort/type.d.ts +0 -6
- package/dist/query/type.d.ts +0 -16
- package/dist/query/utils/alias.d.ts +0 -2
- package/dist/query/utils/index.d.ts +0 -3
- package/dist/query/utils/key.d.ts +0 -1
- package/dist/query/utils/option.d.ts +0 -1
- package/dist/seeder/entity.d.ts +0 -42
- package/dist/seeder/executor.d.ts +0 -24
- package/dist/seeder/factory/index.d.ts +0 -4
- package/dist/seeder/factory/manager.d.ts +0 -8
- package/dist/seeder/factory/module.d.ts +0 -17
- package/dist/seeder/factory/type.d.ts +0 -12
- package/dist/seeder/factory/utils.d.ts +0 -7
- package/dist/seeder/index.d.ts +0 -6
- package/dist/seeder/module.d.ts +0 -5
- package/dist/seeder/type.d.ts +0 -44
- package/dist/seeder/utils/file-path.d.ts +0 -7
- package/dist/seeder/utils/index.d.ts +0 -3
- package/dist/seeder/utils/prepare.d.ts +0 -2
- package/dist/seeder/utils/template.d.ts +0 -1
- package/dist/utils/code-transformation/constants.d.ts +0 -4
- package/dist/utils/code-transformation/index.d.ts +0 -2
- package/dist/utils/code-transformation/module.d.ts +0 -3
- package/dist/utils/entity.d.ts +0 -2
- package/dist/utils/file-path.d.ts +0 -9
- package/dist/utils/file-system.d.ts +0 -1
- package/dist/utils/has-property.d.ts +0 -2
- package/dist/utils/index.d.ts +0 -10
- package/dist/utils/object.d.ts +0 -2
- package/dist/utils/promise.d.ts +0 -1
- package/dist/utils/separator.d.ts +0 -3
- package/dist/utils/slash.d.ts +0 -2
- package/dist/utils/tsconfig/index.d.ts +0 -2
- package/dist/utils/tsconfig/module.d.ts +0 -2
- package/dist/utils/tsconfig/type.d.ts +0 -13
package/bin/cli.mjs
CHANGED
|
@@ -1,273 +1,544 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import
|
|
8
|
-
import
|
|
9
|
-
import
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
} catch (e) {
|
|
73
|
-
consola.warn('Failed to create database.');
|
|
74
|
-
consola.error(e);
|
|
75
|
-
process.exit(1);
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
constructor(){
|
|
79
|
-
this.command = 'db:create';
|
|
80
|
-
this.describe = 'Create database.';
|
|
81
|
-
}
|
|
2
|
+
import "reflect-metadata";
|
|
3
|
+
import { defineCommand, runMain } from "citty";
|
|
4
|
+
import process from "node:process";
|
|
5
|
+
import { PathResolverMode, SeederExecutor, buildDataSourceOptions, buildSeederFileName, buildSeederFileTemplate, createDatabase, createPathResolver, dropDatabase, getSchemaDrift, isDirectory, parseFilePath, setDataSourceOptions, useDataSource } from "typeorm-extension";
|
|
6
|
+
import { removeFileNameExtension } from "locter";
|
|
7
|
+
import fs from "node:fs";
|
|
8
|
+
import path from "node:path";
|
|
9
|
+
import { pascalCase } from "pascal-case";
|
|
10
|
+
//#region src/cli/logger.ts
|
|
11
|
+
const LogLevel = {
|
|
12
|
+
Silent: "silent",
|
|
13
|
+
Info: "info",
|
|
14
|
+
Debug: "debug"
|
|
15
|
+
};
|
|
16
|
+
const LOG_LEVEL_VALUES = Object.values(LogLevel);
|
|
17
|
+
const RANK = {
|
|
18
|
+
[LogLevel.Silent]: 0,
|
|
19
|
+
[LogLevel.Info]: 1,
|
|
20
|
+
[LogLevel.Debug]: 2
|
|
21
|
+
};
|
|
22
|
+
const RESET = "\x1B[0m";
|
|
23
|
+
const BOLD = "\x1B[1m";
|
|
24
|
+
const DIM = "\x1B[2m";
|
|
25
|
+
const RED = "\x1B[31m";
|
|
26
|
+
const GREEN = "\x1B[32m";
|
|
27
|
+
const YELLOW = "\x1B[33m";
|
|
28
|
+
const BLUE = "\x1B[34m";
|
|
29
|
+
const CYAN = "\x1B[36m";
|
|
30
|
+
const ICON_INFO = "ℹ";
|
|
31
|
+
const ICON_SUCCESS = "✔";
|
|
32
|
+
const ICON_WARN = "⚠";
|
|
33
|
+
const ICON_ERROR = "✖";
|
|
34
|
+
const ICON_DEBUG = "›";
|
|
35
|
+
function createLogger(level = LogLevel.Info) {
|
|
36
|
+
const enabled = (target) => RANK[level] >= RANK[target];
|
|
37
|
+
const tty = process.stderr.isTTY;
|
|
38
|
+
const tint = (code, text) => tty ? `${code}${text}${RESET}` : text;
|
|
39
|
+
const write = (line) => process.stderr.write(`${line}\n`);
|
|
40
|
+
return {
|
|
41
|
+
info: (msg) => {
|
|
42
|
+
if (enabled(LogLevel.Info)) write(`${tint(CYAN, ICON_INFO)} ${msg}`);
|
|
43
|
+
},
|
|
44
|
+
success: (msg) => {
|
|
45
|
+
if (enabled(LogLevel.Info)) write(`${tint(GREEN, ICON_SUCCESS)} ${msg}`);
|
|
46
|
+
},
|
|
47
|
+
warn: (msg) => {
|
|
48
|
+
if (enabled(LogLevel.Info)) write(`${tint(YELLOW, ICON_WARN)} ${msg}`);
|
|
49
|
+
},
|
|
50
|
+
error: (msg) => {
|
|
51
|
+
write(`${tint(RED, ICON_ERROR)} ${msg}`);
|
|
52
|
+
},
|
|
53
|
+
debug: (msg) => {
|
|
54
|
+
if (enabled(LogLevel.Debug)) write(`${tint(DIM, `${ICON_DEBUG} ${msg}`)}`);
|
|
55
|
+
},
|
|
56
|
+
section: (title) => {
|
|
57
|
+
if (enabled(LogLevel.Info)) {
|
|
58
|
+
write("");
|
|
59
|
+
write(tint(`${BOLD}${BLUE}`, title));
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
kv: (key, value, padTo = 0) => {
|
|
63
|
+
if (enabled(LogLevel.Info)) {
|
|
64
|
+
const pad = " ".repeat(Math.max(0, padTo - key.length));
|
|
65
|
+
write(` ${tint(DIM, key)}${pad} ${value}`);
|
|
66
|
+
}
|
|
67
|
+
},
|
|
68
|
+
blank: () => {
|
|
69
|
+
if (enabled(LogLevel.Info)) write("");
|
|
70
|
+
}
|
|
71
|
+
};
|
|
82
72
|
}
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
default: false,
|
|
88
|
-
type: 'boolean',
|
|
89
|
-
describe: 'This option indicates if file paths should be preserved.'
|
|
90
|
-
}).option('root', {
|
|
91
|
-
alias: 'r',
|
|
92
|
-
default: process.cwd(),
|
|
93
|
-
describe: 'Root directory of the project.'
|
|
94
|
-
}).option('tsconfig', {
|
|
95
|
-
alias: 'tc',
|
|
96
|
-
default: 'tsconfig.json',
|
|
97
|
-
describe: 'Name (or relative path incl. name) of the tsconfig file.'
|
|
98
|
-
}).option('dataSource', {
|
|
99
|
-
alias: 'd',
|
|
100
|
-
default: 'data-source',
|
|
101
|
-
describe: 'Name (or relative path incl. name) of the data-source file.'
|
|
102
|
-
}).option('initialDatabase', {
|
|
103
|
-
describe: 'Specify the initial database to connect to.'
|
|
104
|
-
});
|
|
105
|
-
}
|
|
106
|
-
async handler(raw) {
|
|
107
|
-
const args = raw;
|
|
108
|
-
let tsconfig;
|
|
109
|
-
let sourcePath = resolveFilePath(args.dataSource, args.root);
|
|
110
|
-
if (!args.preserveFilePaths) {
|
|
111
|
-
tsconfig = await readTSConfig(resolveFilePath(args.root, args.tsconfig));
|
|
112
|
-
sourcePath = await adjustFilePath(sourcePath, tsconfig);
|
|
113
|
-
}
|
|
114
|
-
const source = parseFilePath(sourcePath);
|
|
115
|
-
consola.info(`DataSource Directory: ${source.directory}`);
|
|
116
|
-
consola.info(`DataSource Name: ${source.name}`);
|
|
117
|
-
const dataSourceOptions = await buildDataSourceOptions({
|
|
118
|
-
directory: source.directory,
|
|
119
|
-
dataSourceName: source.name,
|
|
120
|
-
tsconfig,
|
|
121
|
-
preserveFilePaths: args.preserveFilePaths
|
|
122
|
-
});
|
|
123
|
-
const context = {
|
|
124
|
-
ifExist: true,
|
|
125
|
-
options: dataSourceOptions
|
|
126
|
-
};
|
|
127
|
-
if (typeof args.initialDatabase === 'string' && args.initialDatabase !== '') {
|
|
128
|
-
context.initialDatabase = args.initialDatabase;
|
|
129
|
-
}
|
|
130
|
-
try {
|
|
131
|
-
await dropDatabase(context);
|
|
132
|
-
consola.success('Dropped database.');
|
|
133
|
-
process.exit(0);
|
|
134
|
-
} catch (e) {
|
|
135
|
-
consola.warn('Failed to drop database.');
|
|
136
|
-
consola.error(e);
|
|
137
|
-
process.exit(1);
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
constructor(){
|
|
141
|
-
this.command = 'db:drop';
|
|
142
|
-
this.describe = 'Drop database.';
|
|
143
|
-
}
|
|
73
|
+
function normalizeLogLevel(input) {
|
|
74
|
+
if (!input) return LogLevel.Info;
|
|
75
|
+
if (LOG_LEVEL_VALUES.includes(input)) return input;
|
|
76
|
+
throw new CLIUserError(`Unknown log level "${input}". Supported: ${LOG_LEVEL_VALUES.join(", ")}.`);
|
|
144
77
|
}
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
timestamp = Date.now();
|
|
172
|
-
} else {
|
|
173
|
-
timestamp = args.timestamp;
|
|
174
|
-
}
|
|
175
|
-
const sourcePath = parseFilePath(args.name, args.root);
|
|
176
|
-
const dirNameIsDirectory = await isDirectory(sourcePath.directory);
|
|
177
|
-
if (!dirNameIsDirectory) {
|
|
178
|
-
consola.warn(`The output directory ${sourcePath.directory} does not exist.`);
|
|
179
|
-
process.exit(1);
|
|
180
|
-
}
|
|
181
|
-
const extension = args.javascript ? '.js' : '.ts';
|
|
182
|
-
const nameExtension = getFileNameExtension(sourcePath.name);
|
|
183
|
-
const nameWithoutExtension = removeFileNameExtension(sourcePath.name);
|
|
184
|
-
let fileName;
|
|
185
|
-
if (nameExtension) {
|
|
186
|
-
fileName = `${timestamp}-${sourcePath.name}`;
|
|
187
|
-
} else {
|
|
188
|
-
fileName = `${timestamp}-${sourcePath.name}${extension}`;
|
|
189
|
-
}
|
|
190
|
-
const filePath = sourcePath.directory + path.sep + fileName;
|
|
191
|
-
const template = buildSeederFileTemplate(nameWithoutExtension, timestamp);
|
|
192
|
-
consola.info(`Seed Directory: ${sourcePath.directory}`);
|
|
193
|
-
consola.info(`Seed FileName: ${fileName}`);
|
|
194
|
-
consola.info(`Seed Name: ${pascalCase(nameWithoutExtension)}`);
|
|
195
|
-
try {
|
|
196
|
-
await fs.promises.writeFile(filePath, template, {
|
|
197
|
-
encoding: 'utf-8'
|
|
198
|
-
});
|
|
199
|
-
} catch (e) {
|
|
200
|
-
consola.warn(`The seed could not be written to the path ${filePath}.`);
|
|
201
|
-
process.exit(1);
|
|
202
|
-
}
|
|
203
|
-
process.exit(0);
|
|
204
|
-
}
|
|
205
|
-
constructor(){
|
|
206
|
-
this.command = 'seed:create';
|
|
207
|
-
this.describe = 'Create a seeder file.';
|
|
208
|
-
}
|
|
78
|
+
var CLIUserError = class extends Error {
|
|
79
|
+
constructor(message) {
|
|
80
|
+
super(message);
|
|
81
|
+
this.name = "CLIUserError";
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
//#endregion
|
|
85
|
+
//#region src/cli/exit.ts
|
|
86
|
+
const ExitCode = {
|
|
87
|
+
Success: 0,
|
|
88
|
+
UserError: 1,
|
|
89
|
+
InternalError: 2
|
|
90
|
+
};
|
|
91
|
+
async function runWithExitCode(logger, fn) {
|
|
92
|
+
try {
|
|
93
|
+
await fn();
|
|
94
|
+
process.exit(ExitCode.Success);
|
|
95
|
+
} catch (err) {
|
|
96
|
+
if (err instanceof CLIUserError) {
|
|
97
|
+
logger.error(err.message);
|
|
98
|
+
process.exit(ExitCode.UserError);
|
|
99
|
+
}
|
|
100
|
+
if (err instanceof Error) logger.error(err.stack ?? err.message);
|
|
101
|
+
else logger.error(String(err));
|
|
102
|
+
process.exit(ExitCode.InternalError);
|
|
103
|
+
}
|
|
209
104
|
}
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
105
|
+
//#endregion
|
|
106
|
+
//#region src/cli/commands/database/create.ts
|
|
107
|
+
function defineCLIDatabaseCreateCommand() {
|
|
108
|
+
return defineCommand({
|
|
109
|
+
meta: {
|
|
110
|
+
name: "create",
|
|
111
|
+
description: "Create database."
|
|
112
|
+
},
|
|
113
|
+
args: {
|
|
114
|
+
preserveFilePaths: {
|
|
115
|
+
type: "boolean",
|
|
116
|
+
default: false,
|
|
117
|
+
description: "This option indicates if file paths should be preserved."
|
|
118
|
+
},
|
|
119
|
+
root: {
|
|
120
|
+
type: "string",
|
|
121
|
+
alias: "r",
|
|
122
|
+
default: process.cwd(),
|
|
123
|
+
description: "Root directory of the project."
|
|
124
|
+
},
|
|
125
|
+
tsconfig: {
|
|
126
|
+
type: "string",
|
|
127
|
+
alias: "tc",
|
|
128
|
+
default: "tsconfig.json",
|
|
129
|
+
description: "Name (or relative path incl. name) of the tsconfig file."
|
|
130
|
+
},
|
|
131
|
+
dataSource: {
|
|
132
|
+
type: "string",
|
|
133
|
+
alias: "d",
|
|
134
|
+
default: "data-source",
|
|
135
|
+
description: "Name (or relative path incl. name) of the data-source file."
|
|
136
|
+
},
|
|
137
|
+
synchronize: {
|
|
138
|
+
type: "enum",
|
|
139
|
+
alias: "s",
|
|
140
|
+
default: "yes",
|
|
141
|
+
options: ["yes", "no"],
|
|
142
|
+
description: "Create database schema for all entities."
|
|
143
|
+
},
|
|
144
|
+
initialDatabase: {
|
|
145
|
+
type: "string",
|
|
146
|
+
description: "Specify the initial database to connect to."
|
|
147
|
+
},
|
|
148
|
+
"log-level": {
|
|
149
|
+
type: "string",
|
|
150
|
+
description: "Logger verbosity.",
|
|
151
|
+
valueHint: LOG_LEVEL_VALUES.join("|"),
|
|
152
|
+
options: LOG_LEVEL_VALUES
|
|
153
|
+
}
|
|
154
|
+
},
|
|
155
|
+
async run({ args }) {
|
|
156
|
+
const logger = createLogger(normalizeLogLevel(args["log-level"]));
|
|
157
|
+
await runWithExitCode(logger, async () => {
|
|
158
|
+
logger.info("Creating database");
|
|
159
|
+
const pathResolver = createPathResolver({
|
|
160
|
+
root: args.root,
|
|
161
|
+
tsconfig: args.tsconfig,
|
|
162
|
+
mode: args.preserveFilePaths ? PathResolverMode.PRESERVE : PathResolverMode.AUTO
|
|
163
|
+
});
|
|
164
|
+
const source = parseFilePath(await pathResolver.resolve(args.dataSource));
|
|
165
|
+
logger.section("DataSource");
|
|
166
|
+
const pad = 9;
|
|
167
|
+
logger.kv("directory", source.directory, pad);
|
|
168
|
+
logger.kv("name", source.name, pad);
|
|
169
|
+
const context = {
|
|
170
|
+
ifNotExist: true,
|
|
171
|
+
options: await buildDataSourceOptions({
|
|
172
|
+
directory: source.directory,
|
|
173
|
+
dataSourceName: source.name,
|
|
174
|
+
tsconfig: await pathResolver.tsconfig(),
|
|
175
|
+
preserveFilePaths: args.preserveFilePaths
|
|
176
|
+
}),
|
|
177
|
+
synchronize: args.synchronize === "yes"
|
|
178
|
+
};
|
|
179
|
+
if (typeof args.initialDatabase === "string" && args.initialDatabase !== "") context.initialDatabase = args.initialDatabase;
|
|
180
|
+
logger.blank();
|
|
181
|
+
await createDatabase(context);
|
|
182
|
+
logger.success("Created database.");
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
//#endregion
|
|
188
|
+
//#region src/cli/commands/database/drift.ts
|
|
189
|
+
function defineCLIDatabaseDriftCommand() {
|
|
190
|
+
return defineCommand({
|
|
191
|
+
meta: {
|
|
192
|
+
name: "drift",
|
|
193
|
+
description: "Assert that the database schema matches the entity metadata."
|
|
194
|
+
},
|
|
195
|
+
args: {
|
|
196
|
+
preserveFilePaths: {
|
|
197
|
+
type: "boolean",
|
|
198
|
+
default: false,
|
|
199
|
+
description: "This option indicates if file paths should be preserved."
|
|
200
|
+
},
|
|
201
|
+
root: {
|
|
202
|
+
type: "string",
|
|
203
|
+
alias: "r",
|
|
204
|
+
default: process.cwd(),
|
|
205
|
+
description: "Root directory of the project."
|
|
206
|
+
},
|
|
207
|
+
tsconfig: {
|
|
208
|
+
type: "string",
|
|
209
|
+
alias: "tc",
|
|
210
|
+
default: "tsconfig.json",
|
|
211
|
+
description: "Name (or relative path incl. name) of the tsconfig file."
|
|
212
|
+
},
|
|
213
|
+
dataSource: {
|
|
214
|
+
type: "string",
|
|
215
|
+
alias: "d",
|
|
216
|
+
default: "data-source",
|
|
217
|
+
description: "Name (or relative path incl. name) of the data-source file."
|
|
218
|
+
},
|
|
219
|
+
skipWithoutMigrations: {
|
|
220
|
+
type: "boolean",
|
|
221
|
+
default: false,
|
|
222
|
+
description: "Report no drift if the data-source has no migrations registered."
|
|
223
|
+
},
|
|
224
|
+
"log-level": {
|
|
225
|
+
type: "string",
|
|
226
|
+
description: "Logger verbosity.",
|
|
227
|
+
valueHint: LOG_LEVEL_VALUES.join("|"),
|
|
228
|
+
options: LOG_LEVEL_VALUES
|
|
229
|
+
}
|
|
230
|
+
},
|
|
231
|
+
async run({ args }) {
|
|
232
|
+
const logger = createLogger(normalizeLogLevel(args["log-level"]));
|
|
233
|
+
await runWithExitCode(logger, async () => {
|
|
234
|
+
logger.info("Checking schema drift");
|
|
235
|
+
const pathResolver = createPathResolver({
|
|
236
|
+
root: args.root,
|
|
237
|
+
tsconfig: args.tsconfig,
|
|
238
|
+
mode: args.preserveFilePaths ? PathResolverMode.PRESERVE : PathResolverMode.AUTO
|
|
239
|
+
});
|
|
240
|
+
const source = parseFilePath(await pathResolver.resolve(args.dataSource));
|
|
241
|
+
logger.section("DataSource");
|
|
242
|
+
const pad = 9;
|
|
243
|
+
logger.kv("directory", source.directory, pad);
|
|
244
|
+
logger.kv("name", source.name, pad);
|
|
245
|
+
const dataSourceOptions = await buildDataSourceOptions({
|
|
246
|
+
directory: source.directory,
|
|
247
|
+
dataSourceName: source.name,
|
|
248
|
+
tsconfig: await pathResolver.tsconfig(),
|
|
249
|
+
preserveFilePaths: args.preserveFilePaths
|
|
250
|
+
});
|
|
251
|
+
logger.blank();
|
|
252
|
+
const drift = await getSchemaDrift(dataSourceOptions, { skipWithoutMigrations: args.skipWithoutMigrations });
|
|
253
|
+
if (!drift.exists) {
|
|
254
|
+
logger.success("No schema drift detected.");
|
|
255
|
+
return;
|
|
256
|
+
}
|
|
257
|
+
logger.section("Statements");
|
|
258
|
+
for (let i = 0; i < drift.up.length; i++) {
|
|
259
|
+
const statement = drift.up[i];
|
|
260
|
+
logger.warn(statement.parameters && statement.parameters.length > 0 ? `${statement.query} -- ${JSON.stringify(statement.parameters)}` : statement.query);
|
|
261
|
+
}
|
|
262
|
+
logger.blank();
|
|
263
|
+
throw new CLIUserError(`The database schema deviates from the entity metadata (${drift.up.length} statement(s) required to reconcile it).`);
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
//#endregion
|
|
269
|
+
//#region src/cli/commands/database/drop.ts
|
|
270
|
+
function defineCLIDatabaseDropCommand() {
|
|
271
|
+
return defineCommand({
|
|
272
|
+
meta: {
|
|
273
|
+
name: "drop",
|
|
274
|
+
description: "Drop database."
|
|
275
|
+
},
|
|
276
|
+
args: {
|
|
277
|
+
preserveFilePaths: {
|
|
278
|
+
type: "boolean",
|
|
279
|
+
default: false,
|
|
280
|
+
description: "This option indicates if file paths should be preserved."
|
|
281
|
+
},
|
|
282
|
+
root: {
|
|
283
|
+
type: "string",
|
|
284
|
+
alias: "r",
|
|
285
|
+
default: process.cwd(),
|
|
286
|
+
description: "Root directory of the project."
|
|
287
|
+
},
|
|
288
|
+
tsconfig: {
|
|
289
|
+
type: "string",
|
|
290
|
+
alias: "tc",
|
|
291
|
+
default: "tsconfig.json",
|
|
292
|
+
description: "Name (or relative path incl. name) of the tsconfig file."
|
|
293
|
+
},
|
|
294
|
+
dataSource: {
|
|
295
|
+
type: "string",
|
|
296
|
+
alias: "d",
|
|
297
|
+
default: "data-source",
|
|
298
|
+
description: "Name (or relative path incl. name) of the data-source file."
|
|
299
|
+
},
|
|
300
|
+
initialDatabase: {
|
|
301
|
+
type: "string",
|
|
302
|
+
description: "Specify the initial database to connect to."
|
|
303
|
+
},
|
|
304
|
+
"log-level": {
|
|
305
|
+
type: "string",
|
|
306
|
+
description: "Logger verbosity.",
|
|
307
|
+
valueHint: LOG_LEVEL_VALUES.join("|"),
|
|
308
|
+
options: LOG_LEVEL_VALUES
|
|
309
|
+
}
|
|
310
|
+
},
|
|
311
|
+
async run({ args }) {
|
|
312
|
+
const logger = createLogger(normalizeLogLevel(args["log-level"]));
|
|
313
|
+
await runWithExitCode(logger, async () => {
|
|
314
|
+
logger.info("Dropping database");
|
|
315
|
+
const pathResolver = createPathResolver({
|
|
316
|
+
root: args.root,
|
|
317
|
+
tsconfig: args.tsconfig,
|
|
318
|
+
mode: args.preserveFilePaths ? PathResolverMode.PRESERVE : PathResolverMode.AUTO
|
|
319
|
+
});
|
|
320
|
+
const source = parseFilePath(await pathResolver.resolve(args.dataSource));
|
|
321
|
+
logger.section("DataSource");
|
|
322
|
+
const pad = 9;
|
|
323
|
+
logger.kv("directory", source.directory, pad);
|
|
324
|
+
logger.kv("name", source.name, pad);
|
|
325
|
+
const context = {
|
|
326
|
+
ifExist: true,
|
|
327
|
+
options: await buildDataSourceOptions({
|
|
328
|
+
directory: source.directory,
|
|
329
|
+
dataSourceName: source.name,
|
|
330
|
+
tsconfig: await pathResolver.tsconfig(),
|
|
331
|
+
preserveFilePaths: args.preserveFilePaths
|
|
332
|
+
})
|
|
333
|
+
};
|
|
334
|
+
if (typeof args.initialDatabase === "string" && args.initialDatabase !== "") context.initialDatabase = args.initialDatabase;
|
|
335
|
+
logger.blank();
|
|
336
|
+
await dropDatabase(context);
|
|
337
|
+
logger.success("Dropped database.");
|
|
338
|
+
});
|
|
339
|
+
}
|
|
340
|
+
});
|
|
341
|
+
}
|
|
342
|
+
//#endregion
|
|
343
|
+
//#region src/cli/commands/database/index.ts
|
|
344
|
+
function defineCLIDatabaseCommand() {
|
|
345
|
+
return defineCommand({
|
|
346
|
+
meta: {
|
|
347
|
+
name: "db",
|
|
348
|
+
description: "Database operations."
|
|
349
|
+
},
|
|
350
|
+
subCommands: {
|
|
351
|
+
create: defineCLIDatabaseCreateCommand(),
|
|
352
|
+
drift: defineCLIDatabaseDriftCommand(),
|
|
353
|
+
drop: defineCLIDatabaseDropCommand()
|
|
354
|
+
}
|
|
355
|
+
});
|
|
356
|
+
}
|
|
357
|
+
//#endregion
|
|
358
|
+
//#region src/cli/commands/seed/create.ts
|
|
359
|
+
function defineCLISeedCreateCommand() {
|
|
360
|
+
return defineCommand({
|
|
361
|
+
meta: {
|
|
362
|
+
name: "create",
|
|
363
|
+
description: "Create a seeder file."
|
|
364
|
+
},
|
|
365
|
+
args: {
|
|
366
|
+
root: {
|
|
367
|
+
type: "string",
|
|
368
|
+
alias: "r",
|
|
369
|
+
default: process.cwd(),
|
|
370
|
+
description: "Root directory of the project."
|
|
371
|
+
},
|
|
372
|
+
timestamp: {
|
|
373
|
+
type: "string",
|
|
374
|
+
alias: "t",
|
|
375
|
+
description: "Custom timestamp for the seeder name."
|
|
376
|
+
},
|
|
377
|
+
javascript: {
|
|
378
|
+
type: "boolean",
|
|
379
|
+
alias: "j",
|
|
380
|
+
default: false,
|
|
381
|
+
description: "Generate a seeder file for JavaScript instead of TypeScript."
|
|
382
|
+
},
|
|
383
|
+
name: {
|
|
384
|
+
type: "string",
|
|
385
|
+
alias: "n",
|
|
386
|
+
required: true,
|
|
387
|
+
description: "Name (or relative path incl. name) of the seeder."
|
|
388
|
+
},
|
|
389
|
+
"log-level": {
|
|
390
|
+
type: "string",
|
|
391
|
+
description: "Logger verbosity.",
|
|
392
|
+
valueHint: LOG_LEVEL_VALUES.join("|"),
|
|
393
|
+
options: LOG_LEVEL_VALUES
|
|
394
|
+
}
|
|
395
|
+
},
|
|
396
|
+
async run({ args }) {
|
|
397
|
+
const logger = createLogger(normalizeLogLevel(args["log-level"]));
|
|
398
|
+
await runWithExitCode(logger, async () => {
|
|
399
|
+
logger.info("Creating seeder file");
|
|
400
|
+
const parsedTimestamp = typeof args.timestamp === "string" ? Number.parseInt(args.timestamp, 10) : NaN;
|
|
401
|
+
const timestamp = Number.isNaN(parsedTimestamp) ? Date.now() : parsedTimestamp;
|
|
402
|
+
const sourcePath = parseFilePath(args.name, args.root);
|
|
403
|
+
if (!await isDirectory(sourcePath.directory)) throw new CLIUserError(`The output directory ${sourcePath.directory} does not exist.`);
|
|
404
|
+
const nameWithoutExtension = removeFileNameExtension(sourcePath.name);
|
|
405
|
+
const fileName = buildSeederFileName(sourcePath.name, timestamp, { javascript: args.javascript });
|
|
406
|
+
const filePath = path.join(sourcePath.directory, fileName);
|
|
407
|
+
const template = buildSeederFileTemplate(nameWithoutExtension, timestamp);
|
|
408
|
+
logger.section("Seed");
|
|
409
|
+
const pad = 9;
|
|
410
|
+
logger.kv("directory", sourcePath.directory, pad);
|
|
411
|
+
logger.kv("fileName", fileName, pad);
|
|
412
|
+
logger.kv("name", pascalCase(nameWithoutExtension), pad);
|
|
413
|
+
try {
|
|
414
|
+
await fs.promises.writeFile(filePath, template, { encoding: "utf-8" });
|
|
415
|
+
} catch {
|
|
416
|
+
throw new CLIUserError(`The seed could not be written to the path ${filePath}.`);
|
|
417
|
+
}
|
|
418
|
+
logger.blank();
|
|
419
|
+
logger.success("Created seeder file.");
|
|
420
|
+
});
|
|
421
|
+
}
|
|
422
|
+
});
|
|
423
|
+
}
|
|
424
|
+
//#endregion
|
|
425
|
+
//#region src/cli/commands/seed/run.ts
|
|
426
|
+
function defineCLISeedRunCommand() {
|
|
427
|
+
return defineCommand({
|
|
428
|
+
meta: {
|
|
429
|
+
name: "run",
|
|
430
|
+
description: "Populate the database with an initial data set or generated data by a factory."
|
|
431
|
+
},
|
|
432
|
+
args: {
|
|
433
|
+
preserveFilePaths: {
|
|
434
|
+
type: "boolean",
|
|
435
|
+
default: false,
|
|
436
|
+
description: "This option indicates if file paths should be preserved."
|
|
437
|
+
},
|
|
438
|
+
root: {
|
|
439
|
+
type: "string",
|
|
440
|
+
alias: "r",
|
|
441
|
+
default: process.cwd(),
|
|
442
|
+
description: "Root directory of the project."
|
|
443
|
+
},
|
|
444
|
+
tsconfig: {
|
|
445
|
+
type: "string",
|
|
446
|
+
alias: "tc",
|
|
447
|
+
default: "tsconfig.json",
|
|
448
|
+
description: "Name (or relative path incl. name) of the tsconfig file."
|
|
449
|
+
},
|
|
450
|
+
dataSource: {
|
|
451
|
+
type: "string",
|
|
452
|
+
alias: "d",
|
|
453
|
+
default: "data-source",
|
|
454
|
+
description: "Name (or relative path incl. name) of the data-source file."
|
|
455
|
+
},
|
|
456
|
+
name: {
|
|
457
|
+
type: "string",
|
|
458
|
+
alias: "n",
|
|
459
|
+
description: "Name (or relative path incl. name) of the seeder."
|
|
460
|
+
},
|
|
461
|
+
"log-level": {
|
|
462
|
+
type: "string",
|
|
463
|
+
description: "Logger verbosity.",
|
|
464
|
+
valueHint: LOG_LEVEL_VALUES.join("|"),
|
|
465
|
+
options: LOG_LEVEL_VALUES
|
|
466
|
+
}
|
|
467
|
+
},
|
|
468
|
+
async run({ args }) {
|
|
469
|
+
const logger = createLogger(normalizeLogLevel(args["log-level"]));
|
|
470
|
+
await runWithExitCode(logger, async () => {
|
|
471
|
+
logger.info("Running seeders");
|
|
472
|
+
const pathResolver = createPathResolver({
|
|
473
|
+
root: args.root,
|
|
474
|
+
tsconfig: args.tsconfig,
|
|
475
|
+
mode: args.preserveFilePaths ? PathResolverMode.PRESERVE : PathResolverMode.AUTO
|
|
476
|
+
});
|
|
477
|
+
let { name } = args;
|
|
478
|
+
if (name) name = await pathResolver.transform(name);
|
|
479
|
+
const source = parseFilePath(await pathResolver.resolve(args.dataSource));
|
|
480
|
+
logger.section("DataSource");
|
|
481
|
+
const dsPad = 9;
|
|
482
|
+
logger.kv("directory", source.directory, dsPad);
|
|
483
|
+
logger.kv("name", source.name, dsPad);
|
|
484
|
+
setDataSourceOptions(await buildDataSourceOptions({
|
|
485
|
+
dataSourceName: source.name,
|
|
486
|
+
directory: source.directory,
|
|
487
|
+
tsconfig: await pathResolver.tsconfig(),
|
|
488
|
+
preserveFilePaths: args.preserveFilePaths
|
|
489
|
+
}));
|
|
490
|
+
if (name) {
|
|
491
|
+
logger.section("Seed");
|
|
492
|
+
logger.kv("name", name, 4);
|
|
493
|
+
}
|
|
494
|
+
const executor = new SeederExecutor(await useDataSource(), {
|
|
495
|
+
root: args.root,
|
|
496
|
+
tsconfig: await pathResolver.tsconfig(),
|
|
497
|
+
preserveFilePaths: args.preserveFilePaths
|
|
498
|
+
});
|
|
499
|
+
logger.blank();
|
|
500
|
+
await executor.execute({ seedName: name });
|
|
501
|
+
logger.success("Executed seeders.");
|
|
502
|
+
});
|
|
503
|
+
}
|
|
504
|
+
});
|
|
505
|
+
}
|
|
506
|
+
//#endregion
|
|
507
|
+
//#region src/cli/commands/seed/index.ts
|
|
508
|
+
function defineCLISeedCommand() {
|
|
509
|
+
return defineCommand({
|
|
510
|
+
meta: {
|
|
511
|
+
name: "seed",
|
|
512
|
+
description: "Seeder operations."
|
|
513
|
+
},
|
|
514
|
+
subCommands: {
|
|
515
|
+
create: defineCLISeedCreateCommand(),
|
|
516
|
+
run: defineCLISeedRunCommand()
|
|
517
|
+
}
|
|
518
|
+
});
|
|
519
|
+
}
|
|
520
|
+
//#endregion
|
|
521
|
+
//#region src/cli/module.ts
|
|
522
|
+
function createCLIEntryPointCommand() {
|
|
523
|
+
return defineCommand({
|
|
524
|
+
meta: {
|
|
525
|
+
name: "typeorm-extension",
|
|
526
|
+
description: "CLI for typeorm-extension."
|
|
527
|
+
},
|
|
528
|
+
subCommands: {
|
|
529
|
+
db: defineCLIDatabaseCommand(),
|
|
530
|
+
seed: defineCLISeedCommand(),
|
|
531
|
+
"db:create": defineCLIDatabaseCreateCommand(),
|
|
532
|
+
"db:drop": defineCLIDatabaseDropCommand(),
|
|
533
|
+
"seed:create": defineCLISeedCreateCommand(),
|
|
534
|
+
"seed:run": defineCLISeedRunCommand()
|
|
535
|
+
}
|
|
536
|
+
});
|
|
271
537
|
}
|
|
538
|
+
//#endregion
|
|
539
|
+
//#region src/cli/index.ts
|
|
540
|
+
runMain(createCLIEntryPointCommand());
|
|
541
|
+
//#endregion
|
|
542
|
+
export {};
|
|
272
543
|
|
|
273
|
-
|
|
544
|
+
//# sourceMappingURL=cli.mjs.map
|