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

Sign up to get free protection for your applications and to get access to all the features.
Files changed (141) hide show
  1. package/.pinejs-cache.json +1 -1
  2. package/.versionbot/CHANGELOG.yml +2164 -15
  3. package/CHANGELOG.md +815 -3
  4. package/Gruntfile.ts +9 -6
  5. package/README.md +10 -0
  6. package/build/browser.ts +2 -2
  7. package/build/config.ts +1 -1
  8. package/build/module.ts +2 -2
  9. package/build/server.ts +2 -2
  10. package/docker-compose.npm-test.yml +21 -3
  11. package/out/bin/abstract-sql-compiler.js +5 -5
  12. package/out/bin/abstract-sql-compiler.js.map +1 -1
  13. package/out/bin/odata-compiler.js +10 -10
  14. package/out/bin/odata-compiler.js.map +1 -1
  15. package/out/bin/sbvr-compiler.js +34 -11
  16. package/out/bin/sbvr-compiler.js.map +1 -1
  17. package/out/bin/utils.js +25 -2
  18. package/out/bin/utils.js.map +1 -1
  19. package/out/config-loader/config-loader.d.ts +4 -2
  20. package/out/config-loader/config-loader.js +54 -13
  21. package/out/config-loader/config-loader.js.map +1 -1
  22. package/out/config-loader/env.d.ts +2 -1
  23. package/out/config-loader/env.js +5 -2
  24. package/out/config-loader/env.js.map +1 -1
  25. package/out/data-server/sbvr-server.d.ts +1 -1
  26. package/out/data-server/sbvr-server.js +3 -1
  27. package/out/data-server/sbvr-server.js.map +1 -1
  28. package/out/database-layer/db.js +40 -14
  29. package/out/database-layer/db.js.map +1 -1
  30. package/out/express-emulator/express.js +5 -3
  31. package/out/express-emulator/express.js.map +1 -1
  32. package/out/http-transactions/transactions.d.ts +1 -1
  33. package/out/http-transactions/transactions.js +10 -5
  34. package/out/http-transactions/transactions.js.map +1 -1
  35. package/out/migrator/async.js +32 -5
  36. package/out/migrator/async.js.map +1 -1
  37. package/out/migrator/sync.d.ts +2 -1
  38. package/out/migrator/sync.js +29 -3
  39. package/out/migrator/sync.js.map +1 -1
  40. package/out/migrator/utils.d.ts +6 -3
  41. package/out/migrator/utils.js +30 -4
  42. package/out/migrator/utils.js.map +1 -1
  43. package/out/odata-metadata/odata-metadata-generator.js +4 -1
  44. package/out/odata-metadata/odata-metadata-generator.js.map +1 -1
  45. package/out/passport-pinejs/mount-login-router.d.ts +3 -0
  46. package/out/passport-pinejs/mount-login-router.js +65 -0
  47. package/out/passport-pinejs/mount-login-router.js.map +1 -0
  48. package/out/passport-pinejs/passport-pinejs.d.ts +2 -1
  49. package/out/passport-pinejs/passport-pinejs.js +28 -2
  50. package/out/passport-pinejs/passport-pinejs.js.map +1 -1
  51. package/out/pinejs-session-store/pinejs-session-store.js +30 -7
  52. package/out/pinejs-session-store/pinejs-session-store.js.map +1 -1
  53. package/out/sbvr-api/abstract-sql.d.ts +2 -2
  54. package/out/sbvr-api/abstract-sql.js +35 -9
  55. package/out/sbvr-api/abstract-sql.js.map +1 -1
  56. package/out/sbvr-api/cached-compile.js +9 -6
  57. package/out/sbvr-api/cached-compile.js.map +1 -1
  58. package/out/sbvr-api/common-types.d.ts +1 -1
  59. package/out/sbvr-api/control-flow.js +5 -2
  60. package/out/sbvr-api/control-flow.js.map +1 -1
  61. package/out/sbvr-api/express-extension.d.ts +10 -7
  62. package/out/sbvr-api/express-extension.js +1 -0
  63. package/out/sbvr-api/hooks.d.ts +5 -1
  64. package/out/sbvr-api/hooks.js +12 -10
  65. package/out/sbvr-api/hooks.js.map +1 -1
  66. package/out/sbvr-api/odata-response.d.ts +5 -2
  67. package/out/sbvr-api/odata-response.js +36 -6
  68. package/out/sbvr-api/odata-response.js.map +1 -1
  69. package/out/sbvr-api/permissions.d.ts +6 -7
  70. package/out/sbvr-api/permissions.js +69 -38
  71. package/out/sbvr-api/permissions.js.map +1 -1
  72. package/out/sbvr-api/sbvr-utils.d.ts +21 -10
  73. package/out/sbvr-api/sbvr-utils.js +128 -124
  74. package/out/sbvr-api/sbvr-utils.js.map +1 -1
  75. package/out/sbvr-api/translations.d.ts +2 -2
  76. package/out/sbvr-api/translations.js +17 -10
  77. package/out/sbvr-api/translations.js.map +1 -1
  78. package/out/sbvr-api/uri-parser.d.ts +10 -12
  79. package/out/sbvr-api/uri-parser.js +46 -19
  80. package/out/sbvr-api/uri-parser.js.map +1 -1
  81. package/out/server-glue/global-ext.d.ts +2 -1
  82. package/out/server-glue/module.d.ts +3 -1
  83. package/out/server-glue/module.js +40 -13
  84. package/out/server-glue/module.js.map +1 -1
  85. package/out/server-glue/sbvr-loader.js.map +1 -1
  86. package/out/server-glue/server.js +31 -39
  87. package/out/server-glue/server.js.map +1 -1
  88. package/out/webresource-handler/handlers/NoopHandler.d.ts +7 -0
  89. package/out/webresource-handler/handlers/NoopHandler.js +20 -0
  90. package/out/webresource-handler/handlers/NoopHandler.js.map +1 -0
  91. package/out/webresource-handler/handlers/S3Handler.d.ts +28 -0
  92. package/out/webresource-handler/handlers/S3Handler.js +97 -0
  93. package/out/webresource-handler/handlers/S3Handler.js.map +1 -0
  94. package/out/webresource-handler/handlers/index.d.ts +2 -0
  95. package/out/webresource-handler/handlers/index.js +19 -0
  96. package/out/webresource-handler/handlers/index.js.map +1 -0
  97. package/out/webresource-handler/index.d.ts +34 -0
  98. package/out/webresource-handler/index.js +307 -0
  99. package/out/webresource-handler/index.js.map +1 -0
  100. package/package.json +68 -62
  101. package/src/bin/abstract-sql-compiler.ts +7 -9
  102. package/src/bin/odata-compiler.ts +12 -15
  103. package/src/bin/sbvr-compiler.ts +14 -18
  104. package/src/bin/utils.ts +1 -1
  105. package/src/config-loader/config-loader.ts +44 -10
  106. package/src/config-loader/env.ts +1 -1
  107. package/src/data-server/sbvr-server.js +3 -1
  108. package/src/database-layer/db.ts +23 -19
  109. package/src/express-emulator/express.js +5 -3
  110. package/src/extended-sbvr-parser/extended-sbvr-parser.ts +1 -1
  111. package/src/http-transactions/transactions.js +10 -5
  112. package/src/migrator/async.ts +7 -6
  113. package/src/migrator/sync.ts +10 -7
  114. package/src/migrator/utils.ts +11 -5
  115. package/src/odata-metadata/odata-metadata-generator.ts +2 -2
  116. package/src/passport-pinejs/mount-login-router.ts +46 -0
  117. package/src/passport-pinejs/passport-pinejs.ts +7 -3
  118. package/src/pinejs-session-store/pinejs-session-store.ts +6 -6
  119. package/src/sbvr-api/abstract-sql.ts +5 -5
  120. package/src/sbvr-api/cached-compile.ts +1 -2
  121. package/src/sbvr-api/common-types.ts +1 -1
  122. package/src/sbvr-api/control-flow.ts +1 -1
  123. package/src/sbvr-api/express-extension.ts +12 -8
  124. package/src/sbvr-api/hooks.ts +11 -11
  125. package/src/sbvr-api/odata-response.ts +56 -9
  126. package/src/sbvr-api/permissions.ts +44 -35
  127. package/src/sbvr-api/sbvr-utils.ts +117 -165
  128. package/src/sbvr-api/translations.ts +9 -6
  129. package/src/sbvr-api/uri-parser.ts +25 -30
  130. package/src/server-glue/global-ext.d.ts +2 -1
  131. package/src/server-glue/module.ts +8 -2
  132. package/src/server-glue/sbvr-loader.ts +1 -1
  133. package/src/server-glue/server.ts +11 -49
  134. package/src/webresource-handler/handlers/NoopHandler.ts +21 -0
  135. package/src/webresource-handler/handlers/S3Handler.ts +143 -0
  136. package/src/webresource-handler/handlers/index.ts +2 -0
  137. package/src/webresource-handler/index.ts +450 -0
  138. package/tsconfig.dev.json +2 -1
  139. package/tsconfig.json +1 -1
  140. package/typings/lf-to-abstract-sql.d.ts +1 -1
  141. package/typings/memoizee.d.ts +3 -4
@@ -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 _ = require("lodash");
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 validBatchMethods = new Set(['PUT', 'POST', 'PATCH', 'DELETE', 'GET']);
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 _(sqlName)
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 = _.get(abstractSqlModel.relationships[resolvedResourceName], navigation);
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] = _.noop;
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 = _.last(abstractSqlModel.rules);
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 = _.uniq(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
- _.forEach(body, (v, k) => {
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: _.noop,
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 (_.isError(response)) {
641
+ if (lodash_1.default.isError(response)) {
601
642
  throw response;
602
643
  }
603
- const { body: responseBody, status, headers } = response;
604
- if (status != null && status >= 400) {
605
- const ErrorClass = errors_1.statusCodeToError[status];
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(status, undefined, responseBody, headers);
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 = _.last(request.translateVersions);
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 = await uriParser.parseOData({
642
- id: request.id,
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 validateBatch = (req) => {
675
- const { requests } = req.body;
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.url.startsWith(`/${vocabulary}/$batch`)) {
764
- await Promise.all(req.body.requests.map(async (request) => await (0, hooks_1.runHooks)('PREPARSE', reqHooks, {
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
- if (models[parsedRequest.vocabulary] == null) {
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 = await uriParser.parseOData(requestPart, req.url.startsWith(`/${vocabulary}/$batch`) &&
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 (_.isError(result)) {
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.status == null) {
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 handleODataRequest = async (req, res, next) => {
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 (!req.url.startsWith(`/${apiRoot}/$batch`) ||
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).json({
891
- responses: responses.map((response) => {
892
- if (response instanceof errors_1.HttpError) {
893
- return httpErrorToResponse(response);
894
- }
895
- else {
896
- return response;
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, req);
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, status } = response;
923
+ const { body, headers, statusCode } = response;
930
924
  res.set(headers);
931
- res.status(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, req) => {
940
- const message = err.getResponseBody();
933
+ const httpErrorToResponse = (err) => {
941
934
  return {
942
- status: err.status,
943
- body: req != null && 'batch' in req ? { responses: [], message } : message,
935
+ statusCode: err.status,
936
+ body: err.getResponseBody(),
944
937
  headers: err.headers,
945
938
  };
946
939
  };
@@ -1137,8 +1130,7 @@ const respondGet = async (req, request, result, tx) => {
1137
1130
  : undefined;
1138
1131
  const d = await odataResponse.process(vocab, (0, exports.getAbstractSqlModel)(request), request.originalResourceName, result.rows, { includeMetadata: metadata === 'full' });
1139
1132
  const response = {
1140
- id: request.id,
1141
- status: 200,
1133
+ statusCode: 200,
1142
1134
  body: { d },
1143
1135
  headers: { 'content-type': 'application/json' },
1144
1136
  };
@@ -1154,15 +1146,14 @@ const respondGet = async (req, request, result, tx) => {
1154
1146
  else {
1155
1147
  if (request.resourceName === '$metadata') {
1156
1148
  return {
1157
- id: request.id,
1158
- status: 200,
1149
+ statusCode: 200,
1159
1150
  body: models[vocab].odataMetadata,
1160
1151
  headers: { 'content-type': 'xml' },
1161
1152
  };
1162
1153
  }
1163
1154
  else {
1164
1155
  return {
1165
- status: 404,
1156
+ statusCode: 404,
1166
1157
  };
1167
1158
  }
1168
1159
  }
@@ -1172,7 +1163,7 @@ const runPost = async (_req, request, tx) => {
1172
1163
  if (rowsAffected === 0) {
1173
1164
  throw new errors_1.PermissionError();
1174
1165
  }
1175
- await (0, exports.validateModel)(tx, _.last(request.translateVersions), request);
1166
+ await (0, exports.validateModel)(tx, lodash_1.default.last(request.translateVersions), request);
1176
1167
  return insertId;
1177
1168
  };
1178
1169
  const respondPost = async (req, request, id, tx) => {
@@ -1191,7 +1182,7 @@ const respondPost = async (req, request, id, tx) => {
1191
1182
  }
1192
1183
  }
1193
1184
  const response = {
1194
- status: 201,
1185
+ statusCode: 201,
1195
1186
  body: result.d[0],
1196
1187
  headers: {
1197
1188
  'content-type': 'application/json',
@@ -1219,13 +1210,13 @@ const runPut = async (_req, request, tx) => {
1219
1210
  ({ rowsAffected } = await runQuery(tx, request, undefined, true));
1220
1211
  }
1221
1212
  if (rowsAffected > 0) {
1222
- await (0, exports.validateModel)(tx, _.last(request.translateVersions), request);
1213
+ await (0, exports.validateModel)(tx, lodash_1.default.last(request.translateVersions), request);
1223
1214
  }
1224
1215
  return undefined;
1225
1216
  };
1226
1217
  const respondPut = async (req, request, result, tx) => {
1227
1218
  const response = {
1228
- status: 200,
1219
+ statusCode: 200,
1229
1220
  };
1230
1221
  await (0, hooks_1.runHooks)('PRERESPOND', request.hooks, {
1231
1222
  req,
@@ -1241,7 +1232,7 @@ const respondOptions = respondPut;
1241
1232
  const runDelete = async (_req, request, tx) => {
1242
1233
  const { rowsAffected } = await runQuery(tx, request, undefined, true);
1243
1234
  if (rowsAffected > 0) {
1244
- await (0, exports.validateModel)(tx, _.last(request.translateVersions), request);
1235
+ await (0, exports.validateModel)(tx, lodash_1.default.last(request.translateVersions), request);
1245
1236
  }
1246
1237
  return undefined;
1247
1238
  };
@@ -1312,4 +1303,17 @@ const setup = async (_app, $db) => {
1312
1303
  }
1313
1304
  };
1314
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;
1315
1319
  //# sourceMappingURL=sbvr-utils.js.map