remult 0.25.7 → 0.25.8-exp.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 (46) hide show
  1. package/README.md +6 -12
  2. package/esm/migrations/compare-migration-snapshots.js +39 -0
  3. package/esm/migrations/generate-migrations.js +47 -0
  4. package/esm/migrations/index.js +2 -0
  5. package/esm/migrations/migrate.js +55 -0
  6. package/esm/migrations/migration-types.js +12 -0
  7. package/esm/migrations/update-migrations-ts-file.js +112 -0
  8. package/esm/postgres/postgres-data-provider.js +12 -0
  9. package/esm/postgres/schema-builder.js +35 -26
  10. package/esm/remult-knex/index.js +112 -28
  11. package/esm/remult-sql-js.js +2 -2
  12. package/esm/src/context.js +14 -8
  13. package/esm/src/data-providers/sql-database.js +10 -3
  14. package/esm/src/filter/filter-consumer-bridge-to-sql-request.js +4 -0
  15. package/esm/src/isOfType.js +9 -0
  16. package/esm/src/remult3/remult3.js +20 -13
  17. package/migrations/compare-migration-snapshots.d.ts +26 -0
  18. package/migrations/compare-migration-snapshots.js +101 -0
  19. package/migrations/generate-migrations.d.ts +8 -0
  20. package/migrations/generate-migrations.js +82 -0
  21. package/migrations/index.d.ts +3 -0
  22. package/migrations/index.js +7 -0
  23. package/migrations/migrate.d.ts +7 -0
  24. package/migrations/migrate.js +147 -0
  25. package/migrations/migration-types.d.ts +23 -0
  26. package/migrations/migration-types.js +27 -0
  27. package/migrations/update-migrations-ts-file.d.ts +1 -0
  28. package/migrations/update-migrations-ts-file.js +135 -0
  29. package/package.json +6 -1
  30. package/postgres/postgres-data-provider.d.ts +3 -1
  31. package/postgres/postgres-data-provider.js +34 -0
  32. package/postgres/schema-builder.js +81 -48
  33. package/remult-knex/index.d.ts +10 -3
  34. package/remult-knex/index.js +170 -56
  35. package/remult-sql-js.js +1 -1
  36. package/server/expressBridge.d.ts +9 -1
  37. package/src/context.d.ts +1 -1
  38. package/src/context.js +16 -8
  39. package/src/data-providers/sql-database.d.ts +5 -2
  40. package/src/data-providers/sql-database.js +8 -3
  41. package/src/filter/filter-consumer-bridge-to-sql-request.d.ts +1 -0
  42. package/src/filter/filter-consumer-bridge-to-sql-request.js +6 -1
  43. package/src/isOfType.d.ts +2 -0
  44. package/src/isOfType.js +14 -0
  45. package/src/remult3/remult3.js +20 -13
  46. package/src/sql-command.d.ts +4 -0
@@ -6,14 +6,16 @@ import { getRepository } from '../remult3/RepositoryImplementation.js';
6
6
  import { Sort } from '../sort.js';
7
7
  import { ValueConverters } from '../valueConverters.js';
8
8
  import { getRepositoryInternals } from '../remult3/repository-internals.js';
9
+ import { isOfType } from '../isOfType.js';
9
10
  // @dynamic
10
11
  export class SqlDatabase {
11
12
  sql;
12
13
  static getDb(remult) {
13
14
  const r = (remult || defaultRemult).dataProvider;
14
- if (!r.createCommand)
15
- throw 'the data provider is not an SqlDatabase';
16
- return r;
15
+ if (isOfType(r, 'createCommand'))
16
+ return r;
17
+ else
18
+ throw 'the data provider is not an SqlCommandFactory';
17
19
  }
18
20
  createCommand() {
19
21
  return new LogSQLCommand(this.sql.createCommand(), SqlDatabase.LogToConsole);
@@ -116,7 +118,12 @@ export class SqlDatabase {
116
118
  this.sql = sql;
117
119
  if (sql.wrapIdentifier)
118
120
  this.wrapIdentifier = (x) => sql.wrapIdentifier(x);
121
+ if (isOfType(sql, 'provideMigrationBuilder')) {
122
+ this.provideMigrationBuilder = sql.provideMigrationBuilder;
123
+ }
119
124
  }
125
+ provideMigrationBuilder;
126
+ isProxy;
120
127
  createdEntities = [];
121
128
  }
122
129
  const icons = new Map([
@@ -164,6 +164,10 @@ export function shouldNotCreateField(field, dbNames) {
164
164
  return (field.isServerExpression ||
165
165
  (field.options.sqlExpression && field.dbName != dbNames.$dbNameOf(field)));
166
166
  }
167
+ export function shouldCreateEntity(entity, e) {
168
+ return (!entity.options.sqlExpression &&
169
+ e.$entityName.toLowerCase().indexOf('from ') < 0);
170
+ }
167
171
  export async function dbNamesOf(repo, wrapIdentifierOrOptions) {
168
172
  let options = typeof wrapIdentifierOrOptions === 'function'
169
173
  ? { wrapIdentifier: wrapIdentifierOrOptions }
@@ -0,0 +1,9 @@
1
+ export function isOfType(obj, checkMethod) {
2
+ return typeof obj[checkMethod] === 'function';
3
+ }
4
+ export function cast(obj, checkMethod) {
5
+ if (isOfType(obj, checkMethod)) {
6
+ return obj;
7
+ }
8
+ throw new Error(`Object is not of type ${checkMethod.toString()}`);
9
+ }
@@ -1,22 +1,30 @@
1
1
  export {};
2
- /*y1 - workshop
3
-
4
- * Experiment with doing this with version control - so the students can follow changes
5
- * Prepare stackblitz
6
-
2
+ //p1 - migrations - in docs empesize that mysql doesn't support transactions in ddl, in docs empesize destroy for knex - // await dataProvider.knex.destroy()
3
+ //https://gitkraken.dev/link/dnNjb2RlOi8vZWFtb2Rpby5naXRsZW5zL2xpbmsvci9mMDgzMWU0OWIyODJkMDlkNTA0NTcxYjYwNmUzNTMwODQ3NGIwY2M2L2YvcHJvamVjdHMvcGxheS13aXRoLW1pZ3JhdGlvbnMvc3JjL3NlcnZlci9idWlsZC1taWdyYXRpb25zLnRzP3VybD1odHRwcyUzQSUyRiUyRmdpdGh1Yi5jb20lMkZyZW11bHQlMkZyZW11bHQuZ2l0?origin=gitlens
4
+ /*p1 - processError in remult express
5
+ - Should we merge (notFound,error,forbidden) into one method in `DataApiResponse` type?
6
+ https://gitkraken.dev/link/dnNjb2RlOi8vZWFtb2Rpby5naXRsZW5zL2xpbmsvci9mMDgzMWU0OWIyODJkMDlkNTA0NTcxYjYwNmUzNTMwODQ3NGIwY2M2L2YvcHJvamVjdHMvY29yZS9zcmMvZGF0YS1hcGkudHM%2FdXJsPWh0dHBzJTNBJTJGJTJGZ2l0aHViLmNvbSUyRnJlbXVsdCUyRnJlbXVsdC5naXQ%3D?origin=gitlens
7
+ - The api of the `processError` should recieve an `ErrorInfo` object and return an `ErrorInfo` object? or should it return something more in the line,
8
+ of httpStatus and errorBody. - currently the `serializeError` method is used to build the response
9
+ https://gitkraken.dev/link/dnNjb2RlOi8vZWFtb2Rpby5naXRsZW5zL2xpbmsvci9mMDgzMWU0OWIyODJkMDlkNTA0NTcxYjYwNmUzNTMwODQ3NGIwY2M2L2YvcHJvamVjdHMvY29yZS9zcmMvZGF0YS1hcGkudHM%2FdXJsPWh0dHBzJTNBJTJGJTJGZ2l0aHViLmNvbSUyRnJlbXVsdCUyRnJlbXVsdC5naXQmbGluZXM9NDI1?origin=gitlens
10
+ - I think there should be a way to throw a forbidden exception
11
+ */
12
+ //p1 - cleanup root directory of reult
13
+ //p1 - in this video I'll use remult to turn a frontend app to a fullstack app
14
+ /*y1 - discuss using delete & put - with url query language for deleteMany and updateMany -
15
+ - put & delete, similar to get
16
+ - add where to count, deleteMany,updateMany,
17
+ - prevent delete all and update all - must have meaningful where.
18
+ - try forcing this also in typescript
7
19
 
8
- # influencer:
9
- * review react summit
10
- #
20
+ - protect against deleting of all rows by mistake
21
+ - https://github.com/remult/remult/issues/221#issuecomment-2016519746
11
22
 
23
+ */
12
24
  //y1 - getFields didn't work for kobi in the home component
13
-
14
- //p1 - processError in remult express
15
- //p1 - I think there should be a way to throw a forbidden exception
16
25
  //p1 - add section to Fields doc, explaining field type in db
17
26
  //p1 - add section about union type
18
27
  //p1 - add section about value list field type
19
-
20
28
  /*y1 - Talk JYC - JYC - add some integrity checks on delete
21
29
  - soft delete
22
30
  - delete restrict (implicit, or user selected - and if so, how) (delete & update of id)
@@ -53,7 +61,6 @@ export class Currency {
53
61
  //y1 - I think that the tests you've setup don't cover next app router - I added to the setup, but not sure where else
54
62
  //y1 - talk about the parameter issue with backend methods
55
63
  //y1 - select data provider per entity https://discord.com/channels/975754286384418847/976006081748807690/1201415305885397003
56
- //y1 - migrations
57
64
  //y1 - live query refresh of view on table update
58
65
  //y1 - main vs master
59
66
  //y2 - livequery for findfirst (@JY)
@@ -0,0 +1,26 @@
1
+ import type { MigrationBuilder } from './migration-types.js';
2
+ export declare function compareMigrationSnapshot({ entities, snapshot, migrationBuilder: migrationBuilder, }: {
3
+ entities: any[];
4
+ snapshot: EntitiesSnapshot;
5
+ migrationBuilder: MigrationBuilder;
6
+ }): Promise<{
7
+ version: number;
8
+ entities: Record<string, {
9
+ key: string;
10
+ className: string;
11
+ columns: Record<string, {
12
+ key: string;
13
+ }>;
14
+ }>;
15
+ }>;
16
+ export declare function emptySnapshot(): {
17
+ version: number;
18
+ entities: Record<string, {
19
+ key: string;
20
+ className: string;
21
+ columns: Record<string, {
22
+ key: string;
23
+ }>;
24
+ }>;
25
+ };
26
+ export type EntitiesSnapshot = ReturnType<typeof emptySnapshot>;
@@ -0,0 +1,101 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.emptySnapshot = exports.compareMigrationSnapshot = void 0;
4
+ var tslib_1 = require("tslib");
5
+ var index_js_1 = require("../index.js");
6
+ var filter_consumer_bridge_to_sql_request_js_1 = require("../src/filter/filter-consumer-bridge-to-sql-request.js");
7
+ function compareMigrationSnapshot(_a) {
8
+ var entities = _a.entities, snapshot = _a.snapshot, migrationBuilder = _a.migrationBuilder;
9
+ return tslib_1.__awaiter(this, void 0, void 0, function () {
10
+ var entities_1, entities_1_1, entity, meta, e, entitySnapshot, createColumns, _b, _c, field, column, e_1_1, e_2_1;
11
+ var e_2, _d, e_1, _e;
12
+ return tslib_1.__generator(this, function (_f) {
13
+ switch (_f.label) {
14
+ case 0:
15
+ snapshot = JSON.parse(JSON.stringify(snapshot));
16
+ _f.label = 1;
17
+ case 1:
18
+ _f.trys.push([1, 16, 17, 18]);
19
+ entities_1 = tslib_1.__values(entities), entities_1_1 = entities_1.next();
20
+ _f.label = 2;
21
+ case 2:
22
+ if (!!entities_1_1.done) return [3 /*break*/, 15];
23
+ entity = entities_1_1.value;
24
+ meta = (0, index_js_1.repo)(entity).metadata;
25
+ return [4 /*yield*/, (0, filter_consumer_bridge_to_sql_request_js_1.dbNamesOf)(meta, function (x) { return x; })];
26
+ case 3:
27
+ e = _f.sent();
28
+ if (!(0, filter_consumer_bridge_to_sql_request_js_1.shouldCreateEntity)(meta, e)) return [3 /*break*/, 13];
29
+ entitySnapshot = snapshot.entities[e.$entityName];
30
+ createColumns = true;
31
+ if (!!entitySnapshot) return [3 /*break*/, 5];
32
+ createColumns = false;
33
+ return [4 /*yield*/, migrationBuilder.createTable(meta)];
34
+ case 4:
35
+ _f.sent();
36
+ entitySnapshot = snapshot.entities[e.$entityName] = {
37
+ key: meta.key,
38
+ className: meta.entityType.name,
39
+ columns: {},
40
+ };
41
+ _f.label = 5;
42
+ case 5:
43
+ _f.trys.push([5, 11, 12, 13]);
44
+ _b = (e_1 = void 0, tslib_1.__values(meta.fields)), _c = _b.next();
45
+ _f.label = 6;
46
+ case 6:
47
+ if (!!_c.done) return [3 /*break*/, 10];
48
+ field = _c.value;
49
+ if (!!(0, filter_consumer_bridge_to_sql_request_js_1.shouldNotCreateField)(field, e)) return [3 /*break*/, 9];
50
+ column = entitySnapshot.columns[e.$dbNameOf(field)];
51
+ if (!!column) return [3 /*break*/, 9];
52
+ if (!createColumns) return [3 /*break*/, 8];
53
+ return [4 /*yield*/, migrationBuilder.addColumn(meta, field)];
54
+ case 7:
55
+ _f.sent();
56
+ _f.label = 8;
57
+ case 8:
58
+ entitySnapshot.columns[e.$dbNameOf(field)] = { key: field.key };
59
+ _f.label = 9;
60
+ case 9:
61
+ _c = _b.next();
62
+ return [3 /*break*/, 6];
63
+ case 10: return [3 /*break*/, 13];
64
+ case 11:
65
+ e_1_1 = _f.sent();
66
+ e_1 = { error: e_1_1 };
67
+ return [3 /*break*/, 13];
68
+ case 12:
69
+ try {
70
+ if (_c && !_c.done && (_e = _b.return)) _e.call(_b);
71
+ }
72
+ finally { if (e_1) throw e_1.error; }
73
+ return [7 /*endfinally*/];
74
+ case 13: return [2 /*return*/, snapshot];
75
+ case 14:
76
+ entities_1_1 = entities_1.next();
77
+ return [3 /*break*/, 2];
78
+ case 15: return [3 /*break*/, 18];
79
+ case 16:
80
+ e_2_1 = _f.sent();
81
+ e_2 = { error: e_2_1 };
82
+ return [3 /*break*/, 18];
83
+ case 17:
84
+ try {
85
+ if (entities_1_1 && !entities_1_1.done && (_d = entities_1.return)) _d.call(entities_1);
86
+ }
87
+ finally { if (e_2) throw e_2.error; }
88
+ return [7 /*endfinally*/];
89
+ case 18: return [2 /*return*/];
90
+ }
91
+ });
92
+ });
93
+ }
94
+ exports.compareMigrationSnapshot = compareMigrationSnapshot;
95
+ function emptySnapshot() {
96
+ return {
97
+ version: 1,
98
+ entities: {},
99
+ };
100
+ }
101
+ exports.emptySnapshot = emptySnapshot;
@@ -0,0 +1,8 @@
1
+ import type { DataProvider } from '../index.js';
2
+ export declare function generateMigrations(options: {
3
+ entities: any[];
4
+ dataProvider: Promise<DataProvider> | DataProvider;
5
+ migrationsDir?: string;
6
+ snapshotFileName?: string;
7
+ migrationsTSFilename?: string;
8
+ }): Promise<void>;
@@ -0,0 +1,82 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generateMigrations = void 0;
4
+ var tslib_1 = require("tslib");
5
+ var path_1 = tslib_1.__importDefault(require("path"));
6
+ var fs_1 = tslib_1.__importDefault(require("fs"));
7
+ var compare_migration_snapshots_js_1 = require("./compare-migration-snapshots.js");
8
+ var update_migrations_ts_file_js_1 = require("./update-migrations-ts-file.js");
9
+ var migration_types_js_1 = require("./migration-types.js");
10
+ var isOfType_js_1 = require("../src/isOfType.js");
11
+ function generateMigrations(options) {
12
+ return tslib_1.__awaiter(this, void 0, void 0, function () {
13
+ var migrationDir, snapshotFileName, migrationsTSFilename, dataProvider, _a, _b, p, snapshot, hasSql, steps, code, migrationBuilder;
14
+ var e_1, _c;
15
+ return tslib_1.__generator(this, function (_d) {
16
+ switch (_d.label) {
17
+ case 0:
18
+ migrationDir = options.migrationsDir || path_1.default.join(process.cwd(), 'src/server/migrations');
19
+ snapshotFileName = options.snapshotFileName ||
20
+ path_1.default.join(migrationDir, 'migrations-snapshot.json');
21
+ migrationsTSFilename = options.migrationsTSFilename || path_1.default.join(migrationDir, 'migrations.ts');
22
+ return [4 /*yield*/, options.dataProvider];
23
+ case 1:
24
+ dataProvider = _d.sent();
25
+ try {
26
+ for (_a = tslib_1.__values([snapshotFileName, migrationsTSFilename]), _b = _a.next(); !_b.done; _b = _a.next()) {
27
+ p = _b.value;
28
+ if (!fs_1.default.existsSync(path_1.default.dirname(p))) {
29
+ fs_1.default.mkdirSync(path_1.default.dirname(p), { recursive: true });
30
+ }
31
+ }
32
+ }
33
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
34
+ finally {
35
+ try {
36
+ if (_b && !_b.done && (_c = _a.return)) _c.call(_a);
37
+ }
38
+ finally { if (e_1) throw e_1.error; }
39
+ }
40
+ snapshot = (0, compare_migration_snapshots_js_1.emptySnapshot)();
41
+ if (fs_1.default.existsSync(snapshotFileName)) {
42
+ snapshot = JSON.parse(fs_1.default.readFileSync(snapshotFileName).toString());
43
+ }
44
+ hasSql = false;
45
+ steps = [];
46
+ code = {
47
+ //https://marketplace.visualstudio.com/items?itemName=qufiwefefwoyn.inline-sql-syntax
48
+ addSql: function (sql) {
49
+ steps.push('await sql(`--sql\n' + sql + '`)');
50
+ hasSql = true;
51
+ },
52
+ addTypescriptCode: function (code) { return steps.push(code); },
53
+ addComment: function (comment) {
54
+ return steps.push(comment.indexOf('\n') >= 0 ? "/*".concat(comment, "*/") : "// ".concat(comment));
55
+ },
56
+ };
57
+ migrationBuilder = new migration_types_js_1.DefaultMigrationBuilder(code);
58
+ if ((0, isOfType_js_1.isOfType)(dataProvider, 'provideMigrationBuilder')) {
59
+ migrationBuilder = dataProvider.provideMigrationBuilder(code);
60
+ }
61
+ return [4 /*yield*/, (0, compare_migration_snapshots_js_1.compareMigrationSnapshot)({
62
+ entities: options.entities,
63
+ snapshot: snapshot,
64
+ migrationBuilder: migrationBuilder,
65
+ })];
66
+ case 2:
67
+ snapshot = _d.sent();
68
+ if (!steps.length) return [3 /*break*/, 4];
69
+ return [4 /*yield*/, (0, update_migrations_ts_file_js_1.updateMigrationsFile)(migrationsTSFilename, [
70
+ "async (".concat(hasSql ? '{sql}' : '', ")=>{\n").concat(steps.join('\n'), "\n}"),
71
+ ])];
72
+ case 3:
73
+ _d.sent();
74
+ _d.label = 4;
75
+ case 4:
76
+ fs_1.default.writeFileSync(snapshotFileName, JSON.stringify(snapshot, null, 2));
77
+ return [2 /*return*/];
78
+ }
79
+ });
80
+ });
81
+ }
82
+ exports.generateMigrations = generateMigrations;
@@ -0,0 +1,3 @@
1
+ export { Migrations, MigrationUtils } from './migration-types.js';
2
+ export { generateMigrations } from './generate-migrations.js';
3
+ export { migrate } from './migrate.js';
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.migrate = exports.generateMigrations = void 0;
4
+ var generate_migrations_js_1 = require("./generate-migrations.js");
5
+ Object.defineProperty(exports, "generateMigrations", { enumerable: true, get: function () { return generate_migrations_js_1.generateMigrations; } });
6
+ var migrate_js_1 = require("./migrate.js");
7
+ Object.defineProperty(exports, "migrate", { enumerable: true, get: function () { return migrate_js_1.migrate; } });
@@ -0,0 +1,7 @@
1
+ import { type DataProvider } from '../index.js';
2
+ import type { Migrations } from './migration-types.js';
3
+ export declare function migrate(options: {
4
+ migrations: Migrations;
5
+ dataProvider?: Promise<DataProvider> | DataProvider;
6
+ migrationTableName?: string;
7
+ }): Promise<void>;
@@ -0,0 +1,147 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.migrate = void 0;
4
+ var tslib_1 = require("tslib");
5
+ var index_js_1 = require("../index.js");
6
+ var context_js_1 = require("../src/context.js");
7
+ var isOfType_js_1 = require("../src/isOfType.js");
8
+ function migrate(options) {
9
+ return tslib_1.__awaiter(this, void 0, void 0, function () {
10
+ var migrationTableName, dataProvider, _a, prev, VersionInfo, repo, v, steps, _loop_1, steps_1, steps_1_1, _b, stepText, action, e_1_1;
11
+ var e_1, _c;
12
+ var _this = this;
13
+ return tslib_1.__generator(this, function (_d) {
14
+ switch (_d.label) {
15
+ case 0:
16
+ migrationTableName = options.migrationTableName || '__remult_migration_version';
17
+ if (!options.dataProvider) return [3 /*break*/, 2];
18
+ return [4 /*yield*/, options.dataProvider];
19
+ case 1:
20
+ _a = _d.sent();
21
+ return [3 /*break*/, 3];
22
+ case 2:
23
+ _a = index_js_1.remult.dataProvider;
24
+ _d.label = 3;
25
+ case 3:
26
+ dataProvider = _a;
27
+ prev = index_js_1.remult.dataProvider;
28
+ index_js_1.remult.dataProvider = dataProvider;
29
+ _d.label = 4;
30
+ case 4:
31
+ _d.trys.push([4, , 16, 17]);
32
+ VersionInfo = /** @class */ (function (_super) {
33
+ tslib_1.__extends(VersionInfo, _super);
34
+ function VersionInfo() {
35
+ var _this = _super !== null && _super.apply(this, arguments) || this;
36
+ _this.version = -1;
37
+ return _this;
38
+ }
39
+ tslib_1.__decorate([
40
+ index_js_1.Fields.number(),
41
+ tslib_1.__metadata("design:type", Object)
42
+ ], VersionInfo.prototype, "version", void 0);
43
+ VersionInfo = tslib_1.__decorate([
44
+ (0, index_js_1.Entity)(migrationTableName)
45
+ ], VersionInfo);
46
+ return VersionInfo;
47
+ }(index_js_1.IdEntity));
48
+ repo = new index_js_1.Remult(dataProvider).repo(VersionInfo);
49
+ if (!dataProvider.ensureSchema) return [3 /*break*/, 6];
50
+ return [4 /*yield*/, dataProvider.ensureSchema([repo.metadata])];
51
+ case 5:
52
+ _d.sent();
53
+ _d.label = 6;
54
+ case 6: return [4 /*yield*/, repo.findFirst()];
55
+ case 7:
56
+ v = _d.sent();
57
+ if (!v) {
58
+ v = repo.create();
59
+ v.version = -1;
60
+ }
61
+ steps = Object.entries(options.migrations).sort(function (_a, _b) {
62
+ var _c = tslib_1.__read(_a, 1), a = _c[0];
63
+ var _d = tslib_1.__read(_b, 1), b = _d[0];
64
+ return parseInt(a) - parseInt(b);
65
+ });
66
+ _loop_1 = function (stepText, action) {
67
+ var step;
68
+ return tslib_1.__generator(this, function (_e) {
69
+ switch (_e.label) {
70
+ case 0:
71
+ step = parseInt(stepText);
72
+ if (step < 0)
73
+ throw new Error('Migration step number must be a non-negative integer');
74
+ if (v.version >= step)
75
+ return [2 /*return*/, "continue"];
76
+ console.info('Executing migration step', step);
77
+ return [4 /*yield*/, (0, context_js_1.doTransaction)(index_js_1.remult, function (dp) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
78
+ var utils;
79
+ var _this = this;
80
+ return tslib_1.__generator(this, function (_a) {
81
+ switch (_a.label) {
82
+ case 0:
83
+ utils = {
84
+ sql: function (sql) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
85
+ return tslib_1.__generator(this, function (_a) {
86
+ switch (_a.label) {
87
+ case 0: return [4 /*yield*/, (0, isOfType_js_1.cast)(dp, 'execute').execute(sql)];
88
+ case 1:
89
+ _a.sent();
90
+ return [2 /*return*/];
91
+ }
92
+ });
93
+ }); },
94
+ };
95
+ return [4 /*yield*/, action(utils)];
96
+ case 1:
97
+ _a.sent();
98
+ return [2 /*return*/];
99
+ }
100
+ });
101
+ }); })];
102
+ case 1:
103
+ _e.sent();
104
+ v.version = step;
105
+ return [4 /*yield*/, v.save()];
106
+ case 2:
107
+ _e.sent();
108
+ return [2 /*return*/];
109
+ }
110
+ });
111
+ };
112
+ _d.label = 8;
113
+ case 8:
114
+ _d.trys.push([8, 13, 14, 15]);
115
+ steps_1 = tslib_1.__values(steps), steps_1_1 = steps_1.next();
116
+ _d.label = 9;
117
+ case 9:
118
+ if (!!steps_1_1.done) return [3 /*break*/, 12];
119
+ _b = tslib_1.__read(steps_1_1.value, 2), stepText = _b[0], action = _b[1];
120
+ return [5 /*yield**/, _loop_1(stepText, action)];
121
+ case 10:
122
+ _d.sent();
123
+ _d.label = 11;
124
+ case 11:
125
+ steps_1_1 = steps_1.next();
126
+ return [3 /*break*/, 9];
127
+ case 12: return [3 /*break*/, 15];
128
+ case 13:
129
+ e_1_1 = _d.sent();
130
+ e_1 = { error: e_1_1 };
131
+ return [3 /*break*/, 15];
132
+ case 14:
133
+ try {
134
+ if (steps_1_1 && !steps_1_1.done && (_c = steps_1.return)) _c.call(steps_1);
135
+ }
136
+ finally { if (e_1) throw e_1.error; }
137
+ return [7 /*endfinally*/];
138
+ case 15: return [3 /*break*/, 17];
139
+ case 16:
140
+ index_js_1.remult.dataProvider = prev;
141
+ return [7 /*endfinally*/];
142
+ case 17: return [2 /*return*/];
143
+ }
144
+ });
145
+ });
146
+ }
147
+ exports.migrate = migrate;
@@ -0,0 +1,23 @@
1
+ import type { EntityMetadata, FieldMetadata } from '../index.js';
2
+ export interface CanBuildMigrations {
3
+ provideMigrationBuilder(builder: MigrationCode): MigrationBuilder;
4
+ }
5
+ export interface MigrationBuilder {
6
+ createTable(meta: EntityMetadata): Promise<void>;
7
+ addColumn(meta: EntityMetadata, field: FieldMetadata): Promise<void>;
8
+ }
9
+ export interface MigrationCode {
10
+ addSql(sql: string): void;
11
+ addComment(comment: string): void;
12
+ addTypescriptCode(code: string): void;
13
+ }
14
+ export type Migrations = Record<number, (utils: MigrationUtils) => Promise<unknown>>;
15
+ export type MigrationUtils = {
16
+ sql(sql: string): Promise<unknown>;
17
+ };
18
+ export declare class DefaultMigrationBuilder implements MigrationBuilder {
19
+ code: MigrationCode;
20
+ constructor(code: MigrationCode);
21
+ createTable(meta: EntityMetadata): Promise<void>;
22
+ addColumn(meta: EntityMetadata, field: FieldMetadata): Promise<void>;
23
+ }
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DefaultMigrationBuilder = void 0;
4
+ var tslib_1 = require("tslib");
5
+ var DefaultMigrationBuilder = /** @class */ (function () {
6
+ function DefaultMigrationBuilder(code) {
7
+ this.code = code;
8
+ }
9
+ DefaultMigrationBuilder.prototype.createTable = function (meta) {
10
+ return tslib_1.__awaiter(this, void 0, void 0, function () {
11
+ return tslib_1.__generator(this, function (_a) {
12
+ this.code.addComment('create table ' + meta.entityType.name);
13
+ return [2 /*return*/];
14
+ });
15
+ });
16
+ };
17
+ DefaultMigrationBuilder.prototype.addColumn = function (meta, field) {
18
+ return tslib_1.__awaiter(this, void 0, void 0, function () {
19
+ return tslib_1.__generator(this, function (_a) {
20
+ this.code.addComment('add column ' + meta.entityType.name + '.' + field.key);
21
+ return [2 /*return*/];
22
+ });
23
+ });
24
+ };
25
+ return DefaultMigrationBuilder;
26
+ }());
27
+ exports.DefaultMigrationBuilder = DefaultMigrationBuilder;
@@ -0,0 +1 @@
1
+ export declare function updateMigrationsFile(filePath: string, steps: string[]): Promise<void>;