@proteinjs/db 1.27.0 → 1.28.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.
Files changed (56) hide show
  1. package/dist/generated/index.js +1 -1
  2. package/dist/generated/index.js.map +1 -1
  3. package/dist/generated/test/index.js +3 -3
  4. package/dist/generated/test/index.js.map +1 -1
  5. package/dist/index.d.ts +2 -0
  6. package/dist/index.d.ts.map +1 -1
  7. package/dist/index.js +2 -0
  8. package/dist/index.js.map +1 -1
  9. package/dist/src/MigrationRunner.d.ts +9 -0
  10. package/dist/src/MigrationRunner.d.ts.map +1 -1
  11. package/dist/src/MigrationRunner.js +24 -10
  12. package/dist/src/MigrationRunner.js.map +1 -1
  13. package/dist/src/auth/TableAuth.d.ts +7 -1
  14. package/dist/src/auth/TableAuth.d.ts.map +1 -1
  15. package/dist/src/auth/TableAuth.js +7 -1
  16. package/dist/src/auth/TableAuth.js.map +1 -1
  17. package/dist/src/tables/MigrationTable.d.ts +7 -0
  18. package/dist/src/tables/MigrationTable.d.ts.map +1 -1
  19. package/dist/src/tables/MigrationTable.js +10 -0
  20. package/dist/src/tables/MigrationTable.js.map +1 -1
  21. package/dist/src/transaction/TransactionContextFactory.d.ts +1 -1
  22. package/dist/test/MigrationAuth.test.d.ts +2 -0
  23. package/dist/test/MigrationAuth.test.d.ts.map +1 -0
  24. package/dist/test/MigrationAuth.test.js +77 -0
  25. package/dist/test/MigrationAuth.test.js.map +1 -0
  26. package/dist/test/MigrationRunnerContainment.test.d.ts +2 -0
  27. package/dist/test/MigrationRunnerContainment.test.d.ts.map +1 -0
  28. package/dist/test/MigrationRunnerContainment.test.js +144 -0
  29. package/dist/test/MigrationRunnerContainment.test.js.map +1 -0
  30. package/dist/test/TableServiceAuth.test.js +67 -0
  31. package/dist/test/TableServiceAuth.test.js.map +1 -1
  32. package/dist/test/index.d.ts +1 -0
  33. package/dist/test/index.d.ts.map +1 -1
  34. package/dist/test/index.js +1 -0
  35. package/dist/test/index.js.map +1 -1
  36. package/dist/test/util/DbTestEnvironment.d.ts.map +1 -1
  37. package/dist/test/util/DbTestEnvironment.js +5 -0
  38. package/dist/test/util/DbTestEnvironment.js.map +1 -1
  39. package/dist/test/util/testUser.d.ts +5 -0
  40. package/dist/test/util/testUser.d.ts.map +1 -0
  41. package/dist/test/util/testUser.js +17 -0
  42. package/dist/test/util/testUser.js.map +1 -0
  43. package/generated/index.ts +18 -15
  44. package/generated/test/index.ts +43 -40
  45. package/index.ts +2 -0
  46. package/package.json +6 -7
  47. package/src/MigrationRunner.ts +20 -5
  48. package/src/auth/TableAuth.ts +13 -2
  49. package/src/tables/MigrationTable.ts +10 -0
  50. package/test/MigrationAuth.test.ts +87 -0
  51. package/test/MigrationRunnerContainment.test.ts +104 -0
  52. package/test/TableServiceAuth.test.ts +90 -1
  53. package/test/index.ts +2 -0
  54. package/test/util/DbTestEnvironment.ts +5 -0
  55. package/test/util/testUser.ts +27 -0
  56. package/LICENSE +0 -21
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../generated/test/index.ts"],"names":[],"mappings":";AAAA,oCAAoC;;;;;;;;;;;;;;;;AAEpC,+BAA6B;AAC7B,6BAA2B;AAC3B,iCAA+B;AAC/B,iCAA+B;AAC/B,iCAA+B;AAC/B,8BAA4B;AAC5B,gCAA8B;AAC9B,2BAAyB;AACzB,kBAAgB;AAChB,gBAAc;AAGd,4BAA4B;AAE5B,IAAM,WAAW,GAAG,gj8FAAgj8F,CAAC;AAGrk8F,4BAA4B;AAE5B,0FAAgF;AAChF,yCAAwC;AACxC,0FAA+E;AAC/E,0FAAgF;AAChF,0FAA+E;AAC/E,0FAAgF;AAChF,0FAA+E;AAC/E,0FAA2E;AAC3E,0FAA8E;AAC9E,0FAAmF;AACnF,2FAAkF;AAClF,2FAA6E;AAC7E,2FAA2E;AAC3E,sFAAyE;AACzE,wEAA0E;AAC1E,wEAA8E;AAC9E,4GAAiG;AACjG,4GAAwF;AACxF,4GAAwF;AACxF,4GAA8F;AAC9F,wFAA8E;AAC9E,wFAAqF;AACrF,wFAAiF;AACjF,sFAA4F;AAC5F,sFAAgG;AAChG,mCAAkC;AAClC,iEAAgE;AAChE,6DAA4D;AAC5D,2DAA0D;AAC1D,qEAAoE;AACpE,2FAA0F;AAC1F,iFAAgF;AAChF,yEAAwE;AACxE,0EAAyE;AACzE,kEAAiE;AACjE,6EAA4E;AAE5E,IAAM,WAAW,GAAG;IACnB,8BAA8B,EAAE,wCAAc;IAC9C,qBAAqB,EAAE,aAAK;IAC5B,6BAA6B,EAAE,uCAAa;IAC5C,8BAA8B,EAAE,wCAAc;IAC9C,6BAA6B,EAAE,uCAAa;IAC5C,8BAA8B,EAAE,wCAAc;IAC9C,6BAA6B,EAAE,uCAAa;IAC5C,yBAAyB,EAAE,mCAAS;IACpC,4BAA4B,EAAE,sCAAY;IAC1C,iCAAiC,EAAE,2CAAiB;IACpD,gCAAgC,EAAE,2CAAgB;IAClD,2BAA2B,EAAE,sCAAW;IACxC,yBAAyB,EAAE,oCAAS;IACpC,yBAAyB,EAAE,iCAAS;IACpC,iCAAiC,EAAE,kCAAiB;IACpD,qCAAqC,EAAE,sCAAqB;IAC5D,sCAAsC,EAAE,yDAAsB;IAC9D,6BAA6B,EAAE,gDAAa;IAC5C,6BAA6B,EAAE,gDAAa;IAC5C,mCAAmC,EAAE,sDAAmB;IACxD,6BAA6B,EAAE,sCAAa;IAC5C,oCAAoC,EAAE,6CAAoB;IAC1D,gCAAgC,EAAE,yCAAgB;IAClD,4CAA4C,EAAE,oDAA4B;IAC1E,gDAAgD,EAAE,wDAAgC;IAClF,kBAAkB,EAAE,OAAE;IACtB,iCAAiC,EAAE,qCAAiB;IACpD,+BAA+B,EAAE,iCAAe;IAChD,yBAAyB,EAAE,qBAAS;IACpC,8BAA8B,EAAE,+BAAc;IAC9C,wCAAwC,EAAE,mDAAwB;IAClE,mCAAmC,EAAE,yCAAmB;IACxD,+BAA+B,EAAE,iCAAe;IAChD,kCAAkC,EAAE,uCAAkB;IACtD,8BAA8B,EAAE,+BAAc;IAC9C,iCAAiC,EAAE,qCAAiB;CACpD,CAAC;AAGF,kCAAkC;AAElC,oDAAyD;AACzD,6BAAgB,CAAC,KAAK,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;AAGjD,mDAAiC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../generated/test/index.ts"],"names":[],"mappings":";AAAA,oCAAoC;;;;;;;;;;;;;;;;AAEpC,+BAA6B;AAC7B,6BAA2B;AAC3B,iCAA+B;AAC/B,iCAA+B;AAC/B,iCAA+B;AAC/B,8BAA4B;AAC5B,gCAA8B;AAC9B,2BAAyB;AACzB,kBAAgB;AAChB,gBAAc;AAGd,4BAA4B;AAE5B,IAAM,WAAW,GAAG,w5hGAAw5hG,CAAC;AAG76hG,4BAA4B;AAE5B,0FAAgF;AAChF,yCAAwC;AACxC,0FAA+E;AAC/E,0FAAgF;AAChF,0FAA+E;AAC/E,0FAAgF;AAChF,0FAA+E;AAC/E,0FAA2E;AAC3E,0FAA8E;AAC9E,0FAAmF;AACnF,2FAAkF;AAClF,2FAA6E;AAC7E,2FAA2E;AAC3E,sFAAyE;AACzE,wEAA0E;AAC1E,wEAA8E;AAC9E,4GAAiG;AACjG,4GAAwF;AACxF,4GAAwF;AACxF,4GAA8F;AAC9F,wFAA8E;AAC9E,wFAAqF;AACrF,wFAAiF;AACjF,sFAA4F;AAC5F,sFAAgG;AAChG,mCAAkC;AAClC,iEAAgE;AAChE,6DAA4D;AAC5D,2DAA0D;AAC1D,qEAAoE;AACpE,2FAA0F;AAC1F,iFAAgF;AAChF,yEAAwE;AACxE,kEAAiE;AACjE,0EAAyE;AACzE,6EAA4E;AAE5E,IAAM,WAAW,GAAG;IACnB,8BAA8B,EAAE,wCAAc;IAC9C,qBAAqB,EAAE,aAAK;IAC5B,6BAA6B,EAAE,uCAAa;IAC5C,8BAA8B,EAAE,wCAAc;IAC9C,6BAA6B,EAAE,uCAAa;IAC5C,8BAA8B,EAAE,wCAAc;IAC9C,6BAA6B,EAAE,uCAAa;IAC5C,yBAAyB,EAAE,mCAAS;IACpC,4BAA4B,EAAE,sCAAY;IAC1C,iCAAiC,EAAE,2CAAiB;IACpD,gCAAgC,EAAE,2CAAgB;IAClD,2BAA2B,EAAE,sCAAW;IACxC,yBAAyB,EAAE,oCAAS;IACpC,yBAAyB,EAAE,iCAAS;IACpC,iCAAiC,EAAE,kCAAiB;IACpD,qCAAqC,EAAE,sCAAqB;IAC5D,sCAAsC,EAAE,yDAAsB;IAC9D,6BAA6B,EAAE,gDAAa;IAC5C,6BAA6B,EAAE,gDAAa;IAC5C,mCAAmC,EAAE,sDAAmB;IACxD,6BAA6B,EAAE,sCAAa;IAC5C,oCAAoC,EAAE,6CAAoB;IAC1D,gCAAgC,EAAE,yCAAgB;IAClD,4CAA4C,EAAE,oDAA4B;IAC1E,gDAAgD,EAAE,wDAAgC;IAClF,kBAAkB,EAAE,OAAE;IACtB,iCAAiC,EAAE,qCAAiB;IACpD,+BAA+B,EAAE,iCAAe;IAChD,yBAAyB,EAAE,qBAAS;IACpC,8BAA8B,EAAE,+BAAc;IAC9C,wCAAwC,EAAE,mDAAwB;IAClE,mCAAmC,EAAE,yCAAmB;IACxD,+BAA+B,EAAE,iCAAe;IAChD,8BAA8B,EAAE,+BAAc;IAC9C,kCAAkC,EAAE,uCAAkB;IACtD,iCAAiC,EAAE,qCAAiB;CACpD,CAAC;AAGF,kCAAkC;AAElC,oDAAyD;AACzD,6BAAgB,CAAC,KAAK,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;AAGjD,mDAAiC"}
package/dist/index.d.ts CHANGED
@@ -11,6 +11,8 @@ export * from './src/UpdatePreserving';
11
11
  export * from './src/reference/ReferenceCache';
12
12
  export * from './src/RecordIterator';
13
13
  export * from './src/source/SourceRecord';
14
+ export * from './src/source/SourceRecordRepo';
15
+ export * from './src/MigrationRunner';
14
16
  export * from './src/QueryBuilderFactory';
15
17
  export * from './src/TableWatcher';
16
18
  export * from './src/transaction/Transaction';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,cAAc,aAAa,CAAC;AAC5B,cAAc,sBAAsB,CAAC;AACrC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,gCAAgC,CAAC;AAC/C,cAAc,oCAAoC,CAAC;AACnD,cAAc,2BAA2B,CAAC;AAC1C,cAAc,wBAAwB,CAAC;AACvC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,sBAAsB,CAAC;AACrC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,oBAAoB,CAAC;AACnC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,qCAAqC,CAAC;AACpD,cAAc,6CAA6C,CAAC;AAE5D,cAAc,+BAA+B,CAAC;AAC9C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,2BAA2B,CAAC;AAE1C,cAAc,qBAAqB,CAAC;AACpC,cAAc,6BAA6B,CAAC;AAE5C,cAAc,0BAA0B,CAAC;AACzC,cAAc,uCAAuC,CAAC;AACtD,cAAc,yCAAyC,CAAC;AAExD,cAAc,qBAAqB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,cAAc,aAAa,CAAC;AAC5B,cAAc,sBAAsB,CAAC;AACrC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,gCAAgC,CAAC;AAC/C,cAAc,oCAAoC,CAAC;AACnD,cAAc,2BAA2B,CAAC;AAC1C,cAAc,wBAAwB,CAAC;AACvC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,sBAAsB,CAAC;AACrC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,uBAAuB,CAAC;AACtC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,oBAAoB,CAAC;AACnC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,qCAAqC,CAAC;AACpD,cAAc,6CAA6C,CAAC;AAE5D,cAAc,+BAA+B,CAAC;AAC9C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,2BAA2B,CAAC;AAE1C,cAAc,qBAAqB,CAAC;AACpC,cAAc,6BAA6B,CAAC;AAE5C,cAAc,0BAA0B,CAAC;AACzC,cAAc,uCAAuC,CAAC;AACtD,cAAc,yCAAyC,CAAC;AAExD,cAAc,qBAAqB,CAAC"}
package/dist/index.js CHANGED
@@ -27,6 +27,8 @@ __exportStar(require("./src/UpdatePreserving"), exports);
27
27
  __exportStar(require("./src/reference/ReferenceCache"), exports);
28
28
  __exportStar(require("./src/RecordIterator"), exports);
29
29
  __exportStar(require("./src/source/SourceRecord"), exports);
30
+ __exportStar(require("./src/source/SourceRecordRepo"), exports);
31
+ __exportStar(require("./src/MigrationRunner"), exports);
30
32
  __exportStar(require("./src/QueryBuilderFactory"), exports);
31
33
  __exportStar(require("./src/TableWatcher"), exports);
32
34
  __exportStar(require("./src/transaction/Transaction"), exports);
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,2CAAyB;AACzB,8CAA4B;AAC5B,uDAAqC;AACrC,8DAA4C;AAC5C,gDAA8B;AAC9B,+CAA6B;AAC7B,iEAA+C;AAC/C,qEAAmD;AACnD,4DAA0C;AAC1C,yDAAuC;AACvC,iEAA+C;AAC/C,uDAAqC;AACrC,4DAA0C;AAC1C,4DAA0C;AAC1C,qDAAmC;AACnC,gEAA8C;AAC9C,sEAAoD;AACpD,8EAA4D;AAE5D,gEAA8C;AAC9C,8DAA4C;AAC5C,4DAA0C;AAE1C,sDAAoC;AACpC,8DAA4C;AAE5C,2DAAyC;AACzC,wEAAsD;AACtD,0EAAwD;AAExD,sDAAoC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,2CAAyB;AACzB,8CAA4B;AAC5B,uDAAqC;AACrC,8DAA4C;AAC5C,gDAA8B;AAC9B,+CAA6B;AAC7B,iEAA+C;AAC/C,qEAAmD;AACnD,4DAA0C;AAC1C,yDAAuC;AACvC,iEAA+C;AAC/C,uDAAqC;AACrC,4DAA0C;AAC1C,gEAA8C;AAC9C,wDAAsC;AACtC,4DAA0C;AAC1C,qDAAmC;AACnC,gEAA8C;AAC9C,sEAAoD;AACpD,8EAA4D;AAE5D,gEAA8C;AAC9C,8DAA4C;AAC5C,4DAA0C;AAE1C,sDAAoC;AACpC,8DAA4C;AAE5C,2DAAyC;AACzC,wEAAsD;AACtD,0EAAwD;AAExD,sDAAoC"}
@@ -4,7 +4,16 @@ export declare const getMigrationRunner: () => MigrationRunner;
4
4
  export declare class MigrationRunner implements MigrationRunnerService {
5
5
  private logger;
6
6
  serviceMetadata: Service['serviceMetadata'];
7
+ /**
8
+ * The service dispatches this fire-and-forget (`doNotAwait`). The method is split along that
9
+ * seam: everything knowable before the run starts (a bogus id) throws synchronously — the only
10
+ * path on which an error can still reach the client (the executor wraps it into a
11
+ * ServiceError -> 400). The returned promise MAY REJECT (infrastructure failure while recording
12
+ * run state); the caller owns that rejection — on the service path the executor terminally
13
+ * observes every doNotAwait rejection (logs with method identity, never process death).
14
+ */
7
15
  runMigration(id: string): Promise<void>;
16
+ private runAndRecord;
8
17
  private duration;
9
18
  }
10
19
  //# sourceMappingURL=MigrationRunner.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"MigrationRunner.d.ts","sourceRoot":"","sources":["../../src/MigrationRunner.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,sBAAsB,EAA6B,MAAM,mCAAmC,CAAC;AAEtG,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAG7C,eAAO,MAAM,kBAAkB,uBACyE,CAAC;AAEzG,qBAAa,eAAgB,YAAW,sBAAsB;IAC5D,OAAO,CAAC,MAAM,CAA+C;IACtD,eAAe,EAAE,OAAO,CAAC,iBAAiB,CAAC,CAQhD;IAEI,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA6B7C,OAAO,CAAC,QAAQ;CA4BjB"}
1
+ {"version":3,"file":"MigrationRunner.d.ts","sourceRoot":"","sources":["../../src/MigrationRunner.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,sBAAsB,EAA6B,MAAM,mCAAmC,CAAC;AAEtG,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAG7C,eAAO,MAAM,kBAAkB,uBACyE,CAAC;AAEzG,qBAAa,eAAgB,YAAW,sBAAsB;IAC5D,OAAO,CAAC,MAAM,CAA+C;IACtD,eAAe,EAAE,OAAO,CAAC,iBAAiB,CAAC,CAQhD;IAEF;;;;;;;OAOG;IACH,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;YAUzB,YAAY;IA0B1B,OAAO,CAAC,QAAQ;CA4BjB"}
@@ -51,26 +51,37 @@ var MigrationRunner = /** @class */ (function () {
51
51
  function MigrationRunner() {
52
52
  this.logger = new logger_1.Logger({ name: this.constructor.name });
53
53
  this.serviceMetadata = {
54
- // Explicit, not implicit: running migrations is admin-only. Omitting the auth block would
55
- // fall back to the same default-deny (admin role), but every service is required to declare
56
- // its auth intent explicitly.
54
+ // Running migrations rides the abstract 'dev' PERMISSION (the developer-surface slug the
55
+ // db-ui dev pages also declare), resolved through the consumer app's PermissionRolesMapping.
56
+ // Admin still passes as break-glass. Matches the migration table's doors below the service.
57
57
  auth: {
58
- roles: ['admin'],
58
+ permission: 'dev',
59
59
  },
60
60
  doNotAwait: true,
61
61
  };
62
62
  }
63
+ /**
64
+ * The service dispatches this fire-and-forget (`doNotAwait`). The method is split along that
65
+ * seam: everything knowable before the run starts (a bogus id) throws synchronously — the only
66
+ * path on which an error can still reach the client (the executor wraps it into a
67
+ * ServiceError -> 400). The returned promise MAY REJECT (infrastructure failure while recording
68
+ * run state); the caller owns that rejection — on the service path the executor terminally
69
+ * observes every doNotAwait rejection (logs with method identity, never process death).
70
+ */
63
71
  MigrationRunner.prototype.runMigration = function (id) {
72
+ var migrationTable = new MigrationTable_1.MigrationTable();
73
+ var migration = new SourceRecordRepo_1.SourceRecordRepo().getSourceRecord(migrationTable.name, id);
74
+ if (!migration) {
75
+ throw new Error("Unable to find migration source record for id: ".concat(id));
76
+ }
77
+ return this.runAndRecord(migrationTable, migration);
78
+ };
79
+ MigrationRunner.prototype.runAndRecord = function (migrationTable, migration) {
64
80
  return __awaiter(this, void 0, void 0, function () {
65
- var migrationTable, migration, db, _a, error_1;
81
+ var db, _a, error_1;
66
82
  return __generator(this, function (_b) {
67
83
  switch (_b.label) {
68
84
  case 0:
69
- migrationTable = new MigrationTable_1.MigrationTable();
70
- migration = new SourceRecordRepo_1.SourceRecordRepo().getSourceRecord(migrationTable.name, id);
71
- if (!migration) {
72
- throw new Error("Unable to find migration source record for id: ".concat(id));
73
- }
74
85
  db = (0, Db_1.getDb)();
75
86
  migration.status = 'running';
76
87
  migration.startTime = (0, moment_1.moment)();
@@ -89,6 +100,9 @@ var MigrationRunner = /** @class */ (function () {
89
100
  return [3 /*break*/, 6];
90
101
  case 4:
91
102
  error_1 = _b.sent();
103
+ // Domain bookkeeping, not containment: a migration that throws is a run OUTCOME, recorded
104
+ // as failure status on the record. Only infrastructure failures (the db.update calls
105
+ // themselves) reject the returned promise.
92
106
  migration.failureMessage = error_1.message;
93
107
  migration.failureStack = error_1.stack;
94
108
  migration.status = 'failure';
@@ -1 +1 @@
1
- {"version":3,"file":"MigrationRunner.js","sourceRoot":"","sources":["../../src/MigrationRunner.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,uCAA8C;AAC9C,2BAA6B;AAE7B,8DAA6D;AAC7D,4EAAsG;AACtG,0DAAoE;AAEpE,4CAA2C;AAEpC,IAAM,kBAAkB,GAAG;IAChC,OAAA,OAAO,IAAI,KAAK,WAAW,CAAC,CAAC,CAAC,IAAI,eAAe,EAAE,CAAC,CAAC,CAAE,IAAA,kDAAyB,GAAsB;AAAtG,CAAsG,CAAC;AAD5F,QAAA,kBAAkB,sBAC0E;AAEzG;IAAA;QACU,WAAM,GAAG,IAAI,eAAM,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC;QACtD,oBAAe,GAA+B;YACnD,0FAA0F;YAC1F,4FAA4F;YAC5F,8BAA8B;YAC9B,IAAI,EAAE;gBACJ,KAAK,EAAE,CAAC,OAAO,CAAC;aACjB;YACD,UAAU,EAAE,IAAI;SACjB,CAAC;IA2DJ,CAAC;IAzDO,sCAAY,GAAlB,UAAmB,EAAU;;;;;;wBACrB,cAAc,GAAqB,IAAI,+BAAc,EAAE,CAAC;wBACxD,SAAS,GAAG,IAAI,mCAAgB,EAAE,CAAC,eAAe,CAAY,cAAc,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;wBAC7F,IAAI,CAAC,SAAS,EAAE;4BACd,MAAM,IAAI,KAAK,CAAC,yDAAkD,EAAE,CAAE,CAAC,CAAC;yBACzE;wBAEK,EAAE,GAAG,IAAA,UAAK,GAAE,CAAC;wBACnB,SAAS,CAAC,MAAM,GAAG,SAAS,CAAC;wBAC7B,SAAS,CAAC,SAAS,GAAG,IAAA,eAAM,GAAE,CAAC;wBAC/B,qBAAM,EAAE,CAAC,MAAM,CAAC,cAAc,EAAE,SAAS,CAAC,EAAA;;wBAA1C,SAA0C,CAAC;wBAC3C,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,6BAAsB,SAAS,CAAC,EAAE,eAAK,SAAS,CAAC,WAAW,CAAE,EAAE,CAAC,CAAC;;;;wBAE5F,KAAA,SAAS,CAAA;wBAAU,qBAAM,SAAS,CAAC,GAAG,EAAE,EAAA;;wBAAxC,GAAU,MAAM,GAAG,SAAqB,CAAC;wBACzC,SAAS,CAAC,MAAM,GAAG,SAAS,CAAC;;;;wBAE7B,SAAS,CAAC,cAAc,GAAG,OAAK,CAAC,OAAO,CAAC;wBACzC,SAAS,CAAC,YAAY,GAAG,OAAK,CAAC,KAAK,CAAC;wBACrC,SAAS,CAAC,MAAM,GAAG,SAAS,CAAC;;;wBAE7B,SAAS,CAAC,OAAO,GAAG,IAAA,eAAM,GAAE,CAAC;;;wBAE/B,SAAS,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,SAAS,EAAE,SAAS,CAAC,OAAO,CAAC,CAAC;wBAC3E,qBAAM,EAAE,CAAC,MAAM,CAAC,cAAc,EAAE,SAAS,CAAC,EAAA;;wBAA1C,SAA0C,CAAC;wBAC3C,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;4BACf,OAAO,EAAE,WAAI,SAAS,CAAC,MAAM,gBAAM,SAAS,CAAC,QAAQ,2CAAiC,SAAS,CAAC,EAAE,eAAK,SAAS,CAAC,WAAW,CAAE;yBAC/H,CAAC,CAAC;;;;;KACJ;IAEO,kCAAQ,GAAhB,UAAiB,KAAa,EAAE,GAAW;QACzC,IAAM,QAAQ,GAAG,eAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;QAClD,IAAM,KAAK,GAAa,EAAE,CAAC;QAE3B,IAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAC;QAC7B,IAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,EAAE,CAAC;QAC/B,IAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,EAAE,CAAC;QACnC,IAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,EAAE,CAAC;QACnC,IAAM,YAAY,GAAG,QAAQ,CAAC,YAAY,EAAE,CAAC;QAE7C,IAAI,IAAI,GAAG,CAAC,EAAE;YACZ,KAAK,CAAC,IAAI,CAAC,UAAG,IAAI,iBAAO,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAE,CAAC,CAAC;SACjD;QACD,IAAI,KAAK,GAAG,CAAC,EAAE;YACb,KAAK,CAAC,IAAI,CAAC,UAAG,KAAK,kBAAQ,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAE,CAAC,CAAC;SACpD;QACD,IAAI,OAAO,GAAG,CAAC,EAAE;YACf,KAAK,CAAC,IAAI,CAAC,UAAG,OAAO,iBAAO,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAE,CAAC,CAAC;SACvD;QACD,IAAI,OAAO,GAAG,CAAC,EAAE;YACf,KAAK,CAAC,IAAI,CAAC,UAAG,OAAO,iBAAO,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAE,CAAC,CAAC;SACvD;QACD,IAAI,IAAI,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,OAAO,IAAI,CAAC,IAAI,OAAO,IAAI,CAAC,EAAE;YAC3D,KAAK,CAAC,IAAI,CAAC,UAAG,YAAY,QAAK,CAAC,CAAC;SAClC;QAED,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACzB,CAAC;IACH,sBAAC;AAAD,CAAC,AArED,IAqEC;AArEY,0CAAe"}
1
+ {"version":3,"file":"MigrationRunner.js","sourceRoot":"","sources":["../../src/MigrationRunner.ts"],"names":[],"mappings":"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"}
@@ -3,8 +3,14 @@ import { Table } from '../Table';
3
3
  * @public all users, including guests (do not need to be logged in), do not need any roles
4
4
  * @authenticated - users need to be logged in, do not need any roles
5
5
  * @roles string[] - authenticated users, having at least one of these roles
6
+ * @permission - authenticated users holding an abstract permission slug, resolved to roles at
7
+ * runtime through the consumer app's `PermissionRolesMapping` (see `UserAuth.hasPermission`).
8
+ * Generic tables declare permissions; only the consumer names roles.
6
9
  */
7
- export type Identity = 'public' | 'authenticated' | string[];
10
+ export type PermissionIdentity = {
11
+ permission: string;
12
+ };
13
+ export type Identity = 'public' | 'authenticated' | string[] | PermissionIdentity;
8
14
  /**
9
15
  * These Identities can perform these operations on this table.
10
16
  * If omitted, defaults to requiring the 'admin' role (default deny)
@@ -1 +1 @@
1
- {"version":3,"file":"TableAuth.d.ts","sourceRoot":"","sources":["../../../src/auth/TableAuth.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AAEjC;;;;GAIG;AACH,MAAM,MAAM,QAAQ,GAAG,QAAQ,GAAG,eAAe,GAAG,MAAM,EAAE,CAAC;AAE7D;;;GAGG;AACH,MAAM,MAAM,mBAAmB,GAAG;IAChC,GAAG,CAAC,EAAE,QAAQ,CAAC;IACf,KAAK,CAAC,EAAE,QAAQ,CAAC;IACjB,MAAM,CAAC,EAAE,QAAQ,CAAC;IAClB,MAAM,CAAC,EAAE,QAAQ,CAAC;IAClB,MAAM,CAAC,EAAE,QAAQ,CAAC;CACnB,CAAC;AAEF;;;;;GAKG;AACH,qBAAa,cAAe,SAAQ,KAAK;gBAC3B,OAAO,EAAE,MAAM;CAI5B;AAED;;GAEG;AACH,qBAAa,SAAS;IACpB,OAAO,CAAC,SAAS;IAoBjB,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,EAAE,GAAG,GAAE,IAAI,GAAG,SAAgB,GAAG,IAAI;IAM/D,SAAS,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,EAAE,GAAG,GAAE,IAAI,GAAG,SAAgB,GAAG,IAAI;IAMhE,SAAS,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,EAAE,GAAG,GAAE,IAAI,GAAG,SAAgB,GAAG,IAAI;IAMhE,SAAS,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,EAAE,GAAG,GAAE,IAAI,GAAG,SAAgB,GAAG,IAAI;CAKjE"}
1
+ {"version":3,"file":"TableAuth.d.ts","sourceRoot":"","sources":["../../../src/auth/TableAuth.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AAEjC;;;;;;;GAOG;AACH,MAAM,MAAM,kBAAkB,GAAG;IAAE,UAAU,EAAE,MAAM,CAAA;CAAE,CAAC;AAExD,MAAM,MAAM,QAAQ,GAAG,QAAQ,GAAG,eAAe,GAAG,MAAM,EAAE,GAAG,kBAAkB,CAAC;AAKlF;;;GAGG;AACH,MAAM,MAAM,mBAAmB,GAAG;IAChC,GAAG,CAAC,EAAE,QAAQ,CAAC;IACf,KAAK,CAAC,EAAE,QAAQ,CAAC;IACjB,MAAM,CAAC,EAAE,QAAQ,CAAC;IAClB,MAAM,CAAC,EAAE,QAAQ,CAAC;IAClB,MAAM,CAAC,EAAE,QAAQ,CAAC;CACnB,CAAC;AAEF;;;;;GAKG;AACH,qBAAa,cAAe,SAAQ,KAAK;gBAC3B,OAAO,EAAE,MAAM;CAI5B;AAED;;GAEG;AACH,qBAAa,SAAS;IACpB,OAAO,CAAC,SAAS;IAuBjB,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,EAAE,GAAG,GAAE,IAAI,GAAG,SAAgB,GAAG,IAAI;IAM/D,SAAS,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,EAAE,GAAG,GAAE,IAAI,GAAG,SAAgB,GAAG,IAAI;IAMhE,SAAS,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,EAAE,GAAG,GAAE,IAAI,GAAG,SAAgB,GAAG,IAAI;IAMhE,SAAS,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,EAAE,GAAG,GAAE,IAAI,GAAG,SAAgB,GAAG,IAAI;CAKjE"}
@@ -17,6 +17,9 @@ var __extends = (this && this.__extends) || (function () {
17
17
  Object.defineProperty(exports, "__esModule", { value: true });
18
18
  exports.TableAuth = exports.TableAuthError = void 0;
19
19
  var user_auth_1 = require("@proteinjs/user-auth");
20
+ var isPermissionIdentity = function (identity) {
21
+ return !!identity && typeof identity === 'object' && !Array.isArray(identity) && typeof identity.permission === 'string';
22
+ };
20
23
  /**
21
24
  * A table-auth denial. The message names the table and operation and is safe to show the caller
22
25
  * (it only echoes what they asked for). Name-tagged rather than relying on instanceof — the
@@ -49,7 +52,10 @@ var TableAuth = /** @class */ (function () {
49
52
  (tableAuth.all === 'authenticated' && user_auth_1.UserAuth.isLoggedIn()) ||
50
53
  (tableAuth[operation] === 'authenticated' && user_auth_1.UserAuth.isLoggedIn()) ||
51
54
  (Array.isArray(tableAuth.all) && user_auth_1.UserAuth.hasRoles(tableAuth.all, 'at least one')) ||
52
- (Array.isArray(tableAuth[operation]) && user_auth_1.UserAuth.hasRoles(tableAuth[operation], 'at least one')));
55
+ (Array.isArray(tableAuth[operation]) && user_auth_1.UserAuth.hasRoles(tableAuth[operation], 'at least one')) ||
56
+ (isPermissionIdentity(tableAuth.all) && user_auth_1.UserAuth.hasPermission(tableAuth.all.permission)) ||
57
+ (isPermissionIdentity(tableAuth[operation]) &&
58
+ user_auth_1.UserAuth.hasPermission(tableAuth[operation].permission)));
53
59
  };
54
60
  TableAuth.prototype.canQuery = function (table, api) {
55
61
  if (api === void 0) { api = 'db'; }
@@ -1 +1 @@
1
- {"version":3,"file":"TableAuth.js","sourceRoot":"","sources":["../../../src/auth/TableAuth.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;AAAA,kDAAgD;AAsBhD;;;;;GAKG;AACH;IAAoC,kCAAK;IACvC,wBAAY,OAAe;QAA3B,YACE,kBAAM,OAAO,CAAC,SAEf;QADC,KAAI,CAAC,IAAI,GAAG,gBAAgB,CAAC;;IAC/B,CAAC;IACH,qBAAC;AAAD,CAAC,AALD,CAAoC,KAAK,GAKxC;AALY,wCAAc;AAO3B;;GAEG;AACH;IAAA;IA4CA,CAAC;IA3CS,6BAAS,GAAjB,UACE,KAAiB,EACjB,GAAqB,EACrB,SAAmD;QAEnD,IAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAC3D,IAAI,CAAC,SAAS,IAAI,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,MAAM,IAAI,CAAC,EAAE;YACpD,OAAO,oBAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;SAClC;QAED,OAAO,CACL,SAAS,CAAC,GAAG,KAAK,QAAQ;YAC1B,SAAS,CAAC,SAAS,CAAC,KAAK,QAAQ;YACjC,CAAC,SAAS,CAAC,GAAG,KAAK,eAAe,IAAI,oBAAQ,CAAC,UAAU,EAAE,CAAC;YAC5D,CAAC,SAAS,CAAC,SAAS,CAAC,KAAK,eAAe,IAAI,oBAAQ,CAAC,UAAU,EAAE,CAAC;YACnE,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,oBAAQ,CAAC,QAAQ,CAAC,SAAS,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC;YAClF,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,IAAI,oBAAQ,CAAC,QAAQ,CAAC,SAAS,CAAC,SAAS,CAAa,EAAE,cAAc,CAAC,CAAC,CAC7G,CAAC;IACJ,CAAC;IAED,4BAAQ,GAAR,UAAS,KAAiB,EAAE,GAA4B;QAA5B,oBAAA,EAAA,UAA4B;QACtD,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,GAAG,EAAE,OAAO,CAAC,EAAE;YACxC,MAAM,IAAI,cAAc,CAAC,iDAA0C,KAAK,CAAC,IAAI,CAAE,CAAC,CAAC;SAClF;IACH,CAAC;IAED,6BAAS,GAAT,UAAU,KAAiB,EAAE,GAA4B;QAA5B,oBAAA,EAAA,UAA4B;QACvD,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,GAAG,EAAE,QAAQ,CAAC,EAAE;YACzC,MAAM,IAAI,cAAc,CAAC,+DAAwD,KAAK,CAAC,IAAI,CAAE,CAAC,CAAC;SAChG;IACH,CAAC;IAED,6BAAS,GAAT,UAAU,KAAiB,EAAE,GAA4B;QAA5B,oBAAA,EAAA,UAA4B;QACvD,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,GAAG,EAAE,QAAQ,CAAC,EAAE;YACzC,MAAM,IAAI,cAAc,CAAC,6DAAsD,KAAK,CAAC,IAAI,CAAE,CAAC,CAAC;SAC9F;IACH,CAAC;IAED,6BAAS,GAAT,UAAU,KAAiB,EAAE,GAA4B;QAA5B,oBAAA,EAAA,UAA4B;QACvD,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,GAAG,EAAE,QAAQ,CAAC,EAAE;YACzC,MAAM,IAAI,cAAc,CAAC,+DAAwD,KAAK,CAAC,IAAI,CAAE,CAAC,CAAC;SAChG;IACH,CAAC;IACH,gBAAC;AAAD,CAAC,AA5CD,IA4CC;AA5CY,8BAAS"}
1
+ {"version":3,"file":"TableAuth.js","sourceRoot":"","sources":["../../../src/auth/TableAuth.ts"],"names":[],"mappings":"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"}
@@ -14,6 +14,13 @@ export interface Migration extends SourceRecord {
14
14
  }
15
15
  export declare class MigrationTable extends Table<Migration> {
16
16
  name: string;
17
+ /**
18
+ * Both doors ride the 'dev' permission (consumer-mapped; admin passes as break-glass),
19
+ * matching MigrationRunner's serviceMetadata: the Migrations record table reads/edits via
20
+ * the service api, and the runner writes run state via the db api as the calling user.
21
+ * Boot-time source-record loading is a system path (getDbAsSystem) and bypasses doors.
22
+ */
23
+ auth: Table<Migration>['auth'];
17
24
  columns: {
18
25
  id: import("../Table").Column<string, any>;
19
26
  created: import("../Table").Column<Moment, any>;
@@ -1 +1 @@
1
- {"version":3,"file":"MigrationTable.d.ts","sourceRoot":"","sources":["../../../src/tables/MigrationTable.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAEvC,OAAO,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AACjC,OAAO,EAAE,YAAY,EAA2B,MAAM,wBAAwB,CAAC;AAE/E,MAAM,WAAW,SAAU,SAAQ,YAAY;IAC7C,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,UAAU,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,CAAC;IACxD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,GAAG,CAAC;IACb,GAAG,EAAE,MAAM,OAAO,CAAC,GAAG,GAAG,IAAI,CAAC,CAAC;CAChC;AAED,qBAAa,cAAe,SAAQ,KAAK,CAAC,SAAS,CAAC;IAC3C,IAAI,SAAe;IACnB,OAAO;;;;;;;;;;;;;;;;MASX;IACI,mBAAmB;;;;;MAKxB;CACH"}
1
+ {"version":3,"file":"MigrationTable.d.ts","sourceRoot":"","sources":["../../../src/tables/MigrationTable.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAEvC,OAAO,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AACjC,OAAO,EAAE,YAAY,EAA2B,MAAM,wBAAwB,CAAC;AAE/E,MAAM,WAAW,SAAU,SAAQ,YAAY;IAC7C,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,UAAU,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,CAAC;IACxD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,GAAG,CAAC;IACb,GAAG,EAAE,MAAM,OAAO,CAAC,GAAG,GAAG,IAAI,CAAC,CAAC;CAChC;AAED,qBAAa,cAAe,SAAQ,KAAK,CAAC,SAAS,CAAC;IAC3C,IAAI,SAAe;IAC1B;;;;;OAKG;IACI,IAAI,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,CAGnC;IACK,OAAO;;;;;;;;;;;;;;;;MASX;IACI,mBAAmB;;;;;MAKxB;CACH"}
@@ -60,6 +60,16 @@ var MigrationTable = /** @class */ (function (_super) {
60
60
  function MigrationTable() {
61
61
  var _this = _super !== null && _super.apply(this, arguments) || this;
62
62
  _this.name = 'migration';
63
+ /**
64
+ * Both doors ride the 'dev' permission (consumer-mapped; admin passes as break-glass),
65
+ * matching MigrationRunner's serviceMetadata: the Migrations record table reads/edits via
66
+ * the service api, and the runner writes run state via the db api as the calling user.
67
+ * Boot-time source-record loading is a system path (getDbAsSystem) and bypasses doors.
68
+ */
69
+ _this.auth = {
70
+ db: { all: { permission: 'dev' } },
71
+ service: { all: { permission: 'dev' } },
72
+ };
63
73
  _this.columns = (0, SourceRecord_1.withSourceRecordColumns)({
64
74
  description: new Columns_1.StringColumn('description', {}, 4000),
65
75
  status: new Columns_1.StringColumn('status', { defaultValue: function () { return __awaiter(_this, void 0, void 0, function () { return __generator(this, function (_a) {
@@ -1 +1 @@
1
- {"version":3,"file":"MigrationTable.js","sourceRoot":"","sources":["../../../src/tables/MigrationTable.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACA,sCAAwE;AACxE,kCAAiC;AACjC,uDAA+E;AAc/E;IAAoC,kCAAgB;IAApD;QAAA,qEAkBC;QAjBQ,UAAI,GAAG,WAAW,CAAC;QACnB,aAAO,GAAG,IAAA,sCAAuB,EAAY;YAClD,WAAW,EAAE,IAAI,sBAAY,CAAC,aAAa,EAAE,EAAE,EAAE,IAAI,CAAC;YACtD,MAAM,EAAE,IAAI,sBAAY,CAAC,QAAQ,EAAE,EAAE,YAAY,EAAE;oBAAY,sBAAA,UAAU,EAAA;yBAAA,EAAE,CAAC;YAC5E,cAAc,EAAE,IAAI,sBAAY,CAAC,iBAAiB,EAAE,EAAE,EAAE,IAAI,CAAC;YAC7D,YAAY,EAAE,IAAI,sBAAY,CAAC,eAAe,EAAE,EAAE,EAAE,KAAK,CAAC;YAC1D,SAAS,EAAE,IAAI,wBAAc,CAAC,YAAY,CAAC;YAC3C,OAAO,EAAE,IAAI,wBAAc,CAAC,UAAU,CAAC;YACvC,QAAQ,EAAE,IAAI,sBAAY,CAAC,UAAU,CAAC;YACtC,MAAM,EAAE,IAAI,sBAAY,CAAC,QAAQ,CAAC;SACnC,CAAC,CAAC;QACI,yBAAmB,GAAG;YAC3B,8BAA8B,EAAE,IAAI;YACpC,EAAE,EAAE;gBACF,WAAW,EAAE,IAAI;aAClB;SACF,CAAC;;IACJ,CAAC;IAAD,qBAAC;AAAD,CAAC,AAlBD,CAAoC,aAAK,GAkBxC;AAlBY,wCAAc"}
1
+ {"version":3,"file":"MigrationTable.js","sourceRoot":"","sources":["../../../src/tables/MigrationTable.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACA,sCAAwE;AACxE,kCAAiC;AACjC,uDAA+E;AAc/E;IAAoC,kCAAgB;IAApD;QAAA,qEA4BC;QA3BQ,UAAI,GAAG,WAAW,CAAC;QAC1B;;;;;WAKG;QACI,UAAI,GAA6B;YACtC,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,EAAE;YAClC,OAAO,EAAE,EAAE,GAAG,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,EAAE;SACxC,CAAC;QACK,aAAO,GAAG,IAAA,sCAAuB,EAAY;YAClD,WAAW,EAAE,IAAI,sBAAY,CAAC,aAAa,EAAE,EAAE,EAAE,IAAI,CAAC;YACtD,MAAM,EAAE,IAAI,sBAAY,CAAC,QAAQ,EAAE,EAAE,YAAY,EAAE;oBAAY,sBAAA,UAAU,EAAA;yBAAA,EAAE,CAAC;YAC5E,cAAc,EAAE,IAAI,sBAAY,CAAC,iBAAiB,EAAE,EAAE,EAAE,IAAI,CAAC;YAC7D,YAAY,EAAE,IAAI,sBAAY,CAAC,eAAe,EAAE,EAAE,EAAE,KAAK,CAAC;YAC1D,SAAS,EAAE,IAAI,wBAAc,CAAC,YAAY,CAAC;YAC3C,OAAO,EAAE,IAAI,wBAAc,CAAC,UAAU,CAAC;YACvC,QAAQ,EAAE,IAAI,sBAAY,CAAC,UAAU,CAAC;YACtC,MAAM,EAAE,IAAI,sBAAY,CAAC,QAAQ,CAAC;SACnC,CAAC,CAAC;QACI,yBAAmB,GAAG;YAC3B,8BAA8B,EAAE,IAAI;YACpC,EAAE,EAAE;gBACF,WAAW,EAAE,IAAI;aAClB;SACF,CAAC;;IACJ,CAAC;IAAD,qBAAC;AAAD,CAAC,AA5BD,CAAoC,aAAK,GA4BxC;AA5BY,wCAAc"}
@@ -5,7 +5,7 @@ export type PostCommitHook = () => void | Promise<void>;
5
5
  export interface TransactionContextData {
6
6
  currentTransaction?: any;
7
7
  /**
8
- * Hooks queued to run after the current transaction COMMITS — and never on rollback: a hook
8
+ * Hooks queued to run after the current transaction COMMITS — and never on rollback: a hook
9
9
  * queued for a write that gets rolled back dies with the write. Seeded by `Db.runTransaction`
10
10
  * on the ambient context so every `Db` instance created inside the transaction (table
11
11
  * watchers, nested helpers) shares one queue; registered via `Db.runAfterCommit`, drained by
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=MigrationAuth.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MigrationAuth.test.d.ts","sourceRoot":"","sources":["../../test/MigrationAuth.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,77 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ var user_auth_1 = require("@proteinjs/user-auth");
4
+ // Deep dist path on purpose: the package index doesn't export the auth gate (it is framework
5
+ // plumbing), but the test must exercise the REAL gate, not a re-implementation of its rules.
6
+ var ServiceAuth_1 = require("@proteinjs/service/dist/src/ServiceAuth");
7
+ var reflection_1 = require("@proteinjs/reflection");
8
+ var MigrationRunner_1 = require("../src/MigrationRunner");
9
+ var MigrationTable_1 = require("../src/tables/MigrationTable");
10
+ var TableAuth_1 = require("../src/auth/TableAuth");
11
+ var setUser = function (roles) {
12
+ user_auth_1.UserAuth.userRepo = {
13
+ getUser: function () { return ({ email: 'user@test.local', roles: roles }); },
14
+ };
15
+ };
16
+ var setMapping = function (mapping) {
17
+ user_auth_1.UserAuth.permissionRolesMapping = {
18
+ getRoles: function (permission) { return mapping[permission]; },
19
+ };
20
+ };
21
+ var canRunMigrations = function () {
22
+ var method = new reflection_1.Method('runMigration', undefined, true, false, false, false, 'public', []);
23
+ return ServiceAuth_1.ServiceAuth.canRunService(new MigrationRunner_1.MigrationRunner(), method, ['some-migration-id']);
24
+ };
25
+ describe('migrations ride the dev permission', function () {
26
+ beforeEach(function () {
27
+ setMapping({ dev: ['dev-crew'] });
28
+ });
29
+ afterEach(function () {
30
+ user_auth_1.UserAuth.userRepo = undefined;
31
+ user_auth_1.UserAuth.permissionRolesMapping = undefined;
32
+ });
33
+ it("a consumer-mapped dev-role holder can run migrations and use the migration table's doors", function () {
34
+ setUser(['dev-crew']);
35
+ expect(canRunMigrations()).toBe(true);
36
+ var auth = new TableAuth_1.TableAuth();
37
+ var table = new MigrationTable_1.MigrationTable();
38
+ var _loop_1 = function (api) {
39
+ expect(function () { return auth.canQuery(table, api); }).not.toThrow();
40
+ expect(function () { return auth.canUpdate(table, api); }).not.toThrow();
41
+ };
42
+ // The record-table page reads via the service api; the runner updates via the db api.
43
+ for (var _i = 0, _a = ['db', 'service']; _i < _a.length; _i++) {
44
+ var api = _a[_i];
45
+ _loop_1(api);
46
+ }
47
+ });
48
+ it('a permissionless user is denied the service and both table doors', function () {
49
+ setUser(['ops-team']);
50
+ expect(canRunMigrations()).toBe(false);
51
+ var auth = new TableAuth_1.TableAuth();
52
+ var table = new MigrationTable_1.MigrationTable();
53
+ var _loop_2 = function (api) {
54
+ expect(function () { return auth.canQuery(table, api); }).toThrow('User is not authorized to query table: migration');
55
+ expect(function () { return auth.canUpdate(table, api); }).toThrow('User is not authorized to update records in table: migration');
56
+ };
57
+ for (var _i = 0, _a = ['db', 'service']; _i < _a.length; _i++) {
58
+ var api = _a[_i];
59
+ _loop_2(api);
60
+ }
61
+ });
62
+ it('admin passes everything as break-glass', function () {
63
+ setUser(['admin']);
64
+ expect(canRunMigrations()).toBe(true);
65
+ var auth = new TableAuth_1.TableAuth();
66
+ var table = new MigrationTable_1.MigrationTable();
67
+ var _loop_3 = function (api) {
68
+ expect(function () { return auth.canQuery(table, api); }).not.toThrow();
69
+ expect(function () { return auth.canUpdate(table, api); }).not.toThrow();
70
+ };
71
+ for (var _i = 0, _a = ['db', 'service']; _i < _a.length; _i++) {
72
+ var api = _a[_i];
73
+ _loop_3(api);
74
+ }
75
+ });
76
+ });
77
+ //# sourceMappingURL=MigrationAuth.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MigrationAuth.test.js","sourceRoot":"","sources":["../../test/MigrationAuth.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=MigrationRunnerContainment.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MigrationRunnerContainment.test.d.ts","sourceRoot":"","sources":["../../test/MigrationRunnerContainment.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,144 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __generator = (this && this.__generator) || function (thisArg, body) {
12
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
13
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
14
+ function verb(n) { return function (v) { return step([n, v]); }; }
15
+ function step(op) {
16
+ if (f) throw new TypeError("Generator is already executing.");
17
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
18
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
19
+ if (y = 0, t) op = [op[0] & 2, t.value];
20
+ switch (op[0]) {
21
+ case 0: case 1: t = op; break;
22
+ case 4: _.label++; return { value: op[1], done: false };
23
+ case 5: _.label++; y = op[1]; op = [0]; continue;
24
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
25
+ default:
26
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
27
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
28
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
29
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
30
+ if (t[2]) _.ops.pop();
31
+ _.trys.pop(); continue;
32
+ }
33
+ op = body.call(thisArg, _);
34
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
35
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
36
+ }
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ // EnvInfo.isDev() requires a GlobalDataStorage implementation that only exists in a running app
40
+ // (same mock the @proteinjs/service executor suite uses).
41
+ jest.mock('@proteinjs/server-api', function () { return ({
42
+ EnvInfo: { isDev: function () { return true; } },
43
+ }); });
44
+ var logger_1 = require("@proteinjs/logger");
45
+ var reflection_1 = require("@proteinjs/reflection");
46
+ var serializer_1 = require("@proteinjs/serializer");
47
+ // Deep dist path on purpose: the package index doesn't export the executor (framework plumbing),
48
+ // but the executor check below must run the REAL BUILT owner of the doNotAwait seam.
49
+ var ServiceExecutor_1 = require("@proteinjs/service/dist/src/ServiceExecutor");
50
+ var MigrationRunner_1 = require("../src/MigrationRunner");
51
+ var MigrationTable_1 = require("../src/tables/MigrationTable");
52
+ var SourceRecordRepo_1 = require("../src/source/SourceRecordRepo");
53
+ var testUser_1 = require("./util/testUser");
54
+ /**
55
+ * This harness loads no reflection graph and registers no DefaultDbDriverFactory, so the body's
56
+ * FIRST db access (`new Db()` constructing its table-watcher runner) throws this. The specific
57
+ * message is a harness accident standing in for any mid-run infrastructure failure (db.update
58
+ * rejecting); the contract under test is that the failure escapes as a rejection at all.
59
+ */
60
+ var infrastructureFailure = 'Unable to find type: @proteinjs/db/TableWatcher';
61
+ var plantMigration = function (id) {
62
+ var migration = {
63
+ id: id,
64
+ description: 'containment test migration',
65
+ run: function () { return __awaiter(void 0, void 0, void 0, function () { return __generator(this, function (_a) {
66
+ return [2 /*return*/, undefined];
67
+ }); }); },
68
+ };
69
+ new SourceRecordRepo_1.SourceRecordRepo().loadSourceRecord(new MigrationTable_1.MigrationTable().name, migration);
70
+ return migration;
71
+ };
72
+ describe('MigrationRunner containment (doNotAwait dispatch)', function () {
73
+ it('throws synchronously on a bogus migration id, not through the detached promise', function () {
74
+ var runner = new MigrationRunner_1.MigrationRunner();
75
+ expect(function () { return runner.runMigration('bogus-migration-id'); }).toThrow('Unable to find migration source record for id: bogus-migration-id');
76
+ });
77
+ it('rejects the detached promise on a mid-run infrastructure failure — the caller owns it', function () { return __awaiter(void 0, void 0, void 0, function () {
78
+ var runner;
79
+ return __generator(this, function (_a) {
80
+ switch (_a.label) {
81
+ case 0:
82
+ // The runner no longer swallows infrastructure failures: the rejection escapes to whoever
83
+ // holds the promise.
84
+ plantMigration('containment-test-migration');
85
+ runner = new MigrationRunner_1.MigrationRunner();
86
+ return [4 /*yield*/, expect(runner.runMigration('containment-test-migration')).rejects.toThrow(infrastructureFailure)];
87
+ case 1:
88
+ _a.sent();
89
+ return [2 /*return*/];
90
+ }
91
+ });
92
+ }); });
93
+ it('through the real built executor, an infrastructure-failure rejection is terminally logged — not process death', function () { return __awaiter(void 0, void 0, void 0, function () {
94
+ var runner, method, _interface, executor, entries_1, errorEntry;
95
+ var _a, _b;
96
+ return __generator(this, function (_c) {
97
+ switch (_c.label) {
98
+ case 0:
99
+ // Admin identity passes the service's 'dev' permission as break-glass (MigrationAuth.test.ts
100
+ // pins the mapping itself).
101
+ (0, testUser_1.registerTestUser)();
102
+ _c.label = 1;
103
+ case 1:
104
+ _c.trys.push([1, , 5, 6]);
105
+ plantMigration('containment-test-migration-executor');
106
+ runner = new MigrationRunner_1.MigrationRunner();
107
+ method = new reflection_1.Method('runMigration', undefined, true, false, false, false, 'public', []);
108
+ _interface = new reflection_1.Interface('@proteinjs/db', 'MigrationRunnerService', [], [method]);
109
+ executor = new ServiceExecutor_1.ServiceExecutor(runner, _interface, method);
110
+ entries_1 = [];
111
+ executor.logger = new logger_1.Logger({
112
+ name: 'MigrationRunnerService.runMigration',
113
+ logWriter: { write: function (log) { return entries_1.push(log); } },
114
+ });
115
+ // The client response does not carry the failure — execute resolves immediately.
116
+ return [4 /*yield*/, expect(executor.execute(serializer_1.Serializer.serialize(['containment-test-migration-executor']))).resolves.toBeUndefined()];
117
+ case 2:
118
+ // The client response does not carry the failure — execute resolves immediately.
119
+ _c.sent();
120
+ // The detached rejection settles after the microtask queue drains; flush macrotasks so the
121
+ // executor's terminal catch has written its log entry. Were the rejection unobserved, jest
122
+ // would surface it as a failure here — and a bare node process would die.
123
+ return [4 /*yield*/, new Promise(function (resolve) { return setImmediate(resolve); })];
124
+ case 3:
125
+ // The detached rejection settles after the microtask queue drains; flush macrotasks so the
126
+ // executor's terminal catch has written its log entry. Were the rejection unobserved, jest
127
+ // would surface it as a failure here — and a bare node process would die.
128
+ _c.sent();
129
+ return [4 /*yield*/, new Promise(function (resolve) { return setImmediate(resolve); })];
130
+ case 4:
131
+ _c.sent();
132
+ errorEntry = entries_1.find(function (entry) { return entry.logLevel === 'error'; });
133
+ expect((_a = errorEntry === null || errorEntry === void 0 ? void 0 : errorEntry.error) === null || _a === void 0 ? void 0 : _a.message).toContain(infrastructureFailure);
134
+ expect((_b = errorEntry === null || errorEntry === void 0 ? void 0 : errorEntry.obj) === null || _b === void 0 ? void 0 : _b.functionName).toBe('MigrationRunnerService.runMigration');
135
+ return [3 /*break*/, 6];
136
+ case 5:
137
+ (0, testUser_1.clearTestUser)();
138
+ return [7 /*endfinally*/];
139
+ case 6: return [2 /*return*/];
140
+ }
141
+ });
142
+ }); });
143
+ });
144
+ //# sourceMappingURL=MigrationRunnerContainment.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MigrationRunnerContainment.test.js","sourceRoot":"","sources":["../../test/MigrationRunnerContainment.test.ts"],"names":[],"mappings":"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"}
@@ -74,6 +74,30 @@ var NoAuthTable = /** @class */ (function (_super) {
74
74
  }
75
75
  return NoAuthTable;
76
76
  }(Table_1.Table));
77
+ /**
78
+ * Mirrors the user table's shape: doors keyed to an abstract PERMISSION resolved through the
79
+ * consumer mapping, with a service-protected column reserved to a dedicated service.
80
+ */
81
+ var PermissionGatedTable = /** @class */ (function (_super) {
82
+ __extends(PermissionGatedTable, _super);
83
+ function PermissionGatedTable() {
84
+ var _this = _super !== null && _super.apply(this, arguments) || this;
85
+ _this.name = 'permission_gated_test';
86
+ _this.auth = {
87
+ service: {
88
+ query: { permission: 'users' },
89
+ update: { permission: 'users' },
90
+ },
91
+ serviceProtectedColumns: ['owner'],
92
+ };
93
+ _this.columns = (0, Record_1.withRecordColumns)({
94
+ title: new Columns_1.StringColumn('title'),
95
+ owner: new Columns_1.StringColumn('owner'),
96
+ });
97
+ return _this;
98
+ }
99
+ return PermissionGatedTable;
100
+ }(Table_1.Table));
77
101
  /** Read-only intent: only `query` granted (the canDelete-regression shape). */
78
102
  var ReadOnlyTable = /** @class */ (function (_super) {
79
103
  __extends(ReadOnlyTable, _super);
@@ -97,6 +121,11 @@ var setUser = function (roles) {
97
121
  getUser: function () { return ({ email: 'user@test.local', roles: roles }); },
98
122
  };
99
123
  };
124
+ var setMapping = function (mapping) {
125
+ user_auth_1.UserAuth.permissionRolesMapping = {
126
+ getRoles: function (permission) { return mapping[permission]; },
127
+ };
128
+ };
100
129
  var auth = function () { return new TableServiceAuth_1.TableServiceAuth(); };
101
130
  /** A denial must be a client-safe ServiceError naming the table and operation. */
102
131
  var expectDenied = function (fn, message) {
@@ -138,6 +167,44 @@ describe('TableServiceAuth — per-operation service grants', function () {
138
167
  expectDenied(function () { return auth().canAccess('delete', [table, { id: 'x' }]); }, 'User is not authorized to delete records from table: read_only_test');
139
168
  });
140
169
  });
170
+ describe('TableServiceAuth — permission-keyed doors (the user table shape)', function () {
171
+ afterEach(function () {
172
+ user_auth_1.UserAuth.userRepo = undefined;
173
+ user_auth_1.UserAuth.permissionRolesMapping = undefined;
174
+ });
175
+ it("grants a holder of the consumer's mapped role; denies without the role", function () {
176
+ var table = new PermissionGatedTable();
177
+ setMapping({ users: ['support'] });
178
+ setUser(['support']);
179
+ expect(auth().canAccess('query', [table, {}])).toBe(true);
180
+ expect(auth().canAccess('update', [table, { id: 'x', title: 't' }])).toBe(true);
181
+ setUser(['dev']);
182
+ expectDenied(function () { return auth().canAccess('query', [table, {}]); }, 'User is not authorized to query table: permission_gated_test');
183
+ });
184
+ it('denies everyone but admin when no mapping is registered (default deny)', function () {
185
+ var table = new PermissionGatedTable();
186
+ setUser(['support']);
187
+ expectDenied(function () { return auth().canAccess('query', [table, {}]); }, 'User is not authorized to query table: permission_gated_test');
188
+ setUser(['admin']);
189
+ expect(auth().canAccess('query', [table, {}])).toBe(true);
190
+ });
191
+ it('operations without a grant stay closed even for permission holders (and admin)', function () {
192
+ var table = new PermissionGatedTable();
193
+ setMapping({ users: ['support'] });
194
+ setUser(['support']);
195
+ expectDenied(function () { return auth().canAccess('insert', [table, { title: 't' }]); }, 'User is not authorized to insert records into table: permission_gated_test');
196
+ // An auth block with no grant for the operation is a deliberate lock, not an admin default —
197
+ // the audit-table shape (role_grant_event) depends on this.
198
+ setUser(['admin']);
199
+ expectDenied(function () { return auth().canAccess('delete', [table, { id: 'x' }]); }, 'User is not authorized to delete records from table: permission_gated_test');
200
+ });
201
+ it('the protected column stays unwritable even for a permission holder with the update grant', function () {
202
+ var table = new PermissionGatedTable();
203
+ setMapping({ users: ['support'] });
204
+ setUser(['support']);
205
+ expectDenied(function () { return auth().canAccess('update', [table, { id: 'x', owner: 'someone' }]); }, "Column 'owner' cannot be written via the db service on table: permission_gated_test");
206
+ });
207
+ });
141
208
  describe('TableServiceAuth — default deny (no auth block)', function () {
142
209
  afterEach(function () {
143
210
  user_auth_1.UserAuth.userRepo = undefined;