@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.
- 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
|