@cqrs-ddd/pipeline-job-context 0.5.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.
Files changed (64) hide show
  1. package/COMMERCIAL_LICENSE.txt +34 -0
  2. package/LICENSE +661 -0
  3. package/README.md +42 -0
  4. package/dist/decorators/as-system.decorator.d.ts +36 -0
  5. package/dist/decorators/as-system.decorator.d.ts.map +1 -0
  6. package/dist/decorators/as-system.decorator.js +53 -0
  7. package/dist/decorators/as-system.decorator.js.map +1 -0
  8. package/dist/decorators/in-job-context.decorator.d.ts +35 -0
  9. package/dist/decorators/in-job-context.decorator.d.ts.map +1 -0
  10. package/dist/decorators/in-job-context.decorator.js +47 -0
  11. package/dist/decorators/in-job-context.decorator.js.map +1 -0
  12. package/dist/errors/invalid-job-context.error.d.ts +15 -0
  13. package/dist/errors/invalid-job-context.error.d.ts.map +1 -0
  14. package/dist/errors/invalid-job-context.error.js +20 -0
  15. package/dist/errors/invalid-job-context.error.js.map +1 -0
  16. package/dist/errors/missing-job-context.error.d.ts +14 -0
  17. package/dist/errors/missing-job-context.error.d.ts.map +1 -0
  18. package/dist/errors/missing-job-context.error.js +19 -0
  19. package/dist/errors/missing-job-context.error.js.map +1 -0
  20. package/dist/helpers/method-decorator.d.ts +13 -0
  21. package/dist/helpers/method-decorator.d.ts.map +1 -0
  22. package/dist/helpers/method-decorator.js +24 -0
  23. package/dist/helpers/method-decorator.js.map +1 -0
  24. package/dist/helpers/parse-job-context.d.ts +20 -0
  25. package/dist/helpers/parse-job-context.d.ts.map +1 -0
  26. package/dist/helpers/parse-job-context.js +68 -0
  27. package/dist/helpers/parse-job-context.js.map +1 -0
  28. package/dist/helpers/principal-reference.d.ts +12 -0
  29. package/dist/helpers/principal-reference.d.ts.map +1 -0
  30. package/dist/helpers/principal-reference.js +15 -0
  31. package/dist/helpers/principal-reference.js.map +1 -0
  32. package/dist/helpers/registration.d.ts +39 -0
  33. package/dist/helpers/registration.d.ts.map +1 -0
  34. package/dist/helpers/registration.js +44 -0
  35. package/dist/helpers/registration.js.map +1 -0
  36. package/dist/helpers/with-job-context.d.ts +21 -0
  37. package/dist/helpers/with-job-context.d.ts.map +1 -0
  38. package/dist/helpers/with-job-context.js +46 -0
  39. package/dist/helpers/with-job-context.js.map +1 -0
  40. package/dist/index.d.ts +11 -0
  41. package/dist/index.d.ts.map +1 -0
  42. package/dist/index.js +8 -0
  43. package/dist/index.js.map +1 -0
  44. package/dist/interfaces/context-source.interface.d.ts +23 -0
  45. package/dist/interfaces/context-source.interface.d.ts.map +1 -0
  46. package/dist/interfaces/context-source.interface.js +3 -0
  47. package/dist/interfaces/context-source.interface.js.map +1 -0
  48. package/dist/interfaces/job-context.interface.d.ts +12 -0
  49. package/dist/interfaces/job-context.interface.d.ts.map +1 -0
  50. package/dist/interfaces/job-context.interface.js +3 -0
  51. package/dist/interfaces/job-context.interface.js.map +1 -0
  52. package/dist/interfaces/job-principal.interface.d.ts +28 -0
  53. package/dist/interfaces/job-principal.interface.d.ts.map +1 -0
  54. package/dist/interfaces/job-principal.interface.js +3 -0
  55. package/dist/interfaces/job-principal.interface.js.map +1 -0
  56. package/dist/interfaces/principal-reference.interface.d.ts +12 -0
  57. package/dist/interfaces/principal-reference.interface.d.ts.map +1 -0
  58. package/dist/interfaces/principal-reference.interface.js +3 -0
  59. package/dist/interfaces/principal-reference.interface.js.map +1 -0
  60. package/dist/register-job-context.d.ts +34 -0
  61. package/dist/register-job-context.d.ts.map +1 -0
  62. package/dist/register-job-context.js +32 -0
  63. package/dist/register-job-context.js.map +1 -0
  64. package/package.json +60 -0
package/README.md ADDED
@@ -0,0 +1,42 @@
1
+ # @cqrs-ddd/pipeline-job-context
2
+
3
+ Carries the tenant, correlation id and principal of a request into the queue jobs it
4
+ enqueues, and gives system-started work an explicit context: `registerJobContext()` once
5
+ at startup, `withJobContext()` when a job is enqueued, `@InJobContext()` on the consumer
6
+ and `@AsSystem()` on system work (both TypeScript decorator modes). No framework.
7
+
8
+ **Documentation:** [guide](https://aristoteliss.github.io/ddd-cqrs/packages/pipeline-job-context/) · [API reference](https://aristoteliss.github.io/ddd-cqrs/api/cqrs-ddd/pipeline-job-context/) · [all packages](https://aristoteliss.github.io/ddd-cqrs/)
9
+
10
+ ## Installation
11
+
12
+ ```bash
13
+ pnpm add @cqrs-ddd/pipeline-job-context
14
+ ```
15
+
16
+ Requires Node.js 22.12 or later. Published as an ES module; a CommonJS application loads
17
+ it with `require()`.
18
+
19
+ ## Example
20
+
21
+ ```ts
22
+ registerJobContext({
23
+ principal: new SessionJobPrincipal(sessions),
24
+ tenants: ['acme'],
25
+ sources: { tenantId: tenantSource, correlationId: correlationSource },
26
+ });
27
+
28
+ await queue.add('welcome', withJobContext({ userId }));
29
+
30
+ class WelcomeWorker {
31
+ @InJobContext()
32
+ async process(job: { data: { userId: string } }) {}
33
+ }
34
+ ```
35
+
36
+ A queue payload is untrusted data: it carries only the principal's identity, and the
37
+ principal is re-checked when the job runs.
38
+
39
+ ## License
40
+
41
+ Dual-licensed under **AGPLv3** and a **Commercial License**. See `LICENSE` and
42
+ `COMMERCIAL_LICENSE.txt`.
@@ -0,0 +1,36 @@
1
+ import { type DualMethodDecorator } from '../helpers/method-decorator.js';
2
+ import type { PrincipalReference } from '../interfaces/principal-reference.interface.js';
3
+ /** Options of {@link AsSystem}. */
4
+ export interface AsSystemOptions<TGrant = unknown> {
5
+ /** The service principal the work acts as. */
6
+ principal: PrincipalReference;
7
+ /** The principal's complete authorization; nothing else grants it anything. */
8
+ grants: readonly TGrant[];
9
+ }
10
+ /**
11
+ * Runs system-started work, such as a cron job, once per configured tenant.
12
+ * Each run has its own tenant, a new correlation id, and the declared service
13
+ * principal and grants, bound through the registered `IJobPrincipal`. Grants
14
+ * come only from this declaration, never from data.
15
+ *
16
+ * Tenants run one after another. A failing tenant does not stop the others;
17
+ * the method then rejects with an `AggregateError` of the failures. Its return
18
+ * values are discarded. Place it under the scheduling decorator.
19
+ *
20
+ * @example
21
+ * ```ts
22
+ * class Maintenance {
23
+ * @AsSystem({
24
+ * principal: { id: 'session-cleanup', type: 'service' },
25
+ * grants: [{ action: 'delete', subject: 'Auth' }],
26
+ * })
27
+ * async purgeSessions() {
28
+ * await purgeExpiredSessions();
29
+ * }
30
+ * }
31
+ *
32
+ * cron.schedule('0 3 * * *', () => maintenance.purgeSessions());
33
+ * ```
34
+ */
35
+ export declare function AsSystem<TGrant>(options: AsSystemOptions<TGrant>): DualMethodDecorator;
36
+ //# sourceMappingURL=as-system.decorator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"as-system.decorator.d.ts","sourceRoot":"","sources":["../../src/decorators/as-system.decorator.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,KAAK,mBAAmB,EAEzB,MAAM,gCAAgC,CAAC;AAGxC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gDAAgD,CAAC;AAEzF,mCAAmC;AACnC,MAAM,WAAW,eAAe,CAAC,MAAM,GAAG,OAAO;IAC/C,8CAA8C;IAC9C,SAAS,EAAE,kBAAkB,CAAC;IAC9B,+EAA+E;IAC/E,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;CAC3B;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,QAAQ,CAAC,MAAM,EAC7B,OAAO,EAAE,eAAe,CAAC,MAAM,CAAC,GAC/B,mBAAmB,CAiCrB"}
@@ -0,0 +1,53 @@
1
+ /* Copyright (C) 2026-present Aristotelis — see repository license. */
2
+ import { methodDecorator, } from '../helpers/method-decorator.js';
3
+ import { toReference } from '../helpers/principal-reference.js';
4
+ import { activeRegistration } from '../helpers/registration.js';
5
+ /**
6
+ * Runs system-started work, such as a cron job, once per configured tenant.
7
+ * Each run has its own tenant, a new correlation id, and the declared service
8
+ * principal and grants, bound through the registered `IJobPrincipal`. Grants
9
+ * come only from this declaration, never from data.
10
+ *
11
+ * Tenants run one after another. A failing tenant does not stop the others;
12
+ * the method then rejects with an `AggregateError` of the failures. Its return
13
+ * values are discarded. Place it under the scheduling decorator.
14
+ *
15
+ * @example
16
+ * ```ts
17
+ * class Maintenance {
18
+ * @AsSystem({
19
+ * principal: { id: 'session-cleanup', type: 'service' },
20
+ * grants: [{ action: 'delete', subject: 'Auth' }],
21
+ * })
22
+ * async purgeSessions() {
23
+ * await purgeExpiredSessions();
24
+ * }
25
+ * }
26
+ *
27
+ * cron.schedule('0 3 * * *', () => maintenance.purgeSessions());
28
+ * ```
29
+ */
30
+ export function AsSystem(options) {
31
+ const reference = toReference(options.principal);
32
+ const grants = [...options.grants];
33
+ return methodDecorator((original) => {
34
+ return async function (...args) {
35
+ const { principal, tenants, sources } = activeRegistration();
36
+ const failures = [];
37
+ const failed = [];
38
+ for (const tenant of tenants) {
39
+ try {
40
+ await sources.tenantId.run(tenant, () => sources.correlationId.run(sources.correlationId.create(), () => principal.restore(reference, async () => original.apply(this, args), grants)));
41
+ }
42
+ catch (error) {
43
+ failures.push(error);
44
+ failed.push(tenant);
45
+ }
46
+ }
47
+ if (failures.length > 0) {
48
+ throw new AggregateError(failures, `System work failed in tenants: ${failed.join(', ')}`);
49
+ }
50
+ };
51
+ });
52
+ }
53
+ //# sourceMappingURL=as-system.decorator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"as-system.decorator.js","sourceRoot":"","sources":["../../src/decorators/as-system.decorator.ts"],"names":[],"mappings":"AAAA,sEAAsE;AAEtE,OAAO,EAEL,eAAe,GAChB,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAAE,WAAW,EAAE,MAAM,mCAAmC,CAAC;AAChE,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAWhE;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,UAAU,QAAQ,CACtB,OAAgC;IAEhC,MAAM,SAAS,GAAG,WAAW,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IACjD,MAAM,MAAM,GAAG,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAEnC,OAAO,eAAe,CAAC,CAAC,QAAQ,EAAE,EAAE;QAClC,OAAO,KAAK,WAA0B,GAAG,IAAe;YACtD,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,kBAAkB,EAAE,CAAC;YAC7D,MAAM,QAAQ,GAAc,EAAE,CAAC;YAC/B,MAAM,MAAM,GAAa,EAAE,CAAC;YAC5B,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;gBAC7B,IAAI,CAAC;oBACH,MAAM,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,EAAE,CACtC,OAAO,CAAC,aAAa,CAAC,GAAG,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,EAAE,EAAE,GAAG,EAAE,CAC7D,SAAS,CAAC,OAAO,CACf,SAAS,EACT,KAAK,IAAI,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,EACtC,MAAM,CACP,CACF,CACF,CAAC;gBACJ,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;oBACrB,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;gBACtB,CAAC;YACH,CAAC;YACD,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACxB,MAAM,IAAI,cAAc,CACtB,QAAQ,EACR,kCAAkC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CACtD,CAAC;YACJ,CAAC;QACH,CAAC,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,35 @@
1
+ import { type DualMethodDecorator } from '../helpers/method-decorator.js';
2
+ /** Options of {@link InJobContext}. */
3
+ export interface InJobContextOptions {
4
+ /**
5
+ * Dot path to the job context in the method's first argument.
6
+ *
7
+ * @default 'data.jobContext' (a BullMQ `Job`)
8
+ */
9
+ path?: string;
10
+ }
11
+ /**
12
+ * Runs a job-processing method inside the context `withJobContext` stamped on
13
+ * its payload: the tenant, the correlation id, and the principal the registered
14
+ * `IJobPrincipal` re-checks and binds. The method becomes async.
15
+ *
16
+ * It fails closed before the method runs: a payload without a context, with a
17
+ * malformed one, with an unconfigured tenant, or with a principal carrying
18
+ * anything beyond `id`, `type` and `sessionId` is refused, and so is a
19
+ * principal `restore` rejects. Place it under the transport decorator.
20
+ *
21
+ * @example
22
+ * ```ts
23
+ * class WelcomeEmailWorker {
24
+ * @InJobContext()
25
+ * async process(job: Job<WithJobContext<WelcomeEmail>>) {
26
+ * await sendWelcomeEmail(job.data);
27
+ * }
28
+ * }
29
+ *
30
+ * const worker = new WelcomeEmailWorker();
31
+ * new Worker(WELCOME_EMAIL_QUEUE, (job) => worker.process(job));
32
+ * ```
33
+ */
34
+ export declare function InJobContext(options?: InJobContextOptions): DualMethodDecorator;
35
+ //# sourceMappingURL=in-job-context.decorator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"in-job-context.decorator.d.ts","sourceRoot":"","sources":["../../src/decorators/in-job-context.decorator.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,KAAK,mBAAmB,EAEzB,MAAM,gCAAgC,CAAC;AAIxC,uCAAuC;AACvC,MAAM,WAAW,mBAAmB;IAClC;;;;OAIG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAWD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,YAAY,CAC1B,OAAO,GAAE,mBAAwB,GAChC,mBAAmB,CAoBrB"}
@@ -0,0 +1,47 @@
1
+ /* Copyright (C) 2026-present Aristotelis — see repository license. */
2
+ import { methodDecorator, } from '../helpers/method-decorator.js';
3
+ import { parseJobContext } from '../helpers/parse-job-context.js';
4
+ import { activeRegistration } from '../helpers/registration.js';
5
+ function readPath(value, segments) {
6
+ let current = value;
7
+ for (const segment of segments) {
8
+ if (typeof current !== 'object' || current === null)
9
+ return undefined;
10
+ current = current[segment];
11
+ }
12
+ return current;
13
+ }
14
+ /**
15
+ * Runs a job-processing method inside the context `withJobContext` stamped on
16
+ * its payload: the tenant, the correlation id, and the principal the registered
17
+ * `IJobPrincipal` re-checks and binds. The method becomes async.
18
+ *
19
+ * It fails closed before the method runs: a payload without a context, with a
20
+ * malformed one, with an unconfigured tenant, or with a principal carrying
21
+ * anything beyond `id`, `type` and `sessionId` is refused, and so is a
22
+ * principal `restore` rejects. Place it under the transport decorator.
23
+ *
24
+ * @example
25
+ * ```ts
26
+ * class WelcomeEmailWorker {
27
+ * @InJobContext()
28
+ * async process(job: Job<WithJobContext<WelcomeEmail>>) {
29
+ * await sendWelcomeEmail(job.data);
30
+ * }
31
+ * }
32
+ *
33
+ * const worker = new WelcomeEmailWorker();
34
+ * new Worker(WELCOME_EMAIL_QUEUE, (job) => worker.process(job));
35
+ * ```
36
+ */
37
+ export function InJobContext(options = {}) {
38
+ const segments = (options.path ?? 'data.jobContext').split('.');
39
+ return methodDecorator((original) => {
40
+ return async function (...args) {
41
+ const { principal, tenants, sources } = activeRegistration();
42
+ const context = parseJobContext(readPath(args[0], segments), tenants, sources.correlationId.accepts);
43
+ return sources.tenantId.run(context.tenantId, () => sources.correlationId.run(context.correlationId, () => principal.restore(context.principal, async () => original.apply(this, args))));
44
+ };
45
+ });
46
+ }
47
+ //# sourceMappingURL=in-job-context.decorator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"in-job-context.decorator.js","sourceRoot":"","sources":["../../src/decorators/in-job-context.decorator.ts"],"names":[],"mappings":"AAAA,sEAAsE;AAEtE,OAAO,EAEL,eAAe,GAChB,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAClE,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAYhE,SAAS,QAAQ,CAAC,KAAc,EAAE,QAA2B;IAC3D,IAAI,OAAO,GAAG,KAAK,CAAC;IACpB,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,KAAK,IAAI;YAAE,OAAO,SAAS,CAAC;QACtE,OAAO,GAAI,OAAmC,CAAC,OAAO,CAAC,CAAC;IAC1D,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,UAAU,YAAY,CAC1B,OAAO,GAAwB,EAAE;IAEjC,MAAM,QAAQ,GAAG,CAAC,OAAO,CAAC,IAAI,IAAI,iBAAiB,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAEhE,OAAO,eAAe,CAAC,CAAC,QAAQ,EAAE,EAAE;QAClC,OAAO,KAAK,WAA0B,GAAG,IAAe;YACtD,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,kBAAkB,EAAE,CAAC;YAC7D,MAAM,OAAO,GAAG,eAAe,CAC7B,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC,EAC3B,OAAO,EACP,OAAO,CAAC,aAAa,CAAC,OAAO,CAC9B,CAAC;YACF,OAAO,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,QAAQ,EAAE,GAAG,EAAE,CACjD,OAAO,CAAC,aAAa,CAAC,GAAG,CAAC,OAAO,CAAC,aAAa,EAAE,GAAG,EAAE,CACpD,SAAS,CAAC,OAAO,CAAC,OAAO,CAAC,SAAS,EAAE,KAAK,IAAI,EAAE,CAC9C,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,CAC3B,CACF,CACF,CAAC;QACJ,CAAC,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Raised when a job payload's context is malformed, names an unconfigured
3
+ * tenant, or carries fields a principal reference must not have, such as
4
+ * grants. A payload is data written by whoever can write to the queue.
5
+ *
6
+ * @example
7
+ * ```ts
8
+ * throw new InvalidJobContextError('tenantId is not a configured tenant');
9
+ * ```
10
+ */
11
+ export declare class InvalidJobContextError extends Error {
12
+ readonly reason: string;
13
+ constructor(reason: string);
14
+ }
15
+ //# sourceMappingURL=invalid-job-context.error.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"invalid-job-context.error.d.ts","sourceRoot":"","sources":["../../src/errors/invalid-job-context.error.ts"],"names":[],"mappings":"AAEA;;;;;;;;;GASG;AACH,qBAAa,sBAAuB,SAAQ,KAAK;IACnC,QAAQ,CAAC,MAAM,EAAE,MAAM;IAAnC,YAAqB,MAAM,EAAE,MAAM,EAGlC;CACF"}
@@ -0,0 +1,20 @@
1
+ /* Copyright (C) 2026-present Aristotelis — see repository license. */
2
+ /**
3
+ * Raised when a job payload's context is malformed, names an unconfigured
4
+ * tenant, or carries fields a principal reference must not have, such as
5
+ * grants. A payload is data written by whoever can write to the queue.
6
+ *
7
+ * @example
8
+ * ```ts
9
+ * throw new InvalidJobContextError('tenantId is not a configured tenant');
10
+ * ```
11
+ */
12
+ export class InvalidJobContextError extends Error {
13
+ reason;
14
+ constructor(reason) {
15
+ super(`Invalid job context: ${reason}.`);
16
+ this.reason = reason;
17
+ this.name = InvalidJobContextError.name;
18
+ }
19
+ }
20
+ //# sourceMappingURL=invalid-job-context.error.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"invalid-job-context.error.js","sourceRoot":"","sources":["../../src/errors/invalid-job-context.error.ts"],"names":[],"mappings":"AAAA,sEAAsE;AAEtE;;;;;;;;;GASG;AACH,MAAM,OAAO,sBAAuB,SAAQ,KAAK;IAC1B,MAAM;IAA3B,YAAqB,MAAc;QACjC,KAAK,CAAC,wBAAwB,MAAM,GAAG,CAAC,CAAC;sBADtB,MAAM;QAEzB,IAAI,CAAC,IAAI,GAAG,sBAAsB,CAAC,IAAI,CAAC;IAC1C,CAAC;CACF"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Raised when a job would run, or be enqueued, without part of its execution
3
+ * context. A job never falls back to a default tenant or an anonymous principal.
4
+ *
5
+ * @example
6
+ * ```ts
7
+ * throw new MissingJobContextError('principal');
8
+ * ```
9
+ */
10
+ export declare class MissingJobContextError extends Error {
11
+ readonly missing: string;
12
+ constructor(missing: string);
13
+ }
14
+ //# sourceMappingURL=missing-job-context.error.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"missing-job-context.error.d.ts","sourceRoot":"","sources":["../../src/errors/missing-job-context.error.ts"],"names":[],"mappings":"AAEA;;;;;;;;GAQG;AACH,qBAAa,sBAAuB,SAAQ,KAAK;IACnC,QAAQ,CAAC,OAAO,EAAE,MAAM;IAApC,YAAqB,OAAO,EAAE,MAAM,EAKnC;CACF"}
@@ -0,0 +1,19 @@
1
+ /* Copyright (C) 2026-present Aristotelis — see repository license. */
2
+ /**
3
+ * Raised when a job would run, or be enqueued, without part of its execution
4
+ * context. A job never falls back to a default tenant or an anonymous principal.
5
+ *
6
+ * @example
7
+ * ```ts
8
+ * throw new MissingJobContextError('principal');
9
+ * ```
10
+ */
11
+ export class MissingJobContextError extends Error {
12
+ missing;
13
+ constructor(missing) {
14
+ super(`Missing job context: ${missing}. A job never runs without it and never falls back to a default.`);
15
+ this.missing = missing;
16
+ this.name = MissingJobContextError.name;
17
+ }
18
+ }
19
+ //# sourceMappingURL=missing-job-context.error.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"missing-job-context.error.js","sourceRoot":"","sources":["../../src/errors/missing-job-context.error.ts"],"names":[],"mappings":"AAAA,sEAAsE;AAEtE;;;;;;;;GAQG;AACH,MAAM,OAAO,sBAAuB,SAAQ,KAAK;IAC1B,OAAO;IAA5B,YAAqB,OAAe;QAClC,KAAK,CACH,wBAAwB,OAAO,kEAAkE,CAClG,CAAC;uBAHiB,OAAO;QAI1B,IAAI,CAAC,IAAI,GAAG,sBAAsB,CAAC,IAAI,CAAC;IAC1C,CAAC;CACF"}
@@ -0,0 +1,13 @@
1
+ type AnyMethod = (this: unknown, ...args: any[]) => unknown;
2
+ /** A method decorator for the standard and the `experimentalDecorators` mode. */
3
+ export interface DualMethodDecorator {
4
+ <F extends AnyMethod>(method: F, context: ClassMethodDecoratorContext): F;
5
+ (target: object, propertyKey: string | symbol, descriptor: PropertyDescriptor): PropertyDescriptor;
6
+ }
7
+ /**
8
+ * Builds a decorator that replaces a method with `replace(method, name)`, keeping the
9
+ * method's own name for stack traces.
10
+ */
11
+ export declare function methodDecorator(replace: (method: AnyMethod, name: string) => AnyMethod): DualMethodDecorator;
12
+ export {};
13
+ //# sourceMappingURL=method-decorator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"method-decorator.d.ts","sourceRoot":"","sources":["../../src/helpers/method-decorator.ts"],"names":[],"mappings":"AAGA,KAAK,SAAS,GAAG,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,OAAO,CAAC;AAE5D,iFAAiF;AACjF,MAAM,WAAW,mBAAmB;IAClC,CAAC,CAAC,SAAS,SAAS,EAAE,MAAM,EAAE,CAAC,EAAE,OAAO,EAAE,2BAA2B,GAAG,CAAC,CAAC;IAC1E,CACE,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,GAAG,MAAM,EAC5B,UAAU,EAAE,kBAAkB,GAC7B,kBAAkB,CAAC;CACvB;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,CAAC,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,KAAK,SAAS,GACtD,mBAAmB,CAiBrB"}
@@ -0,0 +1,24 @@
1
+ /* Copyright (C) 2026-present Aristotelis — see repository license. */
2
+ /**
3
+ * Builds a decorator that replaces a method with `replace(method, name)`, keeping the
4
+ * method's own name for stack traces.
5
+ */
6
+ export function methodDecorator(replace) {
7
+ const replaced = (method, name) => {
8
+ const replacement = replace(method, name);
9
+ Object.defineProperty(replacement, 'name', {
10
+ value: method.name,
11
+ configurable: true,
12
+ });
13
+ return replacement;
14
+ };
15
+ return ((target, key, descriptor) => {
16
+ if (typeof key === 'object' && key !== null && 'name' in key) {
17
+ return replaced(target, String(key.name));
18
+ }
19
+ const property = descriptor;
20
+ property.value = replaced(property.value, String(key));
21
+ return property;
22
+ });
23
+ }
24
+ //# sourceMappingURL=method-decorator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"method-decorator.js","sourceRoot":"","sources":["../../src/helpers/method-decorator.ts"],"names":[],"mappings":"AAAA,sEAAsE;AAetE;;;GAGG;AACH,MAAM,UAAU,eAAe,CAC7B,OAAuD;IAEvD,MAAM,QAAQ,GAAG,CAAC,MAAiB,EAAE,IAAY,EAAE,EAAE;QACnD,MAAM,WAAW,GAAG,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QAC1C,MAAM,CAAC,cAAc,CAAC,WAAW,EAAE,MAAM,EAAE;YACzC,KAAK,EAAE,MAAM,CAAC,IAAI;YAClB,YAAY,EAAE,IAAI;SACnB,CAAC,CAAC;QACH,OAAO,WAAW,CAAC;IACrB,CAAC,CAAC;IACF,OAAO,CAAC,CAAC,MAAe,EAAE,GAAY,EAAE,UAA+B,EAAE,EAAE;QACzE,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI,IAAI,MAAM,IAAI,GAAG,EAAE,CAAC;YAC7D,OAAO,QAAQ,CAAC,MAAmB,EAAE,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;QACzD,CAAC;QACD,MAAM,QAAQ,GAAG,UAAgC,CAAC;QAClD,QAAQ,CAAC,KAAK,GAAG,QAAQ,CAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;QACvD,OAAO,QAAQ,CAAC;IAClB,CAAC,CAAwB,CAAC;AAC5B,CAAC"}
@@ -0,0 +1,20 @@
1
+ import type { JobContext } from '../interfaces/job-context.interface.js';
2
+ /**
3
+ * Validates a job payload's context before anything runs with it. Every field
4
+ * is checked, unknown fields are refused, the tenant must be configured, and
5
+ * the correlation id must be one `acceptsCorrelationId` accepts.
6
+ *
7
+ * @param value - The payload's `jobContext` value, as read from the queue.
8
+ * @param tenants - The configured tenants.
9
+ * @param acceptsCorrelationId - The correlation source's `accepts`.
10
+ * @returns A context holding only the validated fields.
11
+ * @throws {MissingJobContextError} When `value` is `undefined`.
12
+ * @throws {InvalidJobContextError} For any other value that is not a valid context.
13
+ *
14
+ * @example
15
+ * ```ts
16
+ * const context = parseJobContext(job.data.jobContext, ['tenant_a'], sources.correlationId.accepts);
17
+ * ```
18
+ */
19
+ export declare function parseJobContext(value: unknown, tenants: readonly string[], acceptsCorrelationId: (id: string) => boolean): JobContext;
20
+ //# sourceMappingURL=parse-job-context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse-job-context.d.ts","sourceRoot":"","sources":["../../src/helpers/parse-job-context.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wCAAwC,CAAC;AAyBzE;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,eAAe,CAC7B,KAAK,EAAE,OAAO,EACd,OAAO,EAAE,SAAS,MAAM,EAAE,EAC1B,oBAAoB,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,GAC5C,UAAU,CAmCZ"}
@@ -0,0 +1,68 @@
1
+ /* Copyright (C) 2026-present Aristotelis — see repository license. */
2
+ import { InvalidJobContextError } from '../errors/invalid-job-context.error.js';
3
+ import { MissingJobContextError } from '../errors/missing-job-context.error.js';
4
+ import { toReference } from './principal-reference.js';
5
+ const CONTEXT_FIELDS = new Set(['tenantId', 'correlationId', 'principal']);
6
+ const PRINCIPAL_FIELDS = new Set(['id', 'type', 'sessionId']);
7
+ function isRecord(value) {
8
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
9
+ }
10
+ function isText(value) {
11
+ return typeof value === 'string' && value.trim() !== '';
12
+ }
13
+ function assertFields(value, allowed, name) {
14
+ const extra = Object.keys(value).find((key) => !allowed.has(key));
15
+ if (extra !== undefined) {
16
+ throw new InvalidJobContextError(`${name} carries the field "${extra}"`);
17
+ }
18
+ }
19
+ /**
20
+ * Validates a job payload's context before anything runs with it. Every field
21
+ * is checked, unknown fields are refused, the tenant must be configured, and
22
+ * the correlation id must be one `acceptsCorrelationId` accepts.
23
+ *
24
+ * @param value - The payload's `jobContext` value, as read from the queue.
25
+ * @param tenants - The configured tenants.
26
+ * @param acceptsCorrelationId - The correlation source's `accepts`.
27
+ * @returns A context holding only the validated fields.
28
+ * @throws {MissingJobContextError} When `value` is `undefined`.
29
+ * @throws {InvalidJobContextError} For any other value that is not a valid context.
30
+ *
31
+ * @example
32
+ * ```ts
33
+ * const context = parseJobContext(job.data.jobContext, ['tenant_a'], sources.correlationId.accepts);
34
+ * ```
35
+ */
36
+ export function parseJobContext(value, tenants, acceptsCorrelationId) {
37
+ if (value === undefined) {
38
+ throw new MissingJobContextError('the payload has no jobContext');
39
+ }
40
+ if (!isRecord(value)) {
41
+ throw new InvalidJobContextError('jobContext is not an object');
42
+ }
43
+ assertFields(value, CONTEXT_FIELDS, 'jobContext');
44
+ const { tenantId, correlationId, principal } = value;
45
+ if (typeof tenantId !== 'string' || !tenants.includes(tenantId)) {
46
+ throw new InvalidJobContextError('tenantId is not a configured tenant');
47
+ }
48
+ if (typeof correlationId !== 'string' ||
49
+ !acceptsCorrelationId(correlationId)) {
50
+ throw new InvalidJobContextError('correlationId is malformed');
51
+ }
52
+ if (!isRecord(principal)) {
53
+ throw new InvalidJobContextError('principal is not an object');
54
+ }
55
+ assertFields(principal, PRINCIPAL_FIELDS, 'principal');
56
+ const { id, type, sessionId } = principal;
57
+ if (!isText(id) ||
58
+ !isText(type) ||
59
+ (sessionId !== undefined && !isText(sessionId))) {
60
+ throw new InvalidJobContextError('principal is malformed');
61
+ }
62
+ return {
63
+ tenantId,
64
+ correlationId,
65
+ principal: toReference({ id, type, sessionId }),
66
+ };
67
+ }
68
+ //# sourceMappingURL=parse-job-context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse-job-context.js","sourceRoot":"","sources":["../../src/helpers/parse-job-context.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import type { PrincipalReference } from '../interfaces/principal-reference.interface.js';
2
+ /**
3
+ * Copies only the identity fields of `principal`, so grants or session data an
4
+ * application object also holds never reach a payload or a restore call.
5
+ *
6
+ * @example
7
+ * ```ts
8
+ * toReference({ id: 'u-1', type: 'user', sid: 's-1', grants: [] }); // { id: 'u-1', type: 'user' }
9
+ * ```
10
+ */
11
+ export declare function toReference(principal: PrincipalReference): PrincipalReference;
12
+ //# sourceMappingURL=principal-reference.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"principal-reference.d.ts","sourceRoot":"","sources":["../../src/helpers/principal-reference.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gDAAgD,CAAC;AAEzF;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CAAC,SAAS,EAAE,kBAAkB,GAAG,kBAAkB,CAG7E"}
@@ -0,0 +1,15 @@
1
+ /* Copyright (C) 2026-present Aristotelis — see repository license. */
2
+ /**
3
+ * Copies only the identity fields of `principal`, so grants or session data an
4
+ * application object also holds never reach a payload or a restore call.
5
+ *
6
+ * @example
7
+ * ```ts
8
+ * toReference({ id: 'u-1', type: 'user', sid: 's-1', grants: [] }); // { id: 'u-1', type: 'user' }
9
+ * ```
10
+ */
11
+ export function toReference(principal) {
12
+ const { id, type, sessionId } = principal;
13
+ return sessionId === undefined ? { id, type } : { id, type, sessionId };
14
+ }
15
+ //# sourceMappingURL=principal-reference.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"principal-reference.js","sourceRoot":"","sources":["../../src/helpers/principal-reference.ts"],"names":[],"mappings":"AAAA,sEAAsE;AAItE;;;;;;;;GAQG;AACH,MAAM,UAAU,WAAW,CAAC,SAA6B;IACvD,MAAM,EAAE,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,SAAS,CAAC;IAC1C,OAAO,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;AAC1E,CAAC"}
@@ -0,0 +1,39 @@
1
+ import type { JobContextSources } from '../interfaces/context-source.interface.js';
2
+ import type { IJobPrincipal } from '../interfaces/job-principal.interface.js';
3
+ /** What `registerJobContext` registers for the decorators. */
4
+ export interface Registration {
5
+ readonly principal: IJobPrincipal;
6
+ readonly tenants: readonly string[];
7
+ readonly sources: JobContextSources;
8
+ }
9
+ /**
10
+ * Makes `registration` the one the decorators and `withJobContext` use.
11
+ *
12
+ * @example
13
+ * ```ts
14
+ * register({ principal, tenants: ['tenant_a'], sources });
15
+ * ```
16
+ */
17
+ export declare function register(registration: Registration): void;
18
+ /**
19
+ * Removes `registration` if it is still the active one, so closing one
20
+ * application does not remove another's.
21
+ *
22
+ * @example
23
+ * ```ts
24
+ * unregister(registration);
25
+ * ```
26
+ */
27
+ export declare function unregister(registration: Registration): void;
28
+ /**
29
+ * The active registration.
30
+ *
31
+ * @throws {MissingJobContextError} When no job context is registered.
32
+ *
33
+ * @example
34
+ * ```ts
35
+ * const { principal, tenants, sources } = activeRegistration();
36
+ * ```
37
+ */
38
+ export declare function activeRegistration(): Registration;
39
+ //# sourceMappingURL=registration.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registration.d.ts","sourceRoot":"","sources":["../../src/helpers/registration.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,2CAA2C,CAAC;AACnF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,0CAA0C,CAAC;AAE9E,8DAA8D;AAC9D,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,SAAS,EAAE,aAAa,CAAC;IAClC,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,QAAQ,CAAC,OAAO,EAAE,iBAAiB,CAAC;CACrC;AAID;;;;;;;GAOG;AACH,wBAAgB,QAAQ,CAAC,YAAY,EAAE,YAAY,GAAG,IAAI,CAEzD;AAED;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CAAC,YAAY,EAAE,YAAY,GAAG,IAAI,CAE3D;AAED;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,IAAI,YAAY,CAOjD"}
@@ -0,0 +1,44 @@
1
+ /* Copyright (C) 2026-present Aristotelis — see repository license. */
2
+ import { MissingJobContextError } from '../errors/missing-job-context.error.js';
3
+ let active;
4
+ /**
5
+ * Makes `registration` the one the decorators and `withJobContext` use.
6
+ *
7
+ * @example
8
+ * ```ts
9
+ * register({ principal, tenants: ['tenant_a'], sources });
10
+ * ```
11
+ */
12
+ export function register(registration) {
13
+ active = registration;
14
+ }
15
+ /**
16
+ * Removes `registration` if it is still the active one, so closing one
17
+ * application does not remove another's.
18
+ *
19
+ * @example
20
+ * ```ts
21
+ * unregister(registration);
22
+ * ```
23
+ */
24
+ export function unregister(registration) {
25
+ if (active === registration)
26
+ active = undefined;
27
+ }
28
+ /**
29
+ * The active registration.
30
+ *
31
+ * @throws {MissingJobContextError} When no job context is registered.
32
+ *
33
+ * @example
34
+ * ```ts
35
+ * const { principal, tenants, sources } = activeRegistration();
36
+ * ```
37
+ */
38
+ export function activeRegistration() {
39
+ if (active === undefined) {
40
+ throw new MissingJobContextError('a job context registered with registerJobContext');
41
+ }
42
+ return active;
43
+ }
44
+ //# sourceMappingURL=registration.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registration.js","sourceRoot":"","sources":["../../src/helpers/registration.ts"],"names":[],"mappings":"AAAA,sEAAsE;AAEtE,OAAO,EAAE,sBAAsB,EAAE,MAAM,wCAAwC,CAAC;AAWhF,IAAI,MAAgC,CAAC;AAErC;;;;;;;GAOG;AACH,MAAM,UAAU,QAAQ,CAAC,YAA0B;IACjD,MAAM,GAAG,YAAY,CAAC;AACxB,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,UAAU,CAAC,YAA0B;IACnD,IAAI,MAAM,KAAK,YAAY;QAAE,MAAM,GAAG,SAAS,CAAC;AAClD,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,kBAAkB;IAChC,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QACzB,MAAM,IAAI,sBAAsB,CAC9B,kDAAkD,CACnD,CAAC;IACJ,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,21 @@
1
+ import type { WithJobContext } from '../interfaces/job-context.interface.js';
2
+ /**
3
+ * Stamps the current execution context onto a job payload: the tenant and
4
+ * correlation id of the registered sources (a new one from the correlation
5
+ * source's `create()` when none is active), and the principal the registered `IJobPrincipal`
6
+ * captures, reduced to its identity. The processor restores it with
7
+ * `@InJobContext`.
8
+ *
9
+ * @param data - The payload. Must be a plain object; a shallow copy is returned.
10
+ * @returns A copy of `data` with `jobContext` added.
11
+ * @throws {TypeError} When `data` is not a plain object.
12
+ * @throws {MissingJobContextError} Without a `registerJobContext` registration, a
13
+ * current tenant, or a current principal.
14
+ *
15
+ * @example
16
+ * ```ts
17
+ * await queue.add('send', withJobContext({ userId, email }));
18
+ * ```
19
+ */
20
+ export declare function withJobContext<T extends Record<string, unknown>>(data: T): WithJobContext<T>;
21
+ //# sourceMappingURL=with-job-context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"with-job-context.d.ts","sourceRoot":"","sources":["../../src/helpers/with-job-context.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wCAAwC,CAAC;AAI7E;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,cAAc,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9D,IAAI,EAAE,CAAC,GACN,cAAc,CAAC,CAAC,CAAC,CAwBnB"}