@balena/pinejs 15.3.6-build-fixes-expand-on-parent-resource-34e60c2a2921e971b04422e7901f4dbc4df2dde7-1 → 15.3.6-build-balena-lint-v7-e12b277bc505d89507b61730b026cea7a7e71bc5-1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (86) hide show
  1. package/.versionbot/CHANGELOG.yml +55 -4
  2. package/CHANGELOG.md +9 -3
  3. package/Gruntfile.ts +4 -1
  4. package/README.md +1 -0
  5. package/out/bin/abstract-sql-compiler.js +1 -1
  6. package/out/bin/abstract-sql-compiler.js.map +1 -1
  7. package/out/bin/odata-compiler.js +1 -1
  8. package/out/bin/odata-compiler.js.map +1 -1
  9. package/out/bin/sbvr-compiler.js +1 -1
  10. package/out/bin/sbvr-compiler.js.map +1 -1
  11. package/out/bin/utils.js.map +1 -1
  12. package/out/config-loader/config-loader.js +2 -2
  13. package/out/config-loader/config-loader.js.map +1 -1
  14. package/out/data-server/sbvr-server.d.ts +1 -1
  15. package/out/data-server/sbvr-server.js +3 -1
  16. package/out/data-server/sbvr-server.js.map +1 -1
  17. package/out/database-layer/db.js +10 -10
  18. package/out/database-layer/db.js.map +1 -1
  19. package/out/express-emulator/express.js +4 -2
  20. package/out/express-emulator/express.js.map +1 -1
  21. package/out/http-transactions/transactions.d.ts +1 -1
  22. package/out/http-transactions/transactions.js +10 -5
  23. package/out/http-transactions/transactions.js.map +1 -1
  24. package/out/migrator/utils.d.ts +2 -2
  25. package/out/passport-pinejs/passport-pinejs.d.ts +1 -1
  26. package/out/passport-pinejs/passport-pinejs.js +5 -1
  27. package/out/passport-pinejs/passport-pinejs.js.map +1 -1
  28. package/out/pinejs-session-store/pinejs-session-store.js +6 -6
  29. package/out/pinejs-session-store/pinejs-session-store.js.map +1 -1
  30. package/out/sbvr-api/abstract-sql.js +1 -1
  31. package/out/sbvr-api/abstract-sql.js.map +1 -1
  32. package/out/sbvr-api/cached-compile.js.map +1 -1
  33. package/out/sbvr-api/hooks.js +3 -4
  34. package/out/sbvr-api/hooks.js.map +1 -1
  35. package/out/sbvr-api/odata-response.d.ts +1 -1
  36. package/out/sbvr-api/odata-response.js +2 -9
  37. package/out/sbvr-api/odata-response.js.map +1 -1
  38. package/out/sbvr-api/permissions.d.ts +4 -5
  39. package/out/sbvr-api/permissions.js +6 -4
  40. package/out/sbvr-api/permissions.js.map +1 -1
  41. package/out/sbvr-api/sbvr-utils.d.ts +1 -1
  42. package/out/sbvr-api/sbvr-utils.js +4 -2
  43. package/out/sbvr-api/sbvr-utils.js.map +1 -1
  44. package/out/sbvr-api/uri-parser.js +1 -1
  45. package/out/sbvr-api/uri-parser.js.map +1 -1
  46. package/out/server-glue/global-ext.d.ts +2 -1
  47. package/out/server-glue/module.js.map +1 -1
  48. package/out/webresource-handler/handlers/NoopHandler.d.ts +1 -1
  49. package/out/webresource-handler/handlers/NoopHandler.js +1 -1
  50. package/out/webresource-handler/handlers/NoopHandler.js.map +1 -1
  51. package/out/webresource-handler/index.d.ts +0 -4
  52. package/out/webresource-handler/index.js +30 -20
  53. package/out/webresource-handler/index.js.map +1 -1
  54. package/package.json +8 -8
  55. package/src/bin/abstract-sql-compiler.ts +1 -1
  56. package/src/bin/odata-compiler.ts +1 -1
  57. package/src/bin/sbvr-compiler.ts +1 -1
  58. package/src/bin/utils.ts +1 -1
  59. package/src/config-loader/config-loader.ts +2 -3
  60. package/src/data-server/sbvr-server.js +3 -1
  61. package/src/database-layer/db.ts +18 -14
  62. package/src/express-emulator/express.js +4 -2
  63. package/src/extended-sbvr-parser/extended-sbvr-parser.ts +1 -1
  64. package/src/http-transactions/transactions.js +10 -5
  65. package/src/migrator/sync.ts +1 -1
  66. package/src/migrator/utils.ts +2 -2
  67. package/src/odata-metadata/odata-metadata-generator.ts +1 -1
  68. package/src/passport-pinejs/passport-pinejs.ts +8 -3
  69. package/src/pinejs-session-store/pinejs-session-store.ts +6 -6
  70. package/src/sbvr-api/abstract-sql.ts +1 -1
  71. package/src/sbvr-api/cached-compile.ts +0 -1
  72. package/src/sbvr-api/express-extension.ts +4 -2
  73. package/src/sbvr-api/hooks.ts +3 -4
  74. package/src/sbvr-api/odata-response.ts +10 -19
  75. package/src/sbvr-api/permissions.ts +20 -14
  76. package/src/sbvr-api/sbvr-utils.ts +8 -4
  77. package/src/sbvr-api/uri-parser.ts +1 -1
  78. package/src/server-glue/global-ext.d.ts +2 -1
  79. package/src/server-glue/module.ts +1 -0
  80. package/src/server-glue/sbvr-loader.ts +1 -1
  81. package/src/server-glue/server.ts +2 -2
  82. package/src/webresource-handler/handlers/NoopHandler.ts +1 -1
  83. package/src/webresource-handler/index.ts +47 -28
  84. package/tsconfig.dev.json +2 -1
  85. package/typings/lf-to-abstract-sql.d.ts +1 -1
  86. package/typings/memoizee.d.ts +3 -4
@@ -32,7 +32,6 @@ import {
32
32
  getUploaderMiddlware,
33
33
  WebResourceHandler,
34
34
  setupUploadHooks,
35
- setupWebresourceHandler,
36
35
  } from '../webresource-handler';
37
36
  import { AliasValidNodeType } from '../sbvr-api/translations';
38
37
 
@@ -206,7 +205,6 @@ export const setup = (app: Express.Application) => {
206
205
  const webResourceHandler =
207
206
  data.webResourceHandler ?? getDefaultHandler();
208
207
 
209
- setupWebresourceHandler(webResourceHandler);
210
208
  const fileUploadMiddleware =
211
209
  getUploaderMiddlware(webResourceHandler);
212
210
  app
@@ -379,7 +377,7 @@ export const setup = (app: Express.Application) => {
379
377
  switch (fileExtension) {
380
378
  case '.coffee':
381
379
  case '.ts':
382
- case '.js':
380
+ case '.js': {
383
381
  const loadeMigration = nodeRequire(filePath);
384
382
  const migration = loadeMigration.default ?? loadeMigration;
385
383
 
@@ -394,6 +392,7 @@ export const setup = (app: Express.Application) => {
394
392
 
395
393
  assignMigrationWithCategory(migrationKey, migration);
396
394
  break;
395
+ }
397
396
  case '.sql':
398
397
  if (migrationCategory === MigrationCategories.async) {
399
398
  console.error(
@@ -48,7 +48,7 @@ const serverIsOnAir = async (_req, _res, next) => {
48
48
  };
49
49
 
50
50
  /** @type {import('../config-loader/config-loader').Config} */
51
- export let config = {
51
+ export const config = {
52
52
  models: [
53
53
  {
54
54
  modelName: 'ui',
@@ -267,6 +267,8 @@ export async function setup(app, sbvrUtils, db) {
267
267
  try {
268
268
  await tx.executeSql(query);
269
269
  } catch (err) {
270
+ // TODO: Consider changing this to a custom Error
271
+ // eslint-disable-next-line no-throw-literal
270
272
  throw [query, err];
271
273
  }
272
274
  }
@@ -168,7 +168,7 @@ const atomicExecuteSql: Database['executeSql'] = async function (
168
168
  };
169
169
 
170
170
  const asyncTryFn = (fn: () => any) => {
171
- Promise.resolve().then(fn);
171
+ void Promise.resolve().then(fn);
172
172
  };
173
173
 
174
174
  type RejectedFunctions = (message: string) => {
@@ -215,7 +215,10 @@ class AutomaticClose {
215
215
  private automaticCloseTimeout: ReturnType<typeof setTimeout>;
216
216
  private automaticClose: () => void;
217
217
  private pending: false | number = 0;
218
- constructor(tx: Tx, private stackTraceErr?: Error) {
218
+ constructor(
219
+ tx: Tx,
220
+ private stackTraceErr?: Error,
221
+ ) {
219
222
  this.automaticClose = () => {
220
223
  console.error(
221
224
  `Transaction still open after ${env.db.timeoutMS}ms without an execute call.`,
@@ -223,7 +226,7 @@ class AutomaticClose {
223
226
  if (this.stackTraceErr) {
224
227
  console.error(this.stackTraceErr.stack);
225
228
  }
226
- tx.rollback();
229
+ void tx.rollback();
227
230
  };
228
231
  this.automaticCloseTimeout = setTimeout(
229
232
  this.automaticClose,
@@ -400,10 +403,13 @@ export abstract class Tx {
400
403
  protected abstract _rollback(): Promise<void>;
401
404
  protected abstract _commit(): Promise<void>;
402
405
 
406
+ // TODO: Re-enable the lint rule once eslint properly supports abstract class base implementations
403
407
  public async getTxLevelLock(
408
+ /* eslint-disable @typescript-eslint/no-unused-vars */
404
409
  _namespaceKey: string,
405
410
  _key: number,
406
411
  _blocking: boolean = true,
412
+ /* eslint-enable @typescript-eslint/no-unused-vars */
407
413
  ): Promise<boolean> {
408
414
  throw new Error(
409
415
  'The getTxLevelLock method is not implemented for the current engine.',
@@ -462,7 +468,6 @@ const createTransaction = (createFunc: CreateTransactionFn): TransactionFn => {
462
468
 
463
469
  let maybePg: typeof Pg | undefined;
464
470
  try {
465
- // tslint:disable-next-line:no-var-requires
466
471
  maybePg = require('pg');
467
472
  } catch (e) {
468
473
  // Ignore errors
@@ -497,7 +502,7 @@ if (maybePg != null) {
497
502
  const p = new pg.Pool(config);
498
503
  if (PG_SCHEMA != null) {
499
504
  p.on('connect', (client) => {
500
- client.query({ text: `SET search_path TO "${PG_SCHEMA}"` });
505
+ void client.query({ text: `SET search_path TO "${PG_SCHEMA}"` });
501
506
  });
502
507
  }
503
508
  p.on('connect', (client) => {
@@ -519,6 +524,7 @@ if (maybePg != null) {
519
524
  let pool: Pg.Pool;
520
525
  let replica: Pg.Pool;
521
526
  if (typeof connectString === 'string') {
527
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
522
528
  const pgConnectionString: typeof PgConnectionString = require('pg-connection-string');
523
529
  // We have to cast because of the use of null vs undefined
524
530
  const config = pgConnectionString.parse(connectString) as Pg.PoolConfig;
@@ -617,9 +623,9 @@ if (maybePg != null) {
617
623
  );
618
624
  this.db.release();
619
625
  } catch (err: any) {
620
- err = wrapDatabaseError(err);
621
- this.db.release(err);
622
- throw err;
626
+ const errorToReturn = wrapDatabaseError(err);
627
+ this.db.release(errorToReturn);
628
+ throw errorToReturn;
623
629
  }
624
630
  }
625
631
 
@@ -686,13 +692,13 @@ if (maybePg != null) {
686
692
  transaction: createTransaction(async (stackTraceErr) => {
687
693
  const client = await pool.connect();
688
694
  const tx = new PostgresTx(client, false, stackTraceErr);
689
- tx.executeSql('START TRANSACTION;');
695
+ void tx.executeSql('START TRANSACTION;');
690
696
  return tx;
691
697
  }),
692
698
  readTransaction: createTransaction(async (stackTraceErr) => {
693
699
  const client = await replica.connect();
694
700
  const tx = new PostgresTx(client, false, stackTraceErr);
695
- tx.executeSql('START TRANSACTION READ ONLY;');
701
+ void tx.executeSql('START TRANSACTION READ ONLY;');
696
702
  return tx.asReadOnly();
697
703
  }),
698
704
  ...alwaysExport,
@@ -702,7 +708,6 @@ if (maybePg != null) {
702
708
 
703
709
  let maybeMysql: typeof Mysql | undefined;
704
710
  try {
705
- // tslint:disable-next-line:no-var-requires
706
711
  maybeMysql = require('mysql');
707
712
  } catch (e) {
708
713
  // Ignore errors
@@ -809,14 +814,14 @@ if (maybeMysql != null) {
809
814
  const client = await getConnectionAsync();
810
815
  const close = () => client.release();
811
816
  const tx = new MySqlTx(client, close, false, stackTraceErr);
812
- tx.executeSql('START TRANSACTION;');
817
+ void tx.executeSql('START TRANSACTION;');
813
818
  return tx;
814
819
  }),
815
820
  readTransaction: createTransaction(async (stackTraceErr) => {
816
821
  const client = await getConnectionAsync();
817
822
  const close = () => client.release();
818
823
  const tx = new MySqlTx(client, close, false, stackTraceErr);
819
- tx.executeSql('START TRANSACTION READ ONLY;');
824
+ void tx.executeSql('START TRANSACTION READ ONLY;');
820
825
  return tx.asReadOnly();
821
826
  }),
822
827
  ...alwaysExport,
@@ -935,7 +940,6 @@ if (typeof window !== 'undefined' && window.openDatabase != null) {
935
940
  // allowing us to use async calls within the API.
936
941
  private asyncRecurse = () => {
937
942
  let args: AsyncQuery | undefined;
938
- // tslint:disable-next-line no-conditional-assignment
939
943
  while ((args = this.queue.pop())) {
940
944
  console.debug('Running', args[0]);
941
945
  this.tx.executeSql(args[0], args[1], args[2], args[3]);
@@ -34,10 +34,10 @@ const app = (function () {
34
34
  /** @type {string} */ match,
35
35
  /** @type import('express').Handler[] */ ...middleware
36
36
  ) {
37
- //Strip wildcard
37
+ // Strip wildcard
38
38
  let paramName;
39
39
  match = match.toLowerCase();
40
- const newMatch = match.replace(/[\/\*]*$/, '');
40
+ const newMatch = match.replace(/[/*]*$/, '');
41
41
  if (newMatch !== match) {
42
42
  match = newMatch;
43
43
  paramName = '*';
@@ -59,6 +59,8 @@ const app = (function () {
59
59
  /** @type any */ body = '',
60
60
  ) {
61
61
  if (!handlers[method]) {
62
+ // TODO: Consider changing this to a custom Error
63
+ // eslint-disable-next-line no-throw-literal
62
64
  throw [404, null, null];
63
65
  }
64
66
  const req = {
@@ -1,5 +1,5 @@
1
1
  import { SBVRParser } from '@balena/sbvr-parser';
2
- // tslint:disable-next-line:no-var-requires
2
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
3
3
  const Types: string = require('@balena/sbvr-types/Type.sbvr');
4
4
  import { version as sbvrParserVersion } from '@balena/sbvr-parser/package.json';
5
5
  import { version } from '@balena/sbvr-parser/package.json';
@@ -1,10 +1,10 @@
1
- import * as _ from 'lodash';
2
1
  import { odataNameToSqlName } from '@balena/odata-to-abstract-sql';
3
- // @ts-ignore
2
+ // @ts-expect-error b/c TS doesn't know what the result of requiring an sbvr file would be
3
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
4
4
  const transactionModel = require('./transaction.sbvr');
5
5
 
6
6
  /** @type {import('../config-loader/config-loader').Config} */
7
- export let config = {
7
+ export const config = {
8
8
  models: [
9
9
  {
10
10
  apiRoot: 'transaction',
@@ -130,7 +130,12 @@ WHERE "conditional field"."conditional resource" = ?;`,
130
130
  modelField.dataType === 'ForeignKey' &&
131
131
  Number.isNaN(Number(fieldValue))
132
132
  ) {
133
- if (!placeholders.hasOwnProperty(fieldValue)) {
133
+ if (
134
+ !Object.prototype.hasOwnProperty.call(
135
+ placeholders,
136
+ fieldValue,
137
+ )
138
+ ) {
134
139
  throw new Error('Cannot resolve placeholder' + fieldValue);
135
140
  } else {
136
141
  try {
@@ -170,7 +175,7 @@ WHERE "conditional resource"."transaction" = ?;\
170
175
  resolve = $resolve;
171
176
  reject = $reject;
172
177
  });
173
- // @ts-ignore
178
+ // @ts-expect-error we use resolve & reject before they are assigned b/c we treat them as a deferred.
174
179
  placeholders[placeholder] = { promise, resolve, reject };
175
180
  }
176
181
  }
@@ -15,7 +15,7 @@ import type { Config, Model } from '../config-loader/config-loader';
15
15
  import * as _ from 'lodash';
16
16
  import * as sbvrUtils from '../sbvr-api/sbvr-utils';
17
17
 
18
- // tslint:disable-next-line:no-var-requires
18
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
19
19
  const modelText = require('./migrations.sbvr');
20
20
 
21
21
  type ApiRootModel = Model & { apiRoot: string };
@@ -32,12 +32,12 @@ export type AsyncMigrationFn = (
32
32
  sbvrUtils: SbvrUtils,
33
33
  ) => Resolvable<number>;
34
34
 
35
- type AddFn<T extends {}, x extends 'sync' | 'async'> = T & {
35
+ type AddFn<T extends object, x extends 'sync' | 'async'> = T & {
36
36
  [key in `${x}Fn`]: key extends 'syncFn' ? MigrationFn : AsyncMigrationFn;
37
37
  } & {
38
38
  [key in `${x}Sql`]?: undefined;
39
39
  };
40
- type AddSql<T extends {}, x extends 'sync' | 'async'> = T & {
40
+ type AddSql<T extends object, x extends 'sync' | 'async'> = T & {
41
41
  [key in `${x}Fn`]?: undefined;
42
42
  } & {
43
43
  [key in `${x}Sql`]: string;
@@ -5,7 +5,7 @@ import type {
5
5
 
6
6
  import sbvrTypes, { SbvrType } from '@balena/sbvr-types';
7
7
 
8
- // tslint:disable-next-line:no-var-requires
8
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
9
9
  const { version }: { version: string } = require('../../package.json');
10
10
 
11
11
  const getResourceName = (resourceName: string): string =>
@@ -10,7 +10,7 @@ import * as permissions from '../sbvr-api/permissions';
10
10
  export let login: (
11
11
  fn: (
12
12
  err: any,
13
- user: {} | null | false | undefined,
13
+ user: object | null | false | undefined,
14
14
  req: Express.Request,
15
15
  res: Express.Response,
16
16
  next: Express.NextFunction,
@@ -35,12 +35,13 @@ export const checkPassword: PassportLocal.VerifyFunction = async (
35
35
 
36
36
  const setup: ConfigLoader.SetupFunction = async (app: Express.Application) => {
37
37
  if (!process.browser) {
38
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
38
39
  const passport: typeof Passport = require('passport');
39
40
  app.use(passport.initialize());
40
41
  app.use(passport.session());
41
42
 
42
43
  const {
43
- Strategy: LocalStrategy,
44
+ Strategy: LocalStrategy, // eslint-disable-next-line @typescript-eslint/no-var-requires
44
45
  }: typeof PassportLocal = require('passport-local');
45
46
 
46
47
  passport.serializeUser((user, done) => {
@@ -66,7 +67,11 @@ const setup: ConfigLoader.SetupFunction = async (app: Express.Application) => {
66
67
 
67
68
  logout = (req, _res, next) => {
68
69
  req.logout((error) => {
69
- error ? next(error) : next();
70
+ if (error) {
71
+ next(error);
72
+ return;
73
+ }
74
+ next();
70
75
  });
71
76
  };
72
77
  } else {
@@ -50,7 +50,7 @@ const asCallback = async <T>(
50
50
 
51
51
  export class PinejsSessionStore extends Store {
52
52
  public get = ((sid, callback) => {
53
- asCallback(
53
+ void asCallback(
54
54
  callback,
55
55
  api.session
56
56
  .get({
@@ -77,7 +77,7 @@ export class PinejsSessionStore extends Store {
77
77
  data,
78
78
  expiry_time: data?.cookie?.expires ?? null,
79
79
  };
80
- asCallback(
80
+ void asCallback(
81
81
  callback,
82
82
  api.session.put({
83
83
  resource: 'session',
@@ -91,7 +91,7 @@ export class PinejsSessionStore extends Store {
91
91
  }) as Store['set'];
92
92
 
93
93
  public destroy = ((sid, callback) => {
94
- asCallback(
94
+ void asCallback(
95
95
  callback,
96
96
  api.session.delete({
97
97
  resource: 'session',
@@ -104,7 +104,7 @@ export class PinejsSessionStore extends Store {
104
104
  }) as Store['destroy'];
105
105
 
106
106
  public all = ((callback) => {
107
- asCallback(
107
+ void asCallback(
108
108
  callback,
109
109
  api.session
110
110
  .get({
@@ -124,7 +124,7 @@ export class PinejsSessionStore extends Store {
124
124
  }) as Store['all'];
125
125
 
126
126
  public clear = ((callback) => {
127
- asCallback(
127
+ void asCallback(
128
128
  callback,
129
129
  // TODO: Use a truncate
130
130
  api.session.delete({
@@ -137,7 +137,7 @@ export class PinejsSessionStore extends Store {
137
137
  }) as Store['clear'];
138
138
 
139
139
  public length = ((callback) => {
140
- asCallback(
140
+ void asCallback(
141
141
  callback,
142
142
  api.session.get({
143
143
  resource: 'session/',
@@ -116,7 +116,7 @@ export const getAndCheckBindValues = async (
116
116
  [dataType, value] = odataBinds[bindValue];
117
117
  field = { dataType };
118
118
  } else if (typeof bindValue === 'string') {
119
- if (!odataBinds.hasOwnProperty(bindValue)) {
119
+ if (!Object.prototype.hasOwnProperty.call(odataBinds, bindValue)) {
120
120
  console.error(
121
121
  `Invalid binding '${bindValue}' for binds: `,
122
122
  odataBinds,
@@ -12,7 +12,6 @@ let cache: null | {
12
12
  } = null;
13
13
  let fs: undefined | typeof Fs;
14
14
  try {
15
- // tslint:disable-next-line:no-var-requires
16
15
  fs = require('fs');
17
16
  } catch (e) {
18
17
  // Ignore error
@@ -1,11 +1,13 @@
1
1
  // Augment express.js with pinejs-specific attributes via declaration merging.
2
2
 
3
- // tslint:disable-next-line:no-namespace
3
+ // eslint-disable-next-line @typescript-eslint/no-namespace, @typescript-eslint/no-unused-vars
4
4
  declare namespace Express {
5
5
  type PineUser = import('./sbvr-utils').User;
6
6
 
7
- // tslint:disable-next-line:no-empty-interface
7
+ // Augment Express.User to include the props of our PineUser.
8
+ // eslint-disable-next-line @typescript-eslint/no-empty-interface
8
9
  interface User extends PineUser {}
10
+
9
11
  interface Request {
10
12
  user?: User;
11
13
  apiKey?: import('./sbvr-utils').ApiKey;
@@ -101,7 +101,7 @@ class SideEffectHook<T extends HookFn> extends Hook<T> {
101
101
 
102
102
  public registerRollback(fn: RollbackAction): void {
103
103
  if (this.rolledBack) {
104
- (async () => {
104
+ void (async () => {
105
105
  try {
106
106
  await fn();
107
107
  } catch {
@@ -140,7 +140,7 @@ export const rollbackRequestHooks = <T extends InstantiatedHooks>(
140
140
  if (sideEffectHooks.length === 0) {
141
141
  return;
142
142
  }
143
- settleMapSeries(sideEffectHooks, async (hook) => {
143
+ void settleMapSeries(sideEffectHooks, async (hook) => {
144
144
  await hook.rollback();
145
145
  });
146
146
  };
@@ -391,8 +391,7 @@ const getReadOnlyArgs = <T extends keyof Hooks>(
391
391
  // If we don't have a tx then read-only/writable is irrelevant
392
392
  return args;
393
393
  }
394
- let readOnlyArgs: typeof args;
395
- readOnlyArgs = { ...args, tx: args.tx.asReadOnly() };
394
+ const readOnlyArgs: typeof args = { ...args, tx: args.tx.asReadOnly() };
396
395
  if ((args as HookArgs).request != null) {
397
396
  defineApi(modelName, readOnlyArgs as HookArgs);
398
397
  }
@@ -1,5 +1,11 @@
1
+ import type {
2
+ AbstractSqlModel,
3
+ AbstractSqlTable,
4
+ } from '@balena/abstract-sql-compiler';
5
+
6
+ // Augment express.js with pinejs-specific attributes via declaration merging.
1
7
  declare module '@balena/abstract-sql-compiler' {
2
- interface AbstractSqlTable {
8
+ export interface AbstractSqlTable {
3
9
  fetchProcessingFields?: {
4
10
  [field: string]: NonNullable<SbvrType['fetchProcessing']>;
5
11
  };
@@ -9,20 +15,12 @@ declare module '@balena/abstract-sql-compiler' {
9
15
  }
10
16
  }
11
17
 
12
- import type {
13
- AbstractSqlModel,
14
- AbstractSqlTable,
15
- } from '@balena/abstract-sql-compiler';
16
18
  import type { Result, Row } from '../database-layer/db';
17
19
 
18
20
  import { sqlNameToODataName } from '@balena/odata-to-abstract-sql';
19
21
  import sbvrTypes, { SbvrType } from '@balena/sbvr-types';
20
22
  import * as _ from 'lodash';
21
23
  import { resolveNavigationResource, resolveSynonym } from './sbvr-utils';
22
- import {
23
- getWebresourceHandler,
24
- isWebResourceField,
25
- } from '../webresource-handler';
26
24
 
27
25
  const checkForExpansion = async (
28
26
  vocab: string,
@@ -148,28 +146,21 @@ export const process = async (
148
146
 
149
147
  const fetchProcessingFields = getFetchProcessingFields(table);
150
148
  const processedFields = fieldNames.filter((fieldName) =>
151
- fetchProcessingFields.hasOwnProperty(fieldName),
149
+ Object.prototype.hasOwnProperty.call(fetchProcessingFields, fieldName),
152
150
  );
153
151
 
154
152
  const localFields = getLocalFields(table);
155
153
  // We check that it's not a local field, rather than that it is a foreign key because of the case where the foreign key is on the other resource
156
154
  // and hence not known to this resource
157
155
  const expandableFields = fieldNames.filter(
158
- (fieldName) => !localFields.hasOwnProperty(fieldName),
156
+ (fieldName) =>
157
+ !Object.prototype.hasOwnProperty.call(localFields, fieldName),
159
158
  );
160
159
 
161
160
  const odataIdField = sqlNameToODataName(table.idField);
162
- const webResourceHandler = getWebresourceHandler();
163
161
  for (const row of rows) {
164
162
  for (const fieldName of processedFields) {
165
163
  row[fieldName] = fetchProcessingFields[fieldName](row[fieldName]);
166
- if (
167
- webResourceHandler &&
168
- isWebResourceField(fieldName, table) &&
169
- row[fieldName]?.href != null
170
- ) {
171
- row[fieldName] = await webResourceHandler.onPreRespond(row[fieldName]);
172
- }
173
164
  }
174
165
  if (includeMetadata) {
175
166
  row.__metadata = {
@@ -52,7 +52,7 @@ import {
52
52
  } from './uri-parser';
53
53
  import memoizeWeak = require('memoizee/weak');
54
54
 
55
- // tslint:disable-next-line:no-var-requires
55
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
56
56
  const userModel: string = require('./user.sbvr');
57
57
 
58
58
  const DEFAULT_ACTOR_BIND = '@__ACTOR_ID';
@@ -87,7 +87,7 @@ interface NestedCheckOr<T> {
87
87
  interface NestedCheckAnd<T> {
88
88
  and: NestedCheckArray<T>;
89
89
  }
90
- interface NestedCheckArray<T> extends Array<NestedCheck<T>> {}
90
+ type NestedCheckArray<T> = Array<NestedCheck<T>>;
91
91
  type NestedCheck<T> =
92
92
  | NestedCheckOr<T>
93
93
  | NestedCheckAnd<T>
@@ -175,22 +175,26 @@ const isAnd = <T>(x: any): x is NestedCheckAnd<T> =>
175
175
  typeof x === 'object' && 'and' in x;
176
176
  const isOr = <T>(x: any): x is NestedCheckOr<T> =>
177
177
  typeof x === 'object' && 'or' in x;
178
- export function nestedCheck<I extends {}, O>(
179
- check: string,
178
+ export function nestedCheck<I extends string, O>(
179
+ check: I,
180
180
  stringCallback: (s: string) => O,
181
181
  ): O;
182
- export function nestedCheck<I extends {}, O>(
183
- check: boolean,
182
+ export function nestedCheck<I extends boolean, O>(
183
+ check: I,
184
184
  stringCallback: (s: string) => O,
185
185
  ): boolean;
186
- export function nestedCheck<I extends {}, O>(
186
+ export function nestedCheck<I extends NonNullable<unknown>, O>(
187
187
  check: NestedCheck<I>,
188
188
  stringCallback: (s: string) => O,
189
189
  ): Exclude<I, string> | O | MappedNestedCheck<typeof check, I, O>;
190
- export function nestedCheck<I extends {}, O>(
191
- check: NestedCheck<I>,
190
+ export function nestedCheck<I extends object, O>(
191
+ check: NestedCheck<I> | string | boolean,
192
192
  stringCallback: (s: string) => O,
193
- ): boolean | Exclude<I, string> | O | MappedNestedCheck<typeof check, I, O> {
193
+ ):
194
+ | boolean
195
+ | Exclude<I, string>
196
+ | O
197
+ | MappedNestedCheck<Exclude<typeof check, string | boolean>, I, O> {
194
198
  if (typeof check === 'string') {
195
199
  return stringCallback(check);
196
200
  }
@@ -228,10 +232,11 @@ export function nestedCheck<I extends {}, O>(
228
232
  }
229
233
  const checkType = checkTypes[0];
230
234
  switch (checkType.toUpperCase()) {
231
- case 'AND':
235
+ case 'AND': {
232
236
  const and = (check as NestedCheckAnd<I>)[checkType as 'and'];
233
237
  return nestedCheck(and, stringCallback);
234
- case 'OR':
238
+ }
239
+ case 'OR': {
235
240
  const or = (check as NestedCheckOr<I>)[checkType as 'or'];
236
241
  let results: any[] = [];
237
242
  for (const subcheck of or) {
@@ -255,6 +260,7 @@ export function nestedCheck<I extends {}, O>(
255
260
  };
256
261
  }
257
262
  return false;
263
+ }
258
264
  default:
259
265
  throw new Error('Cannot parse required checking logic: ' + checkType);
260
266
  }
@@ -425,7 +431,7 @@ const convertToLambda = (filter: AnyObject, identifier: string) => {
425
431
  }
426
432
  }
427
433
 
428
- if (object.hasOwnProperty('name')) {
434
+ if (Object.prototype.hasOwnProperty.call(object, 'name')) {
429
435
  object.property = { ...object };
430
436
  object.name = identifier;
431
437
  delete object.lambda;
@@ -721,7 +727,7 @@ const deepFreezeExceptDefinition = (obj: AnyObject) => {
721
727
  // We skip the definition because we know it's a property we've defined that will throw an error in some cases
722
728
  if (
723
729
  prop !== 'definition' &&
724
- obj.hasOwnProperty(prop) &&
730
+ Object.prototype.hasOwnProperty.call(obj, prop) &&
725
731
  obj[prop] !== null &&
726
732
  !['object', 'function'].includes(typeof obj[prop])
727
733
  ) {
@@ -3,7 +3,9 @@ import type * as Db from '../database-layer/db';
3
3
  import type { Model } from '../config-loader/config-loader';
4
4
  import type { AnyObject, RequiredField } from './common-types';
5
5
 
6
+ // Augment the Express typings
6
7
  declare global {
8
+ // eslint-disable-next-line @typescript-eslint/no-namespace
7
9
  namespace Express {
8
10
  export interface Request {
9
11
  tx?: Db.Tx;
@@ -38,7 +40,7 @@ import * as asyncMigrator from '../migrator/async';
38
40
  import * as syncMigrator from '../migrator/sync';
39
41
  import { generateODataMetadata } from '../odata-metadata/odata-metadata-generator';
40
42
 
41
- // tslint:disable-next-line:no-var-requires
43
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
42
44
  const devModel = require('./dev.sbvr');
43
45
  import * as permissions from './permissions';
44
46
  import {
@@ -249,13 +251,14 @@ const prettifyConstraintError = (
249
251
  err.message,
250
252
  );
251
253
  break;
252
- case 'postgres':
254
+ case 'postgres': {
253
255
  const resourceName = resolveSynonym(request);
254
256
  const abstractSqlModel = getFinalAbstractSqlModel(request);
255
257
  matches = new RegExp(
256
258
  '"' + abstractSqlModel.tables[resourceName].name + '_(.*?)_key"',
257
259
  ).exec(err.message);
258
260
  break;
261
+ }
259
262
  }
260
263
  // We know it's the right error type, so if matches exists just throw a generic error message, since we have failed to get the info for a more specific one.
261
264
  if (matches == null) {
@@ -282,7 +285,7 @@ const prettifyConstraintError = (
282
285
  err.message,
283
286
  );
284
287
  break;
285
- case 'postgres':
288
+ case 'postgres': {
286
289
  const resourceName = resolveSynonym(request);
287
290
  const abstractSqlModel = getFinalAbstractSqlModel(request);
288
291
  const tableName = abstractSqlModel.tables[resourceName].name;
@@ -301,6 +304,7 @@ const prettifyConstraintError = (
301
304
  ).exec(err.message);
302
305
  }
303
306
  break;
307
+ }
304
308
  }
305
309
  // We know it's the right error type, so if no matches exists just throw a generic error message,
306
310
  // since we have failed to get the info for a more specific one.
@@ -983,7 +987,7 @@ export class PinejsClient extends PinejsClientCore<PinejsClient> {
983
987
  req?: permissions.PermissionReq;
984
988
  custom?: AnyObject;
985
989
  }) {
986
- return (await runURI(method, url, body, tx, req, custom)) as {};
990
+ return (await runURI(method, url, body, tx, req, custom)) as object;
987
991
  }
988
992
  }
989
993
 
@@ -416,7 +416,7 @@ export const translateUri = <
416
416
  request = { ...request };
417
417
  request.values = new Proxy(request.values, {
418
418
  set: (obj: ODataRequest['values'], prop: string, value) => {
419
- if (!obj.hasOwnProperty(prop)) {
419
+ if (!Object.prototype.hasOwnProperty.call(obj, prop)) {
420
420
  sbvrUtils.api[request.vocabulary].logger.warn(
421
421
  `Assigning a new request.values property '${prop}' however it will be ignored`,
422
422
  );
@@ -1,5 +1,6 @@
1
+ // We have to use var when extending the global namespace
2
+ // eslint-disable-next-line no-var
1
3
  declare var nodeRequire: NodeRequire;
2
- /* tslint:disable-next-line:no-namespace */
3
4
  declare namespace NodeJS {
4
5
  export interface Process {
5
6
  browser: boolean;