@balena/pinejs 16.0.0-build--batch-f2ffc3d6bcb9f3294fd4fc9de3c21bfe167e100d-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.
- package/.pinejs-cache.json +1 -1
- package/.versionbot/CHANGELOG.yml +2168 -11
- package/CHANGELOG.md +815 -2
- 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 +20 -9
- package/out/sbvr-api/sbvr-utils.js +134 -136
- 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 +7 -10
- 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 +118 -172
- package/src/sbvr-api/translations.ts +9 -6
- package/src/sbvr-api/uri-parser.ts +22 -28
- 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
@@ -1,46 +1,72 @@
|
|
1
1
|
"use strict";
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
3
|
+
if (k2 === undefined) k2 = k;
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
7
|
+
}
|
8
|
+
Object.defineProperty(o, k2, desc);
|
9
|
+
}) : (function(o, m, k, k2) {
|
10
|
+
if (k2 === undefined) k2 = k;
|
11
|
+
o[k2] = m[k];
|
12
|
+
}));
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
15
|
+
}) : function(o, v) {
|
16
|
+
o["default"] = v;
|
17
|
+
});
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
19
|
+
if (mod && mod.__esModule) return mod;
|
20
|
+
var result = {};
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
22
|
+
__setModuleDefault(result, mod);
|
23
|
+
return result;
|
24
|
+
};
|
25
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
26
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
27
|
+
};
|
2
28
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
-
exports.setup = exports.executeStandardModels = exports.handleHttpErrors = exports.onHandleHttpError = exports.handleODataRequest = exports.getAffectedIds = exports.getAbstractSqlModel = exports.runURI = exports.api = exports.PinejsClient = exports.runRule = exports.getID = exports.deleteModel = exports.executeModels = exports.executeModel = exports.generateModels = exports.generateSqlModel = exports.generateAbstractSqlModel = exports.generateLfModel = exports.validateModel = exports.isModelNew = exports.resolveNavigationResource = exports.resolveSynonym = exports.resolveOdataBind = exports.sbvrTypes = exports.db = exports.addSideEffectHook = exports.addPureHook = void 0;
|
4
|
-
const
|
29
|
+
exports.postSetup = exports.setup = exports.executeStandardModels = exports.handleHttpErrors = exports.onHandleHttpError = exports.handleODataRequest = exports.getApiRoot = exports.getModel = exports.getAffectedIds = exports.getAbstractSqlModel = exports.runURI = exports.api = exports.PinejsClient = exports.runRule = exports.getID = exports.deleteModel = exports.postExecuteModels = exports.executeModels = exports.executeModel = exports.generateModels = exports.generateSqlModel = exports.generateAbstractSqlModel = exports.generateLfModel = exports.validateModel = exports.isModelNew = exports.resolveNavigationResource = exports.resolveSynonym = exports.resolveOdataBind = exports.sbvrTypes = exports.db = exports.addSideEffectHook = exports.addPureHook = void 0;
|
30
|
+
const lodash_1 = __importDefault(require("lodash"));
|
5
31
|
const cached_compile_1 = require("./cached-compile");
|
6
|
-
const AbstractSQLCompiler = require("@balena/abstract-sql-compiler");
|
32
|
+
const AbstractSQLCompiler = __importStar(require("@balena/abstract-sql-compiler"));
|
7
33
|
const package_json_1 = require("@balena/abstract-sql-compiler/package.json");
|
8
|
-
const LF2AbstractSQL = require("@balena/lf-to-abstract-sql");
|
34
|
+
const LF2AbstractSQL = __importStar(require("@balena/lf-to-abstract-sql"));
|
9
35
|
const odata_to_abstract_sql_1 = require("@balena/odata-to-abstract-sql");
|
10
|
-
const sbvr_types_1 = require("@balena/sbvr-types");
|
36
|
+
const sbvr_types_1 = __importDefault(require("@balena/sbvr-types"));
|
11
37
|
exports.sbvrTypes = sbvr_types_1.default;
|
12
38
|
const deepFreeze = require("deep-freeze");
|
13
39
|
const pinejs_client_core_1 = require("pinejs-client-core");
|
14
40
|
const extended_sbvr_parser_1 = require("../extended-sbvr-parser/extended-sbvr-parser");
|
15
|
-
const asyncMigrator = require("../migrator/async");
|
16
|
-
const syncMigrator = require("../migrator/sync");
|
41
|
+
const asyncMigrator = __importStar(require("../migrator/async"));
|
42
|
+
const syncMigrator = __importStar(require("../migrator/sync"));
|
17
43
|
const odata_metadata_generator_1 = require("../odata-metadata/odata-metadata-generator");
|
18
44
|
const devModel = require('./dev.sbvr');
|
19
|
-
const permissions = require("./permissions");
|
45
|
+
const permissions = __importStar(require("./permissions"));
|
20
46
|
const errors_1 = require("./errors");
|
21
|
-
const uriParser = require("./uri-parser");
|
47
|
+
const uriParser = __importStar(require("./uri-parser"));
|
22
48
|
const hooks_1 = require("./hooks");
|
23
49
|
var hooks_2 = require("./hooks");
|
24
50
|
Object.defineProperty(exports, "addPureHook", { enumerable: true, get: function () { return hooks_2.addPureHook; } });
|
25
51
|
Object.defineProperty(exports, "addSideEffectHook", { enumerable: true, get: function () { return hooks_2.addSideEffectHook; } });
|
26
52
|
const memoizeWeak = require("memoizee/weak");
|
27
|
-
const controlFlow = require("./control-flow");
|
53
|
+
const controlFlow = __importStar(require("./control-flow"));
|
28
54
|
exports.db = undefined;
|
29
55
|
const package_json_2 = require("@balena/lf-to-abstract-sql/package.json");
|
30
56
|
const package_json_3 = require("@balena/sbvr-types/package.json");
|
31
57
|
const abstract_sql_1 = require("./abstract-sql");
|
32
58
|
var abstract_sql_2 = require("./abstract-sql");
|
33
59
|
Object.defineProperty(exports, "resolveOdataBind", { enumerable: true, get: function () { return abstract_sql_2.resolveOdataBind; } });
|
34
|
-
const odataResponse = require("./odata-response");
|
60
|
+
const odataResponse = __importStar(require("./odata-response"));
|
35
61
|
const module_1 = require("../server-glue/module");
|
36
62
|
const translations_1 = require("./translations");
|
37
|
-
const
|
63
|
+
const utils_1 = require("../migrator/utils");
|
38
64
|
const LF2AbstractSQLTranslator = LF2AbstractSQL.createTranslator(sbvr_types_1.default);
|
39
65
|
const LF2AbstractSQLTranslatorVersion = `${package_json_2.version}+${package_json_3.version}`;
|
40
66
|
const models = {};
|
41
67
|
const memoizedResolvedSynonym = memoizeWeak((abstractSqlModel, resourceName) => {
|
42
68
|
const sqlName = (0, odata_to_abstract_sql_1.odataNameToSqlName)(resourceName);
|
43
|
-
return
|
69
|
+
return (0, lodash_1.default)(sqlName)
|
44
70
|
.split('-')
|
45
71
|
.map((namePart) => {
|
46
72
|
const synonym = abstractSqlModel.synonyms[namePart];
|
@@ -62,7 +88,7 @@ const memoizedResolveNavigationResource = memoizeWeak((abstractSqlModel, resourc
|
|
62
88
|
.flatMap((namePart) => memoizedResolvedSynonym(abstractSqlModel, namePart).split('-'));
|
63
89
|
navigation.push('$');
|
64
90
|
const resolvedResourceName = memoizedResolvedSynonym(abstractSqlModel, resourceName);
|
65
|
-
const mapping =
|
91
|
+
const mapping = lodash_1.default.get(abstractSqlModel.relationships[resolvedResourceName], navigation);
|
66
92
|
if (mapping == null) {
|
67
93
|
throw new Error(`Cannot navigate from '${resourceName}' to '${navigationName}'`);
|
68
94
|
}
|
@@ -85,11 +111,12 @@ const prettifyConstraintError = (err, request) => {
|
|
85
111
|
matches =
|
86
112
|
/ER_DUP_ENTRY: Duplicate entry '.*?[^\\]' for key '(.*?[^\\])'/.exec(err.message);
|
87
113
|
break;
|
88
|
-
case 'postgres':
|
114
|
+
case 'postgres': {
|
89
115
|
const resourceName = (0, exports.resolveSynonym)(request);
|
90
116
|
const abstractSqlModel = getFinalAbstractSqlModel(request);
|
91
117
|
matches = new RegExp('"' + abstractSqlModel.tables[resourceName].name + '_(.*?)_key"').exec(err.message);
|
92
118
|
break;
|
119
|
+
}
|
93
120
|
}
|
94
121
|
if (matches == null) {
|
95
122
|
throw new exports.db.UniqueConstraintError('Unique key constraint violated');
|
@@ -108,7 +135,7 @@ const prettifyConstraintError = (err, request) => {
|
|
108
135
|
matches =
|
109
136
|
/ER_ROW_IS_REFERENCED_: Cannot delete or update a parent row: a foreign key constraint fails \(".*?"\.(".*?").*/.exec(err.message);
|
110
137
|
break;
|
111
|
-
case 'postgres':
|
138
|
+
case 'postgres': {
|
112
139
|
const resourceName = (0, exports.resolveSynonym)(request);
|
113
140
|
const abstractSqlModel = getFinalAbstractSqlModel(request);
|
114
141
|
const tableName = abstractSqlModel.tables[resourceName].name;
|
@@ -123,6 +150,7 @@ const prettifyConstraintError = (err, request) => {
|
|
123
150
|
'_(.*?)_fkey"').exec(err.message);
|
124
151
|
}
|
125
152
|
break;
|
153
|
+
}
|
126
154
|
}
|
127
155
|
if (matches == null) {
|
128
156
|
throw new exports.db.ForeignKeyConstraintError('Foreign key constraint violated');
|
@@ -277,7 +305,7 @@ const executeModels = async (tx, execModels) => {
|
|
277
305
|
try {
|
278
306
|
const compiledModels = await Promise.all(execModels.map(async (model) => {
|
279
307
|
const { apiRoot } = model;
|
280
|
-
await syncMigrator.run(tx, model);
|
308
|
+
const migrationExecutionResult = await syncMigrator.run(tx, model);
|
281
309
|
const compiledModel = generateModels(model, exports.db.engine);
|
282
310
|
if (compiledModel.sql) {
|
283
311
|
for (const createStatement of compiledModel.sql.createSchema) {
|
@@ -300,6 +328,9 @@ const executeModels = async (tx, execModels) => {
|
|
300
328
|
models[apiRoot] = {
|
301
329
|
...compiledModel,
|
302
330
|
versions,
|
331
|
+
modelExecutionResult: {
|
332
|
+
migrationExecutionResult,
|
333
|
+
},
|
303
334
|
};
|
304
335
|
if (compiledModel.sql) {
|
305
336
|
await (0, exports.validateModel)(tx, apiRoot);
|
@@ -314,7 +345,7 @@ const executeModels = async (tx, execModels) => {
|
|
314
345
|
if (key !== 'Console' &&
|
315
346
|
typeof logger[key] === 'function' &&
|
316
347
|
!(model.logging?.[key] ?? defaultSetting)) {
|
317
|
-
logger[key] =
|
348
|
+
logger[key] = lodash_1.default.noop;
|
318
349
|
}
|
319
350
|
}
|
320
351
|
}
|
@@ -385,6 +416,16 @@ const executeModels = async (tx, execModels) => {
|
|
385
416
|
}
|
386
417
|
};
|
387
418
|
exports.executeModels = executeModels;
|
419
|
+
const postExecuteModels = async (tx) => {
|
420
|
+
for (const modelKey of Object.keys(models)) {
|
421
|
+
const pendingToSetExecutedMigrations = models[modelKey]?.modelExecutionResult?.migrationExecutionResult
|
422
|
+
?.pendingUnsetMigrations;
|
423
|
+
if (pendingToSetExecutedMigrations != null) {
|
424
|
+
await (0, utils_1.setExecutedMigrations)(tx, modelKey, pendingToSetExecutedMigrations);
|
425
|
+
}
|
426
|
+
}
|
427
|
+
};
|
428
|
+
exports.postExecuteModels = postExecuteModels;
|
388
429
|
const cleanupModel = (vocab) => {
|
389
430
|
delete models[vocab];
|
390
431
|
delete exports.api[vocab];
|
@@ -479,7 +520,7 @@ exports.runRule = (() => {
|
|
479
520
|
resourceName = ruleLF[1][1][1][2][1];
|
480
521
|
}
|
481
522
|
let fetchingViolators = false;
|
482
|
-
const ruleAbs =
|
523
|
+
const ruleAbs = lodash_1.default.last(abstractSqlModel.rules);
|
483
524
|
if (ruleAbs == null) {
|
484
525
|
throw new Error('Unable to generate rule');
|
485
526
|
}
|
@@ -530,7 +571,7 @@ exports.runRule = (() => {
|
|
530
571
|
const table = models[vocab].abstractSql.tables[resourceName];
|
531
572
|
const odataIdField = (0, odata_to_abstract_sql_1.sqlNameToODataName)(table.idField);
|
532
573
|
let ids = result.rows.map((row) => row[table.idField]);
|
533
|
-
ids =
|
574
|
+
ids = lodash_1.default.uniq(ids);
|
534
575
|
ids = ids.map((id) => odataIdField + ' eq ' + id);
|
535
576
|
let filter;
|
536
577
|
if (ids.length > 0) {
|
@@ -578,13 +619,13 @@ const runURI = async (method, uri, body = {}, tx, req, custom) => {
|
|
578
619
|
permissions: [],
|
579
620
|
};
|
580
621
|
}
|
581
|
-
|
622
|
+
lodash_1.default.forEach(body, (v, k) => {
|
582
623
|
if (v === undefined) {
|
583
624
|
delete body[k];
|
584
625
|
}
|
585
626
|
});
|
586
627
|
const emulatedReq = {
|
587
|
-
on:
|
628
|
+
on: lodash_1.default.noop,
|
588
629
|
custom,
|
589
630
|
user,
|
590
631
|
apiKey,
|
@@ -597,16 +638,16 @@ const runURI = async (method, uri, body = {}, tx, req, custom) => {
|
|
597
638
|
};
|
598
639
|
const { promise } = runODataRequest(emulatedReq, apiRoot);
|
599
640
|
const [response] = await promise;
|
600
|
-
if (
|
641
|
+
if (lodash_1.default.isError(response)) {
|
601
642
|
throw response;
|
602
643
|
}
|
603
|
-
const { body: responseBody,
|
604
|
-
if (
|
605
|
-
const ErrorClass = errors_1.statusCodeToError[
|
644
|
+
const { body: responseBody, statusCode, headers } = response;
|
645
|
+
if (statusCode != null && statusCode >= 400) {
|
646
|
+
const ErrorClass = errors_1.statusCodeToError[statusCode];
|
606
647
|
if (ErrorClass != null) {
|
607
648
|
throw new ErrorClass(undefined, responseBody, headers);
|
608
649
|
}
|
609
|
-
throw new errors_1.HttpError(
|
650
|
+
throw new errors_1.HttpError(statusCode, undefined, responseBody, headers);
|
610
651
|
}
|
611
652
|
return responseBody;
|
612
653
|
};
|
@@ -616,7 +657,7 @@ const getAbstractSqlModel = (request) => {
|
|
616
657
|
};
|
617
658
|
exports.getAbstractSqlModel = getAbstractSqlModel;
|
618
659
|
const getFinalAbstractSqlModel = (request) => {
|
619
|
-
const finalModel =
|
660
|
+
const finalModel = lodash_1.default.last(request.translateVersions);
|
620
661
|
return (request.finalAbstractSqlModel ??= models[finalModel].abstractSql);
|
621
662
|
};
|
622
663
|
const getIdField = (request) => getFinalAbstractSqlModel(request).tables[(0, exports.resolveSynonym)(request)].idField;
|
@@ -638,8 +679,7 @@ const $getAffectedIds = async ({ req, request, tx, }) => {
|
|
638
679
|
if (!['PATCH', 'DELETE'].includes(request.method)) {
|
639
680
|
throw new Error('Can only call `getAffectedIds` with PATCH/DELETE requests');
|
640
681
|
}
|
641
|
-
const parsedRequest =
|
642
|
-
id: request.batchRequestId,
|
682
|
+
const parsedRequest = uriParser.parseOData({
|
643
683
|
method: request.method,
|
644
684
|
url: `/${request.vocabulary}${request.url}`,
|
645
685
|
});
|
@@ -671,61 +711,14 @@ const $getAffectedIds = async ({ req, request, tx, }) => {
|
|
671
711
|
}
|
672
712
|
return result.rows.map((row) => row[idField]);
|
673
713
|
};
|
674
|
-
const
|
675
|
-
|
676
|
-
if (!Array.isArray(requests)) {
|
677
|
-
throw new errors_1.BadRequestError('Batch requests must include an array of requests in the body via the "requests" property');
|
678
|
-
}
|
679
|
-
if (req.headers != null && req.headers['content-type'] == null) {
|
680
|
-
throw new errors_1.BadRequestError('Headers in a batch request must include a "content-type" header if they are provided');
|
681
|
-
}
|
682
|
-
if (requests.find((request) => request.headers?.authorization != null ||
|
683
|
-
request.url?.includes('apikey=')) != null) {
|
684
|
-
throw new errors_1.BadRequestError('Authorization may only be passed to the main batch request');
|
685
|
-
}
|
686
|
-
const ids = new Set(requests
|
687
|
-
.map((request) => request.id)
|
688
|
-
.filter((id) => typeof id === 'string'));
|
689
|
-
if (ids.size !== requests.length) {
|
690
|
-
throw new errors_1.BadRequestError('All requests in a batch request must have unique string ids');
|
691
|
-
}
|
692
|
-
for (const request of requests) {
|
693
|
-
if (request.headers != null &&
|
694
|
-
request.headers['content-type'] == null &&
|
695
|
-
(req.headers == null || req.headers['content-type'] == null)) {
|
696
|
-
throw new errors_1.BadRequestError('Requests of a batch request that have headers must include a "content-type" header');
|
697
|
-
}
|
698
|
-
if (request.method == null) {
|
699
|
-
throw new errors_1.BadRequestError('Requests of a batch request must have a "method"');
|
700
|
-
}
|
701
|
-
const upperCaseMethod = request.method.toUpperCase();
|
702
|
-
if (!validBatchMethods.has(upperCaseMethod)) {
|
703
|
-
throw new errors_1.BadRequestError(`Requests of a batch request must have a method matching one of the following: ${Array.from(validBatchMethods).join(', ')}`);
|
704
|
-
}
|
705
|
-
if (request.body !== undefined &&
|
706
|
-
(upperCaseMethod === 'GET' || upperCaseMethod === 'DELETE')) {
|
707
|
-
throw new errors_1.BadRequestError('GET and DELETE requests of a batch request must not have a body');
|
708
|
-
}
|
709
|
-
}
|
710
|
-
const urls = new Set(requests.map((request) => request.url));
|
711
|
-
if (urls.has(undefined)) {
|
712
|
-
throw new errors_1.BadRequestError('Requests of a batch request must have a "url"');
|
713
|
-
}
|
714
|
-
if (urls.has('/university/$batch')) {
|
715
|
-
throw new errors_1.BadRequestError('Batch requests cannot contain batch requests');
|
716
|
-
}
|
717
|
-
const urlModels = new Set(Array.from(urls.values()).map((url) => url.split('/')[1]));
|
718
|
-
if (urlModels.size > 1) {
|
719
|
-
throw new errors_1.BadRequestError('Batch requests must consist of requests for only one model');
|
720
|
-
}
|
714
|
+
const getModel = (vocabulary) => {
|
715
|
+
return models[vocabulary];
|
721
716
|
};
|
717
|
+
exports.getModel = getModel;
|
722
718
|
const runODataRequest = (req, vocabulary) => {
|
723
719
|
if (module_1.env.DEBUG) {
|
724
720
|
exports.api[vocabulary].logger.log('Parsing', req.method, req.url);
|
725
721
|
}
|
726
|
-
if (req.url.startsWith(`/${vocabulary}/$batch`)) {
|
727
|
-
validateBatch(req);
|
728
|
-
}
|
729
722
|
const { versions } = models[vocabulary];
|
730
723
|
const reqHooks = versions.map((version) => [
|
731
724
|
version,
|
@@ -760,25 +753,27 @@ const runODataRequest = (req, vocabulary) => {
|
|
760
753
|
promise: (async () => {
|
761
754
|
await (0, hooks_1.runHooks)('PREPARSE', reqHooks, { req, tx: req.tx });
|
762
755
|
let requests;
|
763
|
-
if (req.
|
764
|
-
|
765
|
-
req: request,
|
766
|
-
tx: req.tx,
|
767
|
-
})));
|
768
|
-
requests = req.body.requests;
|
756
|
+
if (req.batch != null && req.batch.length > 0) {
|
757
|
+
requests = req.batch;
|
769
758
|
}
|
770
759
|
else {
|
771
760
|
const { method, url, body } = req;
|
772
|
-
requests = [{ method, url, body }];
|
761
|
+
requests = [{ method, url, data: body }];
|
773
762
|
}
|
774
763
|
const prepareRequest = async (parsedRequest) => {
|
775
|
-
|
764
|
+
const abstractSqlModel = (0, exports.getAbstractSqlModel)(parsedRequest);
|
765
|
+
if (abstractSqlModel == null) {
|
776
766
|
throw new errors_1.BadRequestError('Unknown vocabulary: ' + parsedRequest.vocabulary);
|
777
767
|
}
|
778
768
|
parsedRequest.engine = exports.db.engine;
|
779
769
|
parsedRequest.translateVersions = [...versions];
|
780
770
|
const $request = parsedRequest;
|
781
771
|
try {
|
772
|
+
const resolvedResourceName = (0, exports.resolveSynonym)($request);
|
773
|
+
if (abstractSqlModel.tables[resolvedResourceName] == null &&
|
774
|
+
!resolvedResourceName.endsWith('#canAccess')) {
|
775
|
+
throw new errors_1.UnauthorizedError();
|
776
|
+
}
|
782
777
|
$request.hooks = [];
|
783
778
|
for (const version of versions) {
|
784
779
|
const hooks = [
|
@@ -813,10 +808,7 @@ const runODataRequest = (req, vocabulary) => {
|
|
813
808
|
}
|
814
809
|
};
|
815
810
|
const results = await mappingFn(requests, async (requestPart) => {
|
816
|
-
const parsedRequest =
|
817
|
-
!requestPart.url.includes(`/${vocabulary}/$batch`)
|
818
|
-
? req.headers
|
819
|
-
: undefined);
|
811
|
+
const parsedRequest = uriParser.parseOData(requestPart);
|
820
812
|
let request;
|
821
813
|
if (Array.isArray(parsedRequest)) {
|
822
814
|
request = await controlFlow.mapSeries(parsedRequest, prepareRequest);
|
@@ -851,13 +843,13 @@ const runODataRequest = (req, vocabulary) => {
|
|
851
843
|
});
|
852
844
|
});
|
853
845
|
const responses = results.map((result) => {
|
854
|
-
if (
|
846
|
+
if (lodash_1.default.isError(result)) {
|
855
847
|
return convertToHttpError(result);
|
856
848
|
}
|
857
849
|
else {
|
858
850
|
if (!Array.isArray(result) &&
|
859
851
|
result.body == null &&
|
860
|
-
result.
|
852
|
+
result.statusCode == null) {
|
861
853
|
console.error('No status or body set', req.url, responses);
|
862
854
|
return new errors_1.InternalRequestError();
|
863
855
|
}
|
@@ -868,8 +860,13 @@ const runODataRequest = (req, vocabulary) => {
|
|
868
860
|
})(),
|
869
861
|
};
|
870
862
|
};
|
871
|
-
const
|
863
|
+
const getApiRoot = (req) => {
|
872
864
|
const [, apiRoot] = req.url.split('/', 2);
|
865
|
+
return apiRoot;
|
866
|
+
};
|
867
|
+
exports.getApiRoot = getApiRoot;
|
868
|
+
const handleODataRequest = async (req, res, next) => {
|
869
|
+
const apiRoot = (0, exports.getApiRoot)(req);
|
873
870
|
if (apiRoot == null || models[apiRoot] == null) {
|
874
871
|
return next('route');
|
875
872
|
}
|
@@ -878,8 +875,7 @@ const handleODataRequest = async (req, res, next) => {
|
|
878
875
|
res.on('close', tryCancelRequest);
|
879
876
|
const responses = await promise;
|
880
877
|
res.set('Cache-Control', 'no-cache');
|
881
|
-
if (
|
882
|
-
req.body.requests?.length === 0) {
|
878
|
+
if (req.batch == null || req.batch.length === 0) {
|
883
879
|
let [response] = responses;
|
884
880
|
if (response instanceof errors_1.HttpError) {
|
885
881
|
response = httpErrorToResponse(response);
|
@@ -887,16 +883,14 @@ const handleODataRequest = async (req, res, next) => {
|
|
887
883
|
handleResponse(res, response);
|
888
884
|
}
|
889
885
|
else {
|
890
|
-
res.status(200).
|
891
|
-
|
892
|
-
|
893
|
-
|
894
|
-
|
895
|
-
|
896
|
-
|
897
|
-
|
898
|
-
}),
|
899
|
-
});
|
886
|
+
res.status(200).sendMulti(responses.map((response) => {
|
887
|
+
if (response instanceof errors_1.HttpError) {
|
888
|
+
return httpErrorToResponse(response);
|
889
|
+
}
|
890
|
+
else {
|
891
|
+
return response;
|
892
|
+
}
|
893
|
+
}));
|
900
894
|
}
|
901
895
|
}
|
902
896
|
catch (e) {
|
@@ -918,7 +912,7 @@ const handleHttpErrors = (req, res, err) => {
|
|
918
912
|
for (const handleErrorFn of handleErrorFns) {
|
919
913
|
handleErrorFn(req, err);
|
920
914
|
}
|
921
|
-
const response = httpErrorToResponse(err
|
915
|
+
const response = httpErrorToResponse(err);
|
922
916
|
handleResponse(res, response);
|
923
917
|
return true;
|
924
918
|
}
|
@@ -926,9 +920,9 @@ const handleHttpErrors = (req, res, err) => {
|
|
926
920
|
};
|
927
921
|
exports.handleHttpErrors = handleHttpErrors;
|
928
922
|
const handleResponse = (res, response) => {
|
929
|
-
const { body, headers,
|
923
|
+
const { body, headers, statusCode } = response;
|
930
924
|
res.set(headers);
|
931
|
-
res.status(
|
925
|
+
res.status(statusCode);
|
932
926
|
if (!body) {
|
933
927
|
res.end();
|
934
928
|
}
|
@@ -936,11 +930,10 @@ const handleResponse = (res, response) => {
|
|
936
930
|
res.json(body);
|
937
931
|
}
|
938
932
|
};
|
939
|
-
const httpErrorToResponse = (err
|
940
|
-
const message = err.getResponseBody();
|
933
|
+
const httpErrorToResponse = (err) => {
|
941
934
|
return {
|
942
|
-
|
943
|
-
body:
|
935
|
+
statusCode: err.status,
|
936
|
+
body: err.getResponseBody(),
|
944
937
|
headers: err.headers,
|
945
938
|
};
|
946
939
|
};
|
@@ -1032,8 +1025,7 @@ const runChangeSet = (req, tx) => async (changeSetResults, request) => {
|
|
1032
1025
|
throw new Error('No request id');
|
1033
1026
|
}
|
1034
1027
|
result.headers ??= {};
|
1035
|
-
result.headers['content-id'] = request.
|
1036
|
-
result.id = request.batchRequestId;
|
1028
|
+
result.headers['content-id'] = request.id;
|
1037
1029
|
changeSetResults.set(request.id, result);
|
1038
1030
|
};
|
1039
1031
|
const updateBinds = (changeSetResults, request) => {
|
@@ -1054,29 +1046,22 @@ const updateBinds = (changeSetResults, request) => {
|
|
1054
1046
|
return request;
|
1055
1047
|
};
|
1056
1048
|
const prepareResponse = async (req, request, result, tx) => {
|
1057
|
-
let response;
|
1058
1049
|
switch (request.method) {
|
1059
1050
|
case 'GET':
|
1060
|
-
|
1061
|
-
break;
|
1051
|
+
return await respondGet(req, request, result, tx);
|
1062
1052
|
case 'POST':
|
1063
|
-
|
1064
|
-
break;
|
1053
|
+
return await respondPost(req, request, result, tx);
|
1065
1054
|
case 'PUT':
|
1066
1055
|
case 'PATCH':
|
1067
1056
|
case 'MERGE':
|
1068
|
-
|
1069
|
-
break;
|
1057
|
+
return await respondPut(req, request, result, tx);
|
1070
1058
|
case 'DELETE':
|
1071
|
-
|
1072
|
-
break;
|
1059
|
+
return await respondDelete(req, request, result, tx);
|
1073
1060
|
case 'OPTIONS':
|
1074
|
-
|
1075
|
-
break;
|
1061
|
+
return await respondOptions(req, request, result, tx);
|
1076
1062
|
default:
|
1077
1063
|
throw new errors_1.MethodNotAllowedError();
|
1078
1064
|
}
|
1079
|
-
return { ...response, id: request.batchRequestId };
|
1080
1065
|
};
|
1081
1066
|
const checkReadOnlyRequests = (request) => {
|
1082
1067
|
if (request.method !== 'GET') {
|
@@ -1145,7 +1130,7 @@ const respondGet = async (req, request, result, tx) => {
|
|
1145
1130
|
: undefined;
|
1146
1131
|
const d = await odataResponse.process(vocab, (0, exports.getAbstractSqlModel)(request), request.originalResourceName, result.rows, { includeMetadata: metadata === 'full' });
|
1147
1132
|
const response = {
|
1148
|
-
|
1133
|
+
statusCode: 200,
|
1149
1134
|
body: { d },
|
1150
1135
|
headers: { 'content-type': 'application/json' },
|
1151
1136
|
};
|
@@ -1161,14 +1146,14 @@ const respondGet = async (req, request, result, tx) => {
|
|
1161
1146
|
else {
|
1162
1147
|
if (request.resourceName === '$metadata') {
|
1163
1148
|
return {
|
1164
|
-
|
1149
|
+
statusCode: 200,
|
1165
1150
|
body: models[vocab].odataMetadata,
|
1166
1151
|
headers: { 'content-type': 'xml' },
|
1167
1152
|
};
|
1168
1153
|
}
|
1169
1154
|
else {
|
1170
1155
|
return {
|
1171
|
-
|
1156
|
+
statusCode: 404,
|
1172
1157
|
};
|
1173
1158
|
}
|
1174
1159
|
}
|
@@ -1178,7 +1163,7 @@ const runPost = async (_req, request, tx) => {
|
|
1178
1163
|
if (rowsAffected === 0) {
|
1179
1164
|
throw new errors_1.PermissionError();
|
1180
1165
|
}
|
1181
|
-
await (0, exports.validateModel)(tx,
|
1166
|
+
await (0, exports.validateModel)(tx, lodash_1.default.last(request.translateVersions), request);
|
1182
1167
|
return insertId;
|
1183
1168
|
};
|
1184
1169
|
const respondPost = async (req, request, id, tx) => {
|
@@ -1197,7 +1182,7 @@ const respondPost = async (req, request, id, tx) => {
|
|
1197
1182
|
}
|
1198
1183
|
}
|
1199
1184
|
const response = {
|
1200
|
-
|
1185
|
+
statusCode: 201,
|
1201
1186
|
body: result.d[0],
|
1202
1187
|
headers: {
|
1203
1188
|
'content-type': 'application/json',
|
@@ -1225,13 +1210,13 @@ const runPut = async (_req, request, tx) => {
|
|
1225
1210
|
({ rowsAffected } = await runQuery(tx, request, undefined, true));
|
1226
1211
|
}
|
1227
1212
|
if (rowsAffected > 0) {
|
1228
|
-
await (0, exports.validateModel)(tx,
|
1213
|
+
await (0, exports.validateModel)(tx, lodash_1.default.last(request.translateVersions), request);
|
1229
1214
|
}
|
1230
1215
|
return undefined;
|
1231
1216
|
};
|
1232
1217
|
const respondPut = async (req, request, result, tx) => {
|
1233
1218
|
const response = {
|
1234
|
-
|
1219
|
+
statusCode: 200,
|
1235
1220
|
};
|
1236
1221
|
await (0, hooks_1.runHooks)('PRERESPOND', request.hooks, {
|
1237
1222
|
req,
|
@@ -1247,7 +1232,7 @@ const respondOptions = respondPut;
|
|
1247
1232
|
const runDelete = async (_req, request, tx) => {
|
1248
1233
|
const { rowsAffected } = await runQuery(tx, request, undefined, true);
|
1249
1234
|
if (rowsAffected > 0) {
|
1250
|
-
await (0, exports.validateModel)(tx,
|
1235
|
+
await (0, exports.validateModel)(tx, lodash_1.default.last(request.translateVersions), request);
|
1251
1236
|
}
|
1252
1237
|
return undefined;
|
1253
1238
|
};
|
@@ -1318,4 +1303,17 @@ const setup = async (_app, $db) => {
|
|
1318
1303
|
}
|
1319
1304
|
};
|
1320
1305
|
exports.setup = setup;
|
1306
|
+
const postSetup = async (_app, $db) => {
|
1307
|
+
exports.db = exports.db = $db;
|
1308
|
+
try {
|
1309
|
+
await exports.db.transaction(async (tx) => {
|
1310
|
+
await (0, exports.postExecuteModels)(tx);
|
1311
|
+
});
|
1312
|
+
}
|
1313
|
+
catch (err) {
|
1314
|
+
console.error('Could not post execute models', err);
|
1315
|
+
process.exit(1);
|
1316
|
+
}
|
1317
|
+
};
|
1318
|
+
exports.postSetup = postSetup;
|
1321
1319
|
//# sourceMappingURL=sbvr-utils.js.map
|