@balena/pinejs 16.0.0-build--batch-f2ffc3d6bcb9f3294fd4fc9de3c21bfe167e100d-1 → 16.0.0-build-fisehara-update-sbvr-types-cfbbecbb0387e87e17e14be8991be73d1a4efdd0-1

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 (141) hide show
  1. package/.pinejs-cache.json +1 -1
  2. package/.versionbot/CHANGELOG.yml +2168 -11
  3. package/CHANGELOG.md +815 -2
  4. package/Gruntfile.ts +9 -6
  5. package/README.md +10 -0
  6. package/build/browser.ts +2 -2
  7. package/build/config.ts +1 -1
  8. package/build/module.ts +2 -2
  9. package/build/server.ts +2 -2
  10. package/docker-compose.npm-test.yml +21 -3
  11. package/out/bin/abstract-sql-compiler.js +5 -5
  12. package/out/bin/abstract-sql-compiler.js.map +1 -1
  13. package/out/bin/odata-compiler.js +10 -10
  14. package/out/bin/odata-compiler.js.map +1 -1
  15. package/out/bin/sbvr-compiler.js +34 -11
  16. package/out/bin/sbvr-compiler.js.map +1 -1
  17. package/out/bin/utils.js +25 -2
  18. package/out/bin/utils.js.map +1 -1
  19. package/out/config-loader/config-loader.d.ts +4 -2
  20. package/out/config-loader/config-loader.js +54 -13
  21. package/out/config-loader/config-loader.js.map +1 -1
  22. package/out/config-loader/env.d.ts +2 -1
  23. package/out/config-loader/env.js +5 -2
  24. package/out/config-loader/env.js.map +1 -1
  25. package/out/data-server/sbvr-server.d.ts +1 -1
  26. package/out/data-server/sbvr-server.js +3 -1
  27. package/out/data-server/sbvr-server.js.map +1 -1
  28. package/out/database-layer/db.js +40 -14
  29. package/out/database-layer/db.js.map +1 -1
  30. package/out/express-emulator/express.js +5 -3
  31. package/out/express-emulator/express.js.map +1 -1
  32. package/out/http-transactions/transactions.d.ts +1 -1
  33. package/out/http-transactions/transactions.js +10 -5
  34. package/out/http-transactions/transactions.js.map +1 -1
  35. package/out/migrator/async.js +32 -5
  36. package/out/migrator/async.js.map +1 -1
  37. package/out/migrator/sync.d.ts +2 -1
  38. package/out/migrator/sync.js +29 -3
  39. package/out/migrator/sync.js.map +1 -1
  40. package/out/migrator/utils.d.ts +6 -3
  41. package/out/migrator/utils.js +30 -4
  42. package/out/migrator/utils.js.map +1 -1
  43. package/out/odata-metadata/odata-metadata-generator.js +4 -1
  44. package/out/odata-metadata/odata-metadata-generator.js.map +1 -1
  45. package/out/passport-pinejs/mount-login-router.d.ts +3 -0
  46. package/out/passport-pinejs/mount-login-router.js +65 -0
  47. package/out/passport-pinejs/mount-login-router.js.map +1 -0
  48. package/out/passport-pinejs/passport-pinejs.d.ts +2 -1
  49. package/out/passport-pinejs/passport-pinejs.js +28 -2
  50. package/out/passport-pinejs/passport-pinejs.js.map +1 -1
  51. package/out/pinejs-session-store/pinejs-session-store.js +30 -7
  52. package/out/pinejs-session-store/pinejs-session-store.js.map +1 -1
  53. package/out/sbvr-api/abstract-sql.d.ts +2 -2
  54. package/out/sbvr-api/abstract-sql.js +35 -9
  55. package/out/sbvr-api/abstract-sql.js.map +1 -1
  56. package/out/sbvr-api/cached-compile.js +9 -6
  57. package/out/sbvr-api/cached-compile.js.map +1 -1
  58. package/out/sbvr-api/common-types.d.ts +1 -1
  59. package/out/sbvr-api/control-flow.js +5 -2
  60. package/out/sbvr-api/control-flow.js.map +1 -1
  61. package/out/sbvr-api/express-extension.d.ts +10 -7
  62. package/out/sbvr-api/express-extension.js +1 -0
  63. package/out/sbvr-api/hooks.d.ts +5 -1
  64. package/out/sbvr-api/hooks.js +12 -10
  65. package/out/sbvr-api/hooks.js.map +1 -1
  66. package/out/sbvr-api/odata-response.d.ts +5 -2
  67. package/out/sbvr-api/odata-response.js +36 -6
  68. package/out/sbvr-api/odata-response.js.map +1 -1
  69. package/out/sbvr-api/permissions.d.ts +6 -7
  70. package/out/sbvr-api/permissions.js +69 -38
  71. package/out/sbvr-api/permissions.js.map +1 -1
  72. package/out/sbvr-api/sbvr-utils.d.ts +20 -9
  73. package/out/sbvr-api/sbvr-utils.js +134 -136
  74. package/out/sbvr-api/sbvr-utils.js.map +1 -1
  75. package/out/sbvr-api/translations.d.ts +2 -2
  76. package/out/sbvr-api/translations.js +17 -10
  77. package/out/sbvr-api/translations.js.map +1 -1
  78. package/out/sbvr-api/uri-parser.d.ts +7 -10
  79. package/out/sbvr-api/uri-parser.js +46 -19
  80. package/out/sbvr-api/uri-parser.js.map +1 -1
  81. package/out/server-glue/global-ext.d.ts +2 -1
  82. package/out/server-glue/module.d.ts +3 -1
  83. package/out/server-glue/module.js +40 -13
  84. package/out/server-glue/module.js.map +1 -1
  85. package/out/server-glue/sbvr-loader.js.map +1 -1
  86. package/out/server-glue/server.js +31 -39
  87. package/out/server-glue/server.js.map +1 -1
  88. package/out/webresource-handler/handlers/NoopHandler.d.ts +7 -0
  89. package/out/webresource-handler/handlers/NoopHandler.js +20 -0
  90. package/out/webresource-handler/handlers/NoopHandler.js.map +1 -0
  91. package/out/webresource-handler/handlers/S3Handler.d.ts +28 -0
  92. package/out/webresource-handler/handlers/S3Handler.js +97 -0
  93. package/out/webresource-handler/handlers/S3Handler.js.map +1 -0
  94. package/out/webresource-handler/handlers/index.d.ts +2 -0
  95. package/out/webresource-handler/handlers/index.js +19 -0
  96. package/out/webresource-handler/handlers/index.js.map +1 -0
  97. package/out/webresource-handler/index.d.ts +34 -0
  98. package/out/webresource-handler/index.js +307 -0
  99. package/out/webresource-handler/index.js.map +1 -0
  100. package/package.json +68 -62
  101. package/src/bin/abstract-sql-compiler.ts +7 -9
  102. package/src/bin/odata-compiler.ts +12 -15
  103. package/src/bin/sbvr-compiler.ts +14 -18
  104. package/src/bin/utils.ts +1 -1
  105. package/src/config-loader/config-loader.ts +44 -10
  106. package/src/config-loader/env.ts +1 -1
  107. package/src/data-server/sbvr-server.js +3 -1
  108. package/src/database-layer/db.ts +23 -19
  109. package/src/express-emulator/express.js +5 -3
  110. package/src/extended-sbvr-parser/extended-sbvr-parser.ts +1 -1
  111. package/src/http-transactions/transactions.js +10 -5
  112. package/src/migrator/async.ts +7 -6
  113. package/src/migrator/sync.ts +10 -7
  114. package/src/migrator/utils.ts +11 -5
  115. package/src/odata-metadata/odata-metadata-generator.ts +2 -2
  116. package/src/passport-pinejs/mount-login-router.ts +46 -0
  117. package/src/passport-pinejs/passport-pinejs.ts +7 -3
  118. package/src/pinejs-session-store/pinejs-session-store.ts +6 -6
  119. package/src/sbvr-api/abstract-sql.ts +5 -5
  120. package/src/sbvr-api/cached-compile.ts +1 -2
  121. package/src/sbvr-api/common-types.ts +1 -1
  122. package/src/sbvr-api/control-flow.ts +1 -1
  123. package/src/sbvr-api/express-extension.ts +12 -8
  124. package/src/sbvr-api/hooks.ts +11 -11
  125. package/src/sbvr-api/odata-response.ts +56 -9
  126. package/src/sbvr-api/permissions.ts +44 -35
  127. package/src/sbvr-api/sbvr-utils.ts +118 -172
  128. package/src/sbvr-api/translations.ts +9 -6
  129. package/src/sbvr-api/uri-parser.ts +22 -28
  130. package/src/server-glue/global-ext.d.ts +2 -1
  131. package/src/server-glue/module.ts +8 -2
  132. package/src/server-glue/sbvr-loader.ts +1 -1
  133. package/src/server-glue/server.ts +11 -49
  134. package/src/webresource-handler/handlers/NoopHandler.ts +21 -0
  135. package/src/webresource-handler/handlers/S3Handler.ts +143 -0
  136. package/src/webresource-handler/handlers/index.ts +2 -0
  137. package/src/webresource-handler/index.ts +450 -0
  138. package/tsconfig.dev.json +2 -1
  139. package/tsconfig.json +1 -1
  140. package/typings/lf-to-abstract-sql.d.ts +1 -1
  141. package/typings/memoizee.d.ts +3 -4
@@ -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,10 @@ 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
+ return next(error);
72
+ }
73
+ next();
70
74
  });
71
75
  };
72
76
  } 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/',
@@ -1,18 +1,18 @@
1
- import * as _ from 'lodash';
1
+ import _ from 'lodash';
2
2
 
3
3
  import * as AbstractSQLCompiler from '@balena/abstract-sql-compiler';
4
4
  import type { BindKey } from '@balena/odata-parser';
5
5
  import {
6
- ODataBinds,
6
+ type ODataBinds,
7
7
  odataNameToSqlName,
8
8
  isBindReference,
9
9
  } from '@balena/odata-to-abstract-sql';
10
10
  import deepFreeze = require('deep-freeze');
11
- import * as memoize from 'memoizee';
11
+ import memoize from 'memoizee';
12
12
  import * as env from '../config-loader/env';
13
13
  import { BadRequestError, SqlCompilationError } from './errors';
14
14
  import * as sbvrUtils from './sbvr-utils';
15
- import { ODataRequest } from './uri-parser';
15
+ import type { ODataRequest } from './uri-parser';
16
16
 
17
17
  const getMemoizedCompileRule = memoize(
18
18
  (engine: AbstractSQLCompiler.Engines) =>
@@ -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,
@@ -1,6 +1,6 @@
1
1
  import type * as Fs from 'fs';
2
2
 
3
- import * as _ from 'lodash';
3
+ import _ from 'lodash';
4
4
 
5
5
  const cacheFile = process.env.PINEJS_CACHE_FILE || '.pinejs-cache.json';
6
6
  let cache: null | {
@@ -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,4 +1,4 @@
1
- export { AnyObject, Dictionary } from 'pinejs-client-core';
1
+ export type { AnyObject, Dictionary } from 'pinejs-client-core';
2
2
 
3
3
  type Overwrite<T, U> = Pick<T, Exclude<keyof T, keyof U>> & U;
4
4
  export type RequiredField<T, F extends keyof T> = Overwrite<
@@ -1,6 +1,6 @@
1
1
  import type { Resolvable } from './common-types';
2
2
 
3
- import * as _ from 'lodash';
3
+ import _ from 'lodash';
4
4
  import { TypedError } from 'typed-error';
5
5
 
6
6
  export type MappingFunction = <T, U>(
@@ -1,13 +1,17 @@
1
1
  // Augment express.js with pinejs-specific attributes via declaration merging.
2
2
 
3
- // tslint:disable-next-line:no-namespace
4
- declare namespace Express {
5
- type PineUser = import('./sbvr-utils').User;
3
+ declare global {
4
+ // eslint-disable-next-line @typescript-eslint/no-namespace
5
+ namespace Express {
6
+ type PineUser = import('./sbvr-utils').User;
6
7
 
7
- // tslint:disable-next-line:no-empty-interface
8
- interface User extends PineUser {}
9
- interface Request {
10
- user?: User;
11
- apiKey?: import('./sbvr-utils').ApiKey;
8
+ // Augment Express.User to include the props of our PineUser.
9
+ // eslint-disable-next-line @typescript-eslint/no-empty-interface
10
+ interface User extends PineUser {}
11
+
12
+ interface Request {
13
+ user?: User;
14
+ apiKey?: import('./sbvr-utils').ApiKey;
15
+ }
12
16
  }
13
17
  }
@@ -5,17 +5,17 @@ import type { AnyObject } from 'pinejs-client-core';
5
5
  import type { TypedError } from 'typed-error';
6
6
  import type { SupportedMethod } from '@balena/odata-to-abstract-sql';
7
7
 
8
- import * as _ from 'lodash';
8
+ import _ from 'lodash';
9
9
  import { settleMapSeries } from './control-flow';
10
- import * as memoize from 'memoizee';
10
+ import memoize from 'memoizee';
11
11
  import {
12
- PinejsClient,
13
- User,
14
- ApiKey,
12
+ type PinejsClient,
13
+ type User,
14
+ type ApiKey,
15
15
  resolveSynonym,
16
16
  getAbstractSqlModel,
17
17
  api,
18
- Response,
18
+ type Response,
19
19
  } from './sbvr-utils';
20
20
 
21
21
  export interface HookReq {
@@ -29,6 +29,7 @@ export interface HookReq {
29
29
  custom?: AnyObject;
30
30
  tx?: Tx;
31
31
  hooks?: InstantiatedHooks;
32
+ is?: (type: string | string[]) => string | false | null;
32
33
  }
33
34
  export interface HookArgs {
34
35
  req: HookReq;
@@ -55,7 +56,7 @@ export interface Hooks {
55
56
  ) => HookResponse;
56
57
  /** These are run in reverse translation order from newest to oldest */
57
58
  'POSTRUN-ERROR'?: (
58
- options: HookArgs & { error: TypedError | any },
59
+ options: HookArgs & { tx: Tx; error: TypedError | any },
59
60
  ) => HookResponse;
60
61
  }
61
62
  export type HookBlueprints = {
@@ -101,7 +102,7 @@ class SideEffectHook<T extends HookFn> extends Hook<T> {
101
102
 
102
103
  public registerRollback(fn: RollbackAction): void {
103
104
  if (this.rolledBack) {
104
- (async () => {
105
+ void (async () => {
105
106
  try {
106
107
  await fn();
107
108
  } catch {
@@ -140,7 +141,7 @@ export const rollbackRequestHooks = <T extends InstantiatedHooks>(
140
141
  if (sideEffectHooks.length === 0) {
141
142
  return;
142
143
  }
143
- settleMapSeries(sideEffectHooks, async (hook) => {
144
+ void settleMapSeries(sideEffectHooks, async (hook) => {
144
145
  await hook.rollback();
145
146
  });
146
147
  };
@@ -391,8 +392,7 @@ const getReadOnlyArgs = <T extends keyof Hooks>(
391
392
  // If we don't have a tx then read-only/writable is irrelevant
392
393
  return args;
393
394
  }
394
- let readOnlyArgs: typeof args;
395
- readOnlyArgs = { ...args, tx: args.tx.asReadOnly() };
395
+ const readOnlyArgs: typeof args = { ...args, tx: args.tx.asReadOnly() };
396
396
  if ((args as HookArgs).request != null) {
397
397
  defineApi(modelName, readOnlyArgs as HookArgs);
398
398
  }
@@ -1,24 +1,30 @@
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
  };
6
12
  localFields?: {
7
13
  [odataName: string]: true;
8
14
  };
15
+ webresourceFields?: {
16
+ [odataName: string]: true;
17
+ };
9
18
  }
10
19
  }
11
20
 
12
- import type {
13
- AbstractSqlModel,
14
- AbstractSqlTable,
15
- } from '@balena/abstract-sql-compiler';
16
21
  import type { Result, Row } from '../database-layer/db';
17
22
 
18
23
  import { sqlNameToODataName } from '@balena/odata-to-abstract-sql';
19
- import sbvrTypes, { SbvrType } from '@balena/sbvr-types';
20
- import * as _ from 'lodash';
24
+ import sbvrTypes, { type SbvrType } from '@balena/sbvr-types';
25
+ import _ from 'lodash';
21
26
  import { resolveNavigationResource, resolveSynonym } from './sbvr-utils';
27
+ import { getWebresourceHandler } from '../webresource-handler';
22
28
 
23
29
  const checkForExpansion = async (
24
30
  vocab: string,
@@ -96,6 +102,20 @@ const getLocalFields = (table: AbstractSqlTable) => {
96
102
  }
97
103
  return table.localFields;
98
104
  };
105
+
106
+ const getWebResourceFields = (table: AbstractSqlTable) => {
107
+ if (table.webresourceFields == null) {
108
+ table.webresourceFields = {};
109
+ for (const { fieldName, dataType } of table.fields) {
110
+ if (dataType === 'WebResource') {
111
+ const odataName = sqlNameToODataName(fieldName);
112
+ table.webresourceFields[odataName] = true;
113
+ }
114
+ }
115
+ }
116
+ return table.webresourceFields;
117
+ };
118
+
99
119
  const getFetchProcessingFields = (table: AbstractSqlTable) => {
100
120
  return (table.fetchProcessingFields ??= _(table.fields)
101
121
  .filter(
@@ -138,20 +158,27 @@ export const process = async (
138
158
  vocabulary: vocab,
139
159
  resourceName,
140
160
  });
161
+ const configuredWebResourceHandler = getWebresourceHandler();
141
162
  const table = abstractSqlModel.tables[sqlResourceName];
142
163
 
143
164
  const fieldNames = Object.keys(rows[0]);
144
165
 
145
166
  const fetchProcessingFields = getFetchProcessingFields(table);
146
167
  const processedFields = fieldNames.filter((fieldName) =>
147
- fetchProcessingFields.hasOwnProperty(fieldName),
168
+ Object.prototype.hasOwnProperty.call(fetchProcessingFields, fieldName),
148
169
  );
149
170
 
150
171
  const localFields = getLocalFields(table);
151
172
  // 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
152
173
  // and hence not known to this resource
153
174
  const expandableFields = fieldNames.filter(
154
- (fieldName) => !localFields.hasOwnProperty(fieldName),
175
+ (fieldName) =>
176
+ !Object.prototype.hasOwnProperty.call(localFields, fieldName),
177
+ );
178
+
179
+ const webresourceFields = getWebResourceFields(table);
180
+ const requiredSigningFields = fieldNames.filter((fieldName) =>
181
+ Object.prototype.hasOwnProperty.call(webresourceFields, fieldName),
155
182
  );
156
183
 
157
184
  const odataIdField = sqlNameToODataName(table.idField);
@@ -166,6 +193,25 @@ export const process = async (
166
193
  }
167
194
  }
168
195
 
196
+ if (
197
+ requiredSigningFields.length > 0 &&
198
+ configuredWebResourceHandler != null
199
+ ) {
200
+ await Promise.all(
201
+ rows.map(async (row) => {
202
+ await Promise.all(
203
+ requiredSigningFields.map(async (fieldName) => {
204
+ if (row[fieldName] != null) {
205
+ row[fieldName] = await configuredWebResourceHandler.onPreRespond(
206
+ row[fieldName],
207
+ );
208
+ }
209
+ }),
210
+ );
211
+ }),
212
+ );
213
+ }
214
+
169
215
  if (expandableFields.length > 0) {
170
216
  await Promise.all(
171
217
  rows.map(async (row) => {
@@ -192,5 +238,6 @@ export const prepareModel = (abstractSqlModel: AbstractSqlModel) => {
192
238
  _.forEach(abstractSqlModel.tables, (table) => {
193
239
  getLocalFields(table);
194
240
  getFetchProcessingFields(table);
241
+ getWebResourceFields(table);
195
242
  });
196
243
  };
@@ -28,17 +28,17 @@ import {
28
28
  isBindReference,
29
29
  type OData2AbstractSQL,
30
30
  odataNameToSqlName,
31
- ResourceFunction,
31
+ type ResourceFunction,
32
32
  sqlNameToODataName,
33
33
  } from '@balena/odata-to-abstract-sql';
34
34
  import * as ODataParser from '@balena/odata-parser';
35
35
 
36
- import * as _ from 'lodash';
37
- import * as memoize from 'memoizee';
36
+ import _ from 'lodash';
37
+ import memoize from 'memoizee';
38
38
  import * as randomstring from 'randomstring';
39
39
  import * as env from '../config-loader/env';
40
40
  import * as sbvrUtils from '../sbvr-api/sbvr-utils';
41
- import { HookReq, addPureHook, addHook } from './hooks';
41
+ import { type HookReq, addPureHook, addHook } from './hooks';
42
42
  import {
43
43
  BadRequestError,
44
44
  PermissionError,
@@ -48,11 +48,11 @@ import {
48
48
  memoizedGetOData2AbstractSQL,
49
49
  memoizedParseOdata,
50
50
  metadataEndpoints,
51
- ODataRequest,
51
+ type ODataRequest,
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>
@@ -95,20 +95,18 @@ type NestedCheck<T> =
95
95
  | T;
96
96
  type PermissionCheck = NestedCheck<string>;
97
97
 
98
- type MappedType<I, O> = O extends NestedCheck<infer T>
99
- ? Exclude<Exclude<I, string> | T, boolean>
100
- : Exclude<Exclude<I, string> | O, boolean>;
101
- type MappedNestedCheck<
102
- T extends NestedCheck<I>,
103
- I,
104
- O,
105
- > = T extends NestedCheckOr<I>
106
- ? NestedCheckOr<MappedType<I, O>>
107
- : T extends NestedCheckAnd<I>
108
- ? NestedCheckAnd<MappedType<I, O>>
109
- : T extends NestedCheckArray<I>
110
- ? NestedCheckArray<MappedType<I, O>>
111
- : Exclude<I, string> | O;
98
+ type MappedType<I, O> =
99
+ O extends NestedCheck<infer T>
100
+ ? Exclude<Exclude<I, string> | T, boolean>
101
+ : Exclude<Exclude<I, string> | O, boolean>;
102
+ type MappedNestedCheck<T extends NestedCheck<I>, I, O> =
103
+ T extends NestedCheckOr<I>
104
+ ? NestedCheckOr<MappedType<I, O>>
105
+ : T extends NestedCheckAnd<I>
106
+ ? NestedCheckAnd<MappedType<I, O>>
107
+ : T extends NestedCheckArray<I>
108
+ ? NestedCheckArray<MappedType<I, O>>
109
+ : Exclude<I, string> | O;
112
110
 
113
111
  const methodPermissions: {
114
112
  [method in Exclude<SupportedMethod, 'OPTIONS'>]: PermissionCheck;
@@ -175,22 +173,26 @@ const isAnd = <T>(x: any): x is NestedCheckAnd<T> =>
175
173
  typeof x === 'object' && 'and' in x;
176
174
  const isOr = <T>(x: any): x is NestedCheckOr<T> =>
177
175
  typeof x === 'object' && 'or' in x;
178
- export function nestedCheck<I extends {}, O>(
179
- check: string,
176
+ export function nestedCheck<I extends string, O>(
177
+ check: I,
180
178
  stringCallback: (s: string) => O,
181
179
  ): O;
182
- export function nestedCheck<I extends {}, O>(
183
- check: boolean,
180
+ export function nestedCheck<I extends boolean, O>(
181
+ check: I,
184
182
  stringCallback: (s: string) => O,
185
183
  ): boolean;
186
- export function nestedCheck<I extends {}, O>(
184
+ export function nestedCheck<I extends NonNullable<unknown>, O>(
187
185
  check: NestedCheck<I>,
188
186
  stringCallback: (s: string) => O,
189
187
  ): Exclude<I, string> | O | MappedNestedCheck<typeof check, I, O>;
190
- export function nestedCheck<I extends {}, O>(
191
- check: NestedCheck<I>,
188
+ export function nestedCheck<I extends object, O>(
189
+ check: NestedCheck<I> | string | boolean,
192
190
  stringCallback: (s: string) => O,
193
- ): boolean | Exclude<I, string> | O | MappedNestedCheck<typeof check, I, O> {
191
+ ):
192
+ | boolean
193
+ | Exclude<I, string>
194
+ | O
195
+ | MappedNestedCheck<Exclude<typeof check, string | boolean>, I, O> {
194
196
  if (typeof check === 'string') {
195
197
  return stringCallback(check);
196
198
  }
@@ -228,10 +230,11 @@ export function nestedCheck<I extends {}, O>(
228
230
  }
229
231
  const checkType = checkTypes[0];
230
232
  switch (checkType.toUpperCase()) {
231
- case 'AND':
233
+ case 'AND': {
232
234
  const and = (check as NestedCheckAnd<I>)[checkType as 'and'];
233
235
  return nestedCheck(and, stringCallback);
234
- case 'OR':
236
+ }
237
+ case 'OR': {
235
238
  const or = (check as NestedCheckOr<I>)[checkType as 'or'];
236
239
  let results: any[] = [];
237
240
  for (const subcheck of or) {
@@ -255,6 +258,7 @@ export function nestedCheck<I extends {}, O>(
255
258
  };
256
259
  }
257
260
  return false;
261
+ }
258
262
  default:
259
263
  throw new Error('Cannot parse required checking logic: ' + checkType);
260
264
  }
@@ -425,7 +429,7 @@ const convertToLambda = (filter: AnyObject, identifier: string) => {
425
429
  }
426
430
  }
427
431
 
428
- if (object.hasOwnProperty('name')) {
432
+ if (Object.prototype.hasOwnProperty.call(object, 'name')) {
429
433
  object.property = { ...object };
430
434
  object.name = identifier;
431
435
  delete object.lambda;
@@ -721,7 +725,7 @@ const deepFreezeExceptDefinition = (obj: AnyObject) => {
721
725
  // We skip the definition because we know it's a property we've defined that will throw an error in some cases
722
726
  if (
723
727
  prop !== 'definition' &&
724
- obj.hasOwnProperty(prop) &&
728
+ Object.prototype.hasOwnProperty.call(obj, prop) &&
725
729
  obj[prop] !== null &&
726
730
  !['object', 'function'].includes(typeof obj[prop])
727
731
  ) {
@@ -1030,9 +1034,14 @@ const getBoundConstrainedMemoizer = memoizeWeak(
1030
1034
  if (!permissionsJSON) {
1031
1035
  return;
1032
1036
  }
1033
- const permissions = JSON.parse(permissionsJSON);
1034
1037
 
1035
1038
  const table = tables[`${resourceName}$bypass`];
1039
+ if (table == null) {
1040
+ // If the table we're based upon doesn't exist then this table also shouldn't exist
1041
+ return;
1042
+ }
1043
+
1044
+ const permissions = JSON.parse(permissionsJSON);
1036
1045
 
1037
1046
  const permissionsTable = (tables[permissionResourceName] = {
1038
1047
  ...table,
@@ -1508,7 +1517,7 @@ export const resolveApiKey = async (
1508
1517
  tx?: Tx,
1509
1518
  ): Promise<PermissionReq['apiKey']> => {
1510
1519
  const apiKey =
1511
- req.params?.[paramName] ?? req.body?.[paramName] ?? req.query?.[paramName];
1520
+ req.params[paramName] ?? req.body[paramName] ?? req.query[paramName];
1512
1521
  if (apiKey == null) {
1513
1522
  return;
1514
1523
  }