jsfe 1.40.0 → 1.40.1

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.
@@ -1 +1 @@
1
- {"version":3,"file":"form-client.d.ts","sourceRoot":"","sources":["../../src/forms/form-client.js"],"names":[],"mappings":"AA2BA,iGAAiG;AACjG;;;;;SAmEC;AAED,+GAA+G;AAC/G;;;;SAgCC;AAED;;GAEG;AACH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA4BC;AA9JD,qCAAsC,eAAe,CAAC"}
1
+ {"version":3,"file":"form-client.d.ts","sourceRoot":"","sources":["../../src/forms/form-client.js"],"names":[],"mappings":"AA2BA,iGAAiG;AACjG;;;;;SA0EC;AAED,+GAA+G;AAC/G;;;;SAgCC;AAED;;GAEG;AACH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA4BC;AArKD,qCAAsC,eAAe,CAAC"}
@@ -40,12 +40,13 @@ export function projectForm(session, flows) {
40
40
  const { state: root, context } = pending, cargo = session.cargo, language = session.language || 'en';
41
41
  // Both the code field and its free-text fallback can contain the one-time code.
42
42
  const collectingOtp = session.flowStacks.flat().some(frame => frame.flowId === 'get-and-validate-otp-code');
43
+ let askedShown = false;
43
44
  const fields = (specs, state, prefix = '', depth = 0) => {
44
45
  if (depth > 16)
45
46
  return [];
46
47
  const out = [];
47
48
  for (const input of specs || []) {
48
- if (!safe(input.name) || input.form_client === false || input.internal || input.bind || input.confirmation || !formInputApplies(input, state.values, cargo, state))
49
+ if (!safe(input.name) || input.form_client === false || input.bind || input.confirmation || !formInputApplies(input, state.values, cargo, state))
49
50
  continue;
50
51
  const path = prefix + input.name;
51
52
  const required = input.required_when === undefined || formInputApplies({ when: input.required_when }, state.values, cargo, state);
@@ -57,6 +58,8 @@ export function projectForm(session, flows) {
57
58
  // An alternative is a group constraint, not several individually required fields.
58
59
  const members = fields(input.any_of, state, prefix, depth + 1).map(field => ({ ...field, required: false }));
59
60
  const groupLabel = language === 'es' ? input.label_es || input.label : input.label;
61
+ if (members.length && isCurrent)
62
+ askedShown = true;
60
63
  if (members.length)
61
64
  out.push({ name: input.name, path, kind: 'alternatives', label: groupLabel || '', required, exclusive: input.exclusive === true, ...(isCurrent ? { current: true } : {}), fields: members });
62
65
  }
@@ -67,6 +70,8 @@ export function projectForm(session, flows) {
67
70
  const snapshot = state.childResults?.[input.name];
68
71
  const virtual = child || { values: state.values?.[input.name] || {}, data: snapshot?.data || {}, prepared: snapshot?.prepared || {}, errors: {} };
69
72
  const nested = fields(child?.specs || input.schema.inputs, virtual, path + '.', depth + 1);
73
+ if (nested.length && isCurrent)
74
+ askedShown = true;
70
75
  if (nested.length)
71
76
  out.push({ name: input.name, path, kind: 'group', label: label(input, language), required, ...(isCurrent ? { current: true } : {}), fields: nested });
72
77
  }
@@ -104,14 +109,21 @@ export function projectForm(session, flows) {
104
109
  if (state.errors?.[input.name])
105
110
  field.error = String(state.errors[input.name]);
106
111
  // The field the conversation is asking for now, so a client can point at it on a redrawn form.
107
- if (isCurrent)
112
+ if (isCurrent) {
108
113
  field.current = true;
114
+ askedShown = true;
115
+ }
109
116
  out.push(field);
110
117
  }
111
118
  }
112
119
  return out;
113
120
  };
114
121
  const projected = fields(root.specs, root);
122
+ // A card that cannot take the answer being asked for (a chat-only or not yet prepared field) is not drawn: the
123
+ // question is answered in chat, never beside a form that has no place for it.
124
+ const asked = context.names?.length || context.current;
125
+ if (asked && !askedShown)
126
+ return null;
115
127
  return projected.length ? { version: 1, form: root.id, language, fields: projected } : null;
116
128
  }
117
129
  /** Host preflight: call before updateActivity. Unknown paths and malformed envelopes never enter execution. */
@@ -1 +1 @@
1
- export const JSFE_RUNTIME_FINGERPRINT = "sha256:66fc7813afb500bc0554e498473cb92a02100e37f3283ccfd6d84471fbd304ee";
1
+ export const JSFE_RUNTIME_FINGERPRINT = "sha256:16e28f7248d2a884103079326baaf8d4f9aaf65486e99a8b3611bd248d646439";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jsfe",
3
- "version": "1.40.0",
3
+ "version": "1.40.1",
4
4
  "description": "TypeScript workflow engine for conversational/automation apps: multi-flow orchestration, interrupt/resume, stack-based control, robust errors, and flexible tool/REST integration.",
5
5
  "license": "MIT",
6
6
  "author": "Ron Pinkas",