@vectoriox/iox-ui 5.79.0 → 5.81.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.
@@ -738,6 +738,101 @@ function normaliseErrors(raw) {
738
738
  return Object.keys(errors).length ? errors : undefined;
739
739
  }
740
740
 
741
+ /**
742
+ * The submit LIFECYCLE's decisions — what a form shows after the server answers, what it says when a
743
+ * submit fails, what a client needs to validate a form, and how its submit button follows its state.
744
+ *
745
+ * Two runtimes act on these and must agree: `IoxFormComponent` (the engine's component path) and the
746
+ * string-form runtime (every header / footer global and every string-rendered page —
747
+ * vectoriox/iox-client-engine#13). The builder canvas reads `submitButtonView` too, for its Sending state.
748
+ *
749
+ * ⚠️ Framework-free, like the rest of forms-core: no Angular, no DOM.
750
+ */
751
+ /** Which of the form's four states is showing — written on the form as `data-iox-state`. */
752
+ var FormRenderState;
753
+ (function (FormRenderState) {
754
+ FormRenderState["Idle"] = "idle";
755
+ FormRenderState["Submitting"] = "submitting";
756
+ FormRenderState["Success"] = "success";
757
+ FormRenderState["Error"] = "error";
758
+ })(FormRenderState || (FormRenderState = {}));
759
+ /** The attribute every renderer writes a form's state on (the canvas switcher, both live paths). */
760
+ const FORM_STATE_ATTRIBUTE = 'data-iox-state';
761
+ /**
762
+ * The server's answer → what the visitor sees. Only a confirmed success is Success; per-field verdicts
763
+ * land on the fields; anything else (a dropped network included) is the designed Error block.
764
+ */
765
+ function submitOutcome(response) {
766
+ if (response?.ok)
767
+ return { state: FormRenderState.Success, reset: true, ...(response.redirect ? { redirect: response.redirect } : {}) };
768
+ if (response?.errors && Object.keys(response.errors).length)
769
+ return { state: FormRenderState.Idle, errors: response.errors, reset: false };
770
+ return { state: FormRenderState.Error, reset: false };
771
+ }
772
+ /** What the live region says after a refused submit: how many fields need attention, or that it did not send. */
773
+ function failureAnnouncement(errors) {
774
+ const count = errors ? Object.keys(errors).length : 0;
775
+ if (!count)
776
+ return 'That did not send.';
777
+ return `${count} ${count === 1 ? 'field needs' : 'fields need'} attention.`;
778
+ }
779
+ const FORM_FIELDS_ATTRIBUTE = 'data-iox-form-fields';
780
+ function clientFormSpec(spec) {
781
+ return { feedback: spec.feedback ?? FeedbackTiming.Smart, fields: [...(spec.fields ?? [])] };
782
+ }
783
+ /** The attribute's value back into a spec, or null when it is missing or not one. */
784
+ function parseClientFormSpec(raw) {
785
+ if (!raw)
786
+ return null;
787
+ try {
788
+ const parsed = JSON.parse(raw);
789
+ if (!parsed || !Array.isArray(parsed.fields))
790
+ return null;
791
+ return { feedback: typeof parsed.feedback === 'string' ? parsed.feedback : FeedbackTiming.Smart, fields: parsed.fields };
792
+ }
793
+ catch {
794
+ return null;
795
+ }
796
+ }
797
+ /** While its form sends, a submit button is busy, and disabled unless its author turned that off — ONE rule for the
798
+ * canvas's Sending state, the component path and the string path. Its "Sending…" label is the shared CSS's, keyed on
799
+ * the same `data-iox-state`. */
800
+ function submitButtonView(state, disableWhileSubmitting = true) {
801
+ const busy = state === FormRenderState.Submitting;
802
+ return { busy, disabled: busy && disableWhileSubmitting !== false };
803
+ }
804
+ /** On a submit button whose author turned "Disable while sending" off. */
805
+ const SUBMIT_KEEP_ENABLED_ATTRIBUTE = 'data-iox-keep-enabled';
806
+ var SubmitLabelClass;
807
+ (function (SubmitLabelClass) {
808
+ SubmitLabelClass["Labels"] = "iox-submit__labels";
809
+ SubmitLabelClass["Idle"] = "iox-submit__idle";
810
+ SubmitLabelClass["Busy"] = "iox-submit__busy";
811
+ })(SubmitLabelClass || (SubmitLabelClass = {}));
812
+ /**
813
+ * A submit button's words, as markup: its label, or — when it has a "While sending" label — both, stacked in one
814
+ * cell (the button keeps the longer one's width and never jumps). The string renderer's copy of
815
+ * `IoxSubmitButtonComponent`'s template; `escape` is the renderer's.
816
+ */
817
+ function submitButtonLabelsHtml(label, loadingLabel, escape) {
818
+ if (!loadingLabel)
819
+ return escape(label);
820
+ return `<span class="${SubmitLabelClass.Labels}"><span class="${SubmitLabelClass.Idle}">${escape(label)}</span>` +
821
+ `<span class="${SubmitLabelClass.Busy}">${escape(loadingLabel)}</span></span>`;
822
+ }
823
+ const FORM_HONEYPOT_CLASS = 'iox-form__hp';
824
+ const FORM_ANNOUNCER_ATTRIBUTE = 'data-iox-form-announcer';
825
+ /**
826
+ * The honeypot and the failure announcer every form holds, as markup — what `IoxFormComponent`'s template
827
+ * renders, for the string renderer. The honeypot is off-screen (some bots skip hidden inputs), out of the
828
+ * Tab order and the accessibility tree; the announcer is present from the start (a live region added at
829
+ * the moment it gains text is not reliably announced).
830
+ */
831
+ function formChromeHtml(honeypotField) {
832
+ return `<div class="${FORM_HONEYPOT_CLASS}" aria-hidden="true"><input type="text" name="${honeypotField}" tabindex="-1" autocomplete="off"></div>` +
833
+ `<div class="${FORM_HONEYPOT_CLASS}" ${FORM_ANNOUNCER_ATTRIBUTE} role="status" aria-live="assertive" aria-atomic="true"></div>`;
834
+ }
835
+
741
836
  /**
742
837
  * FORM PRESETS — a complete, working form as one insert: its fields, its submit label and the words of
743
838
  * its Success and Error blocks. ONE definition (W1.1): the builder's Forms tray builds a preset from
@@ -911,5 +1006,5 @@ function findFormContentInHosts(roots) {
911
1006
  * Generated bundle index. Do not edit.
912
1007
  */
913
1008
 
914
- export { ControlType, DEFAULT_EN_MESSAGES, FIELD_GROUP_NODE_TYPE, FIELD_NODE_TYPE, FORM_CONTENT_TYPES, FORM_ERROR_KEYS, FORM_NODE_TYPE, FORM_PRESETS, FeedbackTiming, FormPresetId, HONEYPOT_FIELD, IMPLIED_PATTERN, INITIAL_FORM_STATE, INTERACTIVE_HOST_TAGS, InteractiveTag, MESSAGE_NAMESPACE, MULTI_VALUE_CONTROLS, PATTERN_MESSAGE_KEYS, PATTERN_PRESETS, PATTERN_PRESET_OPTIONS, PatternPreset, RENDERED_AT_FIELD, RULE_DESCRIPTORS, RULE_MESSAGE_KEYS, RuleName, RuleParamKind, STORE_ACTION, SUBMIT_BUTTON_NODE_TYPE, addableRules, applyServerErrors, collectFieldNodes, collectFormSpec, deriveFieldName, fieldOptionsOf, findFormContentInHosts, firstInvalidField, formContentInHost, formPresetById, interpretSubmitResponse, isFormContent, isInteractiveHost, onFieldBlur, onFieldChange, onSubmitAttempt, parseFieldOptions, resetFormState, rulesFor, shouldShowError, submitEndpointPath, uniqueFieldName, validateField, validateForm, withAntiSpamFields };
1009
+ export { ControlType, DEFAULT_EN_MESSAGES, FIELD_GROUP_NODE_TYPE, FIELD_NODE_TYPE, FORM_ANNOUNCER_ATTRIBUTE, FORM_CONTENT_TYPES, FORM_ERROR_KEYS, FORM_FIELDS_ATTRIBUTE, FORM_HONEYPOT_CLASS, FORM_NODE_TYPE, FORM_PRESETS, FORM_STATE_ATTRIBUTE, FeedbackTiming, FormPresetId, FormRenderState, HONEYPOT_FIELD, IMPLIED_PATTERN, INITIAL_FORM_STATE, INTERACTIVE_HOST_TAGS, InteractiveTag, MESSAGE_NAMESPACE, MULTI_VALUE_CONTROLS, PATTERN_MESSAGE_KEYS, PATTERN_PRESETS, PATTERN_PRESET_OPTIONS, PatternPreset, RENDERED_AT_FIELD, RULE_DESCRIPTORS, RULE_MESSAGE_KEYS, RuleName, RuleParamKind, STORE_ACTION, SUBMIT_BUTTON_NODE_TYPE, SUBMIT_KEEP_ENABLED_ATTRIBUTE, SubmitLabelClass, addableRules, applyServerErrors, clientFormSpec, collectFieldNodes, collectFormSpec, deriveFieldName, failureAnnouncement, fieldOptionsOf, findFormContentInHosts, firstInvalidField, formChromeHtml, formContentInHost, formPresetById, interpretSubmitResponse, isFormContent, isInteractiveHost, onFieldBlur, onFieldChange, onSubmitAttempt, parseClientFormSpec, parseFieldOptions, resetFormState, rulesFor, shouldShowError, submitButtonLabelsHtml, submitButtonView, submitEndpointPath, submitOutcome, uniqueFieldName, validateField, validateForm, withAntiSpamFields };
915
1010
  //# sourceMappingURL=vectoriox-iox-ui-forms-core.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"vectoriox-iox-ui-forms-core.mjs","sources":["../../../projects/iox-ui/src/forms-core/form.model.ts","../../../projects/iox-ui/src/forms-core/messages.ts","../../../projects/iox-ui/src/forms-core/validate.ts","../../../projects/iox-ui/src/forms-core/options.ts","../../../projects/iox-ui/src/forms-core/collect.ts","../../../projects/iox-ui/src/forms-core/runtime.ts","../../../projects/iox-ui/src/forms-core/rule-catalog.ts","../../../projects/iox-ui/src/forms-core/transport.ts","../../../projects/iox-ui/src/forms-core/form-presets.ts","../../../projects/iox-ui/src/forms-core/nesting.ts","../../../projects/iox-ui/src/forms-core/public-api.ts","../../../projects/iox-ui/src/forms-core/vectoriox-iox-ui-forms-core.ts"],"sourcesContent":["// The persisted shape of a form. Pure types + the one derived constant each renderer needs.\n//\n// A FormSpec is DERIVED from the node tree (see `collect.ts`), never hand-maintained beside it —\n// there is one source of truth for \"what fields does this form have\", and it is the tree the author\n// edited. The builder writes the derived spec into the saved page so the SERVER can re-validate\n// against it without re-implementing the builder's tree walk.\n\n/** What the visitor actually types into. Chosen by a trait; it also implies a validation rule. */\nexport enum ControlType {\n Text = 'text',\n Email = 'email',\n Tel = 'tel',\n Url = 'url',\n Number = 'number',\n Password = 'password',\n Textarea = 'textarea',\n Select = 'select',\n Checkbox = 'checkbox',\n /** A checkbox in switch clothing (role=\"switch\") — consent toggles, settings-style forms. */\n Switch = 'switch',\n /** A slider over a numeric range — min/max/step ride the field. */\n Range = 'range',\n Radio = 'radio',\n Date = 'date',\n Time = 'time',\n File = 'file',\n /** Not shown; carries a constant or a bound value (campaign, source page, …). */\n Hidden = 'hidden',\n}\n\n/** The v1 rule grammar. Phase 3's conditional logic reuses these same names for its conditions. */\nexport enum RuleName {\n Required = 'required',\n MinLength = 'minLength',\n MaxLength = 'maxLength',\n Min = 'min',\n Max = 'max',\n Pattern = 'pattern',\n /** Cross-field: this value must equal another field's (confirm email / password). */\n Matches = 'matches',\n /** A checkbox that must be ticked — terms, consent. */\n Accepted = 'accepted',\n FileType = 'fileType',\n FileSize = 'fileSize',\n}\n\n/** Named regexes so an author picks \"Email\" rather than writing one. */\nexport enum PatternPreset {\n Email = 'email',\n Phone = 'phone',\n Url = 'url',\n Digits = 'digits',\n Letters = 'letters',\n Slug = 'slug',\n}\n\n/**\n * Deliberately permissive. A validator that rejects `user+tag@sub.domain.co.uk` or a real-world\n * phone number is worse than one that lets a typo through: the address gets verified by sending to\n * it, and a false rejection is a lost lead with no recourse.\n */\nexport const PATTERN_PRESETS: Readonly<Record<PatternPreset, RegExp>> = Object.freeze({\n [PatternPreset.Email]: /^[^\\s@]+@[^\\s@.]+(\\.[^\\s@.]+)+$/,\n [PatternPreset.Phone]: /^\\+?[\\d\\s().-]{6,20}$/,\n [PatternPreset.Url]: /^(https?:\\/\\/)?[^\\s.]+\\.[^\\s]{2,}$/i,\n [PatternPreset.Digits]: /^\\d+$/,\n [PatternPreset.Letters]: /^[\\p{L}\\s'-]+$/u,\n [PatternPreset.Slug]: /^[a-z0-9]+(-[a-z0-9]+)*$/,\n});\n\nexport interface ValidationRule {\n name: RuleName;\n /** `{ n }` for lengths/bounds · `{ preset } | { regex }` for pattern · `{ field }` for matches. */\n params?: Record<string, any>;\n /** Author's override. Absent → the shared message catalog supplies a translated key. */\n message?: string;\n}\n\nexport interface FieldOption {\n label: string;\n value: string;\n}\n\n/** Options pulled from a data source instead of typed by hand (a Select of CMS categories). */\nexport interface FieldOptionSource {\n source: string;\n sourcePath?: string;\n valuePath: string;\n labelPath: string;\n}\n\nexport interface FieldSpec {\n /** The submitted key. Derived from the label, unique within the form, editable. */\n name: string;\n control: ControlType;\n label: string;\n /** Surfaced as its own switch in the panel rather than buried in the rule list. */\n required?: boolean;\n rules?: ValidationRule[];\n options?: FieldOption[];\n optionsSource?: FieldOptionSource;\n defaultValue?: any;\n}\n\n/** When a field is validated, once the author has stopped deciding it per field. */\nexport enum FeedbackTiming {\n /** Validate on submit, then live per-field once that field has been touched or has failed. */\n Smart = 'smart',\n Submit = 'submit',\n Live = 'live',\n}\n\n/** What happens to a submission, in order. Card #1 (`store`) is always present. */\nexport interface SubmitAction {\n type: string;\n config?: Record<string, any>;\n /** `retry` (default) · `fail` · `ignore`. */\n onFailure?: 'retry' | 'fail' | 'ignore';\n}\n\nexport interface FormSpec {\n formId: string;\n /** Author-facing name — the submissions inbox groups by it. */\n name: string;\n feedback: FeedbackTiming;\n fields: FieldSpec[];\n actions: SubmitAction[];\n antiSpam: { honeypot: boolean; minFillMs: number; turnstile?: boolean };\n retention?: { days: number };\n}\n\n/**\n * The rule a control type implies with no configuration. Choosing \"Email\" IS choosing email\n * validation — the single biggest reason the panel can stay empty and still validate well.\n */\nexport const IMPLIED_PATTERN: Readonly<Partial<Record<ControlType, PatternPreset>>> = Object.freeze({\n [ControlType.Email]: PatternPreset.Email,\n [ControlType.Tel]: PatternPreset.Phone,\n [ControlType.Url]: PatternPreset.Url,\n});\n\n/** Controls whose value is a list rather than a scalar. */\nexport const MULTI_VALUE_CONTROLS: ReadonlySet<ControlType> = new Set([ControlType.File]);\n","// The default message for every rule, as an i18n KEY — never a rendered string.\n//\n// This is what lets the Validation panel stay empty and still produce good errors: an author who\n// configures nothing gets \"Enter a valid email address\", not \"Invalid\". The author's own `message`\n// on a rule always wins; this is the fallback, and it is the only place a default lives.\n//\n// Consumers translate the key with their own i18n (the CMS client via ngx-translate, the engine via\n// the page's locale bundle). The backend returns the key too, so a server-side rejection renders in\n// the visitor's language rather than in the server's.\n\nimport { RuleName } from './form.model';\n\n/** Namespace for every forms validation key. Keep in sync with `en.json` / `he.json`. */\nexport const MESSAGE_NAMESPACE = 'forms.validation';\n\n/**\n * Rule → i18n key. Params travel beside the key (`{ n: 8 }`, `{ field: 'Email' }`) so a translation\n * can place the number wherever its grammar needs it, rather than having it baked into the string.\n */\nexport const RULE_MESSAGE_KEYS: Readonly<Record<RuleName, string>> = Object.freeze({\n [RuleName.Required]: `${MESSAGE_NAMESPACE}.required`,\n [RuleName.MinLength]: `${MESSAGE_NAMESPACE}.minLength`,\n [RuleName.MaxLength]: `${MESSAGE_NAMESPACE}.maxLength`,\n [RuleName.Min]: `${MESSAGE_NAMESPACE}.min`,\n [RuleName.Max]: `${MESSAGE_NAMESPACE}.max`,\n // ⚠️ `.pattern.generic`, not `.pattern`: the preset keys below live UNDER `pattern`, and a JSON\n // translation bundle cannot have the same key be both a string and an object — ngx-translate\n // would hand back the object (or the raw key) for the generic case.\n [RuleName.Pattern]: `${MESSAGE_NAMESPACE}.pattern.generic`,\n [RuleName.Matches]: `${MESSAGE_NAMESPACE}.matches`,\n [RuleName.Accepted]: `${MESSAGE_NAMESPACE}.accepted`,\n [RuleName.FileType]: `${MESSAGE_NAMESPACE}.fileType`,\n [RuleName.FileSize]: `${MESSAGE_NAMESPACE}.fileSize`,\n});\n\n/**\n * A pattern failure deserves better than \"Invalid format\". Each preset gets its own key so the\n * message can say what a valid value looks like, which is the difference between a visitor fixing\n * a typo and a visitor giving up.\n */\nexport const PATTERN_MESSAGE_KEYS: Readonly<Record<string, string>> = Object.freeze({\n email: `${MESSAGE_NAMESPACE}.pattern.email`,\n phone: `${MESSAGE_NAMESPACE}.pattern.phone`,\n url: `${MESSAGE_NAMESPACE}.pattern.url`,\n digits: `${MESSAGE_NAMESPACE}.pattern.digits`,\n letters: `${MESSAGE_NAMESPACE}.pattern.letters`,\n slug: `${MESSAGE_NAMESPACE}.pattern.slug`,\n});\n\n/** Form-level outcomes the visitor sees in the Error state. One designed block, five reasons. */\nexport const FORM_ERROR_KEYS = Object.freeze({\n Network: `${MESSAGE_NAMESPACE}.form.network`,\n Rejected: `${MESSAGE_NAMESPACE}.form.rejected`,\n Spam: `${MESSAGE_NAMESPACE}.form.spam`,\n RateLimited: `${MESSAGE_NAMESPACE}.form.rateLimited`,\n Server: `${MESSAGE_NAMESPACE}.form.server`,\n});\n\n/** The English defaults, so a consumer that has not added the keys yet still shows real text. */\nexport const DEFAULT_EN_MESSAGES: Readonly<Record<string, string>> = Object.freeze({\n [RULE_MESSAGE_KEYS[RuleName.Required]]: 'This field is required',\n [RULE_MESSAGE_KEYS[RuleName.MinLength]]: 'Use at least {{n}} characters',\n [RULE_MESSAGE_KEYS[RuleName.MaxLength]]: 'Use no more than {{n}} characters',\n [RULE_MESSAGE_KEYS[RuleName.Min]]: 'Enter {{n}} or more',\n [RULE_MESSAGE_KEYS[RuleName.Max]]: 'Enter {{n}} or less',\n [RULE_MESSAGE_KEYS[RuleName.Pattern]]: 'Check the format of this value',\n [RULE_MESSAGE_KEYS[RuleName.Matches]]: 'This must match {{field}}',\n [RULE_MESSAGE_KEYS[RuleName.Accepted]]: 'Please tick this to continue',\n [RULE_MESSAGE_KEYS[RuleName.FileType]]: 'That file type isn’t accepted',\n [RULE_MESSAGE_KEYS[RuleName.FileSize]]: 'That file is larger than {{n}}MB',\n [PATTERN_MESSAGE_KEYS['email']]: 'Enter a valid email address',\n [PATTERN_MESSAGE_KEYS['phone']]: 'Enter a valid phone number',\n [PATTERN_MESSAGE_KEYS['url']]: 'Enter a valid web address',\n [PATTERN_MESSAGE_KEYS['digits']]: 'Use digits only',\n [PATTERN_MESSAGE_KEYS['letters']]: 'Use letters only',\n [PATTERN_MESSAGE_KEYS['slug']]: 'Use lowercase letters, numbers and hyphens',\n [FORM_ERROR_KEYS.Network]: 'We couldn’t reach the server — check your connection and try again',\n [FORM_ERROR_KEYS.Rejected]: 'Some answers need fixing',\n [FORM_ERROR_KEYS.Spam]: 'We couldn’t accept this submission',\n [FORM_ERROR_KEYS.RateLimited]: 'Too many attempts — please wait a moment and try again',\n [FORM_ERROR_KEYS.Server]: 'Something went wrong on our side — your answers are still here',\n});\n","// The validator. ONE implementation, run by the builder canvas, the SSR engine and `iox-cms`.\n//\n// Client-side validation is UX; server-side validation is truth. Because both call this function,\n// a visitor can never be told a value is fine and then have the server reject it, and a hand-crafted\n// POST can never bypass a rule the author configured.\n\nimport {\n ControlType,\n FieldSpec,\n FormSpec,\n IMPLIED_PATTERN,\n PATTERN_PRESETS,\n PatternPreset,\n RuleName,\n ValidationRule,\n} from './form.model';\nimport { PATTERN_MESSAGE_KEYS, RULE_MESSAGE_KEYS } from './messages';\n\nexport interface FieldError {\n /** i18n key, or the author's own override string when they set one. */\n messageKey: string;\n /** Interpolation values (`{ n: 8 }`, `{ field: 'Email' }`). */\n params?: Record<string, any>;\n}\n\nexport interface FieldResult extends Partial<FieldError> {\n valid: boolean;\n}\n\nexport interface FormResult {\n valid: boolean;\n /** Keyed by field name. Empty when valid. */\n errors: Record<string, FieldError>;\n}\n\n/** A file, as either runtime hands it over. Kept structural so this file imports no DOM types. */\ninterface FileLike {\n name?: string;\n size?: number;\n type?: string;\n}\n\n/**\n * Validate one field's value.\n *\n * Order is deliberate and is part of the contract:\n * 1. `required` (or `accepted` for a checkbox) — the only rules an EMPTY value can fail.\n * 2. Everything else, in the order the author arranged them, but ONLY for a non-empty value.\n *\n * That second point is what stops an optional \"Phone\" field from shouting \"enter a valid phone\n * number\" at someone who simply left it blank — the single most common validation-UX bug.\n * The FIRST failure wins: a visitor fixes one thing at a time.\n */\nexport function validateField(\n value: unknown,\n spec: FieldSpec,\n form: Record<string, unknown> = {},\n): FieldResult {\n const rules = effectiveRules(spec);\n const empty = isEmpty(value, spec.control);\n\n for (const rule of rules) {\n const appliesToEmpty = rule.name === RuleName.Required || rule.name === RuleName.Accepted;\n if (empty && !appliesToEmpty) continue;\n\n const failure = check(rule, value, spec, form);\n if (failure) {\n return {\n valid: false,\n messageKey: rule.message ?? failure.messageKey,\n params: failure.params,\n };\n }\n }\n return { valid: true };\n}\n\n/**\n * Validate a whole submission. Every field is checked (not short-circuited at the first bad one) so\n * the visitor sees every problem at once instead of fixing them one reload at a time.\n */\nexport function validateForm(\n values: Record<string, unknown>,\n spec: FormSpec,\n): FormResult {\n const errors: Record<string, FieldError> = {};\n for (const field of spec.fields ?? []) {\n const result = validateField(values?.[field.name], field, values ?? {});\n if (!result.valid) {\n errors[field.name] = { messageKey: result.messageKey!, params: result.params };\n }\n }\n return { valid: Object.keys(errors).length === 0, errors };\n}\n\n/** The name of the first field with an error, in spec order — what the browser should focus. */\nexport function firstInvalidField(spec: FormSpec, errors: Record<string, FieldError>): string | null {\n for (const field of spec.fields ?? []) if (errors[field.name]) return field.name;\n return null;\n}\n\n// ─── internals ───────────────────────────────────────────────────────────────\n\n/**\n * The author's rules, plus the ones the field's own configuration implies: `required` from the\n * switch (rather than making the author add a rule for the commonest case) and the pattern implied\n * by an Email/Tel/Url control. An explicitly declared rule of the same name always wins, so an\n * author who sets their own `pattern` on an Email field is not fighting an invisible second one.\n */\nfunction effectiveRules(spec: FieldSpec): ValidationRule[] {\n const declared = spec.rules ?? [];\n const has = (name: RuleName) => declared.some(r => r.name === name);\n const implied: ValidationRule[] = [];\n\n if (spec.required && !has(RuleName.Required)) {\n // A checkbox's \"required\" means TICKED, which is a different message and a different check.\n implied.push(spec.control === ControlType.Checkbox\n ? { name: RuleName.Accepted }\n : { name: RuleName.Required });\n }\n\n const preset = IMPLIED_PATTERN[spec.control];\n if (preset && !has(RuleName.Pattern)) {\n implied.push({ name: RuleName.Pattern, params: { preset } });\n }\n\n return [...implied, ...declared];\n}\n\n/** Empty means \"the visitor gave us nothing\" — per control type, not a blanket falsy check. */\nfunction isEmpty(value: unknown, control: ControlType): boolean {\n if (value === null || value === undefined) return true;\n if (control === ControlType.Checkbox) return value === false;\n if (Array.isArray(value)) return value.length === 0;\n if (typeof value === 'string') return value.trim() === '';\n return false;\n}\n\nfunction check(\n rule: ValidationRule,\n value: unknown,\n spec: FieldSpec,\n form: Record<string, unknown>,\n): FieldError | null {\n const fail = (messageKey: string, params?: Record<string, any>): FieldError => ({ messageKey, params });\n const defaultKey = RULE_MESSAGE_KEYS[rule.name];\n const n = Number(rule.params?.['n']);\n\n switch (rule.name) {\n case RuleName.Required:\n return isEmpty(value, spec.control) ? fail(defaultKey) : null;\n\n case RuleName.Accepted:\n return value === true ? null : fail(defaultKey);\n\n case RuleName.MinLength:\n return text(value).length < n ? fail(defaultKey, { n }) : null;\n\n case RuleName.MaxLength:\n return text(value).length > n ? fail(defaultKey, { n }) : null;\n\n case RuleName.Min: {\n const num = numeric(value);\n return num === null || num < n ? fail(defaultKey, { n }) : null;\n }\n\n case RuleName.Max: {\n const num = numeric(value);\n return num === null || num > n ? fail(defaultKey, { n }) : null;\n }\n\n case RuleName.Pattern: {\n const regex = patternFor(rule);\n if (!regex) return null; // an unparsable custom regex must not block a submission\n if (regex.test(text(value))) return null;\n const preset = rule.params?.['preset'] as string | undefined;\n return fail((preset && PATTERN_MESSAGE_KEYS[preset]) || defaultKey);\n }\n\n case RuleName.Matches: {\n const other = String(rule.params?.['field'] ?? '');\n return text(value) === text(form?.[other]) ? null : fail(defaultKey, { field: other });\n }\n\n case RuleName.FileType: {\n const accepted = list(rule.params?.['types']).map(t => t.toLowerCase().replace(/^\\./, ''));\n if (!accepted.length) return null;\n const bad = files(value).some(f => {\n const ext = (f.name ?? '').split('.').pop()?.toLowerCase() ?? '';\n const mime = (f.type ?? '').toLowerCase();\n return !accepted.some(t => t === ext || mime === t || mime.startsWith(t + '/'));\n });\n return bad ? fail(defaultKey, { types: accepted.join(', ') }) : null;\n }\n\n case RuleName.FileSize: {\n const maxBytes = n * 1024 * 1024;\n return files(value).some(f => (f.size ?? 0) > maxBytes) ? fail(defaultKey, { n }) : null;\n }\n\n default:\n return null;\n }\n}\n\nfunction patternFor(rule: ValidationRule): RegExp | null {\n const preset = rule.params?.['preset'] as PatternPreset | undefined;\n if (preset && PATTERN_PRESETS[preset]) return PATTERN_PRESETS[preset];\n const custom = rule.params?.['regex'];\n if (typeof custom !== 'string' || !custom) return null;\n // A malformed regex is the AUTHOR's mistake; failing open is the only safe reading, because\n // failing closed would make a live form permanently unsubmittable for every visitor.\n try { return new RegExp(custom); } catch { return null; }\n}\n\nconst text = (value: unknown): string =>\n value === null || value === undefined ? '' : String(value).trim();\n\nfunction numeric(value: unknown): number | null {\n const parsed = typeof value === 'number' ? value : parseFloat(text(value));\n return Number.isFinite(parsed) ? parsed : null;\n}\n\nconst list = (value: unknown): string[] =>\n Array.isArray(value) ? value.map(String)\n : typeof value === 'string' ? value.split(',').map(s => s.trim()).filter(Boolean)\n : [];\n\nconst files = (value: unknown): FileLike[] =>\n Array.isArray(value) ? value as FileLike[]\n : value && typeof value === 'object' ? [value as FileLike]\n : [];\n","import { FieldOption } from './form.model';\n\n/** `value|Label` separates a submitted value from what the visitor reads; a bare line is both. */\nconst OPTION_SEPARATOR = '|';\n\n/**\n * A Field's `optionsText` trait — the author's choices, one per line — as options. ONE parser for the\n * builder canvas, both engine paths and iox-cms: until 2026-10-19 nothing parsed the trait, so a Radio\n * group or a Dropdown from the tray rendered no choices at all on the canvas and on the live site.\n */\nexport function parseFieldOptions(text: unknown): FieldOption[] {\n if (typeof text !== 'string') return [];\n const out: FieldOption[] = [];\n for (const line of text.split(/\\r?\\n/)) {\n const raw = line.trim();\n if (!raw) continue;\n const at = raw.indexOf(OPTION_SEPARATOR);\n const value = (at === -1 ? raw : raw.slice(0, at)).trim();\n const label = (at === -1 ? raw : raw.slice(at + 1)).trim() || value;\n if (value) out.push({ value, label });\n }\n return out;\n}\n\n/** The choices a saved Field offers: an explicit `options` list wins, else its `optionsText` parsed. */\nexport function fieldOptionsOf(props: { options?: unknown; optionsText?: unknown } | null | undefined): FieldOption[] {\n if (Array.isArray(props?.options) && props!.options.length) return props!.options as FieldOption[];\n return parseFieldOptions(props?.optionsText);\n}\n","// Derive a FormSpec from a node tree.\n//\n// The tree the author edited is the SINGLE source of truth for \"what fields does this form have\".\n// The spec is derived from it — never maintained beside it — so a field cannot exist in one and not\n// the other. The builder runs this on save and stores the result in the page document; the backend\n// reads THAT stored spec to re-validate a submission (it must never trust a spec sent by the\n// browser). See iox-ai-guidance `architecture/builder/forms-and-inputs-plan.md` §5.1 and D11.\n\nimport {\n ControlType,\n FeedbackTiming,\n FieldSpec,\n FormSpec,\n RuleName,\n SubmitAction,\n ValidationRule,\n} from './form.model';\nimport { fieldOptionsOf } from './options';\n\n/** The minimum a node must look like. Structural on purpose: this file knows no renderer. */\nexport interface FormNodeLike {\n type: string;\n props?: Record<string, any>;\n children?: FormNodeLike[];\n}\n\nexport const FORM_NODE_TYPE = 'Form';\nexport const FIELD_NODE_TYPE = 'Field';\n\n/** Always present, never removable — the safety net that makes \"store first, deliver after\" true. */\nexport const STORE_ACTION: SubmitAction = Object.freeze({ type: 'store' });\n\n/**\n * Turn a label into the key that arrives in the submitted data — `Full name` → `fullName`.\n * Authors never have to invent keys (decision: auto-derive, with an editable override).\n *\n * Diacritics are stripped rather than dropped, so a Hebrew or accented label still yields a usable\n * ASCII key instead of an empty one; a label with no usable characters falls back to `field`.\n */\nexport function deriveFieldName(label: string): string {\n const words = (label ?? '')\n .normalize('NFD').replace(/[̀-ͯ]/g, '')\n .replace(/[^a-zA-Z0-9]+/g, ' ')\n .trim()\n .split(/\\s+/)\n .filter(Boolean);\n if (!words.length) return 'field';\n const [first, ...rest] = words;\n const name = first.toLowerCase() + rest.map(w => w[0].toUpperCase() + w.slice(1).toLowerCase()).join('');\n // A key must not start with a digit — it ends up as an object key and a form control id.\n return /^\\d/.test(name) ? `field${name}` : name;\n}\n\n/** Make `name` unique within `taken`, appending 2, 3, … — two \"Email\" fields must not collide. */\nexport function uniqueFieldName(name: string, taken: ReadonlySet<string>): string {\n if (!taken.has(name)) return name;\n let n = 2;\n while (taken.has(`${name}${n}`)) n++;\n return `${name}${n}`;\n}\n\n/**\n * Walk a Form subtree and produce its spec.\n *\n * Nested forms are not collected: a Field belongs to its NEAREST ancestor Form (decision D1), so the\n * walk stops at any inner Form node rather than stealing its fields.\n */\nexport function collectFormSpec(node: FormNodeLike | null | undefined): FormSpec | null {\n if (!node || node.type !== FORM_NODE_TYPE) return null;\n const props = node.props ?? {};\n\n const fields: FieldSpec[] = [];\n const taken = new Set<string>();\n for (const fieldNode of collectFieldNodes(node.children ?? [])) {\n const spec = toFieldSpec(fieldNode, taken);\n taken.add(spec.name);\n fields.push(spec);\n }\n\n return {\n formId: props['formId'] ?? '',\n name: props['name'] ?? 'Form',\n feedback: (props['feedback'] as FeedbackTiming) ?? FeedbackTiming.Smart,\n fields,\n actions: normaliseActions(props['actions']),\n antiSpam: {\n honeypot: props['honeypot'] !== false,\n minFillMs: Number(props['minFillMs'] ?? 1200),\n ...(props['turnstile'] ? { turnstile: true } : {}),\n },\n ...(props['retentionDays'] ? { retention: { days: Number(props['retentionDays']) } } : {}),\n };\n}\n\n/** Every Field in this subtree, in document order, not descending into a nested Form. */\nexport function collectFieldNodes(nodes: readonly FormNodeLike[]): FormNodeLike[] {\n const out: FormNodeLike[] = [];\n for (const node of nodes ?? []) {\n if (!node?.type) continue;\n if (node.type === FORM_NODE_TYPE) continue; // a nested form owns its own fields\n if (node.type === FIELD_NODE_TYPE) { out.push(node); continue; }\n out.push(...collectFieldNodes(node.children ?? []));\n }\n return out;\n}\n\nfunction toFieldSpec(node: FormNodeLike, taken: ReadonlySet<string>): FieldSpec {\n const props = node.props ?? {};\n const label = props['label'] ?? '';\n // The author's explicit override wins; otherwise derive from the label.\n const name = uniqueFieldName(props['name'] || deriveFieldName(label), taken);\n\n const spec: FieldSpec = {\n name,\n control: (props['control'] as ControlType) ?? ControlType.Text,\n label,\n };\n if (props['required']) spec.required = true;\n const rules = normaliseRules(props['rules']);\n if (rules.length) spec.rules = rules;\n const options = fieldOptionsOf(props);\n if (options.length) spec.options = options;\n if (props['optionsSource']) spec.optionsSource = props['optionsSource'];\n if (props['defaultValue'] !== undefined && props['defaultValue'] !== '') {\n spec.defaultValue = props['defaultValue'];\n }\n return spec;\n}\n\n/** Drop anything that isn't a rule we know — a hand-edited page must not break validation. */\nfunction normaliseRules(raw: unknown): ValidationRule[] {\n if (!Array.isArray(raw)) return [];\n const known = new Set<string>(Object.values(RuleName));\n return raw\n .filter(r => r && known.has(r.name))\n .map(r => ({\n name: r.name as RuleName,\n ...(r.params ? { params: r.params } : {}),\n ...(r.message ? { message: r.message } : {}),\n }));\n}\n\n/** `store` is always first and always present, however the page was edited. */\nfunction normaliseActions(raw: unknown): SubmitAction[] {\n const declared: SubmitAction[] = Array.isArray(raw)\n ? raw.filter(a => a && typeof a.type === 'string')\n : [];\n return [STORE_ACTION, ...declared.filter(a => a.type !== STORE_ACTION.type)];\n}\n","// When a field's error is allowed to be VISIBLE — the pure half of the form runtime.\n//\n// Validity and visibility are different questions. A field can be invalid from the moment the page\n// loads (an empty required field always is), but showing that immediately means greeting a visitor\n// with a wall of red before they have typed anything. This module owns the second question, and it\n// owns it in one place so the builder canvas, the SSR engine and any future runtime agree.\n//\n// Framework-free, like the rest of forms-core.\n\nimport { FeedbackTiming, FormSpec } from './form.model';\nimport { FieldError, validateField, validateForm } from './validate';\n\n/** Everything the runtime needs to remember. Immutable — each transition returns a new state. */\nexport interface FormRuntimeState {\n /** Field names the visitor has left (blurred) at least once. */\n touched: ReadonlySet<string>;\n /** True once a submit has been attempted — after that, every error is fair game. */\n submitted: boolean;\n /** The current errors, whether or not they are being shown. */\n errors: Readonly<Record<string, FieldError>>;\n /** In flight — the submit button shows its loading label and the form is aria-busy. */\n submitting: boolean;\n}\n\nexport const INITIAL_FORM_STATE: FormRuntimeState = Object.freeze({\n touched: new Set<string>(),\n submitted: false,\n errors: {},\n submitting: false,\n});\n\n/**\n * Should this field's error be on screen right now?\n *\n * - `Submit` — only after a submit attempt. Quietest; nothing moves while typing.\n * - `Live` — as soon as it is invalid. Loudest; shouts at a half-typed email address.\n * - `Smart` — the default, and the reason the author gets one dropdown instead of a decision per\n * field: stay quiet until the visitor has either left the field or tried to submit.\n * After that, correct live, so fixing an error clears it as they type.\n */\nexport function shouldShowError(\n fieldName: string,\n state: FormRuntimeState,\n timing: FeedbackTiming | string = FeedbackTiming.Smart,\n): boolean {\n if (!state.errors[fieldName]) return false;\n switch (timing) {\n case FeedbackTiming.Live: return true;\n case FeedbackTiming.Submit: return state.submitted;\n default: return state.submitted || state.touched.has(fieldName);\n }\n}\n\n/**\n * Re-validate one field after a change. Only that field is re-checked, EXCEPT that a `matches` rule\n * makes another field's validity depend on this one — so a confirm-email field stops being wrong\n * the moment you fix the address it points at, rather than waiting for its own blur.\n */\nexport function onFieldChange(\n state: FormRuntimeState,\n fieldName: string,\n values: Record<string, unknown>,\n spec: FormSpec,\n): FormRuntimeState {\n const errors = { ...state.errors };\n const affected = [fieldName, ...dependentsOf(fieldName, spec)];\n\n for (const name of affected) {\n const field = (spec.fields ?? []).find(f => f.name === name);\n if (!field) continue;\n const result = validateField(values?.[name], field, values ?? {});\n if (result.valid) delete errors[name];\n else errors[name] = { messageKey: result.messageKey!, params: result.params };\n }\n return { ...state, errors };\n}\n\n/** Mark a field touched (on blur) and re-check it, so Smart timing can start showing its error. */\nexport function onFieldBlur(\n state: FormRuntimeState,\n fieldName: string,\n values: Record<string, unknown>,\n spec: FormSpec,\n): FormRuntimeState {\n const touched = new Set(state.touched);\n touched.add(fieldName);\n return { ...onFieldChange(state, fieldName, values, spec), touched };\n}\n\n/**\n * A submit attempt. Validates everything and flips `submitted`, so from here on every error shows\n * whatever the timing setting is — a visitor who pressed the button is owed the full picture.\n */\nexport function onSubmitAttempt(\n state: FormRuntimeState,\n values: Record<string, unknown>,\n spec: FormSpec,\n): FormRuntimeState {\n const { errors } = validateForm(values ?? {}, spec);\n return { ...state, submitted: true, errors };\n}\n\n/** Server-side rejection: adopt the server's errors verbatim. It is the authority, not the client. */\nexport function applyServerErrors(\n state: FormRuntimeState,\n errors: Record<string, FieldError>,\n): FormRuntimeState {\n return { ...state, submitted: true, submitting: false, errors: { ...errors } };\n}\n\n/** A clean slate after a successful submit, for a form configured to clear itself. */\nexport function resetFormState(): FormRuntimeState {\n return { touched: new Set<string>(), submitted: false, errors: {}, submitting: false };\n}\n\n/** Field names whose validity depends on `fieldName` through a `matches` rule. */\nfunction dependentsOf(fieldName: string, spec: FormSpec): string[] {\n return (spec.fields ?? [])\n .filter(f => (f.rules ?? []).some(r => r.params?.['field'] === fieldName))\n .map(f => f.name);\n}\n","/**\n * Which rules exist, and which controls they make sense on.\n *\n * The panel must not offer \"must be ticked\" on a text field, or a character limit on a date. That\n * knowledge belongs with the validator, not duplicated into the editor — otherwise the two drift and\n * an author configures a rule that silently never runs.\n *\n * Pure data, in forms-core, so the builder panel, the engine and the backend all read one catalog.\n */\n\nimport { ControlType, PatternPreset, RuleName } from './form.model';\n\n/** How a rule's parameter is edited. The panel maps these to its own controls. */\nexport enum RuleParamKind {\n /** No parameter — the rule is its own statement (`required`, `accepted`). */\n None = 'none',\n /** A single number (`{ n }`) — lengths and bounds. */\n Number = 'number',\n /** A preset regex, or a custom one (`{ preset }` / `{ regex }`). */\n Pattern = 'pattern',\n /** Another field in the same form (`{ field }`). */\n Field = 'field',\n}\n\nexport interface RuleDescriptor {\n name: RuleName;\n /** i18n key for the rule's name in the Add-rule menu. */\n labelKey: string;\n param: RuleParamKind;\n /** Controls this rule can apply to. Empty means every control. */\n controls: readonly ControlType[];\n /** Suggested starting value for the parameter, so a freshly added rule is already valid. */\n defaultParams?: Record<string, any>;\n}\n\n/** Text-ish controls: the ones whose value is a string a person typed. */\nconst TEXTUAL: readonly ControlType[] = [\n ControlType.Text, ControlType.Email, ControlType.Tel, ControlType.Url,\n ControlType.Password, ControlType.Textarea,\n];\n\n/** Controls with a comparable magnitude. */\nconst NUMERIC: readonly ControlType[] = [ControlType.Number, ControlType.Date, ControlType.Time, ControlType.Range];\n\nexport const RULE_DESCRIPTORS: readonly RuleDescriptor[] = Object.freeze([\n {\n name: RuleName.MinLength, labelKey: 'forms.rules.minLength',\n param: RuleParamKind.Number, controls: TEXTUAL, defaultParams: { n: 2 },\n },\n {\n name: RuleName.MaxLength, labelKey: 'forms.rules.maxLength',\n param: RuleParamKind.Number, controls: TEXTUAL, defaultParams: { n: 200 },\n },\n {\n name: RuleName.Min, labelKey: 'forms.rules.min',\n param: RuleParamKind.Number, controls: NUMERIC, defaultParams: { n: 0 },\n },\n {\n name: RuleName.Max, labelKey: 'forms.rules.max',\n param: RuleParamKind.Number, controls: NUMERIC, defaultParams: { n: 100 },\n },\n {\n name: RuleName.Pattern, labelKey: 'forms.rules.pattern',\n param: RuleParamKind.Pattern, controls: TEXTUAL,\n defaultParams: { preset: PatternPreset.Email },\n },\n {\n // Cross-field: confirm-email, confirm-password.\n name: RuleName.Matches, labelKey: 'forms.rules.matches',\n param: RuleParamKind.Field, controls: [],\n },\n {\n // A checkbox's `required` already becomes `accepted`, so offering it again would be a\n // duplicate — it is here for a checkbox the author wants ticked WITHOUT marking it required.\n name: RuleName.Accepted, labelKey: 'forms.rules.accepted',\n param: RuleParamKind.None, controls: [ControlType.Checkbox, ControlType.Switch],\n },\n]);\n\n/** The rules that can be added to a field of this control type. */\nexport function rulesFor(control: ControlType | string): RuleDescriptor[] {\n return RULE_DESCRIPTORS.filter(rule =>\n rule.controls.length === 0 || rule.controls.includes(control as ControlType));\n}\n\n/**\n * The rules an author may still ADD — the catalog minus what is already on the field.\n *\n * Each rule appears once: two `maxLength` rules on one field is not a configuration anyone means,\n * and the validator would apply whichever came first. `pattern` is the exception a caller might\n * expect to repeat, and it deliberately does not: a second pattern can only contradict the first.\n */\nexport function addableRules(\n control: ControlType | string,\n existing: readonly { name: RuleName }[] = [],\n): RuleDescriptor[] {\n const used = new Set(existing.map(rule => rule.name));\n return rulesFor(control).filter(rule => !used.has(rule.name));\n}\n\n/** The preset options a Pattern rule offers, in the order the panel should list them. */\nexport const PATTERN_PRESET_OPTIONS: readonly { value: PatternPreset; labelKey: string }[] = Object.freeze([\n { value: PatternPreset.Email, labelKey: 'forms.rules.preset.email' },\n { value: PatternPreset.Phone, labelKey: 'forms.rules.preset.phone' },\n { value: PatternPreset.Url, labelKey: 'forms.rules.preset.url' },\n { value: PatternPreset.Digits, labelKey: 'forms.rules.preset.digits' },\n { value: PatternPreset.Letters, labelKey: 'forms.rules.preset.letters' },\n { value: PatternPreset.Slug, labelKey: 'forms.rules.preset.slug' },\n]);\n\n// ── MOVED to @vectoriox/iox-ui/actions-core (A0) ─────────────────────────────\n// The descriptor shape and the after-submit catalog are the ONE action vocabulary the whole\n// product shares; element actions (A1) consume the same shape. Re-exported here under the\n// original names so no forms consumer changes a line.\nexport type { ActionDescriptor } from '@vectoriox/iox-ui/actions-core';\nexport { FORM_SUBMIT_ACTION_DESCRIPTORS as ACTION_DESCRIPTORS, addableActions } from '@vectoriox/iox-ui/actions-core';\n","/**\n * The submit transport CONTRACT — what a host must provide to make a form actually send.\n *\n * The Form component deliberately owns no HTTP: the builder canvas must never post (an author\n * clicking Submit while designing would file a real submission), and the SSR engine posts through\n * Angular's HttpClient. What IS shared is everything around the call — the endpoint's shape, the\n * anti-spam fields, and how the server's answer maps onto the form's state. Those live here so the\n * two hosts cannot drift, and so a third host (a hand-built integration) has one thing to read.\n *\n * ⚠️ Framework-free, like the rest of forms-core. No Angular, no RxJS, no fetch.\n */\n\nimport { FieldError } from './validate';\n\n/** The field a honeypot input uses. Must match `iox-cms` `anti-spam.ts` — hence the comment there. */\nexport const HONEYPOT_FIELD = '_iox_hp';\n/** When the form was rendered, so the server can measure fill time. */\nexport const RENDERED_AT_FIELD = '_iox_t';\n\n/**\n * What the form hands its host. There is deliberately no `orgId`: the tenant is the HOST's\n * knowledge, not the form's, and a form that had to be told its org would be one more trait an\n * author could get wrong.\n */\nexport interface SubmitRequest {\n formId: string;\n values: Record<string, any>;\n}\n\n/**\n * The server's answer, normalised. Mirrors `SubmitResult` in `iox-cms`\n * `form-submissions.service.ts` — the two are one contract, so change them together.\n */\nexport interface SubmitResponse {\n ok: boolean;\n /** Per-field verdicts from the server's own validation pass, keyed by field name. */\n errors?: Record<string, FieldError>;\n /** Where to send the visitor after a successful submit, when the form has a redirect action. */\n redirect?: string;\n}\n\n/**\n * The one function a host implements. Rejecting (or throwing) means the call never reached the\n * server — the form shows its Error state, which is the honest thing to show for a dropped network.\n */\nexport type FormTransport = (request: SubmitRequest) => Promise<SubmitResponse>;\n\n/**\n * The public submit path. Built here rather than interpolated at each call site, so the engine and\n * any future host cannot disagree about it — and so changing it is one edit.\n *\n * ⚠️ ROOT-relative (leading slash), never base-relative. A live site is served under a per-org\n * `<base href=\"/<label>/\">`, so a relative `api/…` resolved to `/<label>/api/…` — a path the reverse\n * proxy (`/api` → iox-cms, everything else → the engine) hands to the ENGINE, which answers a POST with\n * 404: no visitor submission ever reached iox-cms from an org path (found 2026-10-19 by\n * e2e:forminsert:real). The org is already in the path segment after `site/`.\n */\nexport function submitEndpointPath(orgId: string, formId: string): string {\n return `/api/site/${encodeURIComponent(orgId)}/forms/${encodeURIComponent(formId)}/submit`;\n}\n\n/**\n * Add the anti-spam fields to the collected values.\n *\n * Both are invisible to a real visitor and cost them nothing (decision D12). `renderedAt` is the\n * time the form was rendered, NOT the time of submit — the server measures the difference to catch\n * a script that fills and posts instantly.\n */\nexport function withAntiSpamFields(\n values: Record<string, any>,\n renderedAt: number,\n honeypotValue = '',\n): Record<string, any> {\n return { ...values, [HONEYPOT_FIELD]: honeypotValue, [RENDERED_AT_FIELD]: renderedAt };\n}\n\n/**\n * Normalise whatever came back into a `SubmitResponse`.\n *\n * Fails CLOSED: anything that is not a recognisable success is treated as a failure. A malformed\n * body must never show the visitor a Success state for a submission that was not stored — that is\n * the one lie this feature must not tell.\n */\nexport function interpretSubmitResponse(body: any): SubmitResponse {\n if (!body || typeof body !== 'object' || body.ok !== true) {\n return {\n ok: false,\n errors: normaliseErrors(body?.errors),\n };\n }\n const redirect = typeof body.redirect === 'string' && body.redirect.trim()\n ? body.redirect.trim()\n : undefined;\n return { ok: true, redirect };\n}\n\n/** Keep only entries that actually carry a message, so a junk key cannot blank a field's error. */\nfunction normaliseErrors(raw: any): Record<string, FieldError> | undefined {\n if (!raw || typeof raw !== 'object') return undefined;\n const errors: Record<string, FieldError> = {};\n for (const [name, value] of Object.entries(raw as Record<string, any>)) {\n const messageKey = typeof value?.messageKey === 'string' ? value.messageKey : '';\n if (!messageKey) continue;\n errors[name] = value?.params ? { messageKey, params: value.params } : { messageKey };\n }\n return Object.keys(errors).length ? errors : undefined;\n}\n","/**\n * FORM PRESETS — a complete, working form as one insert: its fields, its submit label and the words of\n * its Success and Error blocks. ONE definition (W1.1): the builder's Forms tray builds a preset from\n * here (`buildFormPreset`, iox-builder), and the site composer (`generation-core`) stamps the SAME preset\n * into a composed page, so a generated contact form is the real one — never a second, drifting copy.\n * Data only: framework-free, like the rest of forms-core.\n */\n\nexport enum FormPresetId {\n Contact = 'contact',\n Newsletter = 'newsletter',\n Application = 'application',\n Booking = 'booking',\n}\n\nexport interface FormPresetField {\n label: string;\n control: string;\n required?: boolean;\n help?: string;\n placeholder?: string;\n /** Choices for select/radio, `value|Label` per line — the Field's `optionsText` trait. */\n optionsText?: string;\n rows?: number;\n}\n\nexport interface FormPresetDef {\n id: `${FormPresetId}`;\n name: string;\n icon: string;\n /** One line in the panel: what it collects and where it goes. */\n description: string;\n /** The form's author-facing name, which the submissions inbox groups by. */\n formName: string;\n fields: FormPresetField[];\n submitLabel: string;\n successText: string;\n errorText: string;\n}\n\n// forms-core is imported by both renderers (the field runtime), and a renderer that never reads the presets\n// must drop them: the call is `@__PURE__`, and the ids are written as the enum's VALUES (typed by it, pinned\n// to it by form-presets.spec) — a read of `FormPresetId.X` counts as a side effect to a bundler and kept the\n// whole list in the engine's bundle.\nexport const FORM_PRESETS: readonly FormPresetDef[] = /* @__PURE__ */ Object.freeze([\n {\n id: 'contact', name: 'Contact', icon: 'ph-thin ph-envelope-simple',\n description: 'Name, email and a message. Stored, and emailed to you.',\n formName: 'Contact form',\n fields: [\n { label: 'Full name', control: 'text', required: true },\n { label: 'Email', control: 'email', required: true },\n { label: 'Message', control: 'textarea', required: true, rows: 5 },\n ],\n submitLabel: 'Send message',\n successText: 'Thanks — we’ll be in touch shortly.',\n errorText: 'We couldn’t send your message. Please try again — your answers are still here.',\n },\n {\n id: 'newsletter', name: 'Newsletter', icon: 'ph-thin ph-paper-plane-tilt',\n description: 'One email field plus consent. Stored.',\n formName: 'Newsletter signup',\n fields: [\n { label: 'Email', control: 'email', required: true, placeholder: 'you@company.com' },\n // Consent is a checkbox that must be TICKED — `required` on a checkbox becomes the\n // `accepted` rule, with its own message, rather than a generic \"this is required\".\n { label: 'Email me occasional updates', control: 'checkbox', required: true },\n ],\n submitLabel: 'Subscribe',\n successText: 'You’re on the list.',\n errorText: 'We couldn’t sign you up. Please try again.',\n },\n {\n id: 'application', name: 'Application', icon: 'ph-thin ph-read-cv-logo',\n description: 'Details plus a CV upload. Stored, with an auto-reply.',\n formName: 'Application',\n fields: [\n { label: 'Full name', control: 'text', required: true },\n { label: 'Email', control: 'email', required: true },\n { label: 'Phone', control: 'tel' },\n { label: 'Role', control: 'select', required: true, optionsText: 'Design\\nEngineering\\nOther' },\n { label: 'CV', control: 'file', required: true, help: 'PDF or Word, up to 5MB' },\n { label: 'Anything else', control: 'textarea', rows: 4 },\n ],\n submitLabel: 'Apply',\n successText: 'Application received — we’ll read it properly and reply.',\n errorText: 'We couldn’t submit your application. Please try again.',\n },\n {\n id: 'booking', name: 'Booking request', icon: 'ph-thin ph-calendar-check',\n description: 'Date and party size. Stored, and it notifies you.',\n formName: 'Booking request',\n fields: [\n { label: 'Name', control: 'text', required: true },\n { label: 'Email', control: 'email', required: true },\n { label: 'Date', control: 'date', required: true },\n { label: 'People', control: 'number', required: true },\n { label: 'Notes', control: 'textarea', rows: 3, help: 'Allergies, access needs, anything useful' },\n ],\n submitLabel: 'Request a booking',\n successText: 'Request received — we’ll confirm by email.',\n errorText: 'We couldn’t send your request. Please try again.',\n },\n]);\n\n/** The preset with this id, or undefined. */\nexport function formPresetById(id: string | null | undefined): FormPresetDef | undefined {\n return FORM_PRESETS.find(p => p.id === id);\n}\n","// Where form content may NOT render (Doron, 2026-10-20): inside a link or a button.\n//\n// HTML forbids interactive content inside `<a>` and `<button>`, and a click in a field may follow the\n// link. ONE table and ONE walk, shared by the builder's insert rule (refuse it), the builder's audit\n// (find it in a page saved before the rule) and the engine (warn about it, never rewrite it).\n\nimport { FIELD_NODE_TYPE, FORM_NODE_TYPE } from './collect';\n\nexport enum InteractiveTag {\n Anchor = 'a',\n Button = 'button',\n}\n\n/**\n * Every node type that renders as an interactive element, and the element(s) it can render. A ButtonBlock\n * renders `<a>` or `<button>` by its `tag` trait — both interactive, so switching the tag never lifts the\n * rule. Pinned to the engine components' selectors by `interactive-hosts.spec.ts`.\n */\nexport const INTERACTIVE_HOST_TAGS: Readonly<Record<string, readonly InteractiveTag[]>> = Object.freeze({\n // A LinkedContainer is an <a>, or — as an Accordion's header (CC2) — a <button>.\n LinkedContainer: [InteractiveTag.Anchor, InteractiveTag.Button],\n Link: [InteractiveTag.Anchor],\n Button: [InteractiveTag.Anchor],\n ButtonBlock: [InteractiveTag.Anchor, InteractiveTag.Button],\n SubmitButton: [InteractiveTag.Button],\n});\n\nexport const FIELD_GROUP_NODE_TYPE = 'FieldGroup';\nexport const SUBMIT_BUTTON_NODE_TYPE = 'SubmitButton';\n\n/**\n * Form content — what a link or a button must never hold: a Form (its controls), a Field (an input, select\n * or textarea), a SubmitButton (a `<button>`) and a FieldGroup (it exists only to hold fields, so it moves as\n * one). A Success / Error block is text and lives only inside its form, so it is not on the list.\n */\nexport const FORM_CONTENT_TYPES: ReadonlySet<string> = new Set([\n FORM_NODE_TYPE, FIELD_NODE_TYPE, FIELD_GROUP_NODE_TYPE, SUBMIT_BUTTON_NODE_TYPE,\n]);\n\n/** The minimum a node must look like — a builder ComponentNode and a saved layout node both do. */\nexport interface NestingNode {\n id?: string;\n type?: string;\n label?: string;\n children?: NestingNode[] | null;\n}\n\nexport function isInteractiveHost(node: NestingNode | null | undefined): boolean {\n return !!node?.type && Object.prototype.hasOwnProperty.call(INTERACTIVE_HOST_TAGS, node.type);\n}\n\nexport function isFormContent(node: NestingNode | null | undefined): boolean {\n return !!node?.type && FORM_CONTENT_TYPES.has(node.type);\n}\n\n/**\n * The first form-content node in `node`'s subtree that sits inside an interactive host, or null. `insideHost`\n * is true when `node` is placed under a host already — so a Form dropped into a link and a link that holds a\n * Form are the same finding.\n */\nexport function formContentInHost(node: NestingNode | null | undefined, insideHost = false): NestingNode | null {\n if (!node) return null;\n if (insideHost && isFormContent(node)) return node;\n const nowInside = insideHost || isInteractiveHost(node);\n for (const child of node.children ?? []) {\n const found = formContentInHost(child, nowInside);\n if (found) return found;\n }\n return null;\n}\n\n/** One place a tree holds form content inside a link or a button. */\nexport interface MisplacedFormContent<N extends NestingNode = NestingNode> {\n /** The OUTERMOST interactive host holding it. */\n host: N;\n /** A MAXIMAL form-content subtree inside it — the Form, never each of its fields. */\n content: N;\n}\n\n/** Every form-content subtree a tree holds inside an interactive host, in document order. */\nexport function findFormContentInHosts<N extends NestingNode>(roots: readonly N[] | null | undefined): MisplacedFormContent<N>[] {\n const out: MisplacedFormContent<N>[] = [];\n const visit = (node: N, host: N | null): void => {\n if (host && isFormContent(node)) {\n out.push({ host, content: node });\n return;\n }\n const nextHost = host ?? (isInteractiveHost(node) ? node : null);\n for (const child of (node.children ?? []) as N[]) visit(child, nextHost);\n };\n for (const root of roots ?? []) visit(root, null);\n return out;\n}\n","/*\n * @vectoriox/iox-ui/forms-core — the shared, FRAMEWORK-FREE core of the forms feature.\n *\n * ⚠️ Nothing in this entry point may import Angular, RxJS, the DOM, or Node. It is consumed by\n * THREE runtimes: the builder canvas (Angular), the SSR engine (Angular), and `iox-cms` (NestJS,\n * plain Node). The main `@vectoriox/iox-ui` entry pulls in `@angular/core`, which Nest must never\n * load — that is the entire reason this secondary entry point exists.\n *\n * Client-side validation is UX; server-side validation is truth. Both run THIS code, so they cannot\n * disagree. See iox-ai-guidance `architecture/builder/forms-and-inputs-plan.md` §5.\n */\n\nexport * from './form.model';\nexport * from './messages';\nexport * from './validate';\nexport * from './collect';\nexport * from './options';\nexport * from './runtime';\nexport * from './rule-catalog';\nexport * from './transport';\nexport * from './form-presets';\nexport * from './nesting';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"vectoriox-iox-ui-forms-core.mjs","sources":["../../../projects/iox-ui/src/forms-core/form.model.ts","../../../projects/iox-ui/src/forms-core/messages.ts","../../../projects/iox-ui/src/forms-core/validate.ts","../../../projects/iox-ui/src/forms-core/options.ts","../../../projects/iox-ui/src/forms-core/collect.ts","../../../projects/iox-ui/src/forms-core/runtime.ts","../../../projects/iox-ui/src/forms-core/rule-catalog.ts","../../../projects/iox-ui/src/forms-core/transport.ts","../../../projects/iox-ui/src/forms-core/submit-lifecycle.ts","../../../projects/iox-ui/src/forms-core/form-presets.ts","../../../projects/iox-ui/src/forms-core/nesting.ts","../../../projects/iox-ui/src/forms-core/public-api.ts","../../../projects/iox-ui/src/forms-core/vectoriox-iox-ui-forms-core.ts"],"sourcesContent":["// The persisted shape of a form. Pure types + the one derived constant each renderer needs.\n//\n// A FormSpec is DERIVED from the node tree (see `collect.ts`), never hand-maintained beside it —\n// there is one source of truth for \"what fields does this form have\", and it is the tree the author\n// edited. The builder writes the derived spec into the saved page so the SERVER can re-validate\n// against it without re-implementing the builder's tree walk.\n\n/** What the visitor actually types into. Chosen by a trait; it also implies a validation rule. */\nexport enum ControlType {\n Text = 'text',\n Email = 'email',\n Tel = 'tel',\n Url = 'url',\n Number = 'number',\n Password = 'password',\n Textarea = 'textarea',\n Select = 'select',\n Checkbox = 'checkbox',\n /** A checkbox in switch clothing (role=\"switch\") — consent toggles, settings-style forms. */\n Switch = 'switch',\n /** A slider over a numeric range — min/max/step ride the field. */\n Range = 'range',\n Radio = 'radio',\n Date = 'date',\n Time = 'time',\n File = 'file',\n /** Not shown; carries a constant or a bound value (campaign, source page, …). */\n Hidden = 'hidden',\n}\n\n/** The v1 rule grammar. Phase 3's conditional logic reuses these same names for its conditions. */\nexport enum RuleName {\n Required = 'required',\n MinLength = 'minLength',\n MaxLength = 'maxLength',\n Min = 'min',\n Max = 'max',\n Pattern = 'pattern',\n /** Cross-field: this value must equal another field's (confirm email / password). */\n Matches = 'matches',\n /** A checkbox that must be ticked — terms, consent. */\n Accepted = 'accepted',\n FileType = 'fileType',\n FileSize = 'fileSize',\n}\n\n/** Named regexes so an author picks \"Email\" rather than writing one. */\nexport enum PatternPreset {\n Email = 'email',\n Phone = 'phone',\n Url = 'url',\n Digits = 'digits',\n Letters = 'letters',\n Slug = 'slug',\n}\n\n/**\n * Deliberately permissive. A validator that rejects `user+tag@sub.domain.co.uk` or a real-world\n * phone number is worse than one that lets a typo through: the address gets verified by sending to\n * it, and a false rejection is a lost lead with no recourse.\n */\nexport const PATTERN_PRESETS: Readonly<Record<PatternPreset, RegExp>> = Object.freeze({\n [PatternPreset.Email]: /^[^\\s@]+@[^\\s@.]+(\\.[^\\s@.]+)+$/,\n [PatternPreset.Phone]: /^\\+?[\\d\\s().-]{6,20}$/,\n [PatternPreset.Url]: /^(https?:\\/\\/)?[^\\s.]+\\.[^\\s]{2,}$/i,\n [PatternPreset.Digits]: /^\\d+$/,\n [PatternPreset.Letters]: /^[\\p{L}\\s'-]+$/u,\n [PatternPreset.Slug]: /^[a-z0-9]+(-[a-z0-9]+)*$/,\n});\n\nexport interface ValidationRule {\n name: RuleName;\n /** `{ n }` for lengths/bounds · `{ preset } | { regex }` for pattern · `{ field }` for matches. */\n params?: Record<string, any>;\n /** Author's override. Absent → the shared message catalog supplies a translated key. */\n message?: string;\n}\n\nexport interface FieldOption {\n label: string;\n value: string;\n}\n\n/** Options pulled from a data source instead of typed by hand (a Select of CMS categories). */\nexport interface FieldOptionSource {\n source: string;\n sourcePath?: string;\n valuePath: string;\n labelPath: string;\n}\n\nexport interface FieldSpec {\n /** The submitted key. Derived from the label, unique within the form, editable. */\n name: string;\n control: ControlType;\n label: string;\n /** Surfaced as its own switch in the panel rather than buried in the rule list. */\n required?: boolean;\n rules?: ValidationRule[];\n options?: FieldOption[];\n optionsSource?: FieldOptionSource;\n defaultValue?: any;\n}\n\n/** When a field is validated, once the author has stopped deciding it per field. */\nexport enum FeedbackTiming {\n /** Validate on submit, then live per-field once that field has been touched or has failed. */\n Smart = 'smart',\n Submit = 'submit',\n Live = 'live',\n}\n\n/** What happens to a submission, in order. Card #1 (`store`) is always present. */\nexport interface SubmitAction {\n type: string;\n config?: Record<string, any>;\n /** `retry` (default) · `fail` · `ignore`. */\n onFailure?: 'retry' | 'fail' | 'ignore';\n}\n\nexport interface FormSpec {\n formId: string;\n /** Author-facing name — the submissions inbox groups by it. */\n name: string;\n feedback: FeedbackTiming;\n fields: FieldSpec[];\n actions: SubmitAction[];\n antiSpam: { honeypot: boolean; minFillMs: number; turnstile?: boolean };\n retention?: { days: number };\n}\n\n/**\n * The rule a control type implies with no configuration. Choosing \"Email\" IS choosing email\n * validation — the single biggest reason the panel can stay empty and still validate well.\n */\nexport const IMPLIED_PATTERN: Readonly<Partial<Record<ControlType, PatternPreset>>> = Object.freeze({\n [ControlType.Email]: PatternPreset.Email,\n [ControlType.Tel]: PatternPreset.Phone,\n [ControlType.Url]: PatternPreset.Url,\n});\n\n/** Controls whose value is a list rather than a scalar. */\nexport const MULTI_VALUE_CONTROLS: ReadonlySet<ControlType> = new Set([ControlType.File]);\n","// The default message for every rule, as an i18n KEY — never a rendered string.\n//\n// This is what lets the Validation panel stay empty and still produce good errors: an author who\n// configures nothing gets \"Enter a valid email address\", not \"Invalid\". The author's own `message`\n// on a rule always wins; this is the fallback, and it is the only place a default lives.\n//\n// Consumers translate the key with their own i18n (the CMS client via ngx-translate, the engine via\n// the page's locale bundle). The backend returns the key too, so a server-side rejection renders in\n// the visitor's language rather than in the server's.\n\nimport { RuleName } from './form.model';\n\n/** Namespace for every forms validation key. Keep in sync with `en.json` / `he.json`. */\nexport const MESSAGE_NAMESPACE = 'forms.validation';\n\n/**\n * Rule → i18n key. Params travel beside the key (`{ n: 8 }`, `{ field: 'Email' }`) so a translation\n * can place the number wherever its grammar needs it, rather than having it baked into the string.\n */\nexport const RULE_MESSAGE_KEYS: Readonly<Record<RuleName, string>> = Object.freeze({\n [RuleName.Required]: `${MESSAGE_NAMESPACE}.required`,\n [RuleName.MinLength]: `${MESSAGE_NAMESPACE}.minLength`,\n [RuleName.MaxLength]: `${MESSAGE_NAMESPACE}.maxLength`,\n [RuleName.Min]: `${MESSAGE_NAMESPACE}.min`,\n [RuleName.Max]: `${MESSAGE_NAMESPACE}.max`,\n // ⚠️ `.pattern.generic`, not `.pattern`: the preset keys below live UNDER `pattern`, and a JSON\n // translation bundle cannot have the same key be both a string and an object — ngx-translate\n // would hand back the object (or the raw key) for the generic case.\n [RuleName.Pattern]: `${MESSAGE_NAMESPACE}.pattern.generic`,\n [RuleName.Matches]: `${MESSAGE_NAMESPACE}.matches`,\n [RuleName.Accepted]: `${MESSAGE_NAMESPACE}.accepted`,\n [RuleName.FileType]: `${MESSAGE_NAMESPACE}.fileType`,\n [RuleName.FileSize]: `${MESSAGE_NAMESPACE}.fileSize`,\n});\n\n/**\n * A pattern failure deserves better than \"Invalid format\". Each preset gets its own key so the\n * message can say what a valid value looks like, which is the difference between a visitor fixing\n * a typo and a visitor giving up.\n */\nexport const PATTERN_MESSAGE_KEYS: Readonly<Record<string, string>> = Object.freeze({\n email: `${MESSAGE_NAMESPACE}.pattern.email`,\n phone: `${MESSAGE_NAMESPACE}.pattern.phone`,\n url: `${MESSAGE_NAMESPACE}.pattern.url`,\n digits: `${MESSAGE_NAMESPACE}.pattern.digits`,\n letters: `${MESSAGE_NAMESPACE}.pattern.letters`,\n slug: `${MESSAGE_NAMESPACE}.pattern.slug`,\n});\n\n/** Form-level outcomes the visitor sees in the Error state. One designed block, five reasons. */\nexport const FORM_ERROR_KEYS = Object.freeze({\n Network: `${MESSAGE_NAMESPACE}.form.network`,\n Rejected: `${MESSAGE_NAMESPACE}.form.rejected`,\n Spam: `${MESSAGE_NAMESPACE}.form.spam`,\n RateLimited: `${MESSAGE_NAMESPACE}.form.rateLimited`,\n Server: `${MESSAGE_NAMESPACE}.form.server`,\n});\n\n/** The English defaults, so a consumer that has not added the keys yet still shows real text. */\nexport const DEFAULT_EN_MESSAGES: Readonly<Record<string, string>> = Object.freeze({\n [RULE_MESSAGE_KEYS[RuleName.Required]]: 'This field is required',\n [RULE_MESSAGE_KEYS[RuleName.MinLength]]: 'Use at least {{n}} characters',\n [RULE_MESSAGE_KEYS[RuleName.MaxLength]]: 'Use no more than {{n}} characters',\n [RULE_MESSAGE_KEYS[RuleName.Min]]: 'Enter {{n}} or more',\n [RULE_MESSAGE_KEYS[RuleName.Max]]: 'Enter {{n}} or less',\n [RULE_MESSAGE_KEYS[RuleName.Pattern]]: 'Check the format of this value',\n [RULE_MESSAGE_KEYS[RuleName.Matches]]: 'This must match {{field}}',\n [RULE_MESSAGE_KEYS[RuleName.Accepted]]: 'Please tick this to continue',\n [RULE_MESSAGE_KEYS[RuleName.FileType]]: 'That file type isn’t accepted',\n [RULE_MESSAGE_KEYS[RuleName.FileSize]]: 'That file is larger than {{n}}MB',\n [PATTERN_MESSAGE_KEYS['email']]: 'Enter a valid email address',\n [PATTERN_MESSAGE_KEYS['phone']]: 'Enter a valid phone number',\n [PATTERN_MESSAGE_KEYS['url']]: 'Enter a valid web address',\n [PATTERN_MESSAGE_KEYS['digits']]: 'Use digits only',\n [PATTERN_MESSAGE_KEYS['letters']]: 'Use letters only',\n [PATTERN_MESSAGE_KEYS['slug']]: 'Use lowercase letters, numbers and hyphens',\n [FORM_ERROR_KEYS.Network]: 'We couldn’t reach the server — check your connection and try again',\n [FORM_ERROR_KEYS.Rejected]: 'Some answers need fixing',\n [FORM_ERROR_KEYS.Spam]: 'We couldn’t accept this submission',\n [FORM_ERROR_KEYS.RateLimited]: 'Too many attempts — please wait a moment and try again',\n [FORM_ERROR_KEYS.Server]: 'Something went wrong on our side — your answers are still here',\n});\n","// The validator. ONE implementation, run by the builder canvas, the SSR engine and `iox-cms`.\n//\n// Client-side validation is UX; server-side validation is truth. Because both call this function,\n// a visitor can never be told a value is fine and then have the server reject it, and a hand-crafted\n// POST can never bypass a rule the author configured.\n\nimport {\n ControlType,\n FieldSpec,\n FormSpec,\n IMPLIED_PATTERN,\n PATTERN_PRESETS,\n PatternPreset,\n RuleName,\n ValidationRule,\n} from './form.model';\nimport { PATTERN_MESSAGE_KEYS, RULE_MESSAGE_KEYS } from './messages';\n\nexport interface FieldError {\n /** i18n key, or the author's own override string when they set one. */\n messageKey: string;\n /** Interpolation values (`{ n: 8 }`, `{ field: 'Email' }`). */\n params?: Record<string, any>;\n}\n\nexport interface FieldResult extends Partial<FieldError> {\n valid: boolean;\n}\n\nexport interface FormResult {\n valid: boolean;\n /** Keyed by field name. Empty when valid. */\n errors: Record<string, FieldError>;\n}\n\n/** A file, as either runtime hands it over. Kept structural so this file imports no DOM types. */\ninterface FileLike {\n name?: string;\n size?: number;\n type?: string;\n}\n\n/**\n * Validate one field's value.\n *\n * Order is deliberate and is part of the contract:\n * 1. `required` (or `accepted` for a checkbox) — the only rules an EMPTY value can fail.\n * 2. Everything else, in the order the author arranged them, but ONLY for a non-empty value.\n *\n * That second point is what stops an optional \"Phone\" field from shouting \"enter a valid phone\n * number\" at someone who simply left it blank — the single most common validation-UX bug.\n * The FIRST failure wins: a visitor fixes one thing at a time.\n */\nexport function validateField(\n value: unknown,\n spec: FieldSpec,\n form: Record<string, unknown> = {},\n): FieldResult {\n const rules = effectiveRules(spec);\n const empty = isEmpty(value, spec.control);\n\n for (const rule of rules) {\n const appliesToEmpty = rule.name === RuleName.Required || rule.name === RuleName.Accepted;\n if (empty && !appliesToEmpty) continue;\n\n const failure = check(rule, value, spec, form);\n if (failure) {\n return {\n valid: false,\n messageKey: rule.message ?? failure.messageKey,\n params: failure.params,\n };\n }\n }\n return { valid: true };\n}\n\n/**\n * Validate a whole submission. Every field is checked (not short-circuited at the first bad one) so\n * the visitor sees every problem at once instead of fixing them one reload at a time.\n */\nexport function validateForm(\n values: Record<string, unknown>,\n spec: FormSpec,\n): FormResult {\n const errors: Record<string, FieldError> = {};\n for (const field of spec.fields ?? []) {\n const result = validateField(values?.[field.name], field, values ?? {});\n if (!result.valid) {\n errors[field.name] = { messageKey: result.messageKey!, params: result.params };\n }\n }\n return { valid: Object.keys(errors).length === 0, errors };\n}\n\n/** The name of the first field with an error, in spec order — what the browser should focus. */\nexport function firstInvalidField(spec: FormSpec, errors: Record<string, FieldError>): string | null {\n for (const field of spec.fields ?? []) if (errors[field.name]) return field.name;\n return null;\n}\n\n// ─── internals ───────────────────────────────────────────────────────────────\n\n/**\n * The author's rules, plus the ones the field's own configuration implies: `required` from the\n * switch (rather than making the author add a rule for the commonest case) and the pattern implied\n * by an Email/Tel/Url control. An explicitly declared rule of the same name always wins, so an\n * author who sets their own `pattern` on an Email field is not fighting an invisible second one.\n */\nfunction effectiveRules(spec: FieldSpec): ValidationRule[] {\n const declared = spec.rules ?? [];\n const has = (name: RuleName) => declared.some(r => r.name === name);\n const implied: ValidationRule[] = [];\n\n if (spec.required && !has(RuleName.Required)) {\n // A checkbox's \"required\" means TICKED, which is a different message and a different check.\n implied.push(spec.control === ControlType.Checkbox\n ? { name: RuleName.Accepted }\n : { name: RuleName.Required });\n }\n\n const preset = IMPLIED_PATTERN[spec.control];\n if (preset && !has(RuleName.Pattern)) {\n implied.push({ name: RuleName.Pattern, params: { preset } });\n }\n\n return [...implied, ...declared];\n}\n\n/** Empty means \"the visitor gave us nothing\" — per control type, not a blanket falsy check. */\nfunction isEmpty(value: unknown, control: ControlType): boolean {\n if (value === null || value === undefined) return true;\n if (control === ControlType.Checkbox) return value === false;\n if (Array.isArray(value)) return value.length === 0;\n if (typeof value === 'string') return value.trim() === '';\n return false;\n}\n\nfunction check(\n rule: ValidationRule,\n value: unknown,\n spec: FieldSpec,\n form: Record<string, unknown>,\n): FieldError | null {\n const fail = (messageKey: string, params?: Record<string, any>): FieldError => ({ messageKey, params });\n const defaultKey = RULE_MESSAGE_KEYS[rule.name];\n const n = Number(rule.params?.['n']);\n\n switch (rule.name) {\n case RuleName.Required:\n return isEmpty(value, spec.control) ? fail(defaultKey) : null;\n\n case RuleName.Accepted:\n return value === true ? null : fail(defaultKey);\n\n case RuleName.MinLength:\n return text(value).length < n ? fail(defaultKey, { n }) : null;\n\n case RuleName.MaxLength:\n return text(value).length > n ? fail(defaultKey, { n }) : null;\n\n case RuleName.Min: {\n const num = numeric(value);\n return num === null || num < n ? fail(defaultKey, { n }) : null;\n }\n\n case RuleName.Max: {\n const num = numeric(value);\n return num === null || num > n ? fail(defaultKey, { n }) : null;\n }\n\n case RuleName.Pattern: {\n const regex = patternFor(rule);\n if (!regex) return null; // an unparsable custom regex must not block a submission\n if (regex.test(text(value))) return null;\n const preset = rule.params?.['preset'] as string | undefined;\n return fail((preset && PATTERN_MESSAGE_KEYS[preset]) || defaultKey);\n }\n\n case RuleName.Matches: {\n const other = String(rule.params?.['field'] ?? '');\n return text(value) === text(form?.[other]) ? null : fail(defaultKey, { field: other });\n }\n\n case RuleName.FileType: {\n const accepted = list(rule.params?.['types']).map(t => t.toLowerCase().replace(/^\\./, ''));\n if (!accepted.length) return null;\n const bad = files(value).some(f => {\n const ext = (f.name ?? '').split('.').pop()?.toLowerCase() ?? '';\n const mime = (f.type ?? '').toLowerCase();\n return !accepted.some(t => t === ext || mime === t || mime.startsWith(t + '/'));\n });\n return bad ? fail(defaultKey, { types: accepted.join(', ') }) : null;\n }\n\n case RuleName.FileSize: {\n const maxBytes = n * 1024 * 1024;\n return files(value).some(f => (f.size ?? 0) > maxBytes) ? fail(defaultKey, { n }) : null;\n }\n\n default:\n return null;\n }\n}\n\nfunction patternFor(rule: ValidationRule): RegExp | null {\n const preset = rule.params?.['preset'] as PatternPreset | undefined;\n if (preset && PATTERN_PRESETS[preset]) return PATTERN_PRESETS[preset];\n const custom = rule.params?.['regex'];\n if (typeof custom !== 'string' || !custom) return null;\n // A malformed regex is the AUTHOR's mistake; failing open is the only safe reading, because\n // failing closed would make a live form permanently unsubmittable for every visitor.\n try { return new RegExp(custom); } catch { return null; }\n}\n\nconst text = (value: unknown): string =>\n value === null || value === undefined ? '' : String(value).trim();\n\nfunction numeric(value: unknown): number | null {\n const parsed = typeof value === 'number' ? value : parseFloat(text(value));\n return Number.isFinite(parsed) ? parsed : null;\n}\n\nconst list = (value: unknown): string[] =>\n Array.isArray(value) ? value.map(String)\n : typeof value === 'string' ? value.split(',').map(s => s.trim()).filter(Boolean)\n : [];\n\nconst files = (value: unknown): FileLike[] =>\n Array.isArray(value) ? value as FileLike[]\n : value && typeof value === 'object' ? [value as FileLike]\n : [];\n","import { FieldOption } from './form.model';\n\n/** `value|Label` separates a submitted value from what the visitor reads; a bare line is both. */\nconst OPTION_SEPARATOR = '|';\n\n/**\n * A Field's `optionsText` trait — the author's choices, one per line — as options. ONE parser for the\n * builder canvas, both engine paths and iox-cms: until 2026-10-19 nothing parsed the trait, so a Radio\n * group or a Dropdown from the tray rendered no choices at all on the canvas and on the live site.\n */\nexport function parseFieldOptions(text: unknown): FieldOption[] {\n if (typeof text !== 'string') return [];\n const out: FieldOption[] = [];\n for (const line of text.split(/\\r?\\n/)) {\n const raw = line.trim();\n if (!raw) continue;\n const at = raw.indexOf(OPTION_SEPARATOR);\n const value = (at === -1 ? raw : raw.slice(0, at)).trim();\n const label = (at === -1 ? raw : raw.slice(at + 1)).trim() || value;\n if (value) out.push({ value, label });\n }\n return out;\n}\n\n/** The choices a saved Field offers: an explicit `options` list wins, else its `optionsText` parsed. */\nexport function fieldOptionsOf(props: { options?: unknown; optionsText?: unknown } | null | undefined): FieldOption[] {\n if (Array.isArray(props?.options) && props!.options.length) return props!.options as FieldOption[];\n return parseFieldOptions(props?.optionsText);\n}\n","// Derive a FormSpec from a node tree.\n//\n// The tree the author edited is the SINGLE source of truth for \"what fields does this form have\".\n// The spec is derived from it — never maintained beside it — so a field cannot exist in one and not\n// the other. The builder runs this on save and stores the result in the page document; the backend\n// reads THAT stored spec to re-validate a submission (it must never trust a spec sent by the\n// browser). See iox-ai-guidance `architecture/builder/forms-and-inputs-plan.md` §5.1 and D11.\n\nimport {\n ControlType,\n FeedbackTiming,\n FieldSpec,\n FormSpec,\n RuleName,\n SubmitAction,\n ValidationRule,\n} from './form.model';\nimport { fieldOptionsOf } from './options';\n\n/** The minimum a node must look like. Structural on purpose: this file knows no renderer. */\nexport interface FormNodeLike {\n type: string;\n props?: Record<string, any>;\n children?: FormNodeLike[];\n}\n\nexport const FORM_NODE_TYPE = 'Form';\nexport const FIELD_NODE_TYPE = 'Field';\n\n/** Always present, never removable — the safety net that makes \"store first, deliver after\" true. */\nexport const STORE_ACTION: SubmitAction = Object.freeze({ type: 'store' });\n\n/**\n * Turn a label into the key that arrives in the submitted data — `Full name` → `fullName`.\n * Authors never have to invent keys (decision: auto-derive, with an editable override).\n *\n * Diacritics are stripped rather than dropped, so a Hebrew or accented label still yields a usable\n * ASCII key instead of an empty one; a label with no usable characters falls back to `field`.\n */\nexport function deriveFieldName(label: string): string {\n const words = (label ?? '')\n .normalize('NFD').replace(/[̀-ͯ]/g, '')\n .replace(/[^a-zA-Z0-9]+/g, ' ')\n .trim()\n .split(/\\s+/)\n .filter(Boolean);\n if (!words.length) return 'field';\n const [first, ...rest] = words;\n const name = first.toLowerCase() + rest.map(w => w[0].toUpperCase() + w.slice(1).toLowerCase()).join('');\n // A key must not start with a digit — it ends up as an object key and a form control id.\n return /^\\d/.test(name) ? `field${name}` : name;\n}\n\n/** Make `name` unique within `taken`, appending 2, 3, … — two \"Email\" fields must not collide. */\nexport function uniqueFieldName(name: string, taken: ReadonlySet<string>): string {\n if (!taken.has(name)) return name;\n let n = 2;\n while (taken.has(`${name}${n}`)) n++;\n return `${name}${n}`;\n}\n\n/**\n * Walk a Form subtree and produce its spec.\n *\n * Nested forms are not collected: a Field belongs to its NEAREST ancestor Form (decision D1), so the\n * walk stops at any inner Form node rather than stealing its fields.\n */\nexport function collectFormSpec(node: FormNodeLike | null | undefined): FormSpec | null {\n if (!node || node.type !== FORM_NODE_TYPE) return null;\n const props = node.props ?? {};\n\n const fields: FieldSpec[] = [];\n const taken = new Set<string>();\n for (const fieldNode of collectFieldNodes(node.children ?? [])) {\n const spec = toFieldSpec(fieldNode, taken);\n taken.add(spec.name);\n fields.push(spec);\n }\n\n return {\n formId: props['formId'] ?? '',\n name: props['name'] ?? 'Form',\n feedback: (props['feedback'] as FeedbackTiming) ?? FeedbackTiming.Smart,\n fields,\n actions: normaliseActions(props['actions']),\n antiSpam: {\n honeypot: props['honeypot'] !== false,\n minFillMs: Number(props['minFillMs'] ?? 1200),\n ...(props['turnstile'] ? { turnstile: true } : {}),\n },\n ...(props['retentionDays'] ? { retention: { days: Number(props['retentionDays']) } } : {}),\n };\n}\n\n/** Every Field in this subtree, in document order, not descending into a nested Form. */\nexport function collectFieldNodes(nodes: readonly FormNodeLike[]): FormNodeLike[] {\n const out: FormNodeLike[] = [];\n for (const node of nodes ?? []) {\n if (!node?.type) continue;\n if (node.type === FORM_NODE_TYPE) continue; // a nested form owns its own fields\n if (node.type === FIELD_NODE_TYPE) { out.push(node); continue; }\n out.push(...collectFieldNodes(node.children ?? []));\n }\n return out;\n}\n\nfunction toFieldSpec(node: FormNodeLike, taken: ReadonlySet<string>): FieldSpec {\n const props = node.props ?? {};\n const label = props['label'] ?? '';\n // The author's explicit override wins; otherwise derive from the label.\n const name = uniqueFieldName(props['name'] || deriveFieldName(label), taken);\n\n const spec: FieldSpec = {\n name,\n control: (props['control'] as ControlType) ?? ControlType.Text,\n label,\n };\n if (props['required']) spec.required = true;\n const rules = normaliseRules(props['rules']);\n if (rules.length) spec.rules = rules;\n const options = fieldOptionsOf(props);\n if (options.length) spec.options = options;\n if (props['optionsSource']) spec.optionsSource = props['optionsSource'];\n if (props['defaultValue'] !== undefined && props['defaultValue'] !== '') {\n spec.defaultValue = props['defaultValue'];\n }\n return spec;\n}\n\n/** Drop anything that isn't a rule we know — a hand-edited page must not break validation. */\nfunction normaliseRules(raw: unknown): ValidationRule[] {\n if (!Array.isArray(raw)) return [];\n const known = new Set<string>(Object.values(RuleName));\n return raw\n .filter(r => r && known.has(r.name))\n .map(r => ({\n name: r.name as RuleName,\n ...(r.params ? { params: r.params } : {}),\n ...(r.message ? { message: r.message } : {}),\n }));\n}\n\n/** `store` is always first and always present, however the page was edited. */\nfunction normaliseActions(raw: unknown): SubmitAction[] {\n const declared: SubmitAction[] = Array.isArray(raw)\n ? raw.filter(a => a && typeof a.type === 'string')\n : [];\n return [STORE_ACTION, ...declared.filter(a => a.type !== STORE_ACTION.type)];\n}\n","// When a field's error is allowed to be VISIBLE — the pure half of the form runtime.\n//\n// Validity and visibility are different questions. A field can be invalid from the moment the page\n// loads (an empty required field always is), but showing that immediately means greeting a visitor\n// with a wall of red before they have typed anything. This module owns the second question, and it\n// owns it in one place so the builder canvas, the SSR engine and any future runtime agree.\n//\n// Framework-free, like the rest of forms-core.\n\nimport { FeedbackTiming, FormSpec } from './form.model';\nimport { FieldError, validateField, validateForm } from './validate';\n\n/** Everything the runtime needs to remember. Immutable — each transition returns a new state. */\nexport interface FormRuntimeState {\n /** Field names the visitor has left (blurred) at least once. */\n touched: ReadonlySet<string>;\n /** True once a submit has been attempted — after that, every error is fair game. */\n submitted: boolean;\n /** The current errors, whether or not they are being shown. */\n errors: Readonly<Record<string, FieldError>>;\n /** In flight — the submit button shows its loading label and the form is aria-busy. */\n submitting: boolean;\n}\n\nexport const INITIAL_FORM_STATE: FormRuntimeState = Object.freeze({\n touched: new Set<string>(),\n submitted: false,\n errors: {},\n submitting: false,\n});\n\n/**\n * Should this field's error be on screen right now?\n *\n * - `Submit` — only after a submit attempt. Quietest; nothing moves while typing.\n * - `Live` — as soon as it is invalid. Loudest; shouts at a half-typed email address.\n * - `Smart` — the default, and the reason the author gets one dropdown instead of a decision per\n * field: stay quiet until the visitor has either left the field or tried to submit.\n * After that, correct live, so fixing an error clears it as they type.\n */\nexport function shouldShowError(\n fieldName: string,\n state: FormRuntimeState,\n timing: FeedbackTiming | string = FeedbackTiming.Smart,\n): boolean {\n if (!state.errors[fieldName]) return false;\n switch (timing) {\n case FeedbackTiming.Live: return true;\n case FeedbackTiming.Submit: return state.submitted;\n default: return state.submitted || state.touched.has(fieldName);\n }\n}\n\n/**\n * Re-validate one field after a change. Only that field is re-checked, EXCEPT that a `matches` rule\n * makes another field's validity depend on this one — so a confirm-email field stops being wrong\n * the moment you fix the address it points at, rather than waiting for its own blur.\n */\nexport function onFieldChange(\n state: FormRuntimeState,\n fieldName: string,\n values: Record<string, unknown>,\n spec: FormSpec,\n): FormRuntimeState {\n const errors = { ...state.errors };\n const affected = [fieldName, ...dependentsOf(fieldName, spec)];\n\n for (const name of affected) {\n const field = (spec.fields ?? []).find(f => f.name === name);\n if (!field) continue;\n const result = validateField(values?.[name], field, values ?? {});\n if (result.valid) delete errors[name];\n else errors[name] = { messageKey: result.messageKey!, params: result.params };\n }\n return { ...state, errors };\n}\n\n/** Mark a field touched (on blur) and re-check it, so Smart timing can start showing its error. */\nexport function onFieldBlur(\n state: FormRuntimeState,\n fieldName: string,\n values: Record<string, unknown>,\n spec: FormSpec,\n): FormRuntimeState {\n const touched = new Set(state.touched);\n touched.add(fieldName);\n return { ...onFieldChange(state, fieldName, values, spec), touched };\n}\n\n/**\n * A submit attempt. Validates everything and flips `submitted`, so from here on every error shows\n * whatever the timing setting is — a visitor who pressed the button is owed the full picture.\n */\nexport function onSubmitAttempt(\n state: FormRuntimeState,\n values: Record<string, unknown>,\n spec: FormSpec,\n): FormRuntimeState {\n const { errors } = validateForm(values ?? {}, spec);\n return { ...state, submitted: true, errors };\n}\n\n/** Server-side rejection: adopt the server's errors verbatim. It is the authority, not the client. */\nexport function applyServerErrors(\n state: FormRuntimeState,\n errors: Record<string, FieldError>,\n): FormRuntimeState {\n return { ...state, submitted: true, submitting: false, errors: { ...errors } };\n}\n\n/** A clean slate after a successful submit, for a form configured to clear itself. */\nexport function resetFormState(): FormRuntimeState {\n return { touched: new Set<string>(), submitted: false, errors: {}, submitting: false };\n}\n\n/** Field names whose validity depends on `fieldName` through a `matches` rule. */\nfunction dependentsOf(fieldName: string, spec: FormSpec): string[] {\n return (spec.fields ?? [])\n .filter(f => (f.rules ?? []).some(r => r.params?.['field'] === fieldName))\n .map(f => f.name);\n}\n","/**\n * Which rules exist, and which controls they make sense on.\n *\n * The panel must not offer \"must be ticked\" on a text field, or a character limit on a date. That\n * knowledge belongs with the validator, not duplicated into the editor — otherwise the two drift and\n * an author configures a rule that silently never runs.\n *\n * Pure data, in forms-core, so the builder panel, the engine and the backend all read one catalog.\n */\n\nimport { ControlType, PatternPreset, RuleName } from './form.model';\n\n/** How a rule's parameter is edited. The panel maps these to its own controls. */\nexport enum RuleParamKind {\n /** No parameter — the rule is its own statement (`required`, `accepted`). */\n None = 'none',\n /** A single number (`{ n }`) — lengths and bounds. */\n Number = 'number',\n /** A preset regex, or a custom one (`{ preset }` / `{ regex }`). */\n Pattern = 'pattern',\n /** Another field in the same form (`{ field }`). */\n Field = 'field',\n}\n\nexport interface RuleDescriptor {\n name: RuleName;\n /** i18n key for the rule's name in the Add-rule menu. */\n labelKey: string;\n param: RuleParamKind;\n /** Controls this rule can apply to. Empty means every control. */\n controls: readonly ControlType[];\n /** Suggested starting value for the parameter, so a freshly added rule is already valid. */\n defaultParams?: Record<string, any>;\n}\n\n/** Text-ish controls: the ones whose value is a string a person typed. */\nconst TEXTUAL: readonly ControlType[] = [\n ControlType.Text, ControlType.Email, ControlType.Tel, ControlType.Url,\n ControlType.Password, ControlType.Textarea,\n];\n\n/** Controls with a comparable magnitude. */\nconst NUMERIC: readonly ControlType[] = [ControlType.Number, ControlType.Date, ControlType.Time, ControlType.Range];\n\nexport const RULE_DESCRIPTORS: readonly RuleDescriptor[] = Object.freeze([\n {\n name: RuleName.MinLength, labelKey: 'forms.rules.minLength',\n param: RuleParamKind.Number, controls: TEXTUAL, defaultParams: { n: 2 },\n },\n {\n name: RuleName.MaxLength, labelKey: 'forms.rules.maxLength',\n param: RuleParamKind.Number, controls: TEXTUAL, defaultParams: { n: 200 },\n },\n {\n name: RuleName.Min, labelKey: 'forms.rules.min',\n param: RuleParamKind.Number, controls: NUMERIC, defaultParams: { n: 0 },\n },\n {\n name: RuleName.Max, labelKey: 'forms.rules.max',\n param: RuleParamKind.Number, controls: NUMERIC, defaultParams: { n: 100 },\n },\n {\n name: RuleName.Pattern, labelKey: 'forms.rules.pattern',\n param: RuleParamKind.Pattern, controls: TEXTUAL,\n defaultParams: { preset: PatternPreset.Email },\n },\n {\n // Cross-field: confirm-email, confirm-password.\n name: RuleName.Matches, labelKey: 'forms.rules.matches',\n param: RuleParamKind.Field, controls: [],\n },\n {\n // A checkbox's `required` already becomes `accepted`, so offering it again would be a\n // duplicate — it is here for a checkbox the author wants ticked WITHOUT marking it required.\n name: RuleName.Accepted, labelKey: 'forms.rules.accepted',\n param: RuleParamKind.None, controls: [ControlType.Checkbox, ControlType.Switch],\n },\n]);\n\n/** The rules that can be added to a field of this control type. */\nexport function rulesFor(control: ControlType | string): RuleDescriptor[] {\n return RULE_DESCRIPTORS.filter(rule =>\n rule.controls.length === 0 || rule.controls.includes(control as ControlType));\n}\n\n/**\n * The rules an author may still ADD — the catalog minus what is already on the field.\n *\n * Each rule appears once: two `maxLength` rules on one field is not a configuration anyone means,\n * and the validator would apply whichever came first. `pattern` is the exception a caller might\n * expect to repeat, and it deliberately does not: a second pattern can only contradict the first.\n */\nexport function addableRules(\n control: ControlType | string,\n existing: readonly { name: RuleName }[] = [],\n): RuleDescriptor[] {\n const used = new Set(existing.map(rule => rule.name));\n return rulesFor(control).filter(rule => !used.has(rule.name));\n}\n\n/** The preset options a Pattern rule offers, in the order the panel should list them. */\nexport const PATTERN_PRESET_OPTIONS: readonly { value: PatternPreset; labelKey: string }[] = Object.freeze([\n { value: PatternPreset.Email, labelKey: 'forms.rules.preset.email' },\n { value: PatternPreset.Phone, labelKey: 'forms.rules.preset.phone' },\n { value: PatternPreset.Url, labelKey: 'forms.rules.preset.url' },\n { value: PatternPreset.Digits, labelKey: 'forms.rules.preset.digits' },\n { value: PatternPreset.Letters, labelKey: 'forms.rules.preset.letters' },\n { value: PatternPreset.Slug, labelKey: 'forms.rules.preset.slug' },\n]);\n\n// ── MOVED to @vectoriox/iox-ui/actions-core (A0) ─────────────────────────────\n// The descriptor shape and the after-submit catalog are the ONE action vocabulary the whole\n// product shares; element actions (A1) consume the same shape. Re-exported here under the\n// original names so no forms consumer changes a line.\nexport type { ActionDescriptor } from '@vectoriox/iox-ui/actions-core';\nexport { FORM_SUBMIT_ACTION_DESCRIPTORS as ACTION_DESCRIPTORS, addableActions } from '@vectoriox/iox-ui/actions-core';\n","/**\n * The submit transport CONTRACT — what a host must provide to make a form actually send.\n *\n * The Form component deliberately owns no HTTP: the builder canvas must never post (an author\n * clicking Submit while designing would file a real submission), and the SSR engine posts through\n * Angular's HttpClient. What IS shared is everything around the call — the endpoint's shape, the\n * anti-spam fields, and how the server's answer maps onto the form's state. Those live here so the\n * two hosts cannot drift, and so a third host (a hand-built integration) has one thing to read.\n *\n * ⚠️ Framework-free, like the rest of forms-core. No Angular, no RxJS, no fetch.\n */\n\nimport { FieldError } from './validate';\n\n/** The field a honeypot input uses. Must match `iox-cms` `anti-spam.ts` — hence the comment there. */\nexport const HONEYPOT_FIELD = '_iox_hp';\n/** When the form was rendered, so the server can measure fill time. */\nexport const RENDERED_AT_FIELD = '_iox_t';\n\n/**\n * What the form hands its host. There is deliberately no `orgId`: the tenant is the HOST's\n * knowledge, not the form's, and a form that had to be told its org would be one more trait an\n * author could get wrong.\n */\nexport interface SubmitRequest {\n formId: string;\n values: Record<string, any>;\n}\n\n/**\n * The server's answer, normalised. Mirrors `SubmitResult` in `iox-cms`\n * `form-submissions.service.ts` — the two are one contract, so change them together.\n */\nexport interface SubmitResponse {\n ok: boolean;\n /** Per-field verdicts from the server's own validation pass, keyed by field name. */\n errors?: Record<string, FieldError>;\n /** Where to send the visitor after a successful submit, when the form has a redirect action. */\n redirect?: string;\n}\n\n/**\n * The one function a host implements. Rejecting (or throwing) means the call never reached the\n * server — the form shows its Error state, which is the honest thing to show for a dropped network.\n */\nexport type FormTransport = (request: SubmitRequest) => Promise<SubmitResponse>;\n\n/**\n * The public submit path. Built here rather than interpolated at each call site, so the engine and\n * any future host cannot disagree about it — and so changing it is one edit.\n *\n * ⚠️ ROOT-relative (leading slash), never base-relative. A live site is served under a per-org\n * `<base href=\"/<label>/\">`, so a relative `api/…` resolved to `/<label>/api/…` — a path the reverse\n * proxy (`/api` → iox-cms, everything else → the engine) hands to the ENGINE, which answers a POST with\n * 404: no visitor submission ever reached iox-cms from an org path (found 2026-10-19 by\n * e2e:forminsert:real). The org is already in the path segment after `site/`.\n */\nexport function submitEndpointPath(orgId: string, formId: string): string {\n return `/api/site/${encodeURIComponent(orgId)}/forms/${encodeURIComponent(formId)}/submit`;\n}\n\n/**\n * Add the anti-spam fields to the collected values.\n *\n * Both are invisible to a real visitor and cost them nothing (decision D12). `renderedAt` is the\n * time the form was rendered, NOT the time of submit — the server measures the difference to catch\n * a script that fills and posts instantly.\n */\nexport function withAntiSpamFields(\n values: Record<string, any>,\n renderedAt: number,\n honeypotValue = '',\n): Record<string, any> {\n return { ...values, [HONEYPOT_FIELD]: honeypotValue, [RENDERED_AT_FIELD]: renderedAt };\n}\n\n/**\n * Normalise whatever came back into a `SubmitResponse`.\n *\n * Fails CLOSED: anything that is not a recognisable success is treated as a failure. A malformed\n * body must never show the visitor a Success state for a submission that was not stored — that is\n * the one lie this feature must not tell.\n */\nexport function interpretSubmitResponse(body: any): SubmitResponse {\n if (!body || typeof body !== 'object' || body.ok !== true) {\n return {\n ok: false,\n errors: normaliseErrors(body?.errors),\n };\n }\n const redirect = typeof body.redirect === 'string' && body.redirect.trim()\n ? body.redirect.trim()\n : undefined;\n return { ok: true, redirect };\n}\n\n/** Keep only entries that actually carry a message, so a junk key cannot blank a field's error. */\nfunction normaliseErrors(raw: any): Record<string, FieldError> | undefined {\n if (!raw || typeof raw !== 'object') return undefined;\n const errors: Record<string, FieldError> = {};\n for (const [name, value] of Object.entries(raw as Record<string, any>)) {\n const messageKey = typeof value?.messageKey === 'string' ? value.messageKey : '';\n if (!messageKey) continue;\n errors[name] = value?.params ? { messageKey, params: value.params } : { messageKey };\n }\n return Object.keys(errors).length ? errors : undefined;\n}\n","/**\n * The submit LIFECYCLE's decisions — what a form shows after the server answers, what it says when a\n * submit fails, what a client needs to validate a form, and how its submit button follows its state.\n *\n * Two runtimes act on these and must agree: `IoxFormComponent` (the engine's component path) and the\n * string-form runtime (every header / footer global and every string-rendered page —\n * vectoriox/iox-client-engine#13). The builder canvas reads `submitButtonView` too, for its Sending state.\n *\n * ⚠️ Framework-free, like the rest of forms-core: no Angular, no DOM.\n */\n\nimport { FeedbackTiming, FieldSpec, FormSpec } from './form.model';\nimport { SubmitResponse } from './transport';\nimport { FieldError } from './validate';\n\n/** Which of the form's four states is showing — written on the form as `data-iox-state`. */\nexport enum FormRenderState {\n Idle = 'idle',\n Submitting = 'submitting',\n Success = 'success',\n Error = 'error',\n}\n\n/** The attribute every renderer writes a form's state on (the canvas switcher, both live paths). */\nexport const FORM_STATE_ATTRIBUTE = 'data-iox-state';\n\n/** What the form does once the server has answered. */\nexport interface SubmitOutcome {\n state: FormRenderState;\n /** Per-field verdicts to put back on the fields (the form stays Idle so the visitor can fix them). */\n errors?: Record<string, FieldError>;\n /** A success clears the answers, so they cannot be sent twice. */\n reset: boolean;\n redirect?: string;\n}\n\n/**\n * The server's answer → what the visitor sees. Only a confirmed success is Success; per-field verdicts\n * land on the fields; anything else (a dropped network included) is the designed Error block.\n */\nexport function submitOutcome(response: SubmitResponse | null | undefined): SubmitOutcome {\n if (response?.ok) return { state: FormRenderState.Success, reset: true, ...(response.redirect ? { redirect: response.redirect } : {}) };\n if (response?.errors && Object.keys(response.errors).length) return { state: FormRenderState.Idle, errors: response.errors, reset: false };\n return { state: FormRenderState.Error, reset: false };\n}\n\n/** What the live region says after a refused submit: how many fields need attention, or that it did not send. */\nexport function failureAnnouncement(errors: Readonly<Record<string, unknown>> | null | undefined): string {\n const count = errors ? Object.keys(errors).length : 0;\n if (!count) return 'That did not send.';\n return `${count} ${count === 1 ? 'field needs' : 'fields need'} attention.`;\n}\n\n/**\n * The fields a CLIENT needs to validate a form: never its actions (where submissions go — an email\n * address, a webhook) and never its anti-spam settings. A string-rendered form carries this on\n * `FORM_FIELDS_ATTRIBUTE`, the way a string slider carries its inputs.\n */\nexport interface ClientFormSpec {\n feedback: FeedbackTiming | string;\n fields: FieldSpec[];\n}\n\nexport const FORM_FIELDS_ATTRIBUTE = 'data-iox-form-fields';\n\nexport function clientFormSpec(spec: Pick<FormSpec, 'feedback' | 'fields'>): ClientFormSpec {\n return { feedback: spec.feedback ?? FeedbackTiming.Smart, fields: [...(spec.fields ?? [])] };\n}\n\n/** The attribute's value back into a spec, or null when it is missing or not one. */\nexport function parseClientFormSpec(raw: string | null | undefined): ClientFormSpec | null {\n if (!raw) return null;\n try {\n const parsed = JSON.parse(raw);\n if (!parsed || !Array.isArray(parsed.fields)) return null;\n return { feedback: typeof parsed.feedback === 'string' ? parsed.feedback : FeedbackTiming.Smart, fields: parsed.fields };\n } catch {\n return null;\n }\n}\n\n/** How a submit button wears its form's state (vectoriox/iox-ui#42). */\nexport interface SubmitButtonView {\n busy: boolean;\n disabled: boolean;\n}\n\n/** While its form sends, a submit button is busy, and disabled unless its author turned that off — ONE rule for the\n * canvas's Sending state, the component path and the string path. Its \"Sending…\" label is the shared CSS's, keyed on\n * the same `data-iox-state`. */\nexport function submitButtonView(state: FormRenderState | string | null | undefined, disableWhileSubmitting = true): SubmitButtonView {\n const busy = state === FormRenderState.Submitting;\n return { busy, disabled: busy && disableWhileSubmitting !== false };\n}\n\n/** On a submit button whose author turned \"Disable while sending\" off. */\nexport const SUBMIT_KEEP_ENABLED_ATTRIBUTE = 'data-iox-keep-enabled';\n\nexport enum SubmitLabelClass {\n Labels = 'iox-submit__labels',\n Idle = 'iox-submit__idle',\n Busy = 'iox-submit__busy',\n}\n\n/**\n * A submit button's words, as markup: its label, or — when it has a \"While sending\" label — both, stacked in one\n * cell (the button keeps the longer one's width and never jumps). The string renderer's copy of\n * `IoxSubmitButtonComponent`'s template; `escape` is the renderer's.\n */\nexport function submitButtonLabelsHtml(label: string, loadingLabel: string | null | undefined, escape: (v: string) => string): string {\n if (!loadingLabel) return escape(label);\n return `<span class=\"${SubmitLabelClass.Labels}\"><span class=\"${SubmitLabelClass.Idle}\">${escape(label)}</span>` +\n `<span class=\"${SubmitLabelClass.Busy}\">${escape(loadingLabel)}</span></span>`;\n}\n\nexport const FORM_HONEYPOT_CLASS = 'iox-form__hp';\nexport const FORM_ANNOUNCER_ATTRIBUTE = 'data-iox-form-announcer';\n\n/**\n * The honeypot and the failure announcer every form holds, as markup — what `IoxFormComponent`'s template\n * renders, for the string renderer. The honeypot is off-screen (some bots skip hidden inputs), out of the\n * Tab order and the accessibility tree; the announcer is present from the start (a live region added at\n * the moment it gains text is not reliably announced).\n */\nexport function formChromeHtml(honeypotField: string): string {\n return `<div class=\"${FORM_HONEYPOT_CLASS}\" aria-hidden=\"true\"><input type=\"text\" name=\"${honeypotField}\" tabindex=\"-1\" autocomplete=\"off\"></div>` +\n `<div class=\"${FORM_HONEYPOT_CLASS}\" ${FORM_ANNOUNCER_ATTRIBUTE} role=\"status\" aria-live=\"assertive\" aria-atomic=\"true\"></div>`;\n}\n","/**\n * FORM PRESETS — a complete, working form as one insert: its fields, its submit label and the words of\n * its Success and Error blocks. ONE definition (W1.1): the builder's Forms tray builds a preset from\n * here (`buildFormPreset`, iox-builder), and the site composer (`generation-core`) stamps the SAME preset\n * into a composed page, so a generated contact form is the real one — never a second, drifting copy.\n * Data only: framework-free, like the rest of forms-core.\n */\n\nexport enum FormPresetId {\n Contact = 'contact',\n Newsletter = 'newsletter',\n Application = 'application',\n Booking = 'booking',\n}\n\nexport interface FormPresetField {\n label: string;\n control: string;\n required?: boolean;\n help?: string;\n placeholder?: string;\n /** Choices for select/radio, `value|Label` per line — the Field's `optionsText` trait. */\n optionsText?: string;\n rows?: number;\n}\n\nexport interface FormPresetDef {\n id: `${FormPresetId}`;\n name: string;\n icon: string;\n /** One line in the panel: what it collects and where it goes. */\n description: string;\n /** The form's author-facing name, which the submissions inbox groups by. */\n formName: string;\n fields: FormPresetField[];\n submitLabel: string;\n successText: string;\n errorText: string;\n}\n\n// forms-core is imported by both renderers (the field runtime), and a renderer that never reads the presets\n// must drop them: the call is `@__PURE__`, and the ids are written as the enum's VALUES (typed by it, pinned\n// to it by form-presets.spec) — a read of `FormPresetId.X` counts as a side effect to a bundler and kept the\n// whole list in the engine's bundle.\nexport const FORM_PRESETS: readonly FormPresetDef[] = /* @__PURE__ */ Object.freeze([\n {\n id: 'contact', name: 'Contact', icon: 'ph-thin ph-envelope-simple',\n description: 'Name, email and a message. Stored, and emailed to you.',\n formName: 'Contact form',\n fields: [\n { label: 'Full name', control: 'text', required: true },\n { label: 'Email', control: 'email', required: true },\n { label: 'Message', control: 'textarea', required: true, rows: 5 },\n ],\n submitLabel: 'Send message',\n successText: 'Thanks — we’ll be in touch shortly.',\n errorText: 'We couldn’t send your message. Please try again — your answers are still here.',\n },\n {\n id: 'newsletter', name: 'Newsletter', icon: 'ph-thin ph-paper-plane-tilt',\n description: 'One email field plus consent. Stored.',\n formName: 'Newsletter signup',\n fields: [\n { label: 'Email', control: 'email', required: true, placeholder: 'you@company.com' },\n // Consent is a checkbox that must be TICKED — `required` on a checkbox becomes the\n // `accepted` rule, with its own message, rather than a generic \"this is required\".\n { label: 'Email me occasional updates', control: 'checkbox', required: true },\n ],\n submitLabel: 'Subscribe',\n successText: 'You’re on the list.',\n errorText: 'We couldn’t sign you up. Please try again.',\n },\n {\n id: 'application', name: 'Application', icon: 'ph-thin ph-read-cv-logo',\n description: 'Details plus a CV upload. Stored, with an auto-reply.',\n formName: 'Application',\n fields: [\n { label: 'Full name', control: 'text', required: true },\n { label: 'Email', control: 'email', required: true },\n { label: 'Phone', control: 'tel' },\n { label: 'Role', control: 'select', required: true, optionsText: 'Design\\nEngineering\\nOther' },\n { label: 'CV', control: 'file', required: true, help: 'PDF or Word, up to 5MB' },\n { label: 'Anything else', control: 'textarea', rows: 4 },\n ],\n submitLabel: 'Apply',\n successText: 'Application received — we’ll read it properly and reply.',\n errorText: 'We couldn’t submit your application. Please try again.',\n },\n {\n id: 'booking', name: 'Booking request', icon: 'ph-thin ph-calendar-check',\n description: 'Date and party size. Stored, and it notifies you.',\n formName: 'Booking request',\n fields: [\n { label: 'Name', control: 'text', required: true },\n { label: 'Email', control: 'email', required: true },\n { label: 'Date', control: 'date', required: true },\n { label: 'People', control: 'number', required: true },\n { label: 'Notes', control: 'textarea', rows: 3, help: 'Allergies, access needs, anything useful' },\n ],\n submitLabel: 'Request a booking',\n successText: 'Request received — we’ll confirm by email.',\n errorText: 'We couldn’t send your request. Please try again.',\n },\n]);\n\n/** The preset with this id, or undefined. */\nexport function formPresetById(id: string | null | undefined): FormPresetDef | undefined {\n return FORM_PRESETS.find(p => p.id === id);\n}\n","// Where form content may NOT render (Doron, 2026-10-20): inside a link or a button.\n//\n// HTML forbids interactive content inside `<a>` and `<button>`, and a click in a field may follow the\n// link. ONE table and ONE walk, shared by the builder's insert rule (refuse it), the builder's audit\n// (find it in a page saved before the rule) and the engine (warn about it, never rewrite it).\n\nimport { FIELD_NODE_TYPE, FORM_NODE_TYPE } from './collect';\n\nexport enum InteractiveTag {\n Anchor = 'a',\n Button = 'button',\n}\n\n/**\n * Every node type that renders as an interactive element, and the element(s) it can render. A ButtonBlock\n * renders `<a>` or `<button>` by its `tag` trait — both interactive, so switching the tag never lifts the\n * rule. Pinned to the engine components' selectors by `interactive-hosts.spec.ts`.\n */\nexport const INTERACTIVE_HOST_TAGS: Readonly<Record<string, readonly InteractiveTag[]>> = Object.freeze({\n // A LinkedContainer is an <a>, or — as an Accordion's header (CC2) — a <button>.\n LinkedContainer: [InteractiveTag.Anchor, InteractiveTag.Button],\n Link: [InteractiveTag.Anchor],\n Button: [InteractiveTag.Anchor],\n ButtonBlock: [InteractiveTag.Anchor, InteractiveTag.Button],\n SubmitButton: [InteractiveTag.Button],\n});\n\nexport const FIELD_GROUP_NODE_TYPE = 'FieldGroup';\nexport const SUBMIT_BUTTON_NODE_TYPE = 'SubmitButton';\n\n/**\n * Form content — what a link or a button must never hold: a Form (its controls), a Field (an input, select\n * or textarea), a SubmitButton (a `<button>`) and a FieldGroup (it exists only to hold fields, so it moves as\n * one). A Success / Error block is text and lives only inside its form, so it is not on the list.\n */\nexport const FORM_CONTENT_TYPES: ReadonlySet<string> = new Set([\n FORM_NODE_TYPE, FIELD_NODE_TYPE, FIELD_GROUP_NODE_TYPE, SUBMIT_BUTTON_NODE_TYPE,\n]);\n\n/** The minimum a node must look like — a builder ComponentNode and a saved layout node both do. */\nexport interface NestingNode {\n id?: string;\n type?: string;\n label?: string;\n children?: NestingNode[] | null;\n}\n\nexport function isInteractiveHost(node: NestingNode | null | undefined): boolean {\n return !!node?.type && Object.prototype.hasOwnProperty.call(INTERACTIVE_HOST_TAGS, node.type);\n}\n\nexport function isFormContent(node: NestingNode | null | undefined): boolean {\n return !!node?.type && FORM_CONTENT_TYPES.has(node.type);\n}\n\n/**\n * The first form-content node in `node`'s subtree that sits inside an interactive host, or null. `insideHost`\n * is true when `node` is placed under a host already — so a Form dropped into a link and a link that holds a\n * Form are the same finding.\n */\nexport function formContentInHost(node: NestingNode | null | undefined, insideHost = false): NestingNode | null {\n if (!node) return null;\n if (insideHost && isFormContent(node)) return node;\n const nowInside = insideHost || isInteractiveHost(node);\n for (const child of node.children ?? []) {\n const found = formContentInHost(child, nowInside);\n if (found) return found;\n }\n return null;\n}\n\n/** One place a tree holds form content inside a link or a button. */\nexport interface MisplacedFormContent<N extends NestingNode = NestingNode> {\n /** The OUTERMOST interactive host holding it. */\n host: N;\n /** A MAXIMAL form-content subtree inside it — the Form, never each of its fields. */\n content: N;\n}\n\n/** Every form-content subtree a tree holds inside an interactive host, in document order. */\nexport function findFormContentInHosts<N extends NestingNode>(roots: readonly N[] | null | undefined): MisplacedFormContent<N>[] {\n const out: MisplacedFormContent<N>[] = [];\n const visit = (node: N, host: N | null): void => {\n if (host && isFormContent(node)) {\n out.push({ host, content: node });\n return;\n }\n const nextHost = host ?? (isInteractiveHost(node) ? node : null);\n for (const child of (node.children ?? []) as N[]) visit(child, nextHost);\n };\n for (const root of roots ?? []) visit(root, null);\n return out;\n}\n","/*\n * @vectoriox/iox-ui/forms-core — the shared, FRAMEWORK-FREE core of the forms feature.\n *\n * ⚠️ Nothing in this entry point may import Angular, RxJS, the DOM, or Node. It is consumed by\n * THREE runtimes: the builder canvas (Angular), the SSR engine (Angular), and `iox-cms` (NestJS,\n * plain Node). The main `@vectoriox/iox-ui` entry pulls in `@angular/core`, which Nest must never\n * load — that is the entire reason this secondary entry point exists.\n *\n * Client-side validation is UX; server-side validation is truth. Both run THIS code, so they cannot\n * disagree. See iox-ai-guidance `architecture/builder/forms-and-inputs-plan.md` §5.\n */\n\nexport * from './form.model';\nexport * from './messages';\nexport * from './validate';\nexport * from './collect';\nexport * from './options';\nexport * from './runtime';\nexport * from './rule-catalog';\nexport * from './transport';\nexport * from './submit-lifecycle';\nexport * from './form-presets';\nexport * from './nesting';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
@@ -15128,7 +15128,10 @@ var AiRefusalCode;
15128
15128
  (function (AiRefusalCode) {
15129
15129
  AiRefusalCode["NotInPlan"] = "ai.notInPlan";
15130
15130
  AiRefusalCode["OutOfCredits"] = "ai.outOfCredits";
15131
+ /** A step used more than twice its estimate (a loop), or the build its plan's `aiCreditsPerGeneration`. */
15131
15132
  AiRefusalCode["CapReached"] = "ai.capReached";
15133
+ /** The build asked for `GENERATION_LIMITS.plans` plans already — build one, change it with a sentence, or start over. */
15134
+ AiRefusalCode["PlansUsed"] = "ai.plansUsed";
15132
15135
  AiRefusalCode["NotConnected"] = "ai.notConnected";
15133
15136
  AiRefusalCode["KeyInvalid"] = "ai.keyInvalid";
15134
15137
  AiRefusalCode["PlanUnknown"] = "ai.planUnknown";
@@ -15138,6 +15141,7 @@ const AI_REFUSAL_STATUS = {
15138
15141
  [AiRefusalCode.NotInPlan]: 403,
15139
15142
  [AiRefusalCode.OutOfCredits]: 402,
15140
15143
  [AiRefusalCode.CapReached]: 402,
15144
+ [AiRefusalCode.PlansUsed]: 409,
15141
15145
  [AiRefusalCode.NotConnected]: 409,
15142
15146
  [AiRefusalCode.KeyInvalid]: 409,
15143
15147
  [AiRefusalCode.PlanUnknown]: 503,
@@ -15151,11 +15155,14 @@ var AiNextKind;
15151
15155
  AiNextKind["Settings"] = "settings";
15152
15156
  /** Try again later, or with less. */
15153
15157
  AiNextKind["Retry"] = "retry";
15158
+ /** Keep the plan there is: build it, or change it with a sentence. */
15159
+ AiNextKind["KeepPlan"] = "keepPlan";
15154
15160
  })(AiNextKind || (AiNextKind = {}));
15155
15161
  const AI_REFUSAL_NEXT = {
15156
15162
  [AiRefusalCode.NotInPlan]: AiNextKind.Contact,
15157
15163
  [AiRefusalCode.OutOfCredits]: AiNextKind.Contact,
15158
15164
  [AiRefusalCode.CapReached]: AiNextKind.Retry,
15165
+ [AiRefusalCode.PlansUsed]: AiNextKind.KeepPlan,
15159
15166
  [AiRefusalCode.NotConnected]: AiNextKind.Settings,
15160
15167
  [AiRefusalCode.KeyInvalid]: AiNextKind.Settings,
15161
15168
  [AiRefusalCode.PlanUnknown]: AiNextKind.Retry,