bank20baht-validator 0.0.4 → 0.0.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 (2) hide show
  1. package/dist/index.js +30 -1
  2. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -7,7 +7,7 @@
7
7
  // request that bypasses the frontend hits the exact same rules — no codegen,
8
8
  // no recompile: swap the stored JSON and validation follows.
9
9
  // ---------------------------------------------------------------------------
10
- import { applyFlags, approvalFields, defaultValue, evaluate, resolveViewFields, setLocale, t, validateField, } from 'bank20baht-ui/engine';
10
+ import { applyFlags, approvalFields, defaultValue, evaluate, resolveViewFields, setLocale, t, validateField, walkPath, } from 'bank20baht-ui/engine';
11
11
  export function isWorkflowDefinition(schema) {
12
12
  return (isRecord(schema) &&
13
13
  typeof schema['workflowId'] === 'string' &&
@@ -73,10 +73,23 @@ export function validateWorkflowData(workflow, input, registry) {
73
73
  }
74
74
  const derived = evaluate(workflow, input);
75
75
  const issues = [...derived.errors];
76
+ // graph mode (spec 03 §6): only the forms on the path this data takes
77
+ // validate; off-path branches are as good as skipped, their data dropped
78
+ const path = workflow.transitions && workflow.transitions.length > 0
79
+ ? new Set(walkPath(workflow, derived.data))
80
+ : null;
81
+ if (path) {
82
+ for (const name of Object.keys(derived.data)) {
83
+ if (!path.has(name))
84
+ delete derived.data[name];
85
+ }
86
+ }
76
87
  const forms = [...workflow.forms].sort((a, b) => a.order - b.order);
77
88
  for (const form of forms) {
78
89
  if (derived.forms[form.formName]?.visible === false)
79
90
  continue;
91
+ if (path && !path.has(form.formName))
92
+ continue;
80
93
  if (form.kind === 'approval') {
81
94
  issues.push(...approvalIssues(form, derived.data));
82
95
  continue;
@@ -158,6 +171,22 @@ export function parseSchema(json) {
158
171
  if (new Set(names).size !== names.length) {
159
172
  throw new Error('formName must be unique in a workflow');
160
173
  }
174
+ if (parsed.transitions !== undefined) {
175
+ if (!Array.isArray(parsed.transitions))
176
+ throw new Error('transitions must be an array');
177
+ const nameSet = new Set(names);
178
+ for (const tr of parsed.transitions) {
179
+ if (!isRecord(tr) || typeof tr.from !== 'string' || typeof tr.to !== 'string') {
180
+ throw new Error('invalid transition: expected { from, to }');
181
+ }
182
+ if (!nameSet.has(tr.from)) {
183
+ throw new Error(`transition from unknown form ${JSON.stringify(tr.from)}`);
184
+ }
185
+ if (tr.to !== 'end' && !nameSet.has(tr.to)) {
186
+ throw new Error(`transition to unknown form ${JSON.stringify(tr.to)}`);
187
+ }
188
+ }
189
+ }
161
190
  return parsed;
162
191
  }
163
192
  if (isFormDefinition(parsed)) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bank20baht-validator",
3
- "version": "0.0.4",
3
+ "version": "0.0.5",
4
4
  "type": "module",
5
5
  "description": "Runtime validation for bahtui form/workflow JSON — the exact engine rules the client runs, on the server.",
6
6
  "license": "MIT",
@@ -39,7 +39,7 @@
39
39
  "test:watch": "vitest"
40
40
  },
41
41
  "dependencies": {
42
- "bank20baht-ui": "^0.0.10"
42
+ "bank20baht-ui": "^0.0.11"
43
43
  },
44
44
  "devDependencies": {
45
45
  "typescript": "^5.8.3",