@balena/pinejs 16.0.0-build--batch-09b8c466600d7df13e6df3eacabaf463d96f652f-1 → 16.0.0-build-fisehara-update-sbvr-types-b58e72aca3193964afac96c955fde178fe39d077-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.
- package/.pinejs-cache.json +1 -1
- package/.versionbot/CHANGELOG.yml +2164 -15
- package/CHANGELOG.md +815 -3
- package/Gruntfile.ts +9 -6
- package/README.md +10 -0
- package/build/browser.ts +2 -2
- package/build/config.ts +1 -1
- package/build/module.ts +2 -2
- package/build/server.ts +2 -2
- package/docker-compose.npm-test.yml +21 -3
- package/out/bin/abstract-sql-compiler.js +5 -5
- package/out/bin/abstract-sql-compiler.js.map +1 -1
- package/out/bin/odata-compiler.js +10 -10
- package/out/bin/odata-compiler.js.map +1 -1
- package/out/bin/sbvr-compiler.js +34 -11
- package/out/bin/sbvr-compiler.js.map +1 -1
- package/out/bin/utils.js +25 -2
- package/out/bin/utils.js.map +1 -1
- package/out/config-loader/config-loader.d.ts +4 -2
- package/out/config-loader/config-loader.js +54 -13
- package/out/config-loader/config-loader.js.map +1 -1
- package/out/config-loader/env.d.ts +2 -1
- package/out/config-loader/env.js +5 -2
- package/out/config-loader/env.js.map +1 -1
- package/out/data-server/sbvr-server.d.ts +1 -1
- package/out/data-server/sbvr-server.js +3 -1
- package/out/data-server/sbvr-server.js.map +1 -1
- package/out/database-layer/db.js +40 -14
- package/out/database-layer/db.js.map +1 -1
- package/out/express-emulator/express.js +5 -3
- package/out/express-emulator/express.js.map +1 -1
- package/out/http-transactions/transactions.d.ts +1 -1
- package/out/http-transactions/transactions.js +10 -5
- package/out/http-transactions/transactions.js.map +1 -1
- package/out/migrator/async.js +32 -5
- package/out/migrator/async.js.map +1 -1
- package/out/migrator/sync.d.ts +2 -1
- package/out/migrator/sync.js +29 -3
- package/out/migrator/sync.js.map +1 -1
- package/out/migrator/utils.d.ts +6 -3
- package/out/migrator/utils.js +30 -4
- package/out/migrator/utils.js.map +1 -1
- package/out/odata-metadata/odata-metadata-generator.js +4 -1
- package/out/odata-metadata/odata-metadata-generator.js.map +1 -1
- package/out/passport-pinejs/mount-login-router.d.ts +3 -0
- package/out/passport-pinejs/mount-login-router.js +65 -0
- package/out/passport-pinejs/mount-login-router.js.map +1 -0
- package/out/passport-pinejs/passport-pinejs.d.ts +2 -1
- package/out/passport-pinejs/passport-pinejs.js +28 -2
- package/out/passport-pinejs/passport-pinejs.js.map +1 -1
- package/out/pinejs-session-store/pinejs-session-store.js +30 -7
- package/out/pinejs-session-store/pinejs-session-store.js.map +1 -1
- package/out/sbvr-api/abstract-sql.d.ts +2 -2
- package/out/sbvr-api/abstract-sql.js +35 -9
- package/out/sbvr-api/abstract-sql.js.map +1 -1
- package/out/sbvr-api/cached-compile.js +9 -6
- package/out/sbvr-api/cached-compile.js.map +1 -1
- package/out/sbvr-api/common-types.d.ts +1 -1
- package/out/sbvr-api/control-flow.js +5 -2
- package/out/sbvr-api/control-flow.js.map +1 -1
- package/out/sbvr-api/express-extension.d.ts +10 -7
- package/out/sbvr-api/express-extension.js +1 -0
- package/out/sbvr-api/hooks.d.ts +5 -1
- package/out/sbvr-api/hooks.js +12 -10
- package/out/sbvr-api/hooks.js.map +1 -1
- package/out/sbvr-api/odata-response.d.ts +5 -2
- package/out/sbvr-api/odata-response.js +36 -6
- package/out/sbvr-api/odata-response.js.map +1 -1
- package/out/sbvr-api/permissions.d.ts +6 -7
- package/out/sbvr-api/permissions.js +69 -38
- package/out/sbvr-api/permissions.js.map +1 -1
- package/out/sbvr-api/sbvr-utils.d.ts +21 -10
- package/out/sbvr-api/sbvr-utils.js +128 -124
- package/out/sbvr-api/sbvr-utils.js.map +1 -1
- package/out/sbvr-api/translations.d.ts +2 -2
- package/out/sbvr-api/translations.js +17 -10
- package/out/sbvr-api/translations.js.map +1 -1
- package/out/sbvr-api/uri-parser.d.ts +10 -12
- package/out/sbvr-api/uri-parser.js +46 -19
- package/out/sbvr-api/uri-parser.js.map +1 -1
- package/out/server-glue/global-ext.d.ts +2 -1
- package/out/server-glue/module.d.ts +3 -1
- package/out/server-glue/module.js +40 -13
- package/out/server-glue/module.js.map +1 -1
- package/out/server-glue/sbvr-loader.js.map +1 -1
- package/out/server-glue/server.js +31 -39
- package/out/server-glue/server.js.map +1 -1
- package/out/webresource-handler/handlers/NoopHandler.d.ts +7 -0
- package/out/webresource-handler/handlers/NoopHandler.js +20 -0
- package/out/webresource-handler/handlers/NoopHandler.js.map +1 -0
- package/out/webresource-handler/handlers/S3Handler.d.ts +28 -0
- package/out/webresource-handler/handlers/S3Handler.js +97 -0
- package/out/webresource-handler/handlers/S3Handler.js.map +1 -0
- package/out/webresource-handler/handlers/index.d.ts +2 -0
- package/out/webresource-handler/handlers/index.js +19 -0
- package/out/webresource-handler/handlers/index.js.map +1 -0
- package/out/webresource-handler/index.d.ts +34 -0
- package/out/webresource-handler/index.js +307 -0
- package/out/webresource-handler/index.js.map +1 -0
- package/package.json +68 -62
- package/src/bin/abstract-sql-compiler.ts +7 -9
- package/src/bin/odata-compiler.ts +12 -15
- package/src/bin/sbvr-compiler.ts +14 -18
- package/src/bin/utils.ts +1 -1
- package/src/config-loader/config-loader.ts +44 -10
- package/src/config-loader/env.ts +1 -1
- package/src/data-server/sbvr-server.js +3 -1
- package/src/database-layer/db.ts +23 -19
- package/src/express-emulator/express.js +5 -3
- package/src/extended-sbvr-parser/extended-sbvr-parser.ts +1 -1
- package/src/http-transactions/transactions.js +10 -5
- package/src/migrator/async.ts +7 -6
- package/src/migrator/sync.ts +10 -7
- package/src/migrator/utils.ts +11 -5
- package/src/odata-metadata/odata-metadata-generator.ts +2 -2
- package/src/passport-pinejs/mount-login-router.ts +46 -0
- package/src/passport-pinejs/passport-pinejs.ts +7 -3
- package/src/pinejs-session-store/pinejs-session-store.ts +6 -6
- package/src/sbvr-api/abstract-sql.ts +5 -5
- package/src/sbvr-api/cached-compile.ts +1 -2
- package/src/sbvr-api/common-types.ts +1 -1
- package/src/sbvr-api/control-flow.ts +1 -1
- package/src/sbvr-api/express-extension.ts +12 -8
- package/src/sbvr-api/hooks.ts +11 -11
- package/src/sbvr-api/odata-response.ts +56 -9
- package/src/sbvr-api/permissions.ts +44 -35
- package/src/sbvr-api/sbvr-utils.ts +117 -165
- package/src/sbvr-api/translations.ts +9 -6
- package/src/sbvr-api/uri-parser.ts +25 -30
- package/src/server-glue/global-ext.d.ts +2 -1
- package/src/server-glue/module.ts +8 -2
- package/src/server-glue/sbvr-loader.ts +1 -1
- package/src/server-glue/server.ts +11 -49
- package/src/webresource-handler/handlers/NoopHandler.ts +21 -0
- package/src/webresource-handler/handlers/S3Handler.ts +143 -0
- package/src/webresource-handler/handlers/index.ts +2 -0
- package/src/webresource-handler/index.ts +450 -0
- package/tsconfig.dev.json +2 -1
- package/tsconfig.json +1 -1
- package/typings/lf-to-abstract-sql.d.ts +1 -1
- 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:
|
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
|
-
|
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
|
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
|
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 (!
|
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
|
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,13 +1,17 @@
|
|
1
1
|
// Augment express.js with pinejs-specific attributes via declaration merging.
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
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
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
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
|
}
|
package/src/sbvr-api/hooks.ts
CHANGED
@@ -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
|
8
|
+
import _ from 'lodash';
|
9
9
|
import { settleMapSeries } from './control-flow';
|
10
|
-
import
|
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
|
-
|
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
|
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
|
-
|
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) =>
|
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
|
37
|
-
import
|
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
|
-
//
|
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
|
-
|
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> =
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
I
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
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
|
179
|
-
check:
|
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
|
183
|
-
check:
|
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
|
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
|
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
|
-
):
|
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
|
-
|
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 (
|
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
|
-
|
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
|
1520
|
+
req.params[paramName] ?? req.body[paramName] ?? req.query[paramName];
|
1512
1521
|
if (apiKey == null) {
|
1513
1522
|
return;
|
1514
1523
|
}
|