@balena/pinejs 16.0.0-build--batch-09b8c466600d7df13e6df3eacabaf463d96f652f-1 → 16.0.0-build-fisehara-update-sbvr-types-b58e72aca3193964afac96c955fde178fe39d077-1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (141) hide show
  1. package/.pinejs-cache.json +1 -1
  2. package/.versionbot/CHANGELOG.yml +2164 -15
  3. package/CHANGELOG.md +815 -3
  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 +21 -10
  73. package/out/sbvr-api/sbvr-utils.js +128 -124
  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 +10 -12
  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 +117 -165
  128. package/src/sbvr-api/translations.ts +9 -6
  129. package/src/sbvr-api/uri-parser.ts +25 -30
  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
  }