@spinajs/orm-cli 2.0.487

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 (70) hide show
  1. package/README.md +247 -0
  2. package/lib/cjs/cli/MigrateCreate.d.ts +59 -0
  3. package/lib/cjs/cli/MigrateCreate.d.ts.map +1 -0
  4. package/lib/cjs/cli/MigrateCreate.js +211 -0
  5. package/lib/cjs/cli/MigrateCreate.js.map +1 -0
  6. package/lib/cjs/cli/MigrateDown.d.ts +23 -0
  7. package/lib/cjs/cli/MigrateDown.d.ts.map +1 -0
  8. package/lib/cjs/cli/MigrateDown.js +74 -0
  9. package/lib/cjs/cli/MigrateDown.js.map +1 -0
  10. package/lib/cjs/cli/MigrateResolve.d.ts +19 -0
  11. package/lib/cjs/cli/MigrateResolve.d.ts.map +1 -0
  12. package/lib/cjs/cli/MigrateResolve.js +66 -0
  13. package/lib/cjs/cli/MigrateResolve.js.map +1 -0
  14. package/lib/cjs/cli/MigrateStatus.d.ts +19 -0
  15. package/lib/cjs/cli/MigrateStatus.d.ts.map +1 -0
  16. package/lib/cjs/cli/MigrateStatus.js +109 -0
  17. package/lib/cjs/cli/MigrateStatus.js.map +1 -0
  18. package/lib/cjs/cli/MigrateUp.d.ts +33 -0
  19. package/lib/cjs/cli/MigrateUp.d.ts.map +1 -0
  20. package/lib/cjs/cli/MigrateUp.js +92 -0
  21. package/lib/cjs/cli/MigrateUp.js.map +1 -0
  22. package/lib/cjs/config/orm-cli.d.ts +9 -0
  23. package/lib/cjs/config/orm-cli.d.ts.map +1 -0
  24. package/lib/cjs/config/orm-cli.js +26 -0
  25. package/lib/cjs/config/orm-cli.js.map +1 -0
  26. package/lib/cjs/index.d.ts +18 -0
  27. package/lib/cjs/index.d.ts.map +1 -0
  28. package/lib/cjs/index.js +34 -0
  29. package/lib/cjs/index.js.map +1 -0
  30. package/lib/cjs/orm.d.ts +31 -0
  31. package/lib/cjs/orm.d.ts.map +1 -0
  32. package/lib/cjs/orm.js +38 -0
  33. package/lib/cjs/orm.js.map +1 -0
  34. package/lib/cjs/package.json +1 -0
  35. package/lib/mjs/cli/MigrateCreate.d.ts +59 -0
  36. package/lib/mjs/cli/MigrateCreate.d.ts.map +1 -0
  37. package/lib/mjs/cli/MigrateCreate.js +173 -0
  38. package/lib/mjs/cli/MigrateCreate.js.map +1 -0
  39. package/lib/mjs/cli/MigrateDown.d.ts +23 -0
  40. package/lib/mjs/cli/MigrateDown.d.ts.map +1 -0
  41. package/lib/mjs/cli/MigrateDown.js +71 -0
  42. package/lib/mjs/cli/MigrateDown.js.map +1 -0
  43. package/lib/mjs/cli/MigrateResolve.d.ts +19 -0
  44. package/lib/mjs/cli/MigrateResolve.d.ts.map +1 -0
  45. package/lib/mjs/cli/MigrateResolve.js +63 -0
  46. package/lib/mjs/cli/MigrateResolve.js.map +1 -0
  47. package/lib/mjs/cli/MigrateStatus.d.ts +19 -0
  48. package/lib/mjs/cli/MigrateStatus.d.ts.map +1 -0
  49. package/lib/mjs/cli/MigrateStatus.js +106 -0
  50. package/lib/mjs/cli/MigrateStatus.js.map +1 -0
  51. package/lib/mjs/cli/MigrateUp.d.ts +33 -0
  52. package/lib/mjs/cli/MigrateUp.d.ts.map +1 -0
  53. package/lib/mjs/cli/MigrateUp.js +89 -0
  54. package/lib/mjs/cli/MigrateUp.js.map +1 -0
  55. package/lib/mjs/config/orm-cli.d.ts +9 -0
  56. package/lib/mjs/config/orm-cli.d.ts.map +1 -0
  57. package/lib/mjs/config/orm-cli.js +24 -0
  58. package/lib/mjs/config/orm-cli.js.map +1 -0
  59. package/lib/mjs/index.d.ts +18 -0
  60. package/lib/mjs/index.d.ts.map +1 -0
  61. package/lib/mjs/index.js +18 -0
  62. package/lib/mjs/index.js.map +1 -0
  63. package/lib/mjs/orm.d.ts +31 -0
  64. package/lib/mjs/orm.d.ts.map +1 -0
  65. package/lib/mjs/orm.js +34 -0
  66. package/lib/mjs/orm.js.map +1 -0
  67. package/lib/mjs/package.json +1 -0
  68. package/lib/tsconfig.cjs.tsbuildinfo +1 -0
  69. package/lib/tsconfig.mjs.tsbuildinfo +1 -0
  70. package/package.json +68 -0
@@ -0,0 +1,59 @@
1
+ import { CliCommand } from '@spinajs/cli';
2
+ import { Log } from '@spinajs/log-common';
3
+ export interface IMigrateCreateCommandOptions {
4
+ name: string;
5
+ dir?: string;
6
+ connection?: string;
7
+ env?: string;
8
+ }
9
+ /**
10
+ * The prefix half of `Prefix_yyyy_MM_dd_HH_mm_ss`. Deliberately narrower than what a TS class
11
+ * name allows: underscores and digits are how the runner finds the timestamp - `MIGRATION_FILE_REGEXP`
12
+ * splits on the LAST `_yyyy_MM_dd_HH_mm_ss`-shaped run - so a prefix that carries its own
13
+ * underscore-digit groups is a name nobody can read back with confidence.
14
+ */
15
+ export declare const MIGRATION_NAME_REGEXP: RegExp;
16
+ /**
17
+ * The connection name is interpolated into `@Migration('...')`, so anything that could close that
18
+ * string literal has to be refused here rather than emitted into a file that will not parse.
19
+ */
20
+ export declare const CONNECTION_NAME_REGEXP: RegExp;
21
+ /**
22
+ * The env tag becomes a dot-segment in the file name AND a string literal inside `@Migration()`,
23
+ * so it may carry neither a dot ( which would read as a second tag ) nor anything that could close
24
+ * that literal.
25
+ */
26
+ export declare const ENV_NAME_REGEXP: RegExp;
27
+ /**
28
+ * Reads `--env` directly off `process.argv`, deliberately more flexible than `Configuration`'s own
29
+ * `parseArgv` ( `packages/configuration/src/util.ts` - not exported from that package's public surface,
30
+ * so this logic is duplicated rather than imported ).
31
+ *
32
+ * `parseArgv` handles only the space-separated form ( `--env local` ), but this helper also accepts
33
+ * the equals form ( `--env=local` ). This is correct here: `packages/cli/src/args.ts` strips both
34
+ * forms from commander's argv, because `Configuration` consumes the framework-level `--env` directly.
35
+ * With `--env=local`, the value is stripped but `Configuration`'s `parseArgv` cannot recognize the
36
+ * equals form, so the CLI process boots under the default environment while the scaffolded file gets
37
+ * its `.local` suffix — harmless for this command, which uses the value only as a filename tag and
38
+ * a decorator string. `-e` is untouched by the strip and reaches commander normally, so it needs no
39
+ * duplicate handling here.
40
+ */
41
+ export declare function parseEnvArgv(argv?: string[]): string | undefined;
42
+ export declare const DEFAULT_MIGRATION_DIR = "./src/migrations";
43
+ export declare const DEFAULT_MIGRATION_CONNECTION = "default";
44
+ /**
45
+ * The scaffold. `connection` is named ( rather than `_connection` ) in both hooks because both
46
+ * bodies are meant to be filled in immediately - and the eslint pragma on the first line is the
47
+ * repo's own convention for a migration whose `down()` legitimately ignores it.
48
+ */
49
+ export declare function migrationTemplate(cls: string, connection: string, env?: string): string;
50
+ /**
51
+ * The one command here that needs no database and no Orm: it writes a file. Keeping it free of
52
+ * `DI.resolve(Orm)` means a developer can scaffold a migration in a checkout whose connections
53
+ * are not configured, or not reachable, which is exactly when new migrations get written.
54
+ */
55
+ export declare class MigrateCreateCommand extends CliCommand {
56
+ protected Log: Log;
57
+ execute(options: IMigrateCreateCommandOptions): Promise<void>;
58
+ }
59
+ //# sourceMappingURL=MigrateCreate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MigrateCreate.d.ts","sourceRoot":"","sources":["../../../src/cli/MigrateCreate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAmB,MAAM,cAAc,CAAC;AAE3D,OAAO,EAAE,GAAG,EAAU,MAAM,qBAAqB,CAAC;AAKlD,MAAM,WAAW,4BAA4B;IAC3C,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,QAA2B,CAAC;AAE9D;;;GAGG;AACH,eAAO,MAAM,sBAAsB,QAAiC,CAAC;AAErE;;;;GAIG;AACH,eAAO,MAAM,eAAe,QAA4B,CAAC;AAYzD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,YAAY,CAAC,IAAI,GAAE,MAAM,EAAiB,GAAG,MAAM,GAAG,SAAS,CAc9E;AAED,eAAO,MAAM,qBAAqB,qBAAqB,CAAC;AAExD,eAAO,MAAM,4BAA4B,YAAY,CAAC;AAEtD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CA0BvF;AAED;;;;GAIG;AACH,qBAKa,oBAAqB,SAAQ,UAAU;IAElD,SAAS,CAAC,GAAG,EAAE,GAAG,CAAC;IAEN,OAAO,CAAC,OAAO,EAAE,4BAA4B,GAAG,OAAO,CAAC,IAAI,CAAC;CA6D3E"}
@@ -0,0 +1,173 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ 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;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ var __metadata = (this && this.__metadata) || function (k, v) {
8
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
+ };
10
+ import { CliCommand, Command, Option } from '@spinajs/cli';
11
+ import { InvalidArgument, IOFail } from '@spinajs/exceptions';
12
+ import { Log, Logger } from '@spinajs/log-common';
13
+ import { DateTime } from 'luxon';
14
+ import * as fs from 'node:fs';
15
+ import * as path from 'node:path';
16
+ /**
17
+ * The prefix half of `Prefix_yyyy_MM_dd_HH_mm_ss`. Deliberately narrower than what a TS class
18
+ * name allows: underscores and digits are how the runner finds the timestamp - `MIGRATION_FILE_REGEXP`
19
+ * splits on the LAST `_yyyy_MM_dd_HH_mm_ss`-shaped run - so a prefix that carries its own
20
+ * underscore-digit groups is a name nobody can read back with confidence.
21
+ */
22
+ export const MIGRATION_NAME_REGEXP = /^[A-Za-z][A-Za-z0-9]*$/;
23
+ /**
24
+ * The connection name is interpolated into `@Migration('...')`, so anything that could close that
25
+ * string literal has to be refused here rather than emitted into a file that will not parse.
26
+ */
27
+ export const CONNECTION_NAME_REGEXP = /^[A-Za-z0-9][A-Za-z0-9_.-]*$/;
28
+ /**
29
+ * The env tag becomes a dot-segment in the file name AND a string literal inside `@Migration()`,
30
+ * so it may carry neither a dot ( which would read as a second tag ) nor anything that could close
31
+ * that literal.
32
+ */
33
+ export const ENV_NAME_REGEXP = /^[A-Za-z][A-Za-z0-9-]*$/;
34
+ /**
35
+ * The three middle segments `parseMigrationFileEnv` provably cannot read back as an environment
36
+ * tag - they are carved out by name there ( a test suite named after its migration, a TypeScript
37
+ * declaration file ), not because they collide with a real tag but because a `<Name>.<tag>.ts` file
38
+ * whose tag is one of these is never read as tagged at all. `--env test` would therefore write a
39
+ * file whose suffix channel is silently dead - and one many projects' `**\/*.test.ts` globs would
40
+ * try to execute as a test suite besides. Refused here rather than left to surprise someone later.
41
+ */
42
+ const RESERVED_ENV_NAMES = ['test', 'spec', 'd'];
43
+ /**
44
+ * Reads `--env` directly off `process.argv`, deliberately more flexible than `Configuration`'s own
45
+ * `parseArgv` ( `packages/configuration/src/util.ts` - not exported from that package's public surface,
46
+ * so this logic is duplicated rather than imported ).
47
+ *
48
+ * `parseArgv` handles only the space-separated form ( `--env local` ), but this helper also accepts
49
+ * the equals form ( `--env=local` ). This is correct here: `packages/cli/src/args.ts` strips both
50
+ * forms from commander's argv, because `Configuration` consumes the framework-level `--env` directly.
51
+ * With `--env=local`, the value is stripped but `Configuration`'s `parseArgv` cannot recognize the
52
+ * equals form, so the CLI process boots under the default environment while the scaffolded file gets
53
+ * its `.local` suffix — harmless for this command, which uses the value only as a filename tag and
54
+ * a decorator string. `-e` is untouched by the strip and reaches commander normally, so it needs no
55
+ * duplicate handling here.
56
+ */
57
+ export function parseEnvArgv(argv = process.argv) {
58
+ for (let i = 0; i < argv.length; i++) {
59
+ const arg = argv[i];
60
+ if (arg === '--env') {
61
+ return argv[i + 1];
62
+ }
63
+ if (arg.startsWith('--env=')) {
64
+ return arg.slice('--env='.length);
65
+ }
66
+ }
67
+ return undefined;
68
+ }
69
+ export const DEFAULT_MIGRATION_DIR = './src/migrations';
70
+ export const DEFAULT_MIGRATION_CONNECTION = 'default';
71
+ /**
72
+ * The scaffold. `connection` is named ( rather than `_connection` ) in both hooks because both
73
+ * bodies are meant to be filled in immediately - and the eslint pragma on the first line is the
74
+ * repo's own convention for a migration whose `down()` legitimately ignores it.
75
+ */
76
+ export function migrationTemplate(cls, connection, env) {
77
+ return `/* eslint-disable @typescript-eslint/no-unused-vars */
78
+ import { Migration, OrmDriver, OrmMigration } from '@spinajs/orm';
79
+
80
+ /**
81
+ * TODO: describe the schema change this migration makes.
82
+ */
83
+ @Migration('${connection}'${env ? `, { Env: '${env}' }` : ''})
84
+ export class ${cls} extends OrmMigration {
85
+ /**
86
+ * Schema changes. Models are NOT wired up yet at this point - reach the database through
87
+ * \`connection\`, never through a model class.
88
+ */
89
+ public async up(connection: OrmDriver): Promise<void> {
90
+ // TODO: await connection.schema().createTable('table_name', (table) => { ... });
91
+ }
92
+
93
+ /**
94
+ * Undoes \`up()\`. Leave it empty only when the change genuinely cannot be reversed - an empty
95
+ * \`down()\` makes migrate-down report success while changing nothing.
96
+ */
97
+ public async down(connection: OrmDriver): Promise<void> {
98
+ // TODO: await connection.schema().dropTable('table_name');
99
+ }
100
+ }
101
+ `;
102
+ }
103
+ /**
104
+ * The one command here that needs no database and no Orm: it writes a file. Keeping it free of
105
+ * `DI.resolve(Orm)` means a developer can scaffold a migration in a checkout whose connections
106
+ * are not configured, or not reachable, which is exactly when new migrations get written.
107
+ */
108
+ let MigrateCreateCommand = class MigrateCreateCommand extends CliCommand {
109
+ async execute(options) {
110
+ const name = options.name ?? '';
111
+ const connection = options.connection ?? DEFAULT_MIGRATION_CONNECTION;
112
+ // An explicit `options.env` wins - that is how the tests in this suite call `execute()`
113
+ // directly - and falls back to a direct argv read for the real CLI path, where
114
+ // `packages/cli/src/args.ts` has already stripped `--env <value>` out of what commander sees.
115
+ // See `parseEnvArgv()`.
116
+ const env = options.env ?? parseEnvArgv();
117
+ if (!MIGRATION_NAME_REGEXP.test(name)) {
118
+ throw new InvalidArgument(`Invalid migration name "${name}" - it must be a plain class-name prefix: a letter followed by letters or digits, no spaces, dashes or underscores. The _yyyy_MM_dd_HH_mm_ss suffix is appended here.`);
119
+ }
120
+ if (!CONNECTION_NAME_REGEXP.test(connection)) {
121
+ throw new InvalidArgument(`Invalid connection name "${connection}" - expected the name of a connection from db.Connections, eg. "default"`);
122
+ }
123
+ if (env !== undefined) {
124
+ if (!ENV_NAME_REGEXP.test(env)) {
125
+ throw new InvalidArgument(`Invalid environment name "${env}" - a letter followed by letters, digits or dashes. It becomes both a file suffix and a string inside @Migration().`);
126
+ }
127
+ if (RESERVED_ENV_NAMES.includes(env)) {
128
+ throw new InvalidArgument(`Invalid environment name "${env}" - "test", "spec" and "d" are carved out by the migration file parser as file-kind markers (a test suite, a TypeScript declaration file), never read back as an environment tag. Choose a different name.`);
129
+ }
130
+ }
131
+ // The timestamp is not decoration: it is the ONLY ordering the migration runner has, and it is
132
+ // read back out of the class name rather than out of the file's mtime or its position on disk.
133
+ const cls = `${name}_${DateTime.now().toFormat('yyyy_MM_dd_HH_mm_ss')}`;
134
+ const dir = options.dir ?? DEFAULT_MIGRATION_DIR;
135
+ const file = path.join(dir, `${cls}${env ? `.${env}` : ''}.ts`);
136
+ fs.mkdirSync(dir, { recursive: true });
137
+ try {
138
+ // 'wx' - never clobber. Two `migrate-create` runs inside the same second produce the same
139
+ // class name, and silently overwriting the first one would delete work that was just written.
140
+ fs.writeFileSync(file, migrationTemplate(cls, connection, env), { flag: 'wx', encoding: 'utf-8' });
141
+ }
142
+ catch (err) {
143
+ if (err.code === 'EEXIST') {
144
+ throw new IOFail(`Migration file ${file} already exists - a migration with this name was created in the same second. Wait a second and run it again, or pass a different --name.`, err);
145
+ }
146
+ throw err;
147
+ }
148
+ // The path goes to stdout on its own line so `$(spinajs migrate-create -n Foo)` is usable;
149
+ // everything else is guidance and belongs in the log.
150
+ // eslint-disable-next-line no-console
151
+ console.log(file);
152
+ // The scan is about the APPLICATION's own directories ( `system.dirs.migrations`, resolved
153
+ // against ITS cwd at runtime ) - not about where this file happened to be scaffolded. Scaffold
154
+ // it inside a package under `<pkg>/src/migrations` and it sits in a directory this same list
155
+ // would scan too, but only when the consumer boots FROM that package's own cwd, which almost
156
+ // never happens: the running process's cwd is the application, not any of its dependencies. A
157
+ // package's migrations must always be re-exported from its own index, or they never run.
158
+ this.Log.info(`Created migration ${cls} for connection "${connection}"${env ? ` in environment "${env}"` : ''}. A file under the application's own system.dirs.migrations is discovered automatically. Inside a package, always re-export it from the package's index - a package's own directories are never scanned at a consumer's runtime - so the @Migration decorator runs and registers it.`);
159
+ }
160
+ };
161
+ __decorate([
162
+ Logger('ORM-CLI'),
163
+ __metadata("design:type", Log)
164
+ ], MigrateCreateCommand.prototype, "Log", void 0);
165
+ MigrateCreateCommand = __decorate([
166
+ Command('migrate-create', 'Scaffolds a new migration file'),
167
+ Option('-n, --name [name]', true, 'migration name prefix - a plain class-name prefix, letters and digits only'),
168
+ Option('-d, --dir [dir]', false, `target directory, default ${DEFAULT_MIGRATION_DIR}`),
169
+ Option('-c, --connection [connection]', false, `connection the migration runs on, default "${DEFAULT_MIGRATION_CONNECTION}"`),
170
+ Option('-e, --env [env]', false, 'environment this migration belongs to, eg. local - omit to run it in every environment')
171
+ ], MigrateCreateCommand);
172
+ export { MigrateCreateCommand };
173
+ //# sourceMappingURL=MigrateCreate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MigrateCreate.js","sourceRoot":"","sources":["../../../src/cli/MigrateCreate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ import { CliCommand } from '@spinajs/cli';
2
+ import { Log } from '@spinajs/log-common';
3
+ export interface IMigrateDownCommandOptions {
4
+ name?: string;
5
+ all?: boolean;
6
+ fake?: boolean;
7
+ connection?: string;
8
+ }
9
+ /**
10
+ * The description says LAST BATCH out loud, and so does the pre-run line below: `down()` defaults
11
+ * to the last applied batch, not to everything, and an operator who assumed otherwise would read
12
+ * a short "rolled back 1 migration" as a complete teardown.
13
+ */
14
+ export declare class MigrateDownCommand extends CliCommand {
15
+ protected Log: Log;
16
+ execute(options: IMigrateDownCommandOptions): Promise<void>;
17
+ /**
18
+ * Says what scope is about to be reversed BEFORE it is reversed, because by the time the result
19
+ * line is printed the schema change has already happened.
20
+ */
21
+ protected announce(options: IMigrateDownCommandOptions): void;
22
+ }
23
+ //# sourceMappingURL=MigrateDown.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MigrateDown.d.ts","sourceRoot":"","sources":["../../../src/cli/MigrateDown.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAmB,MAAM,cAAc,CAAC;AAC3D,OAAO,EAAE,GAAG,EAAU,MAAM,qBAAqB,CAAC;AAGlD,MAAM,WAAW,0BAA0B;IACzC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;GAIG;AACH,qBAKa,kBAAmB,SAAQ,UAAU;IAEhD,SAAS,CAAC,GAAG,EAAE,GAAG,CAAC;IAEN,OAAO,CAAC,OAAO,EAAE,0BAA0B,GAAG,OAAO,CAAC,IAAI,CAAC;IAoBxE;;;OAGG;IACH,SAAS,CAAC,QAAQ,CAAC,OAAO,EAAE,0BAA0B,GAAG,IAAI;CAwB9D"}
@@ -0,0 +1,71 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ 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;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ var __metadata = (this && this.__metadata) || function (k, v) {
8
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
+ };
10
+ import { CliCommand, Command, Option } from '@spinajs/cli';
11
+ import { Log, Logger } from '@spinajs/log-common';
12
+ import { resolveCliOrm } from '../orm.js';
13
+ /**
14
+ * The description says LAST BATCH out loud, and so does the pre-run line below: `down()` defaults
15
+ * to the last applied batch, not to everything, and an operator who assumed otherwise would read
16
+ * a short "rolled back 1 migration" as a complete teardown.
17
+ */
18
+ let MigrateDownCommand = class MigrateDownCommand extends CliCommand {
19
+ async execute(options) {
20
+ // Not `DI.resolve(Orm)`: a boot migration pass would apply the pending migrations on every
21
+ // `Migration.OnStartup` connection and this command would then roll back the batch it had
22
+ // just created. See `resolveCliOrm`.
23
+ const orm = await resolveCliOrm();
24
+ this.announce(options);
25
+ const executed = await orm.Migration.down(options.name, { all: options.all, fake: options.fake, connection: options.connection });
26
+ if (executed.length === 0) {
27
+ const scope = options.connection ? ` on connection ${options.connection}` : ' on any configured connection';
28
+ this.Log.info(options.name ? `Nothing rolled back - ${options.name} is not applied${scope}` : `Nothing to roll back - no applied migrations found${options.connection ? scope : ''}`);
29
+ return;
30
+ }
31
+ this.Log.success(`${options.fake ? 'Recorded as rolled back ( --fake, nothing was executed )' : 'Rolled back'} ${executed.length} migration(s): ${executed.map((m) => m.constructor.name).join(', ')}`);
32
+ }
33
+ /**
34
+ * Says what scope is about to be reversed BEFORE it is reversed, because by the time the result
35
+ * line is printed the schema change has already happened.
36
+ */
37
+ announce(options) {
38
+ // first, and separate from the three below: it narrows all of them, and an operator reading
39
+ // "rolling back EVERY applied migration" needs to know it means every one on ONE connection
40
+ if (options.connection) {
41
+ this.Log.info(`Limited to connection ${options.connection} - no other configured connection is touched`);
42
+ }
43
+ if (options.name) {
44
+ // A named rollback hands the migration service a one-element unit list, so every other
45
+ // applied row in the target batch looks unmatched to it and it warns about them. Those rows
46
+ // are healthy - only the warning is wrong - and the remedy it suggests is destructive if
47
+ // followed here, which is why this line says what to do with those warnings instead of
48
+ // leaving the operator to act on them.
49
+ this.Log.warn(`Rolling back a single migration: ${options.name}. The migration service may warn during this run that other migrations have no matching registered class - that is an artifact of a named rollback, those rows are fine. Do not edit or delete them.`);
50
+ return;
51
+ }
52
+ if (options.all) {
53
+ this.Log.warn('Rolling back EVERY applied migration on every configured connection ( --all )');
54
+ return;
55
+ }
56
+ this.Log.info('Rolling back the LAST APPLIED BATCH only - pass --all to reverse every applied migration');
57
+ }
58
+ };
59
+ __decorate([
60
+ Logger('ORM-CLI'),
61
+ __metadata("design:type", Log)
62
+ ], MigrateDownCommand.prototype, "Log", void 0);
63
+ MigrateDownCommand = __decorate([
64
+ Command('migrate-down', 'Rolls ORM migrations back - the LAST APPLIED BATCH only, unless --all is given'),
65
+ Option('-n, --name [name]', false, 'roll back a single migration, by class name'),
66
+ Option('-c, --connection [connection]', false, 'limit the rollback to one connection, by name'),
67
+ Option('-a, --all', false, 'roll back EVERY applied migration, not just the last batch'),
68
+ Option('-f, --fake', false, 'record the migrations as rolled back without executing them')
69
+ ], MigrateDownCommand);
70
+ export { MigrateDownCommand };
71
+ //# sourceMappingURL=MigrateDown.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MigrateDown.js","sourceRoot":"","sources":["../../../src/cli/MigrateDown.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import { CliCommand } from '@spinajs/cli';
2
+ import { Log } from '@spinajs/log-common';
3
+ import { MigrationResolveAction } from '@spinajs/orm';
4
+ export interface IMigrateResolveCommandOptions {
5
+ name: string;
6
+ applied?: boolean;
7
+ rolledBack?: boolean;
8
+ }
9
+ export declare class MigrateResolveCommand extends CliCommand {
10
+ protected Log: Log;
11
+ execute(options: IMigrateResolveCommandOptions): Promise<void>;
12
+ /**
13
+ * Exactly one of the two flags, never both and never neither: the whole point of this command is
14
+ * to state which of the two things actually happened to the database, and neither the CLI nor
15
+ * the service can find that out on its own.
16
+ */
17
+ protected action(options: IMigrateResolveCommandOptions): MigrationResolveAction;
18
+ }
19
+ //# sourceMappingURL=MigrateResolve.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MigrateResolve.d.ts","sourceRoot":"","sources":["../../../src/cli/MigrateResolve.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAmB,MAAM,cAAc,CAAC;AAE3D,OAAO,EAAE,GAAG,EAAU,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAC;AAGtD,MAAM,WAAW,6BAA6B;IAC5C,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,qBAIa,qBAAsB,SAAQ,UAAU;IAEnD,SAAS,CAAC,GAAG,EAAE,GAAG,CAAC;IAEN,OAAO,CAAC,OAAO,EAAE,6BAA6B,GAAG,OAAO,CAAC,IAAI,CAAC;IAuB3E;;;;OAIG;IACH,SAAS,CAAC,MAAM,CAAC,OAAO,EAAE,6BAA6B,GAAG,sBAAsB;CAcjF"}
@@ -0,0 +1,63 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ 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;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ var __metadata = (this && this.__metadata) || function (k, v) {
8
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
+ };
10
+ import { CliCommand, Command, Option } from '@spinajs/cli';
11
+ import { InvalidArgument } from '@spinajs/exceptions';
12
+ import { Log, Logger } from '@spinajs/log-common';
13
+ import { resolveCliOrm } from '../orm.js';
14
+ let MigrateResolveCommand = class MigrateResolveCommand extends CliCommand {
15
+ async execute(options) {
16
+ // Validated before the Orm is resolved: this refusal is about the command line, and booting
17
+ // an Orm ( which opens connections and can run the startup migration pass ) to reject a
18
+ // malformed invocation would be a side effect nobody asked for.
19
+ const action = this.action(options);
20
+ // Not `DI.resolve(Orm)`: this command is invoked precisely when a connection holds a FAILED
21
+ // row, and a boot migration pass refuses to run against one - so resolving an ordinary Orm
22
+ // would fail here, on the very row this call is about to clear. See `resolveCliOrm`.
23
+ const orm = await resolveCliOrm();
24
+ // The facade refuses anything that is not in the failed state - `FinishedAt` NULL and `Logs`
25
+ // set - so a healthy or absent row throws rather than being silently rewritten. That error is
26
+ // let through unchanged; it names the migration and the connection.
27
+ await orm.Migration.resolve(options.name, action);
28
+ if (action === 'applied') {
29
+ this.Log.success(`Migration ${options.name} is now recorded as applied. It will not run again.`);
30
+ }
31
+ else {
32
+ this.Log.success(`Migration ${options.name} is now recorded as rolled back. It is pending again and WILL run on the next migrate-up.`);
33
+ }
34
+ }
35
+ /**
36
+ * Exactly one of the two flags, never both and never neither: the whole point of this command is
37
+ * to state which of the two things actually happened to the database, and neither the CLI nor
38
+ * the service can find that out on its own.
39
+ */
40
+ action(options) {
41
+ const applied = options.applied === true;
42
+ const rolledBack = options.rolledBack === true;
43
+ if (applied && rolledBack) {
44
+ throw new InvalidArgument('--applied and --rolled-back are mutually exclusive - a migration either reached the database or it did not');
45
+ }
46
+ if (!applied && !rolledBack) {
47
+ throw new InvalidArgument('one of --applied / --rolled-back is required - resolving a failed migration means recording which of the two actually happened');
48
+ }
49
+ return applied ? 'applied' : 'rolled-back';
50
+ }
51
+ };
52
+ __decorate([
53
+ Logger('ORM-CLI'),
54
+ __metadata("design:type", Log)
55
+ ], MigrateResolveCommand.prototype, "Log", void 0);
56
+ MigrateResolveCommand = __decorate([
57
+ Command('migrate-resolve', 'Records the outcome of a FAILED migration - the escape hatch for a run that died halfway'),
58
+ Option('-n, --name [name]', true, 'migration class name'),
59
+ Option('--applied', false, 'record it as applied - the change IS in the database'),
60
+ Option('--rolled-back', false, 'record it as rolled back - the change is NOT in the database, run it again later')
61
+ ], MigrateResolveCommand);
62
+ export { MigrateResolveCommand };
63
+ //# sourceMappingURL=MigrateResolve.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MigrateResolve.js","sourceRoot":"","sources":["../../../src/cli/MigrateResolve.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAC3D,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAElD,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAYnC,IAAM,qBAAqB,GAA3B,MAAM,qBAAsB,SAAQ,UAAU;IAI5C,KAAK,CAAC,OAAO,CAAC,OAAsC;QACzD,4FAA4F;QAC5F,wFAAwF;QACxF,gEAAgE;QAChE,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAEpC,4FAA4F;QAC5F,2FAA2F;QAC3F,qFAAqF;QACrF,MAAM,GAAG,GAAG,MAAM,aAAa,EAAE,CAAC;QAElC,6FAA6F;QAC7F,8FAA8F;QAC9F,oEAAoE;QACpE,MAAM,GAAG,CAAC,SAAS,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QAElD,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YACzB,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,aAAa,OAAO,CAAC,IAAI,qDAAqD,CAAC,CAAC;QACnG,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,aAAa,OAAO,CAAC,IAAI,2FAA2F,CAAC,CAAC;QACzI,CAAC;IACH,CAAC;IAED;;;;OAIG;IACO,MAAM,CAAC,OAAsC;QACrD,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,KAAK,IAAI,CAAC;QACzC,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,KAAK,IAAI,CAAC;QAE/C,IAAI,OAAO,IAAI,UAAU,EAAE,CAAC;YAC1B,MAAM,IAAI,eAAe,CAAC,4GAA4G,CAAC,CAAC;QAC1I,CAAC;QAED,IAAI,CAAC,OAAO,IAAI,CAAC,UAAU,EAAE,CAAC;YAC5B,MAAM,IAAI,eAAe,CAAC,gIAAgI,CAAC,CAAC;QAC9J,CAAC;QAED,OAAO,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,aAAa,CAAC;IAC7C,CAAC;CACF,CAAA;AA5CW;IADT,MAAM,CAAC,SAAS,CAAC;8BACH,GAAG;kDAAC;AAFR,qBAAqB;IAJjC,OAAO,CAAC,iBAAiB,EAAE,0FAA0F,CAAC;IACtH,MAAM,CAAC,mBAAmB,EAAE,IAAI,EAAE,sBAAsB,CAAC;IACzD,MAAM,CAAC,WAAW,EAAE,KAAK,EAAE,sDAAsD,CAAC;IAClF,MAAM,CAAC,eAAe,EAAE,KAAK,EAAE,kFAAkF,CAAC;GACtG,qBAAqB,CA8CjC"}
@@ -0,0 +1,19 @@
1
+ import { CliCommand } from '@spinajs/cli';
2
+ import { IMigrationStatusEntry } from '@spinajs/orm';
3
+ /**
4
+ * The report goes to stdout with `console.log`, not through the framework logger: it is this
5
+ * command's OUTPUT - something an operator greps and a script pipes - and routing it through the
6
+ * log would let a configured level or target silently swallow it.
7
+ */
8
+ export declare class MigrateStatusCommand extends CliCommand {
9
+ execute(): Promise<void>;
10
+ protected state(e: IMigrationStatusEntry): string;
11
+ /**
12
+ * The counterpart to `explainFailed`, and the wording has to carry the difference: a failed row
13
+ * blocks and waits for a decision, an interrupted one blocks nothing and the next `migrate-up`
14
+ * re-runs it whether or not anybody looked.
15
+ */
16
+ protected explainInterrupted(interrupted: IMigrationStatusEntry[]): void;
17
+ protected explainFailed(failed: IMigrationStatusEntry[]): void;
18
+ }
19
+ //# sourceMappingURL=MigrateStatus.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MigrateStatus.d.ts","sourceRoot":"","sources":["../../../src/cli/MigrateStatus.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAW,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAGrD;;;;GAIG;AACH,qBACa,oBAAqB,SAAQ,UAAU;IACrC,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IA2DrC,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,qBAAqB,GAAG,MAAM;IAMjD;;;;OAIG;IACH,SAAS,CAAC,kBAAkB,CAAC,WAAW,EAAE,qBAAqB,EAAE,GAAG,IAAI;IAoBxE,SAAS,CAAC,aAAa,CAAC,MAAM,EAAE,qBAAqB,EAAE,GAAG,IAAI;CAY/D"}
@@ -0,0 +1,106 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ 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;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ /* eslint-disable no-console */
8
+ import { CliCommand, Command } from '@spinajs/cli';
9
+ import { resolveCliOrm } from '../orm.js';
10
+ /**
11
+ * The report goes to stdout with `console.log`, not through the framework logger: it is this
12
+ * command's OUTPUT - something an operator greps and a script pipes - and routing it through the
13
+ * log would let a configured level or target silently swallow it.
14
+ */
15
+ let MigrateStatusCommand = class MigrateStatusCommand extends CliCommand {
16
+ async execute() {
17
+ // Not `DI.resolve(Orm)`: that boots with a migration pass, so this report would apply every
18
+ // pending migration on every `Migration.OnStartup` connection and only then describe the
19
+ // database it had just changed - always "all applied", always exit 0. See `resolveCliOrm`.
20
+ const orm = await resolveCliOrm();
21
+ const entries = await orm.Migration.status();
22
+ if (entries.length === 0) {
23
+ console.log('No migrations are registered for any configured connection.');
24
+ return;
25
+ }
26
+ const width = Math.max(...entries.map((e) => e.connection.length), 'CONNECTION'.length);
27
+ console.log(` ${'STATE'.padEnd(12)} ${'BATCH'.padStart(5)} ${'CONNECTION'.padEnd(width)} MIGRATION`);
28
+ for (const e of entries) {
29
+ // `!!` in the leftmost column, not just the word FAILED: a failed row is the one line in
30
+ // this report that stops every later migrate-up on its connection, and it has to survive
31
+ // being skimmed in a wall of `applied`. `??` earns the same treatment for the opposite
32
+ // reason - an interrupted row stops nothing at all, and the next migrate-up will re-run it.
33
+ const marker = e.failed ? '!!' : e.interrupted ? '??' : ' ';
34
+ const drift = e.checksumMismatch ? ' [checksum mismatch - the file changed after it was applied]' : '';
35
+ console.log(`${marker} ${this.state(e).padEnd(12)} ${String(e.batch ?? '-').padStart(5)} ${e.connection.padEnd(width)} ${e.name}${drift}`);
36
+ }
37
+ const failed = entries.filter((e) => e.failed);
38
+ // `pending` is already false on a failed row ( the service derives it as `!applied && !failed` ),
39
+ // so the counts below never double-count the same entry.
40
+ const pending = entries.filter((e) => e.pending);
41
+ // `pending` from the service covers "will run on the next migrate-up", which includes rows
42
+ // that were rolled back and rows a killed run left open. The STATE column tells those apart,
43
+ // so the summary has to as well - otherwise the report says "0 pending" nowhere and "N
44
+ // pending" against a list in which no line reads `pending`. The three are disjoint: the
45
+ // service never reports `interrupted` on a row carrying RolledBackAt.
46
+ const interrupted = pending.filter((e) => e.interrupted);
47
+ const rolledBack = pending.filter((e) => e.rolledBack);
48
+ const neverRun = pending.filter((e) => !e.rolledBack && !e.interrupted);
49
+ console.log('');
50
+ console.log(`${entries.length} migration(s): ${entries.filter((e) => e.applied).length} applied, ${neverRun.length} pending, ${rolledBack.length} rolled back, ${interrupted.length} interrupted, ${failed.length} failed, ${entries.filter((e) => e.checksumMismatch).length} with a checksum mismatch`);
51
+ if (failed.length > 0) {
52
+ this.explainFailed(failed);
53
+ }
54
+ if (interrupted.length > 0) {
55
+ this.explainInterrupted(interrupted);
56
+ }
57
+ // Pending is an exit code too, not only failure: `migrate-status` is what a deploy gate calls
58
+ // to ask "is this database current?", and an un-run migration is a "no".
59
+ if (failed.length > 0 || pending.length > 0) {
60
+ process.exitCode = 1;
61
+ }
62
+ }
63
+ state(e) {
64
+ // interrupted is checked before rolled-back and pending, and after failed: it is a narrowing
65
+ // of `pending`, so reporting the broader word would lose the only thing worth saying about it
66
+ return e.failed ? 'FAILED' : e.applied ? 'applied' : e.interrupted ? 'INTERRUPTED' : e.rolledBack ? 'rolled-back' : 'pending';
67
+ }
68
+ /**
69
+ * The counterpart to `explainFailed`, and the wording has to carry the difference: a failed row
70
+ * blocks and waits for a decision, an interrupted one blocks nothing and the next `migrate-up`
71
+ * re-runs it whether or not anybody looked.
72
+ */
73
+ explainInterrupted(interrupted) {
74
+ console.log('');
75
+ console.log('An INTERRUPTED migration was started and never finished - the process running it was killed before it could');
76
+ console.log('record either outcome. Nothing blocks: the next migrate-up RE-RUNS it from the top, and how much of the first');
77
+ console.log('attempt is already in the database was never recorded. Establish that before the next run, then either let it');
78
+ console.log('re-run or record what really happened:');
79
+ for (const i of interrupted) {
80
+ console.log('');
81
+ // `startedAt` is typed Date, but a dialect that hands timestamps back as strings puts one
82
+ // here - and `new Date(<odd format>).toISOString()` THROWS, out of a report whose entire job
83
+ // is to be readable when something has gone wrong
84
+ const started = i.startedAt instanceof Date ? i.startedAt.toISOString() : String(i.startedAt);
85
+ console.log(` ${i.name} ( ${i.connection} )${i.startedAt ? `, started ${started}` : ''}`);
86
+ console.log(` migrate-resolve --name ${i.name} --applied # the change IS in the database, do not run it again`);
87
+ console.log(` migrate-resolve --name ${i.name} --rolled-back # the change is NOT, run it again on the next migrate-up`);
88
+ }
89
+ }
90
+ explainFailed(failed) {
91
+ console.log('');
92
+ console.log('A FAILED migration blocks every later migrate-up on its connection. Establish whether the change actually');
93
+ console.log('reached the database, then record that outcome so the connection is unblocked:');
94
+ for (const f of failed) {
95
+ console.log('');
96
+ console.log(` ${f.name} ( ${f.connection} )`);
97
+ console.log(` migrate-resolve --name ${f.name} --applied # the change IS in the database`);
98
+ console.log(` migrate-resolve --name ${f.name} --rolled-back # the change is NOT in the database`);
99
+ }
100
+ }
101
+ };
102
+ MigrateStatusCommand = __decorate([
103
+ Command('migrate-status', 'Prints migration status for every configured connection')
104
+ ], MigrateStatusCommand);
105
+ export { MigrateStatusCommand };
106
+ //# sourceMappingURL=MigrateStatus.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MigrateStatus.js","sourceRoot":"","sources":["../../../src/cli/MigrateStatus.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ import { CliCommand } from '@spinajs/cli';
2
+ import { Log } from '@spinajs/log-common';
3
+ import { Orm } from '@spinajs/orm';
4
+ export interface IMigrateUpCommandOptions {
5
+ name?: string;
6
+ fake?: boolean;
7
+ connection?: string;
8
+ }
9
+ /**
10
+ * `orm.Migration` only exists on a RESOLVED Orm - it is assigned inside `Orm.resolve()`, once the
11
+ * connections it dispatches to have been created. So every command here resolves the Orm first
12
+ * and reaches the facade through it, rather than injecting a migration service directly.
13
+ *
14
+ * Through `resolveCliOrm()`, so that resolve does not run a migration pass of its own: the run
15
+ * below is the one the operator asked for, and it is the only one. Without that, `--fake` on a
16
+ * `Migration.OnStartup` connection would really apply the migrations it promises to merely
17
+ * record, because the boot pass would have executed them before this line is reached.
18
+ */
19
+ export declare class MigrateUpCommand extends CliCommand {
20
+ protected Log: Log;
21
+ execute(options: IMigrateUpCommandOptions): Promise<void>;
22
+ /**
23
+ * Turns an empty `up(name)` into a statement about what actually happened - and a non-zero exit
24
+ * code whenever the requested schema change is not in the database, so a deploy script cannot
25
+ * march past it believing "0 applied" meant "nothing left to do".
26
+ *
27
+ * `status()` here is deliberately NOT narrowed by `--connection`: with the filter on, "the
28
+ * migration lives on a connection this run excluded" is the likeliest reason the run was empty,
29
+ * and a narrowed report could not tell that from "not registered at all".
30
+ */
31
+ protected explainEmptyNamedRun(orm: Orm, name: string, connection?: string): Promise<void>;
32
+ }
33
+ //# sourceMappingURL=MigrateUp.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MigrateUp.d.ts","sourceRoot":"","sources":["../../../src/cli/MigrateUp.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAmB,MAAM,cAAc,CAAC;AAC3D,OAAO,EAAE,GAAG,EAAU,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AAGnC,MAAM,WAAW,wBAAwB;IACvC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;;;GASG;AACH,qBAIa,gBAAiB,SAAQ,UAAU;IAE9C,SAAS,CAAC,GAAG,EAAE,GAAG,CAAC;IAEN,OAAO,CAAC,OAAO,EAAE,wBAAwB,GAAG,OAAO,CAAC,IAAI,CAAC;IAuBtE;;;;;;;;OAQG;cACa,oBAAoB,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CA6BjG"}