@balena/pinejs 15.0.0-delete-state-default-user-permissions-8b5de27c634f2e7581f0bcf3600066d2fe4bbf40 → 15.0.0-deprecate-node12-8a99d72ae66d7708293afc56c5d7eb19b39081cd

Sign up to get free protection for your applications and to get access to all the features.
Files changed (65) hide show
  1. package/.resinci.yml +0 -1
  2. package/.versionbot/CHANGELOG.yml +158 -9
  3. package/CHANGELOG.md +57 -2
  4. package/out/bin/utils.js +1 -1
  5. package/out/bin/utils.js.map +1 -1
  6. package/out/config-loader/config-loader.d.ts +1 -1
  7. package/out/config-loader/config-loader.js +10 -28
  8. package/out/config-loader/config-loader.js.map +1 -1
  9. package/out/data-server/sbvr-server.js +8 -8
  10. package/out/data-server/sbvr-server.js.map +1 -1
  11. package/out/database-layer/db.d.ts +1 -1
  12. package/out/database-layer/db.js +3 -3
  13. package/out/database-layer/db.js.map +1 -1
  14. package/out/express-emulator/express.js +1 -1
  15. package/out/express-emulator/express.js.map +1 -1
  16. package/out/http-transactions/transactions.js +4 -4
  17. package/out/http-transactions/transactions.js.map +1 -1
  18. package/out/migrator/sync.js +6 -6
  19. package/out/migrator/sync.js.map +1 -1
  20. package/out/migrator/utils.d.ts +2 -2
  21. package/out/migrator/utils.js +16 -17
  22. package/out/migrator/utils.js.map +1 -1
  23. package/out/odata-metadata/odata-metadata-generator.js +6 -9
  24. package/out/odata-metadata/odata-metadata-generator.js.map +1 -1
  25. package/out/passport-pinejs/passport-pinejs.js +1 -1
  26. package/out/passport-pinejs/passport-pinejs.js.map +1 -1
  27. package/out/pinejs-session-store/pinejs-session-store.js +1 -1
  28. package/out/pinejs-session-store/pinejs-session-store.js.map +1 -1
  29. package/out/sbvr-api/abstract-sql.d.ts +1 -1
  30. package/out/sbvr-api/abstract-sql.js.map +1 -1
  31. package/out/sbvr-api/control-flow.js.map +1 -1
  32. package/out/sbvr-api/hooks.d.ts +6 -3
  33. package/out/sbvr-api/hooks.js +3 -3
  34. package/out/sbvr-api/hooks.js.map +1 -1
  35. package/out/sbvr-api/odata-response.js +5 -5
  36. package/out/sbvr-api/odata-response.js.map +1 -1
  37. package/out/sbvr-api/permissions.js +25 -20
  38. package/out/sbvr-api/permissions.js.map +1 -1
  39. package/out/sbvr-api/sbvr-utils.d.ts +4 -3
  40. package/out/sbvr-api/sbvr-utils.js +68 -45
  41. package/out/sbvr-api/sbvr-utils.js.map +1 -1
  42. package/out/sbvr-api/uri-parser.d.ts +13 -11
  43. package/out/sbvr-api/uri-parser.js +4 -4
  44. package/out/sbvr-api/uri-parser.js.map +1 -1
  45. package/out/server-glue/module.js.map +1 -1
  46. package/package.json +13 -13
  47. package/src/bin/utils.ts +1 -1
  48. package/src/config-loader/config-loader.ts +15 -35
  49. package/src/data-server/sbvr-server.js +8 -8
  50. package/src/database-layer/db.ts +11 -11
  51. package/src/express-emulator/express.js +1 -1
  52. package/src/http-transactions/transactions.js +4 -4
  53. package/src/migrator/sync.ts +9 -11
  54. package/src/migrator/utils.ts +18 -24
  55. package/src/odata-metadata/odata-metadata-generator.ts +8 -11
  56. package/src/sbvr-api/abstract-sql.ts +6 -3
  57. package/src/sbvr-api/control-flow.ts +2 -2
  58. package/src/sbvr-api/hooks.ts +18 -8
  59. package/src/sbvr-api/odata-response.ts +4 -4
  60. package/src/sbvr-api/permissions.ts +42 -36
  61. package/src/sbvr-api/sbvr-utils.ts +118 -55
  62. package/src/sbvr-api/uri-parser.ts +29 -21
  63. package/src/server-glue/module.ts +1 -1
  64. package/tsconfig.json +1 -3
  65. package/typings/lf-to-abstract-sql.d.ts +6 -9
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@balena/pinejs",
3
- "version": "15.0.0-delete-state-default-user-permissions-8b5de27c634f2e7581f0bcf3600066d2fe4bbf40",
3
+ "version": "15.0.0-deprecate-node12-8a99d72ae66d7708293afc56c5d7eb19b39081cd",
4
4
  "main": "out/server-glue/module",
5
5
  "repository": "git@github.com:balena-io/pinejs.git",
6
6
  "license": "Apache-2.0",
@@ -21,7 +21,7 @@
21
21
  "lint": "balena-lint -e js -e ts src build typings Gruntfile.ts && npx tsc --project tsconfig.dev.json --noEmit",
22
22
  "test": "npm run lint & npm run build && npm run webpack-build",
23
23
  "test:compose": "npm run compose:build && npm run compose:postgres && docker-compose -f docker-compose.test.yml run sut npm run mocha",
24
- "test:fast": " npm run compose:postgres && npm run mocha:local",
24
+ "test:fast": "npm run compose:postgres && npm run mocha:local",
25
25
  "mocha": "TS_NODE_FILES=true mocha",
26
26
  "mocha:local": "DATABASE_URL=postgres://docker:docker@localhost:5431/postgres npm run mocha",
27
27
  "compose:postgres": "docker-compose -f docker-compose.test.yml up -d postgres",
@@ -34,7 +34,7 @@
34
34
  "@balena/abstract-sql-to-typescript": "^1.2.0",
35
35
  "@balena/lf-to-abstract-sql": "^4.5.1",
36
36
  "@balena/odata-parser": "^2.3.0",
37
- "@balena/odata-to-abstract-sql": "^5.4.12",
37
+ "@balena/odata-to-abstract-sql": "^5.4.14",
38
38
  "@balena/sbvr-parser": "^1.4.1",
39
39
  "@balena/sbvr-types": "^3.4.7",
40
40
  "@types/body-parser": "^1.19.2",
@@ -42,20 +42,20 @@
42
42
  "@types/cookie-parser": "^1.4.3",
43
43
  "@types/deep-freeze": "^0.1.2",
44
44
  "@types/express": "^4.17.13",
45
- "@types/express-session": "^1.17.4",
45
+ "@types/express-session": "^1.17.5",
46
46
  "@types/lodash": "^4.14.182",
47
47
  "@types/memoizee": "^0.4.8",
48
48
  "@types/method-override": "^0.0.32",
49
49
  "@types/multer": "^1.4.7",
50
50
  "@types/mysql": "^2.15.21",
51
51
  "@types/node": "^12.20.55",
52
- "@types/passport": "^1.0.8",
52
+ "@types/passport": "^1.0.9",
53
53
  "@types/passport-local": "^1.0.34",
54
54
  "@types/passport-strategy": "^0.2.35",
55
55
  "@types/pg": "^8.6.5",
56
56
  "@types/randomstring": "^1.1.8",
57
57
  "@types/websql": "^0.0.27",
58
- "commander": "^9.3.0",
58
+ "commander": "^9.4.0",
59
59
  "deep-freeze": "^0.0.1",
60
60
  "eventemitter3": "^4.0.7",
61
61
  "express-session": "^1.17.3",
@@ -92,13 +92,13 @@
92
92
  "mocha": "^9.2.2",
93
93
  "raw-loader": "^4.0.2",
94
94
  "require-npm4-to-publish": "^1.0.0",
95
- "supertest": "^6.2.3",
95
+ "supertest": "^6.2.4",
96
96
  "terser-webpack-plugin": "^5.3.3",
97
- "ts-loader": "^9.3.0",
98
- "ts-node": "^10.8.1",
99
- "typescript": "^4.7.3",
97
+ "ts-loader": "^9.3.1",
98
+ "ts-node": "^10.9.1",
99
+ "typescript": "^4.7.4",
100
100
  "webpack": "^5.73.0",
101
- "webpack-dev-server": "^4.9.2"
101
+ "webpack-dev-server": "^4.9.3"
102
102
  },
103
103
  "optionalDependencies": {
104
104
  "bcrypt": "^5.0.1",
@@ -116,7 +116,7 @@
116
116
  "serve-static": "^1.15.0"
117
117
  },
118
118
  "engines": {
119
- "node": ">=10.0.0",
119
+ "node": ">=14.0.0",
120
120
  "npm": ">=6.0.0"
121
121
  },
122
122
  "husky": {
@@ -144,6 +144,6 @@
144
144
  "recursive": true
145
145
  },
146
146
  "versionist": {
147
- "publishedAt": "2022-07-07T13:01:20.151Z"
147
+ "publishedAt": "2022-08-02T12:27:59.997Z"
148
148
  }
149
149
  }
package/src/bin/utils.ts CHANGED
@@ -87,7 +87,7 @@ export const getAbstractSqlModelFromFile = (
87
87
  let lfModel;
88
88
  try {
89
89
  lfModel = generateLfModel(seModel);
90
- } catch (e) {
90
+ } catch (e: any) {
91
91
  throw new Error(
92
92
  `Got '${e.message}' whilst trying to parse the model file as sbvr, if you're using a transpiled language for the model file you will need to either transpile in advance or run via its loader`,
93
93
  );
@@ -44,7 +44,7 @@ export interface Model {
44
44
  export interface User {
45
45
  username: string;
46
46
  password: string;
47
- permissions: string[];
47
+ permissions?: string[];
48
48
  }
49
49
  export interface Config {
50
50
  models: Model[];
@@ -81,7 +81,7 @@ const getOrCreatePermission = async (
81
81
  ) => {
82
82
  try {
83
83
  return await getOrCreate(authApiTx, 'permission', { name: permissionName });
84
- } catch (e) {
84
+ } catch (e: any) {
85
85
  e.message = `Could not create or find permission "${permissionName}": ${e.message}`;
86
86
  throw e;
87
87
  }
@@ -103,20 +103,17 @@ export const setup = (app: Express.Application) => {
103
103
  const permissionsCache: {
104
104
  [index: string]: Promise<number>;
105
105
  } = {};
106
- users.forEach((user) => {
106
+ for (const user of users) {
107
107
  if (user.permissions == null) {
108
- return;
108
+ continue;
109
109
  }
110
- user.permissions.forEach((permissionName) => {
111
- if (permissionsCache[permissionName] != null) {
112
- return;
113
- }
114
- permissionsCache[permissionName] = getOrCreatePermission(
110
+ for (const permissionName of user.permissions) {
111
+ permissionsCache[permissionName] ??= getOrCreatePermission(
115
112
  authApiTx,
116
113
  permissionName,
117
114
  );
118
- });
119
- });
115
+ }
116
+ }
120
117
 
121
118
  await Promise.all(
122
119
  users.map(async (user) => {
@@ -132,34 +129,17 @@ export const setup = (app: Express.Application) => {
132
129
  },
133
130
  );
134
131
  if (user.permissions != null) {
135
- const permissionIds = await Promise.all(
132
+ await Promise.all(
136
133
  user.permissions.map(async (permissionName) => {
137
134
  const permissionID = await permissionsCache[permissionName];
138
135
  await getOrCreate(authApiTx, 'user__has__permission', {
139
136
  user: userID,
140
137
  permission: permissionID,
141
138
  });
142
- return permissionID;
143
139
  }),
144
140
  );
145
-
146
- await authApiTx.delete({
147
- resource: 'user__has__permission',
148
- options: {
149
- $filter: {
150
- user: userID,
151
- ...(permissionIds.length > 0 && {
152
- $not: {
153
- permission: {
154
- $in: permissionIds,
155
- },
156
- },
157
- }),
158
- },
159
- },
160
- });
161
141
  }
162
- } catch (e) {
142
+ } catch (e: any) {
163
143
  e.message = `Could not create or find user "${user.username}": ${e.message}`;
164
144
  throw e;
165
145
  }
@@ -186,7 +166,7 @@ export const setup = (app: Express.Application) => {
186
166
  console.info(
187
167
  'Successfully executed ' + model.modelName + ' model.',
188
168
  );
189
- } catch (err) {
169
+ } catch (err: any) {
190
170
  const message = `Failed to execute ${model.modelName} model from ${model.modelFile}`;
191
171
  if (_.isError(err)) {
192
172
  err.message = message;
@@ -200,11 +180,11 @@ export const setup = (app: Express.Application) => {
200
180
  if (typeof model.customServerCode === 'string') {
201
181
  try {
202
182
  customCode = nodeRequire(model.customServerCode).setup;
203
- } catch (e) {
183
+ } catch (e: any) {
204
184
  e.message = `Error loading custom server code: '${e.message}'`;
205
185
  throw e;
206
186
  }
207
- } else if (_.isObject(model.customServerCode)) {
187
+ } else if (typeof model.customServerCode === 'object') {
208
188
  customCode = model.customServerCode.setup;
209
189
  } else {
210
190
  throw new Error(
@@ -238,7 +218,7 @@ export const setup = (app: Express.Application) => {
238
218
  } else if (typeof config === 'string') {
239
219
  root = path.dirname(config);
240
220
  configObj = await loadConfigFile(config);
241
- } else if (_.isObject(config)) {
221
+ } else if (typeof config === 'object') {
242
222
  root = process.cwd();
243
223
  configObj = config;
244
224
  } else {
@@ -344,7 +324,7 @@ export const setup = (app: Express.Application) => {
344
324
  }),
345
325
  );
346
326
  await loadConfig(configObj);
347
- } catch (err) {
327
+ } catch (err: any) {
348
328
  console.error('Error loading application config', err, err.stack);
349
329
  process.exit(1);
350
330
  }
@@ -228,7 +228,7 @@ export async function setup(app, sbvrUtils, db) {
228
228
  await setupModels(tx);
229
229
  });
230
230
  res.status(200).end();
231
- } catch (err) {
231
+ } catch (/** @type any */ err) {
232
232
  console.error('Error clearing db', err, err.stack);
233
233
  res.status(503).end();
234
234
  }
@@ -255,7 +255,7 @@ export async function setup(app, sbvrUtils, db) {
255
255
  }
256
256
  });
257
257
  res.status(200).end();
258
- } catch (err) {
258
+ } catch (/** @type any */ err) {
259
259
  console.error('Error importing db', err, err.stack);
260
260
  res.status(404).end();
261
261
  }
@@ -278,11 +278,11 @@ export async function setup(app, sbvrUtils, db) {
278
278
  'SELECT * FROM "' + tableName + '";',
279
279
  );
280
280
  let insQuery = '';
281
- result.rows.forEach((currRow) => {
281
+ for (const currRow of result.rows) {
282
282
  let notFirst = false;
283
283
  insQuery += 'INSERT INTO "' + tableName + '" (';
284
284
  let valQuery = '';
285
- for (let propName of Object.keys(currRow)) {
285
+ for (const propName of Object.keys(currRow)) {
286
286
  if (notFirst) {
287
287
  insQuery += ',';
288
288
  valQuery += ',';
@@ -293,13 +293,13 @@ export async function setup(app, sbvrUtils, db) {
293
293
  valQuery += "'" + currRow[propName] + "'";
294
294
  }
295
295
  insQuery += ') values (' + valQuery + ');\n';
296
- });
296
+ }
297
297
  exported += insQuery;
298
298
  }),
299
299
  );
300
300
  });
301
301
  res.json(exported);
302
- } catch (err) {
302
+ } catch (/** @type any */ err) {
303
303
  console.error('Error exporting db', err, err.stack);
304
304
  res.status(503).end();
305
305
  }
@@ -329,7 +329,7 @@ export async function setup(app, sbvrUtils, db) {
329
329
  );
330
330
  });
331
331
  res.status(200).end();
332
- } catch (err) {
332
+ } catch (/** @type any */ err) {
333
333
  console.error('Error backing up db', err, err.stack);
334
334
  res.status(404).end();
335
335
  }
@@ -358,7 +358,7 @@ export async function setup(app, sbvrUtils, db) {
358
358
  );
359
359
  });
360
360
  res.status(200).end();
361
- } catch (err) {
361
+ } catch (/** @type any */ err) {
362
362
  console.error('Error restoring db', err, err.stack);
363
363
  res.status(404).end();
364
364
  }
@@ -36,7 +36,7 @@ const isSqlError = (value: any): value is SQLError => {
36
36
  };
37
37
 
38
38
  export class DatabaseError extends TypedError {
39
- public code: number | string;
39
+ public code?: number | string;
40
40
  constructor(message?: string | CodedError | SQLError) {
41
41
  if (isSqlError(message)) {
42
42
  // If this is a SQLError we have to handle it specially (since it's not actually an instance of Error)
@@ -309,7 +309,7 @@ export abstract class Tx {
309
309
  const t0 = Date.now();
310
310
  try {
311
311
  return await this._executeSql(sql, bindings, ...args);
312
- } catch (err) {
312
+ } catch (err: any) {
313
313
  throw wrapDatabaseError(err);
314
314
  } finally {
315
315
  this.automaticClose.decrementPending();
@@ -420,7 +420,7 @@ const createTransaction = (createFunc: CreateTransactionFn): TransactionFn => {
420
420
  let tx;
421
421
  try {
422
422
  tx = await createFunc(stackTraceErr);
423
- } catch (err) {
423
+ } catch (err: any) {
424
424
  throw wrapDatabaseError(err);
425
425
  }
426
426
  if (fn) {
@@ -428,7 +428,7 @@ const createTransaction = (createFunc: CreateTransactionFn): TransactionFn => {
428
428
  const result = await fn(tx);
429
429
  await tx.end();
430
430
  return result;
431
- } catch (err) {
431
+ } catch (err: any) {
432
432
  try {
433
433
  await tx.rollback();
434
434
  } catch {
@@ -559,7 +559,7 @@ if (maybePg != null) {
559
559
  text: sql,
560
560
  values: bindings,
561
561
  });
562
- } catch (err) {
562
+ } catch (err: any) {
563
563
  if (err.code === PG_UNIQUE_VIOLATION) {
564
564
  throw new UniqueConstraintError(err);
565
565
  }
@@ -584,12 +584,12 @@ if (maybePg != null) {
584
584
  const queryQueue = this.db.queryQueue as Pg.Query[];
585
585
  if (queryQueue.length > 0) {
586
586
  const err = new DatabaseError('Rolling back transaction');
587
- queryQueue.forEach((query) => {
587
+ for (const query of queryQueue) {
588
588
  process.nextTick(() => {
589
589
  // @ts-expect-error typings do not include this function
590
590
  query.handleError(err, this.db.connection);
591
591
  });
592
- });
592
+ }
593
593
  queryQueue.length = 0;
594
594
  }
595
595
  await timeout(
@@ -598,7 +598,7 @@ if (maybePg != null) {
598
598
  'Rolling back transaction timed out',
599
599
  );
600
600
  this.db.release();
601
- } catch (err) {
601
+ } catch (err: any) {
602
602
  err = wrapDatabaseError(err);
603
603
  this.db.release(err);
604
604
  throw err;
@@ -609,7 +609,7 @@ if (maybePg != null) {
609
609
  try {
610
610
  await this.$executeSql('COMMIT;');
611
611
  this.db.release();
612
- } catch (err) {
612
+ } catch (err: any) {
613
613
  this.db.release(err);
614
614
  throw err;
615
615
  }
@@ -719,7 +719,7 @@ if (maybeMysql != null) {
719
719
  result = await fromCallback<MysqlRowArray>((callback) => {
720
720
  this.db.query(sql, bindings, callback);
721
721
  });
722
- } catch (err) {
722
+ } catch (err: any) {
723
723
  if (err.code === MYSQL_UNIQUE_VIOLATION) {
724
724
  // We know that the type is an IError for mysql, but typescript doesn't like the catch obj sugar
725
725
  throw new UniqueConstraintError(err as Mysql.MysqlError);
@@ -852,7 +852,7 @@ if (typeof window !== 'undefined' && window.openDatabase != null) {
852
852
  let result;
853
853
  try {
854
854
  result = await this.tx.executeSql(sql, bindings);
855
- } catch (err) {
855
+ } catch (err: any) {
856
856
  if (err.code === WEBSQL_CONSTRAINT_ERR) {
857
857
  throw new ConstraintError('Constraint failed.');
858
858
  }
@@ -49,7 +49,7 @@ const app = (function () {
49
49
  match,
50
50
  paramName,
51
51
  // Flatten middleware list to handle arrays of middleware in the arg list.
52
- middleware: _.flattenDeep(middleware),
52
+ middleware: middleware.flat(Infinity),
53
53
  });
54
54
  };
55
55
  const process = async function (
@@ -54,7 +54,7 @@ SELECT NOT EXISTS(
54
54
  ) AS result;`,
55
55
  [request.resourceName, id],
56
56
  );
57
- } catch (err) {
57
+ } catch (/** @type any */ err) {
58
58
  logger.error('Unable to check resource locks', err, err.stack);
59
59
  throw new Error('Unable to check resource locks');
60
60
  }
@@ -137,7 +137,7 @@ WHERE "conditional resource"."transaction" = ?;\
137
137
  [transactionID],
138
138
  );
139
139
 
140
- conditionalResources.rows.forEach((conditionalResource) => {
140
+ for (const conditionalResource of conditionalResources.rows) {
141
141
  const { placeholder } = conditionalResource;
142
142
  if (placeholder != null && placeholder.length > 0) {
143
143
  /** @type {Function} */
@@ -151,7 +151,7 @@ WHERE "conditional resource"."transaction" = ?;\
151
151
  // @ts-ignore
152
152
  placeholders[placeholder] = { promise, resolve, reject };
153
153
  }
154
- });
154
+ }
155
155
 
156
156
  // get conditional resources (if exist)
157
157
  await Promise.all(
@@ -255,7 +255,7 @@ WHERE "conditional resource"."transaction" = ?;\
255
255
  await endTransaction(id);
256
256
 
257
257
  res.status(200).end();
258
- } catch (err) {
258
+ } catch (/** @type any */ err) {
259
259
  console.error('Error ending transaction', err, err.stack);
260
260
  res.status(404).json(err);
261
261
  }
@@ -3,7 +3,6 @@ import {
3
3
  MigrationTuple,
4
4
  MigrationError,
5
5
  defaultMigrationCategory,
6
- checkModelAlreadyExists,
7
6
  setExecutedMigrations,
8
7
  getExecutedMigrations,
9
8
  lockMigrations,
@@ -24,17 +23,16 @@ export const postRun = async (tx: Tx, model: ApiRootModel): Promise<void> => {
24
23
  }
25
24
 
26
25
  const modelName = model.apiRoot;
27
-
28
- const exists = await checkModelAlreadyExists(tx, modelName);
29
- if (!exists) {
26
+ const modelIsNew = await sbvrUtils.isModelNew(tx, modelName);
27
+ if (modelIsNew) {
30
28
  (sbvrUtils.api.migrations?.logger.info ?? console.info)(
31
- 'First time executing, running init script',
29
+ `First time executing '${modelName}', running init script`,
32
30
  );
33
31
 
34
32
  await lockMigrations(tx, modelName, async () => {
35
33
  try {
36
34
  await tx.executeSql(initSql);
37
- } catch (err) {
35
+ } catch (err: any) {
38
36
  (sbvrUtils.api.migrations?.logger.error ?? console.error)(
39
37
  `initSql execution error ${err} `,
40
38
  );
@@ -69,10 +67,10 @@ const $run = async (
69
67
 
70
68
  // migrations only run if the model has been executed before,
71
69
  // to make changes that can't be automatically applied
72
- const exists = await checkModelAlreadyExists(tx, modelName);
73
- if (!exists) {
70
+ const modelIsNew = await sbvrUtils.isModelNew(tx, modelName);
71
+ if (modelIsNew) {
74
72
  (sbvrUtils.api.migrations?.logger.info ?? console.info)(
75
- 'First time model has executed, skipping migrations',
73
+ `First time model '${modelName}' has executed, skipping migrations`,
76
74
  );
77
75
 
78
76
  return await setExecutedMigrations(tx, modelName, Object.keys(migrations));
@@ -96,7 +94,7 @@ const $run = async (
96
94
  ...executedMigrations,
97
95
  ...newlyExecutedMigrations,
98
96
  ]);
99
- } catch (err) {
97
+ } catch (err: any) {
100
98
  (sbvrUtils.api.migrations?.logger.error ?? console.error)(
101
99
  `Failed to executed synchronous migrations from api root model ${err}`,
102
100
  );
@@ -124,7 +122,7 @@ const executeMigrations = async (
124
122
  for (const migration of migrations) {
125
123
  await executeMigration(tx, migration);
126
124
  }
127
- } catch (err) {
125
+ } catch (err: any) {
128
126
  (sbvrUtils.api.migrations?.logger.error ?? console.error)(
129
127
  'Error while executing migrations, rolled back',
130
128
  );
@@ -51,7 +51,11 @@ export const lockMigrations = async <T>(
51
51
  tx: Tx,
52
52
  modelName: string,
53
53
  fn: () => Promise<T>,
54
- ): Promise<T> => {
54
+ ): Promise<T | undefined> => {
55
+ if (!(await migrationTablesExist(tx))) {
56
+ return;
57
+ }
58
+
55
59
  try {
56
60
  await tx.executeSql(
57
61
  binds`
@@ -66,7 +70,7 @@ INSERT INTO "migration lock" ("model name")
66
70
  VALUES (${1})`,
67
71
  [modelName],
68
72
  );
69
- } catch (err) {
73
+ } catch (err: any) {
70
74
  await delay(migratorEnv.lockFailDelay);
71
75
  throw err;
72
76
  }
@@ -88,26 +92,6 @@ WHERE "model name" = ${1}`,
88
92
  }
89
93
  };
90
94
 
91
- export const checkModelAlreadyExists = async (
92
- tx: Tx,
93
- modelName: string,
94
- ): Promise<boolean> => {
95
- const result = await tx.tableList("name = 'migration'");
96
- if (result.rows.length === 0) {
97
- return false;
98
- }
99
- const { rows } = await tx.executeSql(
100
- binds`
101
- SELECT 1
102
- FROM "model"
103
- WHERE "model"."is of-vocabulary" = ${1}
104
- LIMIT 1`,
105
- [modelName],
106
- );
107
-
108
- return rows.length > 0;
109
- };
110
-
111
95
  export const setExecutedMigrations = async (
112
96
  tx: Tx,
113
97
  modelName: string,
@@ -115,8 +99,7 @@ export const setExecutedMigrations = async (
115
99
  ): Promise<void> => {
116
100
  const stringifiedMigrations = JSON.stringify(executedMigrations);
117
101
 
118
- const result = await tx.tableList("name = 'migration'");
119
- if (result.rows.length === 0) {
102
+ if (!(await migrationTablesExist(tx))) {
120
103
  return;
121
104
  }
122
105
 
@@ -143,6 +126,10 @@ export const getExecutedMigrations = async (
143
126
  tx: Tx,
144
127
  modelName: string,
145
128
  ): Promise<string[]> => {
129
+ if (!(await migrationTablesExist(tx))) {
130
+ return [];
131
+ }
132
+
146
133
  const { rows } = await tx.executeSql(
147
134
  binds`
148
135
  SELECT "migration"."executed migrations" AS "executed_migrations"
@@ -158,3 +145,10 @@ WHERE "migration"."model name" = ${1}`,
158
145
 
159
146
  return JSON.parse(data.executed_migrations) as string[];
160
147
  };
148
+
149
+ export const migrationTablesExist = async (tx: Tx) => {
150
+ const tables = ['migration', 'migration lock'];
151
+ const where = tables.map((tableName) => `name = '${tableName}'`).join(' OR ');
152
+ const result = await tx.tableList(where);
153
+ return result.rows.length === tables.length;
154
+ };
@@ -21,17 +21,14 @@ const forEachUniqueTable = <T>(
21
21
  const usedTableNames: { [tableName: string]: true } = {};
22
22
 
23
23
  const result = [];
24
- for (const key in model) {
25
- if (model.hasOwnProperty(key)) {
26
- const table = model[key];
27
- if (
28
- typeof table !== 'string' &&
29
- !table.primitive &&
30
- !usedTableNames[table.name]
31
- ) {
32
- usedTableNames[table.name] = true;
33
- result.push(callback(key, table));
34
- }
24
+ for (const [key, table] of Object.entries(model)) {
25
+ if (
26
+ typeof table !== 'string' &&
27
+ !table.primitive &&
28
+ !usedTableNames[table.name]
29
+ ) {
30
+ usedTableNames[table.name] = true;
31
+ result.push(callback(key, table));
35
32
  }
36
33
  }
37
34
  return result;
@@ -47,7 +47,7 @@ export const compileRequest = (request: ODataRequest) => {
47
47
  );
48
48
  request.sqlQuery = sqlQuery;
49
49
  request.modifiedFields = modifiedFields;
50
- } catch (err) {
50
+ } catch (err: any) {
51
51
  sbvrUtils.api[request.vocabulary].logger.error(
52
52
  'Failed to compile abstract sql: ',
53
53
  request.abstractSqlQuery,
@@ -139,7 +139,7 @@ export const getAndCheckBindValues = async (
139
139
 
140
140
  try {
141
141
  return await AbstractSQLCompiler[engine].dataTypeValidate(value, field);
142
- } catch (err) {
142
+ } catch (err: any) {
143
143
  throw new BadRequestError(`"${fieldName}" ${err.message}`);
144
144
  }
145
145
  }),
@@ -173,7 +173,10 @@ const checkModifiedFields = (
173
173
  };
174
174
  export const isRuleAffected = (
175
175
  rule: AbstractSQLCompiler.SqlRule,
176
- request?: ODataRequest,
176
+ request?: Pick<
177
+ ODataRequest,
178
+ 'abstractSqlQuery' | 'modifiedFields' | 'method' | 'vocabulary'
179
+ >,
177
180
  ) => {
178
181
  // If there is no abstract sql query then nothing was modified
179
182
  if (request?.abstractSqlQuery == null) {
@@ -24,7 +24,7 @@ export const settleMapSeries: MappingFunction = async <T, U>(
24
24
  await mapSeries(a, async (p) => {
25
25
  try {
26
26
  return await fn(p);
27
- } catch (err) {
27
+ } catch (err: any) {
28
28
  return ensureError(err);
29
29
  }
30
30
  });
@@ -49,7 +49,7 @@ const mapTill: MappingFunction = async <T, U>(
49
49
  try {
50
50
  const result = await fn(p);
51
51
  results.push(result);
52
- } catch (err) {
52
+ } catch (err: any) {
53
53
  results.push(ensureError(err));
54
54
  break;
55
55
  }