remult 0.25.8-exp.0 → 0.25.8-exp.2

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 (39) hide show
  1. package/esm/migrations/generate-migrations.js +21 -5
  2. package/esm/migrations/migrate.js +35 -14
  3. package/esm/migrations/update-migrations-ts-file.js +1 -1
  4. package/esm/postgres/postgres-data-provider.js +12 -3
  5. package/esm/remult-knex/index.js +6 -2
  6. package/esm/remult-mongo.js +2 -2
  7. package/esm/remult-sql-js.js +5 -0
  8. package/esm/server/expressBridge.js +50 -16
  9. package/esm/src/data-api.js +11 -8
  10. package/esm/src/data-providers/sql-database.js +7 -3
  11. package/esm/src/data-providers/web-sql-data-provider.js +1 -9
  12. package/esm/src/remult3/remult3.js +8 -18
  13. package/esm/src/server-action.js +2 -2
  14. package/migrations/generate-migrations.d.ts +17 -4
  15. package/migrations/generate-migrations.js +24 -6
  16. package/migrations/migrate.d.ts +13 -2
  17. package/migrations/migrate.js +73 -51
  18. package/migrations/migration-types.d.ts +20 -0
  19. package/migrations/update-migrations-ts-file.js +1 -1
  20. package/package.json +1 -1
  21. package/postgres/postgres-data-provider.d.ts +5 -2
  22. package/postgres/postgres-data-provider.js +12 -3
  23. package/remult-knex/index.d.ts +3 -3
  24. package/remult-knex/index.js +6 -2
  25. package/remult-mongo.d.ts +2 -2
  26. package/remult-mongo.js +2 -2
  27. package/remult-sql-js.d.ts +2 -0
  28. package/remult-sql-js.js +14 -0
  29. package/server/expressBridge.d.ts +21 -0
  30. package/server/expressBridge.js +63 -17
  31. package/src/data-api.d.ts +2 -2
  32. package/src/data-api.js +11 -8
  33. package/src/data-providers/sql-database.d.ts +3 -5
  34. package/src/data-providers/sql-database.js +5 -2
  35. package/src/data-providers/web-sql-data-provider.d.ts +1 -2
  36. package/src/data-providers/web-sql-data-provider.js +4 -8
  37. package/src/remult3/remult3.js +8 -18
  38. package/src/server-action.js +2 -2
  39. package/src/sql-command.d.ts +1 -0
@@ -4,12 +4,25 @@ import { compareMigrationSnapshot, emptySnapshot, } from './compare-migration-sn
4
4
  import { updateMigrationsFile } from './update-migrations-ts-file.js';
5
5
  import { DefaultMigrationBuilder, } from './migration-types.js';
6
6
  import { isOfType } from '../src/isOfType.js';
7
+ import { initDataProvider } from '../server/initDataProvider.js';
8
+ /**
9
+ * Generates migration scripts based on changes in entities.
10
+ *
11
+ * @param options - Configuration options for generating migrations.
12
+ * @param options.entities - An array of entity classes to be included in the migration.
13
+ * @param options.dataProvider - The data provider instance or a function returning a promise of the data provider.
14
+ * @param options.migrationsFolder - (Optional) The path to the folder where migration scripts will be stored. Default is 'src/server/migrations'.
15
+ * @param options.snapshotFile - (Optional) The path to the file where the snapshot of the last known state will be stored. Default is 'migrations-snapshot.json' in the `migrationsFolder`.
16
+ * @param options.migrationsTSFile - (Optional) The path to the TypeScript file where the generated migrations will be written. Default is 'migrations.ts' in the `migrationsFolder`.
17
+ * @param options.endConnection - (Optional) Determines whether to close the database connection after generating migrations. Default is true.
18
+ * @see [Migrations](http://remult.dev/docs/migrations.html)
19
+ */
7
20
  export async function generateMigrations(options) {
8
- const migrationDir = options.migrationsDir || path.join(process.cwd(), 'src/server/migrations');
9
- const snapshotFileName = options.snapshotFileName ||
10
- path.join(migrationDir, 'migrations-snapshot.json');
11
- const migrationsTSFilename = options.migrationsTSFilename || path.join(migrationDir, 'migrations.ts');
12
- const dataProvider = await options.dataProvider;
21
+ const migrationDir = options.migrationsFolder ||
22
+ path.join(process.cwd(), 'src/server/migrations');
23
+ const snapshotFileName = options.snapshotFile || path.join(migrationDir, 'migrations-snapshot.json');
24
+ const migrationsTSFilename = options.migrationsTSFile || path.join(migrationDir, 'migrations.ts');
25
+ const dataProvider = await initDataProvider(options.dataProvider);
13
26
  for (const p of [snapshotFileName, migrationsTSFilename]) {
14
27
  if (!fs.existsSync(path.dirname(p))) {
15
28
  fs.mkdirSync(path.dirname(p), { recursive: true });
@@ -44,4 +57,7 @@ export async function generateMigrations(options) {
44
57
  `async (${hasSql ? '{sql}' : ''})=>{\n${steps.join('\n')}\n}`,
45
58
  ]);
46
59
  fs.writeFileSync(snapshotFileName, JSON.stringify(snapshot, null, 2));
60
+ if (options.endConnection !== false && isOfType(dataProvider, 'end')) {
61
+ await dataProvider.end();
62
+ }
47
63
  }
@@ -1,12 +1,21 @@
1
1
  import { __decorate, __metadata } from "tslib";
2
2
  import { Entity, IdEntity, Fields, remult, Remult, } from '../index.js';
3
+ import { initDataProvider } from '../server/initDataProvider.js';
3
4
  import { doTransaction } from '../src/context.js';
4
- import { cast } from '../src/isOfType.js';
5
+ import { cast, isOfType } from '../src/isOfType.js';
6
+ /**
7
+ * Applies migration scripts to update the database schema.
8
+ *
9
+ * @param options - Configuration options for applying migrations.
10
+ * @param options.migrations - An object containing the migration scripts, each keyed by a unique identifier.
11
+ * @param options.dataProvider - The data provider instance or a function returning a promise of the data provider.
12
+ * @param options.migrationsTable - (Optional) The name of the table that tracks applied migrations. Default is '__remult_migrations_version'.
13
+ * @param options.endConnection - (Optional) Determines whether to close the database connection after applying migrations. Default is true.
14
+ * @see [Migrations](http://remult.dev/docs/migrations.html)
15
+ */
5
16
  export async function migrate(options) {
6
- let migrationTableName = options.migrationTableName || '__remult_migration_version';
7
- const dataProvider = options.dataProvider
8
- ? await options.dataProvider
9
- : remult.dataProvider;
17
+ let migrationTableName = options.migrationsTable || '__remult_migrations_version';
18
+ const dataProvider = await initDataProvider(options.dataProvider);
10
19
  const prev = remult.dataProvider;
11
20
  remult.dataProvider = dataProvider;
12
21
  try {
@@ -36,15 +45,24 @@ export async function migrate(options) {
36
45
  throw new Error('Migration step number must be a non-negative integer');
37
46
  if (v.version >= step)
38
47
  continue;
39
- console.info('Executing migration step', step);
40
- await doTransaction(remult, async (dp) => {
41
- const utils = {
42
- sql: async (sql) => {
43
- await cast(dp, 'execute').execute(sql);
44
- },
45
- };
46
- await action(utils);
47
- });
48
+ console.info('Executing migration step ' + step);
49
+ console.time('Completed migration step ' + step);
50
+ try {
51
+ await doTransaction(remult, async (dp) => {
52
+ const utils = {
53
+ sql: async (sql) => {
54
+ await cast(dp, 'execute').execute(sql);
55
+ },
56
+ };
57
+ await action(utils);
58
+ });
59
+ console.timeEnd('Completed migration step ' + step);
60
+ }
61
+ catch (err) {
62
+ console.error('Failed to execute migration step ' + step);
63
+ console.error(err);
64
+ throw err;
65
+ }
48
66
  v.version = step;
49
67
  await v.save();
50
68
  }
@@ -52,4 +70,7 @@ export async function migrate(options) {
52
70
  finally {
53
71
  remult.dataProvider = prev;
54
72
  }
73
+ if (options.endConnection !== false && isOfType(dataProvider, 'end')) {
74
+ await dataProvider.end();
75
+ }
55
76
  }
@@ -10,7 +10,7 @@ export async function updateMigrationsFile(filePath, steps) {
10
10
  fs.writeFileSync(filePath, '');
11
11
  }
12
12
  const importPath = 'remult/migrations';
13
- const importName = 'MigrationSteps';
13
+ const importName = 'Migrations';
14
14
  // Load the file
15
15
  const sourceFile = ts.createSourceFile(filePath, fs.readFileSync(filePath).toString(), ts.ScriptTarget.Latest, true);
16
16
  let migrationsExportFound = false;
@@ -1,3 +1,4 @@
1
+ import { remult as defaultRemult } from '../src/remult-proxy.js';
1
2
  import pg from 'pg';
2
3
  const { Pool } = pg;
3
4
  import { Remult } from '../src/context.js';
@@ -7,9 +8,11 @@ export class PostgresDataProvider {
7
8
  pool;
8
9
  options;
9
10
  supportsJsonColumnType = true;
10
- static getDb(remult) {
11
- const sql = SqlDatabase.getDb(remult);
12
- const me = sql._getSourceSql();
11
+ static getDb(dataProvider) {
12
+ const r = (dataProvider || defaultRemult.dataProvider);
13
+ if (!r._getSourceSql)
14
+ throw 'the data provider is not an SqlDatabase';
15
+ const me = r._getSourceSql();
13
16
  if (!me.pool) {
14
17
  throw 'the data provider is not a PostgresDataProvider';
15
18
  }
@@ -35,6 +38,9 @@ export class PostgresDataProvider {
35
38
  this.pool = new PostgresSchemaWrapper(pool, options.schema);
36
39
  }
37
40
  }
41
+ end() {
42
+ return this.pool.end();
43
+ }
38
44
  provideMigrationBuilder(builder) {
39
45
  var db = new SqlDatabase(this);
40
46
  var sb = new PostgresSchemaBuilder(db, this.options?.schema);
@@ -184,4 +190,7 @@ export class PostgresSchemaWrapper {
184
190
  c.release();
185
191
  }
186
192
  }
193
+ end() {
194
+ return this.pool.end();
195
+ }
187
196
  }
@@ -13,6 +13,10 @@ export class KnexDataProvider {
13
13
  constructor(knex) {
14
14
  this.knex = knex;
15
15
  }
16
+ end() {
17
+ return this.knex.destroy();
18
+ }
19
+ /* @internal */
16
20
  provideMigrationBuilder(builder) {
17
21
  var sb = new KnexSchemaBuilder(this.knex);
18
22
  return {
@@ -37,8 +41,8 @@ export class KnexDataProvider {
37
41
  execute(sql) {
38
42
  return this.createCommand().execute(sql);
39
43
  }
40
- static getDb(remult) {
41
- const r = (remult || remultContext).dataProvider;
44
+ static getDb(dataProvider) {
45
+ const r = (dataProvider || remultContext.dataProvider);
42
46
  if (!r.knex)
43
47
  throw 'the data provider is not an KnexDataProvider';
44
48
  return r.knex;
@@ -16,8 +16,8 @@ export class MongoDataProvider {
16
16
  }
17
17
  session;
18
18
  disableTransactions = false;
19
- static getDb(remult) {
20
- const r = (remult || remultContext).dataProvider;
19
+ static getDb(dataProvider) {
20
+ const r = (dataProvider || remultContext.dataProvider);
21
21
  if (!r.db)
22
22
  throw 'the data provider is not a MongoDataProvider';
23
23
  return { db: r.db, session: r.session };
@@ -6,6 +6,11 @@ export class SqlJsDataProvider {
6
6
  constructor(db) {
7
7
  this.db = db;
8
8
  }
9
+ orderByNullsFirst;
10
+ async end() {
11
+ ;
12
+ (await this.db).close();
13
+ }
9
14
  getLimitSqlSyntax(limit, offset) {
10
15
  return ' limit ' + limit + ' offset ' + offset;
11
16
  }
@@ -13,6 +13,7 @@ import { serverActionField } from '../src/server-action-info.js';
13
13
  import { initDataProvider } from './initDataProvider.js';
14
14
  import { remultStatic } from '../src/remult-static.js';
15
15
  import remultAdminHtml from './remult-admin.js';
16
+ import { isOfType } from '../src/isOfType.js';
16
17
  export function createRemultServerCore(options, serverCoreOptions) {
17
18
  if (!options) {
18
19
  options = {};
@@ -285,7 +286,7 @@ export class RemultServerImplementation {
285
286
  genReq.params = req['_tempParams'];
286
287
  }
287
288
  let myReq = new ExpressRequestBridgeToDataApiRequest(genReq);
288
- let myRes = new ExpressResponseBridgeToDataApiResponse(origRes, req);
289
+ let myRes = new ExpressResponseBridgeToDataApiResponse(origRes, req, this.options.error);
289
290
  try {
290
291
  await this.runWithRemult(async (remult) => {
291
292
  if (req) {
@@ -315,7 +316,7 @@ export class RemultServerImplementation {
315
316
  });
316
317
  }
317
318
  catch (err) {
318
- myRes.error(serializeError(err));
319
+ myRes.error(err, undefined);
319
320
  }
320
321
  };
321
322
  }
@@ -673,15 +674,17 @@ class ExpressRequestBridgeToDataApiRequest {
673
674
  class ExpressResponseBridgeToDataApiResponse {
674
675
  r;
675
676
  req;
677
+ handleError;
676
678
  forbidden() {
677
- this.setStatus(403).end();
679
+ this.error({ message: 'Forbidden' }, undefined, 403);
678
680
  }
679
681
  setStatus(status) {
680
682
  return this.r.status(status);
681
683
  }
682
- constructor(r, req) {
684
+ constructor(r, req, handleError) {
683
685
  this.r = r;
684
686
  this.req = req;
687
+ this.handleError = handleError;
685
688
  }
686
689
  progress(progress) { }
687
690
  success(data) {
@@ -694,22 +697,53 @@ class ExpressResponseBridgeToDataApiResponse {
694
697
  this.setStatus(204).end();
695
698
  }
696
699
  notFound() {
697
- this.setStatus(404).end();
700
+ this.error({ message: 'Forbidden' }, undefined, 404);
698
701
  }
699
- error(data) {
700
- data = serializeError(data);
701
- console.error({
702
- message: data.message,
703
- stack: data.stack?.split('\n'),
704
- url: this.req?.url,
705
- method: this.req?.method,
702
+ async error(exception, entity, httpStatusCode) {
703
+ let data = serializeError(exception);
704
+ if (!httpStatusCode) {
705
+ if (data.httpStatusCode) {
706
+ httpStatusCode = data.httpStatusCode;
707
+ }
708
+ else if (isOfType(exception, 'isForbiddenError') &&
709
+ exception.isForbiddenError) {
710
+ httpStatusCode = 403;
711
+ }
712
+ else if (data.modelState) {
713
+ httpStatusCode = 400;
714
+ }
715
+ else {
716
+ httpStatusCode = 500;
717
+ }
718
+ }
719
+ let responseSent = false;
720
+ const sendError = (httpStatusCode, body) => {
721
+ if (responseSent) {
722
+ throw Error('Error response already sent');
723
+ }
724
+ responseSent = true;
725
+ console.error({
726
+ message: body.message,
727
+ httpStatusCode,
728
+ stack: data.stack?.split('\n'),
729
+ url: this.req?.url,
730
+ method: this.req?.method,
731
+ });
732
+ this.setStatus(httpStatusCode).json(body);
733
+ };
734
+ await this.handleError?.({
735
+ httpStatusCode,
736
+ req: this.req,
737
+ entity,
738
+ exception,
739
+ responseBody: data,
740
+ sendError,
706
741
  });
707
- this.setStatus(400).json(data);
742
+ if (!responseSent) {
743
+ sendError(httpStatusCode, data);
744
+ }
708
745
  }
709
746
  }
710
- function throwError() {
711
- throw 'Invalid';
712
- }
713
747
  class inProcessQueueHandler {
714
748
  storage;
715
749
  constructor(storage) {
@@ -61,7 +61,7 @@ export class DataApi {
61
61
  });
62
62
  }
63
63
  catch (err) {
64
- response.error(err);
64
+ response.error(err, this.repository.metadata);
65
65
  }
66
66
  }
67
67
  async deleteMany(response, request, filterBody) {
@@ -79,7 +79,7 @@ export class DataApi {
79
79
  });
80
80
  }
81
81
  catch (err) {
82
- response.error(err);
82
+ response.error(err, this.repository.metadata);
83
83
  }
84
84
  }
85
85
  async getArrayImpl(response, request, filterBody) {
@@ -159,7 +159,7 @@ export class DataApi {
159
159
  if (err.isForbiddenError)
160
160
  response.forbidden();
161
161
  else
162
- response.error(err);
162
+ response.error(err, this.repository.metadata);
163
163
  }
164
164
  }
165
165
  async liveQuery(response, request, filterBody, serializeContext, queryChannel) {
@@ -185,7 +185,7 @@ export class DataApi {
185
185
  if (err.isForbiddenError)
186
186
  response.forbidden();
187
187
  else
188
- response.error(err);
188
+ response.error(err, this.repository.metadata);
189
189
  }
190
190
  }
191
191
  async buildWhere(request, filterBody) {
@@ -232,13 +232,16 @@ export class DataApi {
232
232
  if (r.length == 0)
233
233
  response.notFound();
234
234
  else if (r.length > 1)
235
- response.error({ message: 'id is not unique' });
235
+ response.error({
236
+ message: `id "${id}" is not unique for entity ` +
237
+ this.repository.metadata.key,
238
+ }, this.repository.metadata, 500);
236
239
  else
237
240
  await what(r[0]);
238
241
  });
239
242
  }
240
243
  catch (err) {
241
- response.error(err);
244
+ response.error(err, this.repository.metadata);
242
245
  }
243
246
  }
244
247
  async updateMany(response, request, body) {
@@ -256,7 +259,7 @@ export class DataApi {
256
259
  });
257
260
  }
258
261
  catch (err) {
259
- response.error(err);
262
+ response.error(err, this.repository.metadata);
260
263
  }
261
264
  }
262
265
  async actualUpdate(row, body) {
@@ -313,7 +316,7 @@ export class DataApi {
313
316
  if (err.isForbiddenError)
314
317
  response.forbidden();
315
318
  else
316
- response.error(err);
319
+ response.error(err, this.repository.metadata);
317
320
  }
318
321
  }
319
322
  }
@@ -10,8 +10,8 @@ import { isOfType } from '../isOfType.js';
10
10
  // @dynamic
11
11
  export class SqlDatabase {
12
12
  sql;
13
- static getDb(remult) {
14
- const r = (remult || defaultRemult).dataProvider;
13
+ static getDb(dataProvider) {
14
+ const r = (dataProvider || defaultRemult.dataProvider);
15
15
  if (isOfType(r, 'createCommand'))
16
16
  return r;
17
17
  else
@@ -76,6 +76,7 @@ export class SqlDatabase {
76
76
  transaction: (z) => x.transaction(z),
77
77
  supportsJsonColumnType: this.sql.supportsJsonColumnType,
78
78
  wrapIdentifier: this.wrapIdentifier,
79
+ end: this.end,
79
80
  }));
80
81
  }
81
82
  finally {
@@ -121,10 +122,13 @@ export class SqlDatabase {
121
122
  if (isOfType(sql, 'provideMigrationBuilder')) {
122
123
  this.provideMigrationBuilder = sql.provideMigrationBuilder;
123
124
  }
125
+ if (isOfType(sql, 'end'))
126
+ this.end = () => sql.end();
124
127
  }
128
+ /* @internal */
125
129
  provideMigrationBuilder;
126
- isProxy;
127
130
  createdEntities = [];
131
+ end;
128
132
  }
129
133
  const icons = new Map([
130
134
  // CRUD
@@ -13,15 +13,7 @@ export class WebSqlDataProvider {
13
13
  //@ts-ignore
14
14
  this.db = window.openDatabase(databaseName, '1.0', databaseName, databaseSize);
15
15
  }
16
- // return instance of websql.Database class - see @types/websql
17
- static getDb(remult) {
18
- const sql = SqlDatabase.getDb(remult);
19
- const me = sql._getSourceSql();
20
- if (!me.db) {
21
- throw 'the data provider is not a WebSqlDataProvider';
22
- }
23
- return me.db;
24
- }
16
+ async end() { }
25
17
  getLimitSqlSyntax(limit, offset) {
26
18
  return ' limit ' + limit + ' offset ' + offset;
27
19
  }
@@ -1,27 +1,17 @@
1
1
  export {};
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
2
  //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
3
+ /*p1 - discuss using delete & put - with url query language for deleteMany and updateMany -
4
+ - put & delete, similar to get
5
+ - add where to count, deleteMany,updateMany,
6
+ - prevent delete all and update all - must have meaningful where.
7
+ - try forcing this also in typescript
19
8
 
20
- - protect against deleting of all rows by mistake
21
- - https://github.com/remult/remult/issues/221#issuecomment-2016519746
9
+ - protect against deleting of all rows by mistake
10
+ - https://github.com/remult/remult/issues/221#issuecomment-2016519746
22
11
 
23
12
  */
24
13
  //y1 - getFields didn't work for kobi in the home component
14
+ //p1 - document offline support
25
15
  //p1 - add section to Fields doc, explaining field type in db
26
16
  //p1 - add section about union type
27
17
  //p1 - add section about value list field type
@@ -65,7 +65,7 @@ export class Action {
65
65
  // got a problem in next with instance of ForbiddenError - so replaced it with this bool
66
66
  res.forbidden();
67
67
  else
68
- res.error(err);
68
+ res.error(err, undefined);
69
69
  }
70
70
  });
71
71
  }
@@ -245,7 +245,7 @@ export function BackendMethod(options) {
245
245
  // got a problem in next with instance of ForbiddenError - so replaced it with this bool
246
246
  res.forbidden();
247
247
  else
248
- res.error(err);
248
+ res.error(err, undefined);
249
249
  }
250
250
  });
251
251
  }
@@ -1,8 +1,21 @@
1
1
  import type { DataProvider } from '../index.js';
2
+ /**
3
+ * Generates migration scripts based on changes in entities.
4
+ *
5
+ * @param options - Configuration options for generating migrations.
6
+ * @param options.entities - An array of entity classes to be included in the migration.
7
+ * @param options.dataProvider - The data provider instance or a function returning a promise of the data provider.
8
+ * @param options.migrationsFolder - (Optional) The path to the folder where migration scripts will be stored. Default is 'src/server/migrations'.
9
+ * @param options.snapshotFile - (Optional) The path to the file where the snapshot of the last known state will be stored. Default is 'migrations-snapshot.json' in the `migrationsFolder`.
10
+ * @param options.migrationsTSFile - (Optional) The path to the TypeScript file where the generated migrations will be written. Default is 'migrations.ts' in the `migrationsFolder`.
11
+ * @param options.endConnection - (Optional) Determines whether to close the database connection after generating migrations. Default is true.
12
+ * @see [Migrations](http://remult.dev/docs/migrations.html)
13
+ */
2
14
  export declare function generateMigrations(options: {
3
15
  entities: any[];
4
- dataProvider: Promise<DataProvider> | DataProvider;
5
- migrationsDir?: string;
6
- snapshotFileName?: string;
7
- migrationsTSFilename?: string;
16
+ dataProvider: DataProvider | Promise<DataProvider> | (() => Promise<DataProvider | undefined>);
17
+ migrationsFolder?: string;
18
+ snapshotFile?: string;
19
+ migrationsTSFile?: string;
20
+ endConnection?: boolean;
8
21
  }): Promise<void>;
@@ -8,6 +8,19 @@ var compare_migration_snapshots_js_1 = require("./compare-migration-snapshots.js
8
8
  var update_migrations_ts_file_js_1 = require("./update-migrations-ts-file.js");
9
9
  var migration_types_js_1 = require("./migration-types.js");
10
10
  var isOfType_js_1 = require("../src/isOfType.js");
11
+ var initDataProvider_js_1 = require("../server/initDataProvider.js");
12
+ /**
13
+ * Generates migration scripts based on changes in entities.
14
+ *
15
+ * @param options - Configuration options for generating migrations.
16
+ * @param options.entities - An array of entity classes to be included in the migration.
17
+ * @param options.dataProvider - The data provider instance or a function returning a promise of the data provider.
18
+ * @param options.migrationsFolder - (Optional) The path to the folder where migration scripts will be stored. Default is 'src/server/migrations'.
19
+ * @param options.snapshotFile - (Optional) The path to the file where the snapshot of the last known state will be stored. Default is 'migrations-snapshot.json' in the `migrationsFolder`.
20
+ * @param options.migrationsTSFile - (Optional) The path to the TypeScript file where the generated migrations will be written. Default is 'migrations.ts' in the `migrationsFolder`.
21
+ * @param options.endConnection - (Optional) Determines whether to close the database connection after generating migrations. Default is true.
22
+ * @see [Migrations](http://remult.dev/docs/migrations.html)
23
+ */
11
24
  function generateMigrations(options) {
12
25
  return tslib_1.__awaiter(this, void 0, void 0, function () {
13
26
  var migrationDir, snapshotFileName, migrationsTSFilename, dataProvider, _a, _b, p, snapshot, hasSql, steps, code, migrationBuilder;
@@ -15,11 +28,11 @@ function generateMigrations(options) {
15
28
  return tslib_1.__generator(this, function (_d) {
16
29
  switch (_d.label) {
17
30
  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];
31
+ migrationDir = options.migrationsFolder ||
32
+ path_1.default.join(process.cwd(), 'src/server/migrations');
33
+ snapshotFileName = options.snapshotFile || path_1.default.join(migrationDir, 'migrations-snapshot.json');
34
+ migrationsTSFilename = options.migrationsTSFile || path_1.default.join(migrationDir, 'migrations.ts');
35
+ return [4 /*yield*/, (0, initDataProvider_js_1.initDataProvider)(options.dataProvider)];
23
36
  case 1:
24
37
  dataProvider = _d.sent();
25
38
  try {
@@ -74,7 +87,12 @@ function generateMigrations(options) {
74
87
  _d.label = 4;
75
88
  case 4:
76
89
  fs_1.default.writeFileSync(snapshotFileName, JSON.stringify(snapshot, null, 2));
77
- return [2 /*return*/];
90
+ if (!(options.endConnection !== false && (0, isOfType_js_1.isOfType)(dataProvider, 'end'))) return [3 /*break*/, 6];
91
+ return [4 /*yield*/, dataProvider.end()];
92
+ case 5:
93
+ _d.sent();
94
+ _d.label = 6;
95
+ case 6: return [2 /*return*/];
78
96
  }
79
97
  });
80
98
  });
@@ -1,7 +1,18 @@
1
1
  import { type DataProvider } from '../index.js';
2
2
  import type { Migrations } from './migration-types.js';
3
+ /**
4
+ * Applies migration scripts to update the database schema.
5
+ *
6
+ * @param options - Configuration options for applying migrations.
7
+ * @param options.migrations - An object containing the migration scripts, each keyed by a unique identifier.
8
+ * @param options.dataProvider - The data provider instance or a function returning a promise of the data provider.
9
+ * @param options.migrationsTable - (Optional) The name of the table that tracks applied migrations. Default is '__remult_migrations_version'.
10
+ * @param options.endConnection - (Optional) Determines whether to close the database connection after applying migrations. Default is true.
11
+ * @see [Migrations](http://remult.dev/docs/migrations.html)
12
+ */
3
13
  export declare function migrate(options: {
4
14
  migrations: Migrations;
5
- dataProvider?: Promise<DataProvider> | DataProvider;
6
- migrationTableName?: string;
15
+ dataProvider: DataProvider | Promise<DataProvider> | (() => Promise<DataProvider | undefined>);
16
+ migrationsTable?: string;
17
+ endConnection?: boolean;
7
18
  }): Promise<void>;