@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.
Files changed (132) hide show
  1. package/README.MD +268 -134
  2. package/README.md +4 -6
  3. package/bin/cli.mjs +538 -267
  4. package/bin/cli.mjs.map +1 -0
  5. package/changes.json +3 -11
  6. package/dist/index.d.mts +1456 -0
  7. package/dist/index.mjs +3123 -2972
  8. package/dist/index.mjs.map +1 -1
  9. package/package.json +50 -56
  10. package/bin/cli.cjs +0 -275
  11. package/dist/cli/commands/database/create.d.ts +0 -27
  12. package/dist/cli/commands/database/drop.d.ts +0 -23
  13. package/dist/cli/commands/database/index.d.ts +0 -2
  14. package/dist/cli/commands/index.d.ts +0 -2
  15. package/dist/cli/commands/seed/create.d.ts +0 -21
  16. package/dist/cli/commands/seed/index.d.ts +0 -2
  17. package/dist/cli/commands/seed/run.d.ts +0 -24
  18. package/dist/cli/index.d.ts +0 -2
  19. package/dist/data-source/find/index.d.ts +0 -2
  20. package/dist/data-source/find/module.d.ts +0 -3
  21. package/dist/data-source/find/type.d.ts +0 -22
  22. package/dist/data-source/index.d.ts +0 -4
  23. package/dist/data-source/options/index.d.ts +0 -4
  24. package/dist/data-source/options/module.d.ts +0 -8
  25. package/dist/data-source/options/singleton.d.ts +0 -4
  26. package/dist/data-source/options/type.d.ts +0 -26
  27. package/dist/data-source/options/utils/env.d.ts +0 -4
  28. package/dist/data-source/options/utils/index.d.ts +0 -2
  29. package/dist/data-source/options/utils/merge.d.ts +0 -2
  30. package/dist/data-source/singleton.d.ts +0 -5
  31. package/dist/data-source/type.d.ts +0 -2
  32. package/dist/database/driver/cockroachdb.d.ts +0 -4
  33. package/dist/database/driver/index.d.ts +0 -9
  34. package/dist/database/driver/mongodb.d.ts +0 -6
  35. package/dist/database/driver/mssql.d.ts +0 -6
  36. package/dist/database/driver/mysql.d.ts +0 -7
  37. package/dist/database/driver/oracle.d.ts +0 -6
  38. package/dist/database/driver/postgres.d.ts +0 -8
  39. package/dist/database/driver/sqlite.d.ts +0 -3
  40. package/dist/database/driver/types.d.ts +0 -20
  41. package/dist/database/driver/utils/build.d.ts +0 -3
  42. package/dist/database/driver/utils/character-set.d.ts +0 -2
  43. package/dist/database/driver/utils/charset.d.ts +0 -2
  44. package/dist/database/driver/utils/create.d.ts +0 -2
  45. package/dist/database/driver/utils/index.d.ts +0 -4
  46. package/dist/database/index.d.ts +0 -3
  47. package/dist/database/methods/check/index.d.ts +0 -2
  48. package/dist/database/methods/check/module.d.ts +0 -7
  49. package/dist/database/methods/check/types.d.ts +0 -51
  50. package/dist/database/methods/create/index.d.ts +0 -1
  51. package/dist/database/methods/create/module.d.ts +0 -10
  52. package/dist/database/methods/drop/index.d.ts +0 -1
  53. package/dist/database/methods/drop/module.d.ts +0 -10
  54. package/dist/database/methods/index.d.ts +0 -4
  55. package/dist/database/methods/type.d.ts +0 -43
  56. package/dist/database/utils/context.d.ts +0 -3
  57. package/dist/database/utils/index.d.ts +0 -5
  58. package/dist/database/utils/migration.d.ts +0 -2
  59. package/dist/database/utils/query.d.ts +0 -3
  60. package/dist/database/utils/schema.d.ts +0 -3
  61. package/dist/database/utils/type.d.ts +0 -32
  62. package/dist/env/constants.d.ts +0 -68
  63. package/dist/env/index.d.ts +0 -3
  64. package/dist/env/module.d.ts +0 -4
  65. package/dist/env/type.d.ts +0 -36
  66. package/dist/env/utils.d.ts +0 -3
  67. package/dist/errors/base.d.ts +0 -2
  68. package/dist/errors/driver.d.ts +0 -6
  69. package/dist/errors/index.d.ts +0 -3
  70. package/dist/errors/options.d.ts +0 -7
  71. package/dist/helpers/entity/error.d.ts +0 -20
  72. package/dist/helpers/entity/index.d.ts +0 -5
  73. package/dist/helpers/entity/join-columns.d.ts +0 -16
  74. package/dist/helpers/entity/metadata.d.ts +0 -10
  75. package/dist/helpers/entity/property-names.d.ts +0 -11
  76. package/dist/helpers/entity/uniqueness.d.ts +0 -28
  77. package/dist/helpers/index.d.ts +0 -1
  78. package/dist/index.cjs +0 -3258
  79. package/dist/index.cjs.map +0 -1
  80. package/dist/index.d.ts +0 -9
  81. package/dist/query/index.d.ts +0 -4
  82. package/dist/query/module.d.ts +0 -5
  83. package/dist/query/parameter/fields/index.d.ts +0 -2
  84. package/dist/query/parameter/fields/module.d.ts +0 -25
  85. package/dist/query/parameter/fields/type.d.ts +0 -6
  86. package/dist/query/parameter/filters/index.d.ts +0 -2
  87. package/dist/query/parameter/filters/module.d.ts +0 -35
  88. package/dist/query/parameter/filters/type.d.ts +0 -12
  89. package/dist/query/parameter/index.d.ts +0 -5
  90. package/dist/query/parameter/pagination/index.d.ts +0 -2
  91. package/dist/query/parameter/pagination/module.d.ts +0 -26
  92. package/dist/query/parameter/pagination/type.d.ts +0 -3
  93. package/dist/query/parameter/relations/index.d.ts +0 -2
  94. package/dist/query/parameter/relations/module.d.ts +0 -27
  95. package/dist/query/parameter/relations/type.d.ts +0 -8
  96. package/dist/query/parameter/sort/index.d.ts +0 -2
  97. package/dist/query/parameter/sort/module.d.ts +0 -26
  98. package/dist/query/parameter/sort/type.d.ts +0 -6
  99. package/dist/query/type.d.ts +0 -16
  100. package/dist/query/utils/alias.d.ts +0 -2
  101. package/dist/query/utils/index.d.ts +0 -3
  102. package/dist/query/utils/key.d.ts +0 -1
  103. package/dist/query/utils/option.d.ts +0 -1
  104. package/dist/seeder/entity.d.ts +0 -42
  105. package/dist/seeder/executor.d.ts +0 -24
  106. package/dist/seeder/factory/index.d.ts +0 -4
  107. package/dist/seeder/factory/manager.d.ts +0 -8
  108. package/dist/seeder/factory/module.d.ts +0 -17
  109. package/dist/seeder/factory/type.d.ts +0 -12
  110. package/dist/seeder/factory/utils.d.ts +0 -7
  111. package/dist/seeder/index.d.ts +0 -6
  112. package/dist/seeder/module.d.ts +0 -5
  113. package/dist/seeder/type.d.ts +0 -44
  114. package/dist/seeder/utils/file-path.d.ts +0 -7
  115. package/dist/seeder/utils/index.d.ts +0 -3
  116. package/dist/seeder/utils/prepare.d.ts +0 -2
  117. package/dist/seeder/utils/template.d.ts +0 -1
  118. package/dist/utils/code-transformation/constants.d.ts +0 -4
  119. package/dist/utils/code-transformation/index.d.ts +0 -2
  120. package/dist/utils/code-transformation/module.d.ts +0 -3
  121. package/dist/utils/entity.d.ts +0 -2
  122. package/dist/utils/file-path.d.ts +0 -9
  123. package/dist/utils/file-system.d.ts +0 -1
  124. package/dist/utils/has-property.d.ts +0 -2
  125. package/dist/utils/index.d.ts +0 -10
  126. package/dist/utils/object.d.ts +0 -2
  127. package/dist/utils/promise.d.ts +0 -1
  128. package/dist/utils/separator.d.ts +0 -3
  129. package/dist/utils/slash.d.ts +0 -2
  130. package/dist/utils/tsconfig/index.d.ts +0 -2
  131. package/dist/utils/tsconfig/module.d.ts +0 -2
  132. 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 'reflect-metadata';
3
- import process$1 from 'node:process';
4
- import yargs from 'yargs';
5
- import { hideBin } from 'yargs/helpers';
6
- import { consola } from 'consola';
7
- import { resolveFilePath, readTSConfig, adjustFilePath, parseFilePath, buildDataSourceOptions, createDatabase, dropDatabase, isDirectory, buildSeederFileTemplate, setDataSourceOptions, useDataSource, SeederExecutor } from 'typeorm-extension';
8
- import { getFileNameExtension, removeFileNameExtension } from 'locter';
9
- import fs from 'node:fs';
10
- import path from 'node:path';
11
- import { pascalCase } from 'pascal-case';
12
-
13
- class DatabaseCreateCommand {
14
- builder(args) {
15
- return args.option('preserveFilePaths', {
16
- default: false,
17
- type: 'boolean',
18
- describe: 'This option indicates if file paths should be preserved.'
19
- }).option('root', {
20
- alias: 'r',
21
- default: process.cwd(),
22
- describe: 'Root directory of the project.'
23
- }).option('tsconfig', {
24
- alias: 'tc',
25
- default: 'tsconfig.json',
26
- describe: 'Name (or relative path incl. name) of the tsconfig file.'
27
- }).option('dataSource', {
28
- alias: 'd',
29
- default: 'data-source',
30
- describe: 'Name (or relative path incl. name) of the data-source file.'
31
- }).option('synchronize', {
32
- alias: 's',
33
- default: 'yes',
34
- describe: 'Create database schema for all entities.',
35
- choices: [
36
- 'yes',
37
- 'no'
38
- ]
39
- }).option('initialDatabase', {
40
- describe: 'Specify the initial database to connect to.'
41
- });
42
- }
43
- async handler(raw) {
44
- const args = raw;
45
- let tsconfig;
46
- let sourcePath = resolveFilePath(args.dataSource, args.root);
47
- if (!args.preserveFilePaths) {
48
- tsconfig = await readTSConfig(resolveFilePath(args.root, args.tsconfig));
49
- sourcePath = await adjustFilePath(sourcePath, tsconfig);
50
- }
51
- const source = parseFilePath(sourcePath);
52
- consola.info(`DataSource Directory: ${source.directory}`);
53
- consola.info(`DataSource Name: ${source.name}`);
54
- const dataSourceOptions = await buildDataSourceOptions({
55
- directory: source.directory,
56
- dataSourceName: source.name,
57
- tsconfig,
58
- preserveFilePaths: args.preserveFilePaths
59
- });
60
- const context = {
61
- ifNotExist: true,
62
- options: dataSourceOptions,
63
- synchronize: args.synchronize === 'yes'
64
- };
65
- if (typeof args.initialDatabase === 'string' && args.initialDatabase !== '') {
66
- context.initialDatabase = args.initialDatabase;
67
- }
68
- try {
69
- await createDatabase(context);
70
- consola.success('Created database.');
71
- process.exit(0);
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
- class DatabaseDropCommand {
85
- builder(args) {
86
- return args.option('preserveFilePaths', {
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
- class SeedCreateCommand {
147
- builder(args) {
148
- return args.option('root', {
149
- alias: 'r',
150
- default: process.cwd(),
151
- describe: 'Root directory of the project.'
152
- }).option('timestamp', {
153
- alias: 't',
154
- type: 'number',
155
- describe: 'Custom timestamp for the seeder name.'
156
- }).option('javascript', {
157
- alias: 'j',
158
- type: 'boolean',
159
- default: false,
160
- describe: 'Generate a seeder file for JavaScript instead of TypeScript.'
161
- }).option('name', {
162
- alias: 'n',
163
- describe: 'Name (or relative path incl. name) of the seeder.',
164
- demandOption: true
165
- });
166
- }
167
- async handler(raw) {
168
- const args = raw;
169
- let timestamp;
170
- if (Number.isNaN(args.timestamp) || !args.timestamp) {
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
- class SeedRunCommand {
212
- builder(args) {
213
- return args.option('preserveFilePaths', {
214
- default: false,
215
- type: 'boolean',
216
- describe: 'This option indicates if file paths should be preserved.'
217
- }).option('root', {
218
- alias: 'r',
219
- default: process.cwd(),
220
- describe: 'Root directory of the project.'
221
- }).option('tsconfig', {
222
- alias: 'tc',
223
- default: 'tsconfig.json',
224
- describe: 'Name (or relative path incl. name) of the tsconfig file.'
225
- }).option('dataSource', {
226
- alias: 'd',
227
- default: 'data-source',
228
- describe: 'Name (or relative path incl. name) of the data-source file.'
229
- }).option('name', {
230
- alias: 'n',
231
- describe: 'Name (or relative path incl. name) of the seeder.'
232
- });
233
- }
234
- async handler(raw) {
235
- const args = raw;
236
- let tsconfig;
237
- let sourcePath = resolveFilePath(args.dataSource, args.root);
238
- if (!args.preserveFilePaths) {
239
- tsconfig = await readTSConfig(args.root);
240
- sourcePath = await adjustFilePath(sourcePath, tsconfig);
241
- args.name = await adjustFilePath(args.name, tsconfig);
242
- }
243
- const source = parseFilePath(sourcePath);
244
- consola.info(`DataSource Directory: ${source.directory}`);
245
- consola.info(`DataSource Name: ${source.name}`);
246
- const dataSourceOptions = await buildDataSourceOptions({
247
- dataSourceName: source.name,
248
- directory: source.directory,
249
- tsconfig,
250
- preserveFilePaths: args.preserveFilePaths
251
- });
252
- setDataSourceOptions(dataSourceOptions);
253
- if (args.name) {
254
- consola.info(`Seed Name: ${args.name}`);
255
- }
256
- const dataSource = await useDataSource();
257
- const executor = new SeederExecutor(dataSource, {
258
- root: args.root,
259
- tsconfig,
260
- preserveFilePaths: args.preserveFilePaths
261
- });
262
- await executor.execute({
263
- seedName: args.name
264
- });
265
- process.exit(0);
266
- }
267
- constructor(){
268
- this.command = 'seed:run';
269
- this.describe = 'Populate the database with an initial data set or generated data by a factory.';
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
- yargs(hideBin(process$1.argv)).scriptName('typeorm-extension').usage('Usage: $0 <command> [options]').demandCommand(1).command(new DatabaseCreateCommand()).command(new DatabaseDropCommand()).command(new SeedRunCommand()).command(new SeedCreateCommand()).strict().alias('v', 'version').help('h').alias('h', 'help').parse();
544
+ //# sourceMappingURL=cli.mjs.map