@rytass/bpm-core-shared 0.17.6 → 0.17.8

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/CHANGELOG.md CHANGED
@@ -1,3 +1,44 @@
1
+ ## 0.17.8 (2026-10-22)
2
+
3
+ ### 🩹 Fixes
4
+
5
+ - **bpm-core-react:** re-enable the instance header actions after a decision ([70e1a92](https://github.com/Rytass/BPMCore/commit/70e1a92))
6
+ - **bpm-core-react:** open the field overview on every field when nothing is set ([f90188d](https://github.com/Rytass/BPMCore/commit/f90188d))
7
+
8
+ ### ❤️ Thank You
9
+
10
+ - Chia Yu Pai @fantasywind
11
+
12
+ ## 0.17.7 (2026-10-22)
13
+
14
+ ### 🚀 Features
15
+
16
+ - **bpm-core-react:** add the field access overview to the template designer ([1de7665](https://github.com/Rytass/BPMCore/commit/1de7665))
17
+ - **shared:** add the field access matrix and its commands ([b0a9aa3](https://github.com/Rytass/BPMCore/commit/b0a9aa3))
18
+ - **bpm-core-react:** let the fill node's approver fill in fields on the case page ([9cd9eb2](https://github.com/Rytass/BPMCore/commit/9cd9eb2))
19
+ - **bpm-core:** flag tasks whose node lets the approver fill in fields ([57f1d61](https://github.com/Rytass/BPMCore/commit/57f1d61))
20
+ - **bpm-core-react:** resolve per-field access for the instance viewer ([7cd040c](https://github.com/Rytass/BPMCore/commit/7cd040c))
21
+ - **bpm-core:** adopt fieldAccess node model per ADR 20 ([b25cf71](https://github.com/Rytass/BPMCore/commit/b25cf71))
22
+ - **bpm-core-client:** send approver-filled data and keep it off launch and resubmit forms ([a33d7f9](https://github.com/Rytass/BPMCore/commit/a33d7f9))
23
+ - **bpm-core:** refuse conditions that read approver-filled fields too early ([5ad995f](https://github.com/Rytass/BPMCore/commit/5ad995f))
24
+ - **bpm-core:** refuse form rules that clash with approver-filled fields ([a55253e](https://github.com/Rytass/BPMCore/commit/a55253e))
25
+ - **bpm-core:** refuse to publish field permissions the engine cannot honour ([7361a9e](https://github.com/Rytass/BPMCore/commit/7361a9e))
26
+ - **bpm-core:** flag task notifications that need the form opened ([77fd492](https://github.com/Rytass/BPMCore/commit/77fd492))
27
+ - **bpm-core:** let the filling node write approver-filled fields on approval ([502500c](https://github.com/Rytass/BPMCore/commit/502500c))
28
+ - **shared:** add field permission helpers for approver-filled fields ([6386b1c](https://github.com/Rytass/BPMCore/commit/6386b1c))
29
+
30
+ ### 🩹 Fixes
31
+
32
+ - **shared:** read a SET_FORM_FIELD path the way the engine writes it ([3ba2962](https://github.com/Rytass/BPMCore/commit/3ba2962))
33
+ - **bpm-core-react:** send only the fill fields the approver changed ([1250eac](https://github.com/Rytass/BPMCore/commit/1250eac))
34
+ - **template:** stop rethrowing designer save and publish errors ([af93e67](https://github.com/Rytass/BPMCore/commit/af93e67))
35
+ - **bpm-core-client:** update launch mocks for the template version definition ([452d600](https://github.com/Rytass/BPMCore/commit/452d600))
36
+
37
+ ### ❤️ Thank You
38
+
39
+ - Chia Yu Pai @fantasywind
40
+ - Kai-Chieh Yang
41
+
1
42
  ## 0.17.6 (2026-10-20)
2
43
 
3
44
  This was a version bump only for shared to align it with other projects, there were no code changes.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rytass/bpm-core-shared",
3
- "version": "0.17.6",
3
+ "version": "0.17.8",
4
4
  "description": "Shared TypeScript contracts for the Rytass BPM approval workflow stack (workflow, form, condition, identity, organization, status types).",
5
5
  "keywords": [
6
6
  "bpm",
package/src/index.d.ts CHANGED
@@ -1,4 +1,7 @@
1
1
  export * from './lib/condition';
2
+ export * from './lib/field-access';
3
+ export * from './lib/field-access-lint';
4
+ export * from './lib/field-access-matrix';
2
5
  export * from './lib/form';
3
6
  export * from './lib/identity';
4
7
  export * from './lib/organization';
package/src/index.js CHANGED
@@ -2,6 +2,9 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const tslib_1 = require("tslib");
4
4
  tslib_1.__exportStar(require("./lib/condition"), exports);
5
+ tslib_1.__exportStar(require("./lib/field-access"), exports);
6
+ tslib_1.__exportStar(require("./lib/field-access-lint"), exports);
7
+ tslib_1.__exportStar(require("./lib/field-access-matrix"), exports);
5
8
  tslib_1.__exportStar(require("./lib/form"), exports);
6
9
  tslib_1.__exportStar(require("./lib/identity"), exports);
7
10
  tslib_1.__exportStar(require("./lib/organization"), exports);
package/src/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../libs/shared/src/index.ts"],"names":[],"mappings":";;;AAAA,0DAAgC;AAChC,qDAA2B;AAC3B,yDAA+B;AAC/B,6DAAmC;AACnC,uDAA6B;AAC7B,yDAA+B;AAC/B,+DAAqC;AACrC,iEAAuC;AACvC,iEAAuC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../libs/shared/src/index.ts"],"names":[],"mappings":";;;AAAA,0DAAgC;AAChC,6DAAmC;AACnC,kEAAwC;AACxC,oEAA0C;AAC1C,qDAA2B;AAC3B,yDAA+B;AAC/B,6DAAmC;AACnC,uDAA6B;AAC7B,yDAA+B;AAC/B,+DAAqC;AACrC,iEAAuC;AACvC,iEAAuC"}
@@ -0,0 +1,119 @@
1
+ import { FormDefinitionSchema, FormFieldDefinition } from './form';
2
+ import type { FieldAccessDisplay, FieldAccessEntry, FieldAccessFill, UserTaskNode, WorkflowDefinition, WorkflowEdge } from './workflow';
3
+ /**
4
+ * The field access rules (ADR 20 §4) as structured issues. The publish lint
5
+ * turns each into its `message` line, and the designer's field access matrix
6
+ * places it on the fields and nodes it names, so the two read one rule set.
7
+ * `lintApproverFilledFieldReads` (a condition reading a field before anybody
8
+ * filled it in) stays in the backend: it needs the expression sources of
9
+ * every node, which the matrix does not show.
10
+ */
11
+ export type FieldAccessIssueCode = 'applicantRuleReadsApproverFilled' | 'approverFilledFieldDataSource' | 'approverFilledFieldFileUpload' | 'approverFilledFieldFormRule' | 'approverFilledMultipleFillNodesOnPath' | 'approverFilledRequiredBoolean' | 'approverFilledTableDataSourceColumn' | 'fieldAccessAutoApprove' | 'fieldAccessDuplicate' | 'fieldAccessFillHidden' | 'fieldAccessGroupPolicy' | 'fieldAccessInvalid' | 'fieldAccessSkipNode' | 'fieldAccessUnknownField' | 'legacyFieldPermissions' | 'setFormFieldApproverFilled';
12
+ export interface FieldAccessIssue {
13
+ readonly code: FieldAccessIssueCode;
14
+ /** The top-level fields the issue is about, the offending one first. */
15
+ readonly fieldKeys: readonly string[];
16
+ /** The publish-lint line, from `WORKFLOW_LINT_MESSAGES`. */
17
+ readonly message: string;
18
+ /** The nodes the issue is about, in definition order where there are two. */
19
+ readonly nodeIds: readonly string[];
20
+ }
21
+ /**
22
+ * Why a user task node cannot let its approver fill fields in: a decision
23
+ * shared by several approvers (`PARALLEL_ALL` / `QUORUM`) has no single
24
+ * filler, and a node that can approve or skip itself would pass without
25
+ * anybody filling anything in.
26
+ */
27
+ export type UserTaskFillConflict = 'autoApprove' | 'groupPolicy' | 'skipNode';
28
+ export declare function readUserTaskFillConflicts(node: UserTaskNode): readonly UserTaskFillConflict[];
29
+ export declare const FIELD_ACCESS_DISPLAYS: readonly FieldAccessDisplay[];
30
+ export declare const FIELD_ACCESS_FILLS: readonly FieldAccessFill[];
31
+ /**
32
+ * Whether a stored entry is one the publish lint accepts. Stricter than
33
+ * `readNodeFieldAccess`, which the engine reads with: a blank `fieldKey`
34
+ * passes there and fails here, so writers check with this one.
35
+ */
36
+ export declare function isFieldAccessEntryValid(entry: unknown): entry is FieldAccessEntry;
37
+ /**
38
+ * One user task node's issues, in publish-lint order: the deprecated
39
+ * `fieldPermissions` key first, then its `fieldAccess`.
40
+ *
41
+ * `fieldPermissions` was reserved and never enforced, so whatever a draft
42
+ * holds there means nothing. Rather than read it as `fieldAccess` (which would
43
+ * suddenly enforce a shape nobody tested) or drop it silently, a draft that
44
+ * still carries the key cannot be published until it is removed.
45
+ *
46
+ * The shape and duplicate checks read the raw `fieldAccess`:
47
+ * `readNodeFieldAccess` tolerates a bad draft by skipping malformed entries
48
+ * and keeping the first entry per `fieldKey`, which is exactly what these two
49
+ * checks have to see. Once the shape is reported, the node's other field
50
+ * access rules are skipped, since they would read a list the engine is not
51
+ * going to honour anyway. Whether each `fieldKey` names a top-level field of
52
+ * the form is checked against the form (`readFormFieldAccessIssues`).
53
+ */
54
+ export declare function readNodeFieldAccessIssues(node: UserTaskNode): readonly FieldAccessIssue[];
55
+ /**
56
+ * The nodes reachable from `startNodeIds` along `edges` without entering one
57
+ * of `blockedNodeIds`, the start nodes included unless blocked. Walks the
58
+ * graph one frontier at a time and drops every node it has already seen, so a
59
+ * cycle ends the walk instead of feeding it.
60
+ */
61
+ export declare function readReachableWorkflowNodeIds(edges: readonly WorkflowEdge[], startNodeIds: readonly string[], blockedNodeIds?: ReadonlySet<string>): ReadonlySet<string>;
62
+ /**
63
+ * Whether two nodes can both run in one case: one reaches the other, or a
64
+ * parallel split sends each down a branch of its own (reachable from one
65
+ * outgoing edge of the split but not from another, and the other way round).
66
+ * Nodes on mutually exclusive branches never both run, and neither do two
67
+ * nodes that both lie after the join, which every branch reaches alike. The
68
+ * graph may hold a cycle, which the reachability walk copes with.
69
+ */
70
+ export declare function createWorkflowCoRunReader(definition: WorkflowDefinition): (nodeId: string, otherNodeId: string) => boolean;
71
+ /**
72
+ * The issues read from the whole definition, in publish-lint order: a system
73
+ * node writing an approver-filled field, then two fill nodes of one field
74
+ * that can both run in one case.
75
+ *
76
+ * A field an approver fills in is empty until then, and the approver's value
77
+ * is the one the case keeps. A system node writing it would either be
78
+ * overwritten or overwrite the approver, so the two are kept apart.
79
+ *
80
+ * One field, one filler per run: when two nodes that fill the same field in
81
+ * can both run in one case (`createWorkflowCoRunReader`), the later one
82
+ * overwrites the earlier and the signed value no longer tells who answered.
83
+ * Fill nodes on mutually exclusive branches (one per region, say) stay
84
+ * allowed. Reported once per field and pair, in node order.
85
+ */
86
+ export declare function readDefinitionFieldAccessIssues(definition: WorkflowDefinition): readonly FieldAccessIssue[];
87
+ /**
88
+ * Why a form field cannot be one an approver fills in, as the issues the
89
+ * publish lint reports once it is: a form-level rule (`required` / `hidden`
90
+ * set to `true`, the others set at all — `required: false` and
91
+ * `hidden: false`, what the form editor writes for "off", are not rules), a
92
+ * data source, a file upload, or a table with a data-source column. Empty
93
+ * when the field can be filled in.
94
+ */
95
+ export declare function readFormFieldFillIssues(field: FormFieldDefinition): readonly FieldAccessIssue[];
96
+ /**
97
+ * True when a CEL expression reads the top-level form field `fieldKey` —
98
+ * `form.x`, `formData.x`, `form["x"]`, or any of those with `form . x` spacing
99
+ * or a deeper step after it (`form.x.y`, `form.x[0]`). `has(form.x)` counts.
100
+ *
101
+ * The root has to be a bare `form` / `formData`: `myform.x` and `a.form.x` are
102
+ * somebody else's `x`. The key has to end there: `form.xy` is another field.
103
+ * `form` and `formData` are the two allowed root identifiers that carry the
104
+ * form data (`WORKFLOW_EXPRESSION_ROOT_IDENTIFIERS`). A string literal that
105
+ * merely spells `form.x` counts too: a false hit only makes the publish lint
106
+ * stricter.
107
+ */
108
+ export declare function referencesFormField(expression: string, fieldKey: string): boolean;
109
+ /**
110
+ * The issues read against the form the definition is bound to, in
111
+ * publish-lint order: a `fieldKey` that is not a top-level field of the form,
112
+ * an approver-filled field the form will not let anybody fill in
113
+ * (`readFormFieldFillIssues`, once per field however many nodes fill it in),
114
+ * `fill: 'REQUIRED'` on a boolean (`false` is an answer, so required can never
115
+ * fail), and an applicant's rule that reads an approver-filled field — the
116
+ * rule is evaluated against the submitted form, where that field is still
117
+ * empty, and the evaluation silently compares against nothing.
118
+ */
119
+ export declare function readFormFieldAccessIssues(definition: WorkflowDefinition, schema: FormDefinitionSchema | null): readonly FieldAccessIssue[];
@@ -0,0 +1,379 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FIELD_ACCESS_FILLS = exports.FIELD_ACCESS_DISPLAYS = void 0;
4
+ exports.readUserTaskFillConflicts = readUserTaskFillConflicts;
5
+ exports.isFieldAccessEntryValid = isFieldAccessEntryValid;
6
+ exports.readNodeFieldAccessIssues = readNodeFieldAccessIssues;
7
+ exports.readReachableWorkflowNodeIds = readReachableWorkflowNodeIds;
8
+ exports.createWorkflowCoRunReader = createWorkflowCoRunReader;
9
+ exports.readDefinitionFieldAccessIssues = readDefinitionFieldAccessIssues;
10
+ exports.readFormFieldFillIssues = readFormFieldFillIssues;
11
+ exports.referencesFormField = referencesFormField;
12
+ exports.readFormFieldAccessIssues = readFormFieldAccessIssues;
13
+ const form_1 = require("./form");
14
+ const field_access_1 = require("./field-access");
15
+ const workflow_graph_1 = require("./workflow-graph");
16
+ function readUserTaskFillConflicts(node) {
17
+ var _a, _b, _c, _d;
18
+ return [
19
+ ...(((_a = node.data.decisionPolicy) === null || _a === void 0 ? void 0 : _a.type) === 'PARALLEL_ALL' ||
20
+ ((_b = node.data.decisionPolicy) === null || _b === void 0 ? void 0 : _b.type) === 'QUORUM'
21
+ ? ['groupPolicy']
22
+ : []),
23
+ ...(((_c = node.data.sla) === null || _c === void 0 ? void 0 : _c.onTimeout) === 'AUTO_APPROVE'
24
+ ? ['autoApprove']
25
+ : []),
26
+ ...(((_d = node.data.excludeInitiator) === null || _d === void 0 ? void 0 : _d.whenEmpty) === 'SKIP_NODE'
27
+ ? ['skipNode']
28
+ : []),
29
+ ];
30
+ }
31
+ const FILL_CONFLICT_ISSUES = {
32
+ autoApprove: {
33
+ code: 'fieldAccessAutoApprove',
34
+ message: workflow_graph_1.WORKFLOW_LINT_MESSAGES.fieldAccessAutoApprove,
35
+ },
36
+ groupPolicy: {
37
+ code: 'fieldAccessGroupPolicy',
38
+ message: workflow_graph_1.WORKFLOW_LINT_MESSAGES.fieldAccessGroupPolicy,
39
+ },
40
+ skipNode: {
41
+ code: 'fieldAccessSkipNode',
42
+ message: workflow_graph_1.WORKFLOW_LINT_MESSAGES.fieldAccessSkipNode,
43
+ },
44
+ };
45
+ function isPlainRecord(value) {
46
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
47
+ }
48
+ exports.FIELD_ACCESS_DISPLAYS = [
49
+ 'SHOW',
50
+ 'HIDE',
51
+ ];
52
+ exports.FIELD_ACCESS_FILLS = [
53
+ 'NONE',
54
+ 'OPTIONAL',
55
+ 'REQUIRED',
56
+ ];
57
+ /**
58
+ * Whether a stored entry is one the publish lint accepts. Stricter than
59
+ * `readNodeFieldAccess`, which the engine reads with: a blank `fieldKey`
60
+ * passes there and fails here, so writers check with this one.
61
+ */
62
+ function isFieldAccessEntryValid(entry) {
63
+ return (isPlainRecord(entry) &&
64
+ typeof entry['fieldKey'] === 'string' &&
65
+ entry['fieldKey'].trim() !== '' &&
66
+ exports.FIELD_ACCESS_DISPLAYS.some((display) => display === entry['display']) &&
67
+ exports.FIELD_ACCESS_FILLS.some((fill) => fill === entry['fill']));
68
+ }
69
+ /**
70
+ * One user task node's issues, in publish-lint order: the deprecated
71
+ * `fieldPermissions` key first, then its `fieldAccess`.
72
+ *
73
+ * `fieldPermissions` was reserved and never enforced, so whatever a draft
74
+ * holds there means nothing. Rather than read it as `fieldAccess` (which would
75
+ * suddenly enforce a shape nobody tested) or drop it silently, a draft that
76
+ * still carries the key cannot be published until it is removed.
77
+ *
78
+ * The shape and duplicate checks read the raw `fieldAccess`:
79
+ * `readNodeFieldAccess` tolerates a bad draft by skipping malformed entries
80
+ * and keeping the first entry per `fieldKey`, which is exactly what these two
81
+ * checks have to see. Once the shape is reported, the node's other field
82
+ * access rules are skipped, since they would read a list the engine is not
83
+ * going to honour anyway. Whether each `fieldKey` names a top-level field of
84
+ * the form is checked against the form (`readFormFieldAccessIssues`).
85
+ */
86
+ function readNodeFieldAccessIssues(node) {
87
+ const nodeId = node.id;
88
+ const legacy = node.data.fieldPermissions;
89
+ const legacyIssues = legacy === undefined
90
+ ? []
91
+ : [
92
+ {
93
+ code: 'legacyFieldPermissions',
94
+ fieldKeys: [],
95
+ message: workflow_graph_1.WORKFLOW_LINT_MESSAGES.legacyFieldPermissions(nodeId),
96
+ nodeIds: [nodeId],
97
+ },
98
+ ];
99
+ const raw = node.data.fieldAccess;
100
+ if (raw === undefined) {
101
+ return legacyIssues;
102
+ }
103
+ const entries = Array.isArray(raw)
104
+ ? raw
105
+ : undefined;
106
+ if (entries === undefined || !entries.every(isFieldAccessEntryValid)) {
107
+ return [
108
+ ...legacyIssues,
109
+ {
110
+ code: 'fieldAccessInvalid',
111
+ fieldKeys: [],
112
+ message: workflow_graph_1.WORKFLOW_LINT_MESSAGES.fieldAccessInvalid(nodeId),
113
+ nodeIds: [nodeId],
114
+ },
115
+ ];
116
+ }
117
+ const fieldKeys = entries.map((entry) => entry.fieldKey);
118
+ const hasFillableField = (0, field_access_1.readNodeFillableFieldKeys)(node).size > 0;
119
+ return [
120
+ ...legacyIssues,
121
+ ...fieldKeys
122
+ .filter((fieldKey, index) => fieldKeys.indexOf(fieldKey) !== index)
123
+ .filter((fieldKey, index, repeated) => repeated.indexOf(fieldKey) === index)
124
+ .map((fieldKey) => ({
125
+ code: 'fieldAccessDuplicate',
126
+ fieldKeys: [fieldKey],
127
+ message: workflow_graph_1.WORKFLOW_LINT_MESSAGES.fieldAccessDuplicate(nodeId, fieldKey),
128
+ nodeIds: [nodeId],
129
+ })),
130
+ ...(0, field_access_1.readNodeFieldAccess)(node)
131
+ .filter((entry) => entry.fill !== 'NONE' && entry.display === 'HIDE')
132
+ .map((entry) => ({
133
+ code: 'fieldAccessFillHidden',
134
+ fieldKeys: [entry.fieldKey],
135
+ message: workflow_graph_1.WORKFLOW_LINT_MESSAGES.fieldAccessFillHidden(nodeId, entry.fieldKey),
136
+ nodeIds: [nodeId],
137
+ })),
138
+ ...(hasFillableField ? readUserTaskFillConflicts(node) : []).map((conflict) => ({
139
+ code: FILL_CONFLICT_ISSUES[conflict].code,
140
+ fieldKeys: [],
141
+ message: FILL_CONFLICT_ISSUES[conflict].message(nodeId),
142
+ nodeIds: [nodeId],
143
+ })),
144
+ ];
145
+ }
146
+ /**
147
+ * The nodes reachable from `startNodeIds` along `edges` without entering one
148
+ * of `blockedNodeIds`, the start nodes included unless blocked. Walks the
149
+ * graph one frontier at a time and drops every node it has already seen, so a
150
+ * cycle ends the walk instead of feeding it.
151
+ */
152
+ function readReachableWorkflowNodeIds(edges, startNodeIds, blockedNodeIds = new Set()) {
153
+ const walk = (frontier, visited) => {
154
+ const fresh = [...new Set(frontier)].filter((nodeId) => !visited.has(nodeId) && !blockedNodeIds.has(nodeId));
155
+ return fresh.length
156
+ ? walk(edges
157
+ .filter((edge) => fresh.includes(edge.source))
158
+ .map((edge) => edge.target), new Set([...visited, ...fresh]))
159
+ : visited;
160
+ };
161
+ return walk(startNodeIds, new Set());
162
+ }
163
+ /**
164
+ * Whether two nodes can both run in one case: one reaches the other, or a
165
+ * parallel split sends each down a branch of its own (reachable from one
166
+ * outgoing edge of the split but not from another, and the other way round).
167
+ * Nodes on mutually exclusive branches never both run, and neither do two
168
+ * nodes that both lie after the join, which every branch reaches alike. The
169
+ * graph may hold a cycle, which the reachability walk copes with.
170
+ */
171
+ function createWorkflowCoRunReader(definition) {
172
+ const reachableCache = new Map();
173
+ const readReachable = (nodeId) => {
174
+ const cached = reachableCache.get(nodeId);
175
+ if (cached !== undefined) {
176
+ return cached;
177
+ }
178
+ const reachable = readReachableWorkflowNodeIds(definition.edges, [nodeId]);
179
+ reachableCache.set(nodeId, reachable);
180
+ return reachable;
181
+ };
182
+ const parallelBranches = definition.nodes
183
+ .filter((node) => node.type === 'parallelGateway')
184
+ .map((node) => definition.edges
185
+ .filter((edge) => edge.source === node.id)
186
+ .map((edge) => readReachable(edge.target)))
187
+ .filter((branches) => branches.length >= 2);
188
+ const isOnOwnBranch = (branches, nodeId, otherNodeId) => branches.some((branch, index) => branch.has(nodeId) &&
189
+ !branch.has(otherNodeId) &&
190
+ branches.some((other, otherIndex) => otherIndex !== index &&
191
+ other.has(otherNodeId) &&
192
+ !other.has(nodeId)));
193
+ return (nodeId, otherNodeId) => readReachable(nodeId).has(otherNodeId) ||
194
+ readReachable(otherNodeId).has(nodeId) ||
195
+ parallelBranches.some((branches) => isOnOwnBranch(branches, nodeId, otherNodeId));
196
+ }
197
+ /**
198
+ * The issues read from the whole definition, in publish-lint order: a system
199
+ * node writing an approver-filled field, then two fill nodes of one field
200
+ * that can both run in one case.
201
+ *
202
+ * A field an approver fills in is empty until then, and the approver's value
203
+ * is the one the case keeps. A system node writing it would either be
204
+ * overwritten or overwrite the approver, so the two are kept apart.
205
+ *
206
+ * One field, one filler per run: when two nodes that fill the same field in
207
+ * can both run in one case (`createWorkflowCoRunReader`), the later one
208
+ * overwrites the earlier and the signed value no longer tells who answered.
209
+ * Fill nodes on mutually exclusive branches (one per region, say) stay
210
+ * allowed. Reported once per field and pair, in node order.
211
+ */
212
+ function readDefinitionFieldAccessIssues(definition) {
213
+ const approverFilled = (0, field_access_1.readApproverFilledFieldKeys)(definition);
214
+ const writeIssues = definition.nodes
215
+ .filter((node) => node.type === 'serviceTask')
216
+ .flatMap((node) => {
217
+ const action = node.data.action;
218
+ const fieldPath = isPlainRecord(action) ? action['fieldPath'] : undefined;
219
+ const fieldKey = isPlainRecord(action) &&
220
+ action['type'] === 'SET_FORM_FIELD' &&
221
+ typeof fieldPath === 'string'
222
+ ? (0, field_access_1.readFormFieldPathTopLevelKey)(fieldPath)
223
+ : undefined;
224
+ return fieldKey !== undefined && approverFilled.has(fieldKey)
225
+ ? [
226
+ {
227
+ code: 'setFormFieldApproverFilled',
228
+ fieldKeys: [fieldKey],
229
+ message: workflow_graph_1.WORKFLOW_LINT_MESSAGES.setFormFieldApproverFilled(node.id, fieldKey),
230
+ nodeIds: [node.id],
231
+ },
232
+ ]
233
+ : [];
234
+ });
235
+ const userTasks = definition.nodes.filter((node) => node.type === 'userTask');
236
+ const canBothRun = createWorkflowCoRunReader(definition);
237
+ const pathIssues = [...approverFilled].flatMap((fieldKey) => {
238
+ const fillNodeIds = [
239
+ ...new Set(userTasks
240
+ .filter((node) => (0, field_access_1.readNodeFillableFieldKeys)(node).has(fieldKey))
241
+ .map((node) => node.id)),
242
+ ];
243
+ return fillNodeIds.flatMap((nodeId, index) => fillNodeIds
244
+ .slice(index + 1)
245
+ .filter((otherNodeId) => canBothRun(nodeId, otherNodeId))
246
+ .map((otherNodeId) => ({
247
+ code: 'approverFilledMultipleFillNodesOnPath',
248
+ fieldKeys: [fieldKey],
249
+ message: workflow_graph_1.WORKFLOW_LINT_MESSAGES.approverFilledMultipleFillNodesOnPath(fieldKey, nodeId, otherNodeId),
250
+ nodeIds: [nodeId, otherNodeId],
251
+ })));
252
+ });
253
+ return [...writeIssues, ...pathIssues];
254
+ }
255
+ /**
256
+ * Why a form field cannot be one an approver fills in, as the issues the
257
+ * publish lint reports once it is: a form-level rule (`required` / `hidden`
258
+ * set to `true`, the others set at all — `required: false` and
259
+ * `hidden: false`, what the form editor writes for "off", are not rules), a
260
+ * data source, a file upload, or a table with a data-source column. Empty
261
+ * when the field can be filled in.
262
+ */
263
+ function readFormFieldFillIssues(field) {
264
+ const { fieldKey } = field;
265
+ const issue = (code, message) => ({
266
+ code,
267
+ fieldKeys: [fieldKey],
268
+ message,
269
+ nodeIds: [],
270
+ });
271
+ return [
272
+ ...workflow_graph_1.APPROVER_FILLED_FORM_RULES.filter((rule) => rule === 'required' || rule === 'hidden'
273
+ ? field[rule] === true
274
+ : field[rule] !== undefined).map((rule) => issue('approverFilledFieldFormRule', workflow_graph_1.WORKFLOW_LINT_MESSAGES.approverFilledFieldFormRule(fieldKey, rule))),
275
+ ...((0, form_1.isFormDataSourceFieldDefinition)(field)
276
+ ? [
277
+ issue('approverFilledFieldDataSource', workflow_graph_1.WORKFLOW_LINT_MESSAGES.approverFilledFieldDataSource(fieldKey)),
278
+ ]
279
+ : []),
280
+ ...(field.type === 'file_upload'
281
+ ? [
282
+ issue('approverFilledFieldFileUpload', workflow_graph_1.WORKFLOW_LINT_MESSAGES.approverFilledFieldFileUpload(fieldKey)),
283
+ ]
284
+ : []),
285
+ ...((0, form_1.isTableFieldDefinition)(field) &&
286
+ field.columns.some(form_1.isFormDataSourceFieldDefinition)
287
+ ? [
288
+ issue('approverFilledTableDataSourceColumn', workflow_graph_1.WORKFLOW_LINT_MESSAGES.approverFilledTableDataSourceColumn(fieldKey)),
289
+ ]
290
+ : []),
291
+ ];
292
+ }
293
+ /**
294
+ * True when a CEL expression reads the top-level form field `fieldKey` —
295
+ * `form.x`, `formData.x`, `form["x"]`, or any of those with `form . x` spacing
296
+ * or a deeper step after it (`form.x.y`, `form.x[0]`). `has(form.x)` counts.
297
+ *
298
+ * The root has to be a bare `form` / `formData`: `myform.x` and `a.form.x` are
299
+ * somebody else's `x`. The key has to end there: `form.xy` is another field.
300
+ * `form` and `formData` are the two allowed root identifiers that carry the
301
+ * form data (`WORKFLOW_EXPRESSION_ROOT_IDENTIFIERS`). A string literal that
302
+ * merely spells `form.x` counts too: a false hit only makes the publish lint
303
+ * stricter.
304
+ */
305
+ function referencesFormField(expression, fieldKey) {
306
+ const escapedKey = fieldKey.replace(/[.*+?^${}()|[\]\\]/gu, '\\$&');
307
+ // Not preceded by an identifier character or a dot, so `myform` and
308
+ // `a.form` do not pass for the root.
309
+ const root = '(?<![\\p{L}\\p{N}_.])(?:formData|form)\\s*';
310
+ return [
311
+ new RegExp(`${root}\\.\\s*${escapedKey}(?![\\p{L}\\p{N}_])`, 'u'),
312
+ new RegExp(`${root}\\[\\s*["']${escapedKey}["']\\s*\\]`, 'u'),
313
+ ].some((pattern) => pattern.test(expression));
314
+ }
315
+ /**
316
+ * The issues read against the form the definition is bound to, in
317
+ * publish-lint order: a `fieldKey` that is not a top-level field of the form,
318
+ * an approver-filled field the form will not let anybody fill in
319
+ * (`readFormFieldFillIssues`, once per field however many nodes fill it in),
320
+ * `fill: 'REQUIRED'` on a boolean (`false` is an answer, so required can never
321
+ * fail), and an applicant's rule that reads an approver-filled field — the
322
+ * rule is evaluated against the submitted form, where that field is still
323
+ * empty, and the evaluation silently compares against nothing.
324
+ */
325
+ function readFormFieldAccessIssues(definition, schema) {
326
+ var _a, _b;
327
+ const fieldsByKey = new Map(((_a = schema === null || schema === void 0 ? void 0 : schema.fields) !== null && _a !== void 0 ? _a : []).map((field) => [
328
+ field.fieldKey,
329
+ field,
330
+ ]));
331
+ const userTasks = definition.nodes.filter((node) => node.type === 'userTask');
332
+ const unknownFieldIssues = userTasks.flatMap((node) => (0, field_access_1.readNodeFieldAccess)(node)
333
+ .filter(({ fieldKey }) => !fieldsByKey.has(fieldKey))
334
+ .map(({ fieldKey }) => ({
335
+ code: 'fieldAccessUnknownField',
336
+ fieldKeys: [fieldKey],
337
+ message: workflow_graph_1.WORKFLOW_LINT_MESSAGES.fieldAccessUnknownField(node.id, fieldKey),
338
+ nodeIds: [node.id],
339
+ })));
340
+ const requiredBooleanIssues = userTasks.flatMap((node) => (0, field_access_1.readNodeFieldAccess)(node)
341
+ .filter(({ fieldKey, fill }) => {
342
+ var _a;
343
+ return fill === 'REQUIRED' &&
344
+ ((_a = fieldsByKey.get(fieldKey)) === null || _a === void 0 ? void 0 : _a.type) === 'boolean';
345
+ })
346
+ .map(({ fieldKey }) => ({
347
+ code: 'approverFilledRequiredBoolean',
348
+ fieldKeys: [fieldKey],
349
+ message: workflow_graph_1.WORKFLOW_LINT_MESSAGES.approverFilledRequiredBoolean(node.id, fieldKey),
350
+ nodeIds: [node.id],
351
+ })));
352
+ const approverFilled = (0, field_access_1.readApproverFilledFieldKeys)(definition);
353
+ const applicantRuleIssues = ((_b = schema === null || schema === void 0 ? void 0 : schema.fields) !== null && _b !== void 0 ? _b : [])
354
+ .filter((field) => !approverFilled.has(field.fieldKey))
355
+ .flatMap((field) => workflow_graph_1.APPLICANT_FIELD_CONDITION_RULES.flatMap((rule) => {
356
+ const expression = field[rule];
357
+ return typeof expression === 'string'
358
+ ? [...approverFilled]
359
+ .filter((fieldKey) => referencesFormField(expression, fieldKey))
360
+ .map((fieldKey) => ({
361
+ code: 'applicantRuleReadsApproverFilled',
362
+ fieldKeys: [field.fieldKey, fieldKey],
363
+ message: workflow_graph_1.WORKFLOW_LINT_MESSAGES.applicantRuleReadsApproverFilled(field.fieldKey, rule, fieldKey),
364
+ nodeIds: [],
365
+ }))
366
+ : [];
367
+ }));
368
+ const fieldIssues = [...approverFilled].flatMap((fieldKey) => {
369
+ const field = fieldsByKey.get(fieldKey);
370
+ return field === undefined ? [] : readFormFieldFillIssues(field);
371
+ });
372
+ return [
373
+ ...unknownFieldIssues,
374
+ ...fieldIssues,
375
+ ...requiredBooleanIssues,
376
+ ...applicantRuleIssues,
377
+ ];
378
+ }
379
+ //# sourceMappingURL=field-access-lint.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"field-access-lint.js","sourceRoot":"","sources":["../../../../../libs/shared/src/lib/field-access-lint.ts"],"names":[],"mappings":"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"}