@objectstack/plugin-approvals 12.5.0 → 13.0.0

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@objectstack/plugin-approvals",
3
- "version": "12.5.0",
3
+ "version": "13.0.0",
4
4
  "license": "Apache-2.0",
5
5
  "description": "Multi-step approval engine for ObjectStack — sys_approval_process + sys_approval_request + sys_approval_action + IApprovalService.",
6
6
  "main": "dist/index.js",
@@ -13,17 +13,17 @@
13
13
  }
14
14
  },
15
15
  "dependencies": {
16
- "@objectstack/core": "12.5.0",
17
- "@objectstack/formula": "12.5.0",
18
- "@objectstack/metadata-core": "12.5.0",
19
- "@objectstack/platform-objects": "12.5.0",
20
- "@objectstack/spec": "12.5.0"
16
+ "@objectstack/core": "13.0.0",
17
+ "@objectstack/formula": "13.0.0",
18
+ "@objectstack/metadata-core": "13.0.0",
19
+ "@objectstack/platform-objects": "13.0.0",
20
+ "@objectstack/spec": "13.0.0"
21
21
  },
22
22
  "devDependencies": {
23
23
  "@types/node": "^26.1.0",
24
24
  "typescript": "^6.0.3",
25
25
  "vitest": "^4.1.10",
26
- "@objectstack/service-automation": "12.5.0"
26
+ "@objectstack/service-automation": "13.0.0"
27
27
  },
28
28
  "keywords": [
29
29
  "objectstack",
@@ -5,7 +5,7 @@ import { AutomationEngine } from '@objectstack/service-automation';
5
5
  import { ApprovalService } from './approval-service.js';
6
6
  import { registerApprovalNode } from './approval-node.js';
7
7
 
8
- const SYSTEM_CTX = { isSystem: true, roles: [], permissions: [] } as any;
8
+ const SYSTEM_CTX = { isSystem: true, positions: [], permissions: [] } as any;
9
9
 
10
10
  const noopLogger = {
11
11
  info() {}, warn() {}, error() {}, debug() {},
@@ -190,7 +190,7 @@ describe('Approval node bridge (ADR-0019)', () => {
190
190
  const request = (await fake.find('sys_approval_request', { where: { status: 'pending' } }))[0];
191
191
 
192
192
  await expect(
193
- service.decideNode(request.id, { decision: 'approve', actorId: 'intruder' }, { isSystem: false, roles: [], permissions: [] } as any),
193
+ service.decideNode(request.id, { decision: 'approve', actorId: 'intruder' }, { isSystem: false, positions: [], permissions: [] } as any),
194
194
  ).rejects.toThrow(/FORBIDDEN/);
195
195
  });
196
196
  });
@@ -48,7 +48,7 @@ interface MinimalLogger {
48
48
  warn?: (msg: any, ...rest: any[]) => void;
49
49
  }
50
50
 
51
- const SYSTEM_CTX = { isSystem: true, roles: [], permissions: [] } as const;
51
+ const SYSTEM_CTX = { isSystem: true, positions: [], permissions: [] } as const;
52
52
 
53
53
  /**
54
54
  * Register the `approval` node executor on the automation engine. Idempotent at
@@ -19,8 +19,8 @@ import { ApprovalService } from './approval-service.js';
19
19
  import { registerApprovalNode } from './approval-node.js';
20
20
  import { bindApprovalLockHook, APPROVALS_HOOK_PACKAGE } from './lifecycle-hooks.js';
21
21
 
22
- const SYSTEM_CTX = { isSystem: true, roles: [], permissions: [] } as any;
23
- const USER_CTX = { isSystem: false, roles: [], permissions: [] } as any;
22
+ const SYSTEM_CTX = { isSystem: true, positions: [], permissions: [] } as any;
23
+ const USER_CTX = { isSystem: false, positions: [], permissions: [] } as any;
24
24
 
25
25
  const noopLogger = { info() {}, warn() {}, error() {}, debug() {} };
26
26
 
@@ -288,7 +288,7 @@ describe('Send back for revision (ADR-0044)', () => {
288
288
  const editAttempt = () => hook!({
289
289
  object: 'fin_expense',
290
290
  input: { id: 'x1', data: { amount: 1200 } },
291
- session: { isSystem: false, roles: [] },
291
+ session: { isSystem: false, positions: [] },
292
292
  });
293
293
 
294
294
  await expect(editAttempt()).rejects.toThrow(/RECORD_LOCKED/); // pending → locked
@@ -110,8 +110,8 @@ function makeFakeEngine() {
110
110
  };
111
111
  }
112
112
 
113
- const CTX = { userId: 'u1', tenantId: 't1', roles: [], permissions: [] } as any;
114
- const SYS = { isSystem: true, roles: [], permissions: [] } as any;
113
+ const CTX = { userId: 'u1', tenantId: 't1', positions: [], permissions: [] } as any;
114
+ const SYS = { isSystem: true, positions: [], permissions: [] } as any;
115
115
 
116
116
  function nodeConfig(approvers: string[], extra: Record<string, any> = {}) {
117
117
  return {
@@ -219,7 +219,7 @@ describe('ApprovalService (node era)', () => {
219
219
  it('decideNode: blocks a non-approver in a non-system context', async () => {
220
220
  const req = await svc.openNodeRequest(openInput(['u9']), CTX);
221
221
  await expect(
222
- svc.decideNode(req.id, { decision: 'approve', actorId: 'mallory' }, { isSystem: false, roles: [], permissions: [] } as any),
222
+ svc.decideNode(req.id, { decision: 'approve', actorId: 'mallory' }, { isSystem: false, positions: [], permissions: [] } as any),
223
223
  ).rejects.toThrow(/FORBIDDEN/);
224
224
  });
225
225
 
@@ -319,7 +319,7 @@ describe('ApprovalService (node era)', () => {
319
319
 
320
320
  it('recall: blocks a non-submitter in a non-system context', async () => {
321
321
  const req = await svc.openNodeRequest(openInput(['u9']), CTX);
322
- await expect(svc.recall(req.id, { actorId: 'u9' }, { roles: [], permissions: [] } as any))
322
+ await expect(svc.recall(req.id, { actorId: 'u9' }, { positions: [], permissions: [] } as any))
323
323
  .rejects.toThrow(/FORBIDDEN/);
324
324
  });
325
325
 
@@ -483,7 +483,7 @@ describe('ApprovalService (node era)', () => {
483
483
 
484
484
  it('remind: only the submitter may nudge', async () => {
485
485
  const req = await svc.openNodeRequest(openInput(['u9']), CTX);
486
- await expect(svc.remind(req.id, { actorId: 'u9' }, { roles: [], permissions: [] } as any))
486
+ await expect(svc.remind(req.id, { actorId: 'u9' }, { positions: [], permissions: [] } as any))
487
487
  .rejects.toThrow(/FORBIDDEN/);
488
488
  });
489
489
 
@@ -503,7 +503,7 @@ describe('ApprovalService (node era)', () => {
503
503
  const req = await svc.openNodeRequest(openInput(['u9']), CTX);
504
504
  await svc.comment(req.id, { actorId: 'u1', comment: 'Numbers attached.' }, CTX);
505
505
  await svc.comment(req.id, { actorId: 'u9', comment: 'Thanks, reviewing.' }, CTX);
506
- await expect(svc.comment(req.id, { actorId: 'outsider', comment: 'hi' }, { roles: [], permissions: [] } as any))
506
+ await expect(svc.comment(req.id, { actorId: 'outsider', comment: 'hi' }, { positions: [], permissions: [] } as any))
507
507
  .rejects.toThrow(/FORBIDDEN/);
508
508
  const actions = await svc.listActions(req.id, SYS);
509
509
  expect(actions.filter(a => a.action === 'comment')).toHaveLength(2);
@@ -882,7 +882,7 @@ describe('record-lock hook (node era)', () => {
882
882
  engine.fire('beforeUpdate', {
883
883
  object: 'opportunity',
884
884
  input: { id: 'opp1', data: { amount: 200 } },
885
- session: { isSystem: false, roles: [], userId: 'u1' },
885
+ session: { isSystem: false, positions: [], userId: 'u1' },
886
886
  }),
887
887
  ).rejects.toThrow(/RECORD_LOCKED/);
888
888
  });
@@ -892,7 +892,7 @@ describe('record-lock hook (node era)', () => {
892
892
  engine.fire('beforeUpdate', {
893
893
  object: 'opportunity',
894
894
  input: { id: 'opp1', data: { approval_status: 'approved' } },
895
- session: { isSystem: false, roles: [] },
895
+ session: { isSystem: false, positions: [] },
896
896
  }),
897
897
  ).resolves.toBeUndefined();
898
898
  });
@@ -902,7 +902,7 @@ describe('record-lock hook (node era)', () => {
902
902
  engine.fire('beforeUpdate', {
903
903
  object: 'opportunity',
904
904
  input: { id: 'opp1', data: { amount: 200 } },
905
- session: { isSystem: true, roles: [] },
905
+ session: { isSystem: true, positions: [] },
906
906
  }),
907
907
  ).resolves.toBeUndefined();
908
908
  });
@@ -922,7 +922,7 @@ describe('record-lock hook (node era)', () => {
922
922
  engine.fire('beforeUpdate', {
923
923
  object: 'opportunity',
924
924
  input: { id: 'other_record', data: { amount: 200 } },
925
- session: { isSystem: false, roles: [] },
925
+ session: { isSystem: false, positions: [] },
926
926
  }),
927
927
  ).resolves.toBeUndefined();
928
928
  });
@@ -97,7 +97,7 @@ export type ActionTokenOutcome =
97
97
  | { ok: true; action: 'approve' | 'reject'; request: ApprovalRequestRow; approverId: string }
98
98
  | { ok: false; reason: 'invalid' | 'expired' | 'consumed' | 'not_pending' | 'not_approver'; request?: ApprovalRequestRow };
99
99
 
100
- const SYSTEM_CTX = { isSystem: true, roles: [], permissions: [] } as const;
100
+ const SYSTEM_CTX = { isSystem: true, positions: [], permissions: [] } as const;
101
101
 
102
102
  function uid(prefix: string): string {
103
103
  const g: any = globalThis as any;