@rytass/bpm-core-nestjs-module 0.13.3 → 0.13.5

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 (143) hide show
  1. package/CHANGELOG.md +56 -0
  2. package/package.json +14 -7
  3. package/src/index.d.ts +1 -0
  4. package/src/index.js +1 -0
  5. package/src/index.js.map +1 -1
  6. package/src/lib/attachment/attachment-storage.provider.d.ts +11 -0
  7. package/src/lib/attachment/attachment-storage.provider.js +15 -1
  8. package/src/lib/attachment/attachment-storage.provider.js.map +1 -1
  9. package/src/lib/bpm/bpm-root-options.d.ts +134 -0
  10. package/src/lib/bpm/bpm-root-options.js +61 -0
  11. package/src/lib/bpm/bpm-root-options.js.map +1 -0
  12. package/src/lib/bpm/bpm-root.module.d.ts +101 -137
  13. package/src/lib/bpm/bpm-root.module.js +83 -118
  14. package/src/lib/bpm/bpm-root.module.js.map +1 -1
  15. package/src/lib/bpm/index.d.ts +1 -0
  16. package/src/lib/bpm/index.js +1 -0
  17. package/src/lib/bpm/index.js.map +1 -1
  18. package/src/lib/calendar/business-calendar.provider.d.ts +8 -4
  19. package/src/lib/calendar/business-calendar.provider.js +15 -6
  20. package/src/lib/calendar/business-calendar.provider.js.map +1 -1
  21. package/src/lib/common/outbox.d.ts +26 -0
  22. package/src/lib/common/outbox.js +64 -0
  23. package/src/lib/common/outbox.js.map +1 -0
  24. package/src/lib/delegation/delegation.service.js +7 -7
  25. package/src/lib/delegation/delegation.service.js.map +1 -1
  26. package/src/lib/form-data-source/form-data-source.module.js +2 -4
  27. package/src/lib/form-data-source/form-data-source.module.js.map +1 -1
  28. package/src/lib/form-data-source/form-data-source.provider.d.ts +14 -0
  29. package/src/lib/form-data-source/form-data-source.provider.js +23 -0
  30. package/src/lib/form-data-source/form-data-source.provider.js.map +1 -0
  31. package/src/lib/form-data-source/index.d.ts +1 -0
  32. package/src/lib/form-data-source/index.js +1 -0
  33. package/src/lib/form-data-source/index.js.map +1 -1
  34. package/src/lib/identity/default-member-resolver.d.ts +39 -0
  35. package/src/lib/identity/default-member-resolver.js +81 -0
  36. package/src/lib/identity/default-member-resolver.js.map +1 -0
  37. package/src/lib/identity/identity.module.d.ts +12 -2
  38. package/src/lib/identity/identity.module.js +2 -1
  39. package/src/lib/identity/identity.module.js.map +1 -1
  40. package/src/lib/identity/index.d.ts +1 -0
  41. package/src/lib/identity/index.js +1 -0
  42. package/src/lib/identity/index.js.map +1 -1
  43. package/src/lib/migrations/0000000023000-workflow-webhook-deliveries.d.ts +17 -0
  44. package/src/lib/migrations/0000000023000-workflow-webhook-deliveries.js +61 -0
  45. package/src/lib/migrations/0000000023000-workflow-webhook-deliveries.js.map +1 -0
  46. package/src/lib/migrations/0000000024000-workflow-webhook-endpoints.d.ts +16 -0
  47. package/src/lib/migrations/0000000024000-workflow-webhook-endpoints.js +71 -0
  48. package/src/lib/migrations/0000000024000-workflow-webhook-endpoints.js.map +1 -0
  49. package/src/lib/migrations/index.d.ts +2 -0
  50. package/src/lib/migrations/index.js +6 -0
  51. package/src/lib/migrations/index.js.map +1 -1
  52. package/src/lib/notification/notification-delivery.service.js +4 -57
  53. package/src/lib/notification/notification-delivery.service.js.map +1 -1
  54. package/src/lib/notification/notification.service.js +4 -3
  55. package/src/lib/notification/notification.service.js.map +1 -1
  56. package/src/lib/template/template.service.d.ts +9 -0
  57. package/src/lib/template/template.service.js +31 -0
  58. package/src/lib/template/template.service.js.map +1 -1
  59. package/src/lib/template/workflow-definition.validator.js +54 -1
  60. package/src/lib/template/workflow-definition.validator.js.map +1 -1
  61. package/src/lib/workflow-engine/workflow-engine.enums.d.ts +3 -1
  62. package/src/lib/workflow-engine/workflow-engine.enums.js +2 -0
  63. package/src/lib/workflow-engine/workflow-engine.enums.js.map +1 -1
  64. package/src/lib/workflow-engine/workflow-engine.module.js +3 -0
  65. package/src/lib/workflow-engine/workflow-engine.module.js.map +1 -1
  66. package/src/lib/workflow-engine/workflow-engine.service.d.ts +5 -2
  67. package/src/lib/workflow-engine/workflow-engine.service.js +150 -26
  68. package/src/lib/workflow-engine/workflow-engine.service.js.map +1 -1
  69. package/src/lib/workflow-webhook/index.d.ts +24 -0
  70. package/src/lib/workflow-webhook/index.js +28 -0
  71. package/src/lib/workflow-webhook/index.js.map +1 -0
  72. package/src/lib/workflow-webhook/workflow-webhook-allowlist.d.ts +38 -0
  73. package/src/lib/workflow-webhook/workflow-webhook-allowlist.js +296 -0
  74. package/src/lib/workflow-webhook/workflow-webhook-allowlist.js.map +1 -0
  75. package/src/lib/workflow-webhook/workflow-webhook-database-source.d.ts +33 -0
  76. package/src/lib/workflow-webhook/workflow-webhook-database-source.js +129 -0
  77. package/src/lib/workflow-webhook/workflow-webhook-database-source.js.map +1 -0
  78. package/src/lib/workflow-webhook/workflow-webhook-delivery-scheduler.service.d.ts +25 -0
  79. package/src/lib/workflow-webhook/workflow-webhook-delivery-scheduler.service.js +92 -0
  80. package/src/lib/workflow-webhook/workflow-webhook-delivery-scheduler.service.js.map +1 -0
  81. package/src/lib/workflow-webhook/workflow-webhook-delivery.entity.d.ts +53 -0
  82. package/src/lib/workflow-webhook/workflow-webhook-delivery.entity.js +97 -0
  83. package/src/lib/workflow-webhook/workflow-webhook-delivery.entity.js.map +1 -0
  84. package/src/lib/workflow-webhook/workflow-webhook-delivery.enums.d.ts +28 -0
  85. package/src/lib/workflow-webhook/workflow-webhook-delivery.enums.js +36 -0
  86. package/src/lib/workflow-webhook/workflow-webhook-delivery.enums.js.map +1 -0
  87. package/src/lib/workflow-webhook/workflow-webhook-delivery.object.d.ts +28 -0
  88. package/src/lib/workflow-webhook/workflow-webhook-delivery.object.js +88 -0
  89. package/src/lib/workflow-webhook/workflow-webhook-delivery.object.js.map +1 -0
  90. package/src/lib/workflow-webhook/workflow-webhook-delivery.resolver.d.ts +9 -0
  91. package/src/lib/workflow-webhook/workflow-webhook-delivery.resolver.js +66 -0
  92. package/src/lib/workflow-webhook/workflow-webhook-delivery.resolver.js.map +1 -0
  93. package/src/lib/workflow-webhook/workflow-webhook-delivery.service.d.ts +116 -0
  94. package/src/lib/workflow-webhook/workflow-webhook-delivery.service.js +705 -0
  95. package/src/lib/workflow-webhook/workflow-webhook-delivery.service.js.map +1 -0
  96. package/src/lib/workflow-webhook/workflow-webhook-delivery.subscriber.d.ts +23 -0
  97. package/src/lib/workflow-webhook/workflow-webhook-delivery.subscriber.js +85 -0
  98. package/src/lib/workflow-webhook/workflow-webhook-delivery.subscriber.js.map +1 -0
  99. package/src/lib/workflow-webhook/workflow-webhook-endpoint-admin.dto.d.ts +85 -0
  100. package/src/lib/workflow-webhook/workflow-webhook-endpoint-admin.dto.js +345 -0
  101. package/src/lib/workflow-webhook/workflow-webhook-endpoint-admin.dto.js.map +1 -0
  102. package/src/lib/workflow-webhook/workflow-webhook-endpoint-admin.resolver.d.ts +23 -0
  103. package/src/lib/workflow-webhook/workflow-webhook-endpoint-admin.resolver.js +159 -0
  104. package/src/lib/workflow-webhook/workflow-webhook-endpoint-admin.resolver.js.map +1 -0
  105. package/src/lib/workflow-webhook/workflow-webhook-endpoint-admin.service.d.ts +93 -0
  106. package/src/lib/workflow-webhook/workflow-webhook-endpoint-admin.service.js +464 -0
  107. package/src/lib/workflow-webhook/workflow-webhook-endpoint-admin.service.js.map +1 -0
  108. package/src/lib/workflow-webhook/workflow-webhook-endpoint.entity.d.ts +52 -0
  109. package/src/lib/workflow-webhook/workflow-webhook-endpoint.entity.js +135 -0
  110. package/src/lib/workflow-webhook/workflow-webhook-endpoint.entity.js.map +1 -0
  111. package/src/lib/workflow-webhook/workflow-webhook-enqueue.d.ts +46 -0
  112. package/src/lib/workflow-webhook/workflow-webhook-enqueue.js +134 -0
  113. package/src/lib/workflow-webhook/workflow-webhook-enqueue.js.map +1 -0
  114. package/src/lib/workflow-webhook/workflow-webhook-options.d.ts +86 -0
  115. package/src/lib/workflow-webhook/workflow-webhook-options.js +88 -0
  116. package/src/lib/workflow-webhook/workflow-webhook-options.js.map +1 -0
  117. package/src/lib/workflow-webhook/workflow-webhook-options.module.d.ts +18 -0
  118. package/src/lib/workflow-webhook/workflow-webhook-options.module.js +57 -0
  119. package/src/lib/workflow-webhook/workflow-webhook-options.module.js.map +1 -0
  120. package/src/lib/workflow-webhook/workflow-webhook-secret-cipher.d.ts +20 -0
  121. package/src/lib/workflow-webhook/workflow-webhook-secret-cipher.js +66 -0
  122. package/src/lib/workflow-webhook/workflow-webhook-secret-cipher.js.map +1 -0
  123. package/src/lib/workflow-webhook/workflow-webhook.errors.d.ts +35 -0
  124. package/src/lib/workflow-webhook/workflow-webhook.errors.js +41 -0
  125. package/src/lib/workflow-webhook/workflow-webhook.errors.js.map +1 -0
  126. package/src/lib/workflow-webhook/workflow-webhook.module.d.ts +9 -0
  127. package/src/lib/workflow-webhook/workflow-webhook.module.js +62 -0
  128. package/src/lib/workflow-webhook/workflow-webhook.module.js.map +1 -0
  129. package/src/lib/workflow-webhook/workflow-webhook.provider.d.ts +12 -0
  130. package/src/lib/workflow-webhook/workflow-webhook.provider.js +21 -0
  131. package/src/lib/workflow-webhook/workflow-webhook.provider.js.map +1 -0
  132. package/src/lib/workflow-webhook/workflow-webhook.queries.d.ts +38 -0
  133. package/src/lib/workflow-webhook/workflow-webhook.queries.js +142 -0
  134. package/src/lib/workflow-webhook/workflow-webhook.queries.js.map +1 -0
  135. package/src/lib/workflow-webhook/workflow-webhook.service.d.ts +50 -0
  136. package/src/lib/workflow-webhook/workflow-webhook.service.js +221 -0
  137. package/src/lib/workflow-webhook/workflow-webhook.service.js.map +1 -0
  138. package/src/lib/workflow-webhook/workflow-webhook.types.d.ts +127 -0
  139. package/src/lib/workflow-webhook/workflow-webhook.types.js +33 -0
  140. package/src/lib/workflow-webhook/workflow-webhook.types.js.map +1 -0
  141. package/src/lib/workflow-webhook/workflow-webhook.validator.d.ts +20 -0
  142. package/src/lib/workflow-webhook/workflow-webhook.validator.js +97 -0
  143. package/src/lib/workflow-webhook/workflow-webhook.validator.js.map +1 -0
@@ -0,0 +1,221 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.WorkflowWebhookService = void 0;
4
+ exports.readRegistryDescriptorErrors = readRegistryDescriptorErrors;
5
+ const tslib_1 = require("tslib");
6
+ const common_1 = require("@nestjs/common");
7
+ const workflow_webhook_allowlist_1 = require("./workflow-webhook-allowlist");
8
+ const workflow_graph_1 = require("@rytass/bpm-core-shared/workflow-graph");
9
+ const workflow_webhook_database_source_1 = require("./workflow-webhook-database-source");
10
+ const workflow_webhook_options_1 = require("./workflow-webhook-options");
11
+ const workflow_webhook_types_1 = require("./workflow-webhook.types");
12
+ /**
13
+ * Wraps the host's synchronous registry as an endpoint source so the catalog,
14
+ * the publish lint and (from P2) the delivery path only ever talk to the
15
+ * source interface. P6 adds the database source beside this one without
16
+ * touching any of them.
17
+ */
18
+ class RegistryWorkflowWebhookEndpointSource {
19
+ constructor(registry) {
20
+ this.registry = registry;
21
+ this.kind = 'REGISTRY';
22
+ }
23
+ async get(key, version) {
24
+ return this.registry.get(key, version);
25
+ }
26
+ async list() {
27
+ return this.registry.list();
28
+ }
29
+ }
30
+ let WorkflowWebhookService = class WorkflowWebhookService {
31
+ constructor(registry, options = workflow_webhook_options_1.DEFAULT_BPM_WORKFLOW_WEBHOOK_OPTIONS, databaseSource) {
32
+ this.registry = registry;
33
+ this.options = options;
34
+ this.databaseSource = databaseSource;
35
+ this.sources = this.options.targetSources.flatMap((kind) => {
36
+ if (kind === 'REGISTRY') {
37
+ return this.registry
38
+ ? [new RegistryWorkflowWebhookEndpointSource(this.registry)]
39
+ : [];
40
+ }
41
+ return this.databaseSource ? [this.databaseSource] : [];
42
+ });
43
+ }
44
+ /**
45
+ * Whether administrators can manage endpoints in the database: requested
46
+ * in `workflowWebhookTargetSources` and guarded by an allowlist and an
47
+ * encryption key (otherwise the options resolution dropped it).
48
+ */
49
+ hasDatabaseSource() {
50
+ return this.sources.some((source) => source.kind === 'DATABASE');
51
+ }
52
+ /** Registered endpoints only; used to keep database keys from colliding. */
53
+ listRegistryEndpoints() {
54
+ return this.registry?.list() ?? [];
55
+ }
56
+ /**
57
+ * A descriptor that contradicts itself would only surface as a confusing
58
+ * publish error much later, so the registry is checked once at boot and the
59
+ * application refuses to start instead.
60
+ */
61
+ onModuleInit() {
62
+ const errors = readRegistryDescriptorErrors(this.registry);
63
+ if (errors.length) {
64
+ throw new Error(`Invalid BPM webhook endpoint registry: ${errors.join('; ')}`);
65
+ }
66
+ }
67
+ /**
68
+ * `false` when no source can ever answer, which is what a publish lint needs
69
+ * in order to refuse a template that references any endpoint at all.
70
+ */
71
+ hasEndpointSources() {
72
+ return this.sources.length > 0;
73
+ }
74
+ async listEndpoints(options = {}) {
75
+ const lists = await Promise.all(this.sources.map(async (source) => (await source.list()).map((endpoint) => ({
76
+ endpoint,
77
+ source: source.kind,
78
+ }))));
79
+ return lists
80
+ .flat()
81
+ .filter((entry, index, entries) =>
82
+ // Source order decides: an endpoint registered in code wins over a
83
+ // database row that claims the same key.
84
+ entries.findIndex((candidate) => (0, workflow_webhook_types_1.readWorkflowWebhookEndpointKey)(candidate.endpoint.descriptor) ===
85
+ (0, workflow_webhook_types_1.readWorkflowWebhookEndpointKey)(entry.endpoint.descriptor)) === index)
86
+ .filter((entry) => Boolean(options.includeDeprecated) ||
87
+ !entry.endpoint.descriptor.deprecated);
88
+ }
89
+ /**
90
+ * `manager` lets a caller already inside a transaction (the engine's
91
+ * enqueue) look endpoints up on its own connection, instead of waiting on
92
+ * a second one from a pool its peers may have exhausted.
93
+ */
94
+ async getEndpoint(key, version, manager) {
95
+ for (const source of this.sources) {
96
+ const endpoint = await source.get(key, version, manager);
97
+ if (endpoint) {
98
+ return { endpoint, source: source.kind };
99
+ }
100
+ }
101
+ return null;
102
+ }
103
+ readOptions() {
104
+ return this.options;
105
+ }
106
+ /**
107
+ * The publish-time allowlist check (ADR 18 §3.13 rule 3). Database
108
+ * endpoints only: calling host code while publishing would be a surprise,
109
+ * and registry URLs are checked before each delivery when enforcement is
110
+ * on. A URL that cannot be read here is left to the delivery path.
111
+ */
112
+ async isEndpointUrlAllowedAtPublish(entry) {
113
+ if (entry.source !== 'DATABASE') {
114
+ return true;
115
+ }
116
+ const url = await Promise.resolve()
117
+ .then(() => entry.endpoint.buildRequest(PUBLISH_CHECK_EVENT))
118
+ .then((request) => typeof request?.url === 'string' ? request.url : null, () => null);
119
+ return (url === null ||
120
+ (0, workflow_webhook_allowlist_1.isWorkflowWebhookUrlAllowed)(url, this.options.allowedUrlPatterns));
121
+ }
122
+ };
123
+ exports.WorkflowWebhookService = WorkflowWebhookService;
124
+ exports.WorkflowWebhookService = WorkflowWebhookService = tslib_1.__decorate([
125
+ (0, common_1.Injectable)(),
126
+ tslib_1.__param(0, (0, common_1.Optional)()),
127
+ tslib_1.__param(0, (0, common_1.Inject)(workflow_webhook_types_1.BPM_WORKFLOW_WEBHOOK_REGISTRY)),
128
+ tslib_1.__param(1, (0, common_1.Optional)()),
129
+ tslib_1.__param(1, (0, common_1.Inject)(workflow_webhook_options_1.BPM_WORKFLOW_WEBHOOK_OPTIONS)),
130
+ tslib_1.__param(2, (0, common_1.Optional)()),
131
+ tslib_1.__metadata("design:paramtypes", [Object, Object, workflow_webhook_database_source_1.DatabaseWorkflowWebhookEndpointSource])
132
+ ], WorkflowWebhookService);
133
+ /** Only used to read a database endpoint's URL; never sent anywhere. */
134
+ const PUBLISH_CHECK_EVENT = {
135
+ attempt: 0,
136
+ deliveryId: 'publish-check',
137
+ endpoint: { key: 'publish-check', version: 1 },
138
+ eventType: 'workflow.notify',
139
+ initiator: { memberId: 'publish-check' },
140
+ instance: {
141
+ id: 'publish-check',
142
+ templateId: 'publish-check',
143
+ templateVersionId: 'publish-check',
144
+ title: 'publish-check',
145
+ },
146
+ node: { id: 'publish-check', label: 'publish-check' },
147
+ occurredAt: new Date(0).toISOString(),
148
+ parameters: {},
149
+ };
150
+ const PARAMETER_TYPES = [
151
+ 'boolean',
152
+ 'json',
153
+ 'number',
154
+ 'string',
155
+ 'stringArray',
156
+ ];
157
+ function readRegistryDescriptorErrors(registry) {
158
+ if (!registry) {
159
+ return [];
160
+ }
161
+ const endpoints = registry.list();
162
+ const seen = new Set();
163
+ return endpoints.flatMap((endpoint, index) => {
164
+ const descriptor = endpoint?.descriptor;
165
+ // A host-code mistake should fail the boot with a sentence, not with
166
+ // "cannot read properties of undefined".
167
+ if (!descriptor || typeof descriptor !== 'object') {
168
+ return [`endpoint #${index} has no descriptor`];
169
+ }
170
+ if (typeof descriptor.key !== 'string' ||
171
+ typeof descriptor.label !== 'string') {
172
+ return [`endpoint #${index} must have a string key and label`];
173
+ }
174
+ const id = (0, workflow_webhook_types_1.readWorkflowWebhookEndpointKey)(descriptor);
175
+ const duplicate = seen.has(id);
176
+ seen.add(id);
177
+ if (!Array.isArray(descriptor.parameters)) {
178
+ return [`${id} must declare parameters as an array`];
179
+ }
180
+ // Compared trimmed, like the template-side structural lint, so " a" and
181
+ // "a" cannot both be declared and then collide in a binding.
182
+ const parameterKeys = descriptor.parameters.map((parameter) => typeof parameter?.key === 'string' ? parameter.key.trim() : '');
183
+ return [
184
+ ...(descriptor.key?.trim() ? [] : ['an endpoint has an empty key']),
185
+ ...(descriptor.key !== descriptor.key?.trim()
186
+ ? [`${id} key must not have surrounding whitespace`]
187
+ : []),
188
+ // The catalog exposes `version` as a GraphQL Int: one value past the
189
+ // int32 range fails the whole query, not just this endpoint.
190
+ ...(Number.isInteger(descriptor.version) &&
191
+ descriptor.version >= 1 &&
192
+ descriptor.version <= workflow_graph_1.NOTIFY_WEBHOOK_ENDPOINT_VERSION_MAX
193
+ ? []
194
+ : [
195
+ `${id} must have an integer version between 1 and ${workflow_graph_1.NOTIFY_WEBHOOK_ENDPOINT_VERSION_MAX}`,
196
+ ]),
197
+ ...(descriptor.label?.trim() ? [] : [`${id} must have a label`]),
198
+ ...(duplicate ? [`${id} is registered more than once`] : []),
199
+ ...(new Set(parameterKeys).size === parameterKeys.length
200
+ ? []
201
+ : [`${id} has duplicate parameter keys`]),
202
+ ...descriptor.parameters.flatMap((parameter, index) => [
203
+ ...(parameterKeys[index]
204
+ ? []
205
+ : [`${id} has a parameter with an empty key`]),
206
+ ...(typeof parameter?.key === 'string' &&
207
+ parameter.key !== parameter.key.trim()
208
+ ? [
209
+ `${id} parameter "${parameter.key}" must not have surrounding whitespace`,
210
+ ]
211
+ : []),
212
+ ...(PARAMETER_TYPES.includes(parameter?.type)
213
+ ? []
214
+ : [
215
+ `${id} parameter "${parameterKeys[index]}" has unsupported type "${String(parameter?.type)}"`,
216
+ ]),
217
+ ]),
218
+ ];
219
+ });
220
+ }
221
+ //# sourceMappingURL=workflow-webhook.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workflow-webhook.service.js","sourceRoot":"","sources":["../../../../../../libs/bpm-core/src/lib/workflow-webhook/workflow-webhook.service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,127 @@
1
+ import { InjectionToken } from '@nestjs/common';
2
+ import type { EntityManager } from 'typeorm';
3
+ import { NotifyWebhookParameterType } from '@rytass/bpm-core-shared/workflow';
4
+ /**
5
+ * Where an endpoint definition came from (ADR 18 §3.13).
6
+ *
7
+ * `REGISTRY` endpoints are registered by host code, so their URL has already
8
+ * been through code review. `DATABASE` endpoints are maintained by a BPM
9
+ * administrator and only exist once P6 ships; the catalog, the publish lint
10
+ * and the delivery path are written against this union from P1 so that phase
11
+ * adds a source rather than rewriting them.
12
+ */
13
+ export type BPMWorkflowWebhookEndpointSourceKind = 'DATABASE' | 'REGISTRY';
14
+ export interface BPMWorkflowWebhookParameter {
15
+ readonly description?: string;
16
+ readonly key: string;
17
+ readonly label: string;
18
+ readonly required: boolean;
19
+ readonly type: NotifyWebhookParameterType;
20
+ }
21
+ export interface BPMWorkflowWebhookEndpointDescriptor {
22
+ /**
23
+ * Hidden from the designer's endpoint picker, but still deliverable: a
24
+ * template that already references it keeps working.
25
+ */
26
+ readonly deprecated?: boolean;
27
+ readonly description?: string;
28
+ /**
29
+ * Switched off by an administrator (database endpoints, P6). Unlike
30
+ * `deprecated`, nothing is delivered any more: queued and new deliveries
31
+ * fail with `WEBHOOK_ENDPOINT_DISABLED`, and templates cannot publish it.
32
+ */
33
+ readonly disabled?: boolean;
34
+ readonly key: string;
35
+ readonly label: string;
36
+ readonly parameters: readonly BPMWorkflowWebhookParameter[];
37
+ readonly version: number;
38
+ }
39
+ /**
40
+ * One NOTIFY webhook event, as handed to the host's `buildRequest()` and, when
41
+ * the host supplies no body, serialized as the request body itself
42
+ * (ADR 18 §3.4).
43
+ */
44
+ export interface BPMWorkflowWebhookEvent {
45
+ /** Which attempt this is, from 1. Does not affect idempotency. */
46
+ readonly attempt: number;
47
+ /** Stable across retries; the receiver's idempotency key. */
48
+ readonly deliveryId: string;
49
+ readonly endpoint: {
50
+ readonly key: string;
51
+ readonly version: number;
52
+ };
53
+ readonly eventType: 'workflow.notify';
54
+ readonly initiator: {
55
+ readonly memberId: string;
56
+ };
57
+ readonly instance: {
58
+ readonly id: string;
59
+ readonly templateId: string;
60
+ readonly templateVersionId: string;
61
+ readonly title: string;
62
+ };
63
+ readonly node: {
64
+ readonly id: string;
65
+ readonly label: string;
66
+ };
67
+ /** When the node ran, not when this attempt is being sent. */
68
+ readonly occurredAt: string;
69
+ /** Only the parameters the template bound; never the whole form. */
70
+ readonly parameters: Readonly<Record<string, unknown>>;
71
+ }
72
+ export interface BPMWorkflowWebhookRequest {
73
+ /** Omitted: BPM sends the JSON-serialized event. */
74
+ readonly body?: string;
75
+ readonly headers?: Readonly<Record<string, string>>;
76
+ /** Omitted: POST. */
77
+ readonly method?: 'PATCH' | 'POST' | 'PUT';
78
+ /** Set to have BPM add the signature headers (ADR 18 §3.6). */
79
+ readonly signingSecret?: string;
80
+ readonly timeoutMs?: number;
81
+ readonly url: string;
82
+ }
83
+ export interface BPMWorkflowWebhookEndpoint {
84
+ readonly descriptor: BPMWorkflowWebhookEndpointDescriptor;
85
+ /**
86
+ * Called once per delivery attempt, never at enqueue time, so a rotated
87
+ * credential or a moved URL takes effect on deliveries that are already
88
+ * queued and on in-flight instances.
89
+ */
90
+ buildRequest(event: BPMWorkflowWebhookEvent): Promise<BPMWorkflowWebhookRequest>;
91
+ }
92
+ /**
93
+ * The host-facing catalog: a plain, synchronous lookup so a host can back it
94
+ * with a literal list. Asynchronous sources (the database one) implement
95
+ * {@link BPMWorkflowWebhookEndpointSource} instead.
96
+ */
97
+ export interface BPMWorkflowWebhookRegistry {
98
+ get(key: string, version: number): BPMWorkflowWebhookEndpoint | null;
99
+ list(): readonly BPMWorkflowWebhookEndpoint[];
100
+ }
101
+ export declare const BPM_WORKFLOW_WEBHOOK_REGISTRY: InjectionToken<BPMWorkflowWebhookRegistry>;
102
+ /** One endpoint plus the source it was resolved from. */
103
+ export interface BPMWorkflowWebhookEndpointEntry {
104
+ readonly endpoint: BPMWorkflowWebhookEndpoint;
105
+ readonly source: BPMWorkflowWebhookEndpointSourceKind;
106
+ }
107
+ /**
108
+ * Internal abstraction over "where endpoints come from". Asynchronous because
109
+ * the database source (P6) reads a table; the registry source resolves
110
+ * immediately.
111
+ */
112
+ export interface BPMWorkflowWebhookEndpointSource {
113
+ readonly kind: BPMWorkflowWebhookEndpointSourceKind;
114
+ get(key: string, version: number, manager?: EntityManager): Promise<BPMWorkflowWebhookEndpoint | null>;
115
+ list(): Promise<readonly BPMWorkflowWebhookEndpoint[]>;
116
+ }
117
+ export declare class EmptyBPMWorkflowWebhookRegistry implements BPMWorkflowWebhookRegistry {
118
+ get(key: string, version: number): BPMWorkflowWebhookEndpoint | null;
119
+ list(): readonly BPMWorkflowWebhookEndpoint[];
120
+ }
121
+ export declare class StaticBPMWorkflowWebhookRegistry implements BPMWorkflowWebhookRegistry {
122
+ private readonly endpoints;
123
+ constructor(endpoints: readonly BPMWorkflowWebhookEndpoint[]);
124
+ get(key: string, version: number): BPMWorkflowWebhookEndpoint | null;
125
+ list(): readonly BPMWorkflowWebhookEndpoint[];
126
+ }
127
+ export declare function readWorkflowWebhookEndpointKey(descriptor: BPMWorkflowWebhookEndpointDescriptor): string;
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.StaticBPMWorkflowWebhookRegistry = exports.EmptyBPMWorkflowWebhookRegistry = exports.BPM_WORKFLOW_WEBHOOK_REGISTRY = void 0;
4
+ exports.readWorkflowWebhookEndpointKey = readWorkflowWebhookEndpointKey;
5
+ exports.BPM_WORKFLOW_WEBHOOK_REGISTRY = Symbol('BPM_WORKFLOW_WEBHOOK_REGISTRY');
6
+ class EmptyBPMWorkflowWebhookRegistry {
7
+ get(key, version) {
8
+ void key;
9
+ void version;
10
+ return null;
11
+ }
12
+ list() {
13
+ return [];
14
+ }
15
+ }
16
+ exports.EmptyBPMWorkflowWebhookRegistry = EmptyBPMWorkflowWebhookRegistry;
17
+ class StaticBPMWorkflowWebhookRegistry {
18
+ constructor(endpoints) {
19
+ this.endpoints = [...endpoints];
20
+ }
21
+ get(key, version) {
22
+ return (this.endpoints.find((endpoint) => endpoint.descriptor.key === key &&
23
+ endpoint.descriptor.version === version) ?? null);
24
+ }
25
+ list() {
26
+ return this.endpoints;
27
+ }
28
+ }
29
+ exports.StaticBPMWorkflowWebhookRegistry = StaticBPMWorkflowWebhookRegistry;
30
+ function readWorkflowWebhookEndpointKey(descriptor) {
31
+ return `${descriptor.key}@${descriptor.version}`;
32
+ }
33
+ //# sourceMappingURL=workflow-webhook.types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workflow-webhook.types.js","sourceRoot":"","sources":["../../../../../../libs/bpm-core/src/lib/workflow-webhook/workflow-webhook.types.ts"],"names":[],"mappings":";;;AA2KA,wEAIC;AAhEY,QAAA,6BAA6B,GACxC,MAAM,CAAC,+BAA+B,CAAC,CAAC;AAwB1C,MAAa,+BAA+B;IAC1C,GAAG,CAAC,GAAW,EAAE,OAAe;QAC9B,KAAK,GAAG,CAAC;QACT,KAAK,OAAO,CAAC;QAEb,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI;QACF,OAAO,EAAE,CAAC;IACZ,CAAC;CACF;AAXD,0EAWC;AAED,MAAa,gCAAgC;IAG3C,YAAY,SAAgD;QAC1D,IAAI,CAAC,SAAS,GAAG,CAAC,GAAG,SAAS,CAAC,CAAC;IAClC,CAAC;IAED,GAAG,CAAC,GAAW,EAAE,OAAe;QAC9B,OAAO,CACL,IAAI,CAAC,SAAS,CAAC,IAAI,CACjB,CAAC,QAAQ,EAAE,EAAE,CACX,QAAQ,CAAC,UAAU,CAAC,GAAG,KAAK,GAAG;YAC/B,QAAQ,CAAC,UAAU,CAAC,OAAO,KAAK,OAAO,CAC1C,IAAI,IAAI,CACV,CAAC;IACJ,CAAC;IAED,IAAI;QACF,OAAO,IAAI,CAAC,SAAS,CAAC;IACxB,CAAC;CACF;AApBD,4EAoBC;AAED,SAAgB,8BAA8B,CAC5C,UAAgD;IAEhD,OAAO,GAAG,UAAU,CAAC,GAAG,IAAI,UAAU,CAAC,OAAO,EAAE,CAAC;AACnD,CAAC"}
@@ -0,0 +1,20 @@
1
+ import { FormDefinitionSchema } from '@rytass/bpm-core-shared/form';
2
+ import { WorkflowDefinition } from '@rytass/bpm-core-shared/workflow';
3
+ import { BPMWorkflowWebhookEndpointEntry } from './workflow-webhook.types';
4
+ export interface LintWorkflowWebhookTargetsInput {
5
+ readonly definition: WorkflowDefinition;
6
+ readonly formSchema: FormDefinitionSchema;
7
+ readonly hasEndpointSources: boolean;
8
+ readonly resolveEndpoint: (key: string, version: number) => Promise<BPMWorkflowWebhookEndpointEntry | null>;
9
+ /**
10
+ * Whether an endpoint's current URL is inside the allowlist (ADR 18 §3.13
11
+ * rule 3). Omitted: not checked at publish, only before each delivery.
12
+ */
13
+ readonly isEndpointUrlAllowed?: (entry: BPMWorkflowWebhookEndpointEntry) => Promise<boolean>;
14
+ }
15
+ /**
16
+ * The publish rules that need the endpoint catalog and the bound form
17
+ * (ADR 18 §4, items 2 and 5–8). The registry-independent shape rules run
18
+ * earlier, in the shared structural lint.
19
+ */
20
+ export declare function lintWorkflowWebhookTargets(input: LintWorkflowWebhookTargetsInput): Promise<readonly string[]>;
@@ -0,0 +1,97 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.lintWorkflowWebhookTargets = lintWorkflowWebhookTargets;
4
+ const workflow_graph_1 = require("@rytass/bpm-core-shared/workflow-graph");
5
+ const workflow_webhook_errors_1 = require("./workflow-webhook.errors");
6
+ /**
7
+ * The publish rules that need the endpoint catalog and the bound form
8
+ * (ADR 18 §4, items 2 and 5–8). The registry-independent shape rules run
9
+ * earlier, in the shared structural lint.
10
+ */
11
+ async function lintWorkflowWebhookTargets(input) {
12
+ const nodes = input.definition.nodes.filter((node) => node.type === 'serviceTask' &&
13
+ (0, workflow_graph_1.readNotifyWebhookTargets)(node.data.action).length > 0);
14
+ if (!nodes.length) {
15
+ return [];
16
+ }
17
+ if (!input.hasEndpointSources) {
18
+ return nodes.map((node) => `workflow.nodes.${node.id}.action.webhooks cannot be published: no webhook endpoint source is configured (${workflow_webhook_errors_1.BPM_WORKFLOW_WEBHOOK_ERROR_CODES.REGISTRY_MISSING})`);
19
+ }
20
+ const results = await Promise.all(nodes.flatMap((node) => {
21
+ const webhooks = node.data.action.type === 'NOTIFY' ? node.data.action.webhooks : [];
22
+ const issues = (0, workflow_graph_1.readNotifyWebhookStructureIssues)(webhooks);
23
+ // A list-level problem (not an array, over the limit) leaves no target
24
+ // worth resolving. Otherwise only the malformed targets are skipped:
25
+ // the shared structural lint already reports them, and reading parsed
26
+ // JSON nobody validated would throw instead of adding to that list.
27
+ if (issues.some((issue) => issue.targetIndex === null)) {
28
+ return [];
29
+ }
30
+ const malformedTargets = new Set(issues.map((issue) => issue.targetIndex));
31
+ return (0, workflow_graph_1.readNotifyWebhookTargets)(node.data.action).flatMap((target, targetIndex) => malformedTargets.has(targetIndex)
32
+ ? []
33
+ : [
34
+ lintTarget({
35
+ formSchema: input.formSchema,
36
+ isEndpointUrlAllowed: input.isEndpointUrlAllowed,
37
+ nodeId: node.id,
38
+ resolveEndpoint: input.resolveEndpoint,
39
+ target,
40
+ targetIndex,
41
+ }),
42
+ ]);
43
+ }));
44
+ return results.flat();
45
+ }
46
+ async function lintTarget({ formSchema, isEndpointUrlAllowed, nodeId, resolveEndpoint, target, targetIndex, }) {
47
+ const entry = await resolveEndpoint(target.endpoint.key, target.endpoint.version);
48
+ const path = `workflow.nodes.${nodeId}.action.webhooks[${targetIndex}]`;
49
+ const catalogIssues = (0, workflow_graph_1.readNotifyWebhookTargetCatalogIssues)({
50
+ endpoint: entry?.endpoint.descriptor ?? null,
51
+ formFields: formSchema.fields,
52
+ target,
53
+ }).map((issue) => readCatalogIssueMessage(issue, target, path));
54
+ // A saved endpoint whose URL a tightened allowlist no longer covers would
55
+ // fail every delivery; say so now rather than after the case runs.
56
+ const urlAllowed = !entry || catalogIssues.length || !isEndpointUrlAllowed
57
+ ? true
58
+ : await isEndpointUrlAllowed(entry);
59
+ return [
60
+ ...catalogIssues,
61
+ ...(urlAllowed
62
+ ? []
63
+ : [
64
+ `${path}.endpoint ${target.endpoint.key}@${target.endpoint.version} calls a URL outside workflowWebhookAllowedUrlPatterns (${workflow_webhook_errors_1.BPM_WORKFLOW_WEBHOOK_ERROR_CODES.URL_NOT_ALLOWED})`,
65
+ ]),
66
+ ];
67
+ }
68
+ /** The developer-facing, path-style wording of the shared catalog rules. */
69
+ function readCatalogIssueMessage(issue, target, path) {
70
+ const endpoint = `${target.endpoint.key}@${target.endpoint.version}`;
71
+ const bindingPath = `${path}.bindings[${issue.bindingIndex ?? 0}]`;
72
+ const parameter = issue.parameter ?? '';
73
+ const codes = workflow_webhook_errors_1.BPM_WORKFLOW_WEBHOOK_ERROR_CODES;
74
+ switch (issue.code) {
75
+ case 'ENDPOINT_MISSING':
76
+ return `${path}.endpoint ${endpoint} is not registered (${codes.ENDPOINT_MISSING})`;
77
+ case 'ENDPOINT_DEPRECATED':
78
+ return `${path}.endpoint ${endpoint} is deprecated (${codes.ENDPOINT_DEPRECATED})`;
79
+ case 'ENDPOINT_DISABLED':
80
+ return `${path}.endpoint ${endpoint} is disabled (${codes.ENDPOINT_DISABLED})`;
81
+ case 'PARAMETER_REQUIRED':
82
+ return `${path}.bindings is missing required parameter "${parameter}" (${codes.PARAMETER_REQUIRED})`;
83
+ case 'PARAMETER_UNKNOWN':
84
+ return `${bindingPath}.parameter "${parameter}" is not declared by the endpoint (${codes.PARAMETER_UNKNOWN})`;
85
+ case 'FIELD_MISSING':
86
+ return `${bindingPath}.from.fieldKey "${issue.fieldKey ?? ''}" does not match a schema field (${codes.BINDING_INCOMPATIBLE})`;
87
+ case 'FIELD_INCOMPATIBLE':
88
+ return `${bindingPath}.from.fieldKey "${issue.fieldKey ?? ''}" (${issue.fieldType ?? ''}) cannot fill parameter "${parameter}" (${issue.parameterType ?? ''}) (${codes.BINDING_INCOMPATIBLE})`;
89
+ case 'CONSTANT_REQUIRED_NULL':
90
+ return `${bindingPath}.from.value cannot be null for required parameter "${parameter}" (${codes.BINDING_INCOMPATIBLE})`;
91
+ case 'CONSTANT_INCOMPATIBLE':
92
+ return `${bindingPath}.from.value does not fit parameter "${parameter}" (${issue.parameterType ?? ''}) (${codes.BINDING_INCOMPATIBLE})`;
93
+ case 'CONTEXT_INCOMPATIBLE':
94
+ return `${bindingPath}.from.path is a string and cannot fill parameter "${parameter}" (${issue.parameterType ?? ''}) (${codes.BINDING_INCOMPATIBLE})`;
95
+ }
96
+ }
97
+ //# sourceMappingURL=workflow-webhook.validator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workflow-webhook.validator.js","sourceRoot":"","sources":["../../../../../../libs/bpm-core/src/lib/workflow-webhook/workflow-webhook.validator.ts"],"names":[],"mappings":"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"}