@businessdash/sdk 0.9.60

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (268) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +899 -0
  3. package/dist/adapters-revalidate.d.ts +44 -0
  4. package/dist/adapters-revalidate.d.ts.map +1 -0
  5. package/dist/adapters-revalidate.js +68 -0
  6. package/dist/adapters-revalidate.js.map +1 -0
  7. package/dist/alpha.d.ts +21 -0
  8. package/dist/alpha.d.ts.map +1 -0
  9. package/dist/alpha.js +21 -0
  10. package/dist/alpha.js.map +1 -0
  11. package/dist/analytics-core.d.ts +34 -0
  12. package/dist/analytics-core.d.ts.map +1 -0
  13. package/dist/analytics-core.js +138 -0
  14. package/dist/analytics-core.js.map +1 -0
  15. package/dist/analytics-server.d.ts +54 -0
  16. package/dist/analytics-server.d.ts.map +1 -0
  17. package/dist/analytics-server.js +78 -0
  18. package/dist/analytics-server.js.map +1 -0
  19. package/dist/attribution-logo.d.ts +2 -0
  20. package/dist/attribution-logo.d.ts.map +1 -0
  21. package/dist/attribution-logo.js +5 -0
  22. package/dist/attribution-logo.js.map +1 -0
  23. package/dist/auth-handler.d.ts +92 -0
  24. package/dist/auth-handler.d.ts.map +1 -0
  25. package/dist/auth-handler.js +277 -0
  26. package/dist/auth-handler.js.map +1 -0
  27. package/dist/biab-forms.css +484 -0
  28. package/dist/cli.d.ts +46 -0
  29. package/dist/cli.d.ts.map +1 -0
  30. package/dist/cli.js +1824 -0
  31. package/dist/cli.js.map +1 -0
  32. package/dist/client.d.ts +1681 -0
  33. package/dist/client.d.ts.map +1 -0
  34. package/dist/client.js +2845 -0
  35. package/dist/client.js.map +1 -0
  36. package/dist/collections.d.ts +13 -0
  37. package/dist/collections.d.ts.map +1 -0
  38. package/dist/collections.js +13 -0
  39. package/dist/collections.js.map +1 -0
  40. package/dist/contracts.d.ts +14609 -0
  41. package/dist/contracts.d.ts.map +1 -0
  42. package/dist/contracts.js +2428 -0
  43. package/dist/contracts.js.map +1 -0
  44. package/dist/data-model-schema.d.ts +962 -0
  45. package/dist/data-model-schema.d.ts.map +1 -0
  46. package/dist/data-model-schema.js +2295 -0
  47. package/dist/data-model-schema.js.map +1 -0
  48. package/dist/distribution.d.ts +38 -0
  49. package/dist/distribution.d.ts.map +1 -0
  50. package/dist/distribution.js +61 -0
  51. package/dist/distribution.js.map +1 -0
  52. package/dist/element.d.ts +121 -0
  53. package/dist/element.d.ts.map +1 -0
  54. package/dist/element.js +276 -0
  55. package/dist/element.js.map +1 -0
  56. package/dist/enums.d.ts +25 -0
  57. package/dist/enums.d.ts.map +1 -0
  58. package/dist/enums.js +38 -0
  59. package/dist/enums.js.map +1 -0
  60. package/dist/errors.d.ts +195 -0
  61. package/dist/errors.d.ts.map +1 -0
  62. package/dist/errors.js +188 -0
  63. package/dist/errors.js.map +1 -0
  64. package/dist/forms-core/autocomplete.d.ts +37 -0
  65. package/dist/forms-core/autocomplete.d.ts.map +1 -0
  66. package/dist/forms-core/autocomplete.js +82 -0
  67. package/dist/forms-core/autocomplete.js.map +1 -0
  68. package/dist/forms-core/business-function.d.ts +61 -0
  69. package/dist/forms-core/business-function.d.ts.map +1 -0
  70. package/dist/forms-core/business-function.js +149 -0
  71. package/dist/forms-core/business-function.js.map +1 -0
  72. package/dist/forms-core/calculation.d.ts +72 -0
  73. package/dist/forms-core/calculation.d.ts.map +1 -0
  74. package/dist/forms-core/calculation.js +103 -0
  75. package/dist/forms-core/calculation.js.map +1 -0
  76. package/dist/forms-core/controller.d.ts +249 -0
  77. package/dist/forms-core/controller.d.ts.map +1 -0
  78. package/dist/forms-core/controller.js +590 -0
  79. package/dist/forms-core/controller.js.map +1 -0
  80. package/dist/forms-core/elements.d.ts +44 -0
  81. package/dist/forms-core/elements.d.ts.map +1 -0
  82. package/dist/forms-core/elements.js +68 -0
  83. package/dist/forms-core/elements.js.map +1 -0
  84. package/dist/forms-core/email-domains.d.ts +10 -0
  85. package/dist/forms-core/email-domains.d.ts.map +1 -0
  86. package/dist/forms-core/email-domains.js +69 -0
  87. package/dist/forms-core/email-domains.js.map +1 -0
  88. package/dist/forms-core/file-rules.d.ts +51 -0
  89. package/dist/forms-core/file-rules.d.ts.map +1 -0
  90. package/dist/forms-core/file-rules.js +105 -0
  91. package/dist/forms-core/file-rules.js.map +1 -0
  92. package/dist/forms-core/formula.d.ts +114 -0
  93. package/dist/forms-core/formula.d.ts.map +1 -0
  94. package/dist/forms-core/formula.js +1170 -0
  95. package/dist/forms-core/formula.js.map +1 -0
  96. package/dist/forms-core/index.d.ts +24 -0
  97. package/dist/forms-core/index.d.ts.map +1 -0
  98. package/dist/forms-core/index.js +28 -0
  99. package/dist/forms-core/index.js.map +1 -0
  100. package/dist/forms-core/units.d.ts +49 -0
  101. package/dist/forms-core/units.d.ts.map +1 -0
  102. package/dist/forms-core/units.js +255 -0
  103. package/dist/forms-core/units.js.map +1 -0
  104. package/dist/forms-core/us-states.d.ts +14 -0
  105. package/dist/forms-core/us-states.d.ts.map +1 -0
  106. package/dist/forms-core/us-states.js +66 -0
  107. package/dist/forms-core/us-states.js.map +1 -0
  108. package/dist/forms-core/validation.d.ts +266 -0
  109. package/dist/forms-core/validation.d.ts.map +1 -0
  110. package/dist/forms-core/validation.js +850 -0
  111. package/dist/forms-core/validation.js.map +1 -0
  112. package/dist/forms.d.ts +19 -0
  113. package/dist/forms.d.ts.map +1 -0
  114. package/dist/forms.js +29 -0
  115. package/dist/forms.js.map +1 -0
  116. package/dist/gallery-types.d.ts +32 -0
  117. package/dist/gallery-types.d.ts.map +1 -0
  118. package/dist/gallery-types.js +2 -0
  119. package/dist/gallery-types.js.map +1 -0
  120. package/dist/graphql.d.ts +97 -0
  121. package/dist/graphql.d.ts.map +1 -0
  122. package/dist/graphql.js +212 -0
  123. package/dist/graphql.js.map +1 -0
  124. package/dist/index.cjs +19448 -0
  125. package/dist/index.d.cts +19 -0
  126. package/dist/index.d.mts +19 -0
  127. package/dist/index.d.ts +19 -0
  128. package/dist/index.d.ts.map +1 -0
  129. package/dist/index.js +20 -0
  130. package/dist/index.js.map +1 -0
  131. package/dist/marketing-schema.d.ts +216 -0
  132. package/dist/marketing-schema.d.ts.map +1 -0
  133. package/dist/marketing-schema.js +200 -0
  134. package/dist/marketing-schema.js.map +1 -0
  135. package/dist/mcp.d.ts +42 -0
  136. package/dist/mcp.d.ts.map +1 -0
  137. package/dist/mcp.js +87 -0
  138. package/dist/mcp.js.map +1 -0
  139. package/dist/native.d.ts +45 -0
  140. package/dist/native.d.ts.map +1 -0
  141. package/dist/native.js +43 -0
  142. package/dist/native.js.map +1 -0
  143. package/dist/next-revalidate.d.ts +43 -0
  144. package/dist/next-revalidate.d.ts.map +1 -0
  145. package/dist/next-revalidate.js +84 -0
  146. package/dist/next-revalidate.js.map +1 -0
  147. package/dist/parallel-pages.d.ts +102 -0
  148. package/dist/parallel-pages.d.ts.map +1 -0
  149. package/dist/parallel-pages.js +108 -0
  150. package/dist/parallel-pages.js.map +1 -0
  151. package/dist/payment-icons.d.ts +66 -0
  152. package/dist/payment-icons.d.ts.map +1 -0
  153. package/dist/payment-icons.js +160 -0
  154. package/dist/payment-icons.js.map +1 -0
  155. package/dist/proxy.d.ts +67 -0
  156. package/dist/proxy.d.ts.map +1 -0
  157. package/dist/proxy.js +97 -0
  158. package/dist/proxy.js.map +1 -0
  159. package/dist/react-analytics.d.ts +39 -0
  160. package/dist/react-analytics.d.ts.map +1 -0
  161. package/dist/react-analytics.js +59 -0
  162. package/dist/react-analytics.js.map +1 -0
  163. package/dist/react-attribution.d.ts +99 -0
  164. package/dist/react-attribution.d.ts.map +1 -0
  165. package/dist/react-attribution.js +52 -0
  166. package/dist/react-attribution.js.map +1 -0
  167. package/dist/react-marketing.d.ts +181 -0
  168. package/dist/react-marketing.d.ts.map +1 -0
  169. package/dist/react-marketing.js +215 -0
  170. package/dist/react-marketing.js.map +1 -0
  171. package/dist/react.d.ts +727 -0
  172. package/dist/react.d.ts.map +1 -0
  173. package/dist/react.js +2418 -0
  174. package/dist/react.js.map +1 -0
  175. package/dist/reserved-paths.d.ts +24 -0
  176. package/dist/reserved-paths.d.ts.map +1 -0
  177. package/dist/reserved-paths.js +60 -0
  178. package/dist/reserved-paths.js.map +1 -0
  179. package/dist/revalidate-verify.d.ts +30 -0
  180. package/dist/revalidate-verify.d.ts.map +1 -0
  181. package/dist/revalidate-verify.js +74 -0
  182. package/dist/revalidate-verify.js.map +1 -0
  183. package/dist/sdk.d.ts +678 -0
  184. package/dist/sdk.d.ts.map +1 -0
  185. package/dist/sdk.js +801 -0
  186. package/dist/sdk.js.map +1 -0
  187. package/dist/seo.d.ts +218 -0
  188. package/dist/seo.d.ts.map +1 -0
  189. package/dist/seo.js +309 -0
  190. package/dist/seo.js.map +1 -0
  191. package/dist/socials.d.ts +47 -0
  192. package/dist/socials.d.ts.map +1 -0
  193. package/dist/socials.js +172 -0
  194. package/dist/socials.js.map +1 -0
  195. package/dist/static.d.ts +14 -0
  196. package/dist/static.d.ts.map +1 -0
  197. package/dist/static.js +14 -0
  198. package/dist/static.js.map +1 -0
  199. package/dist/url-pattern.d.ts +47 -0
  200. package/dist/url-pattern.d.ts.map +1 -0
  201. package/dist/url-pattern.js +124 -0
  202. package/dist/url-pattern.js.map +1 -0
  203. package/dist/vanilla.d.ts +77 -0
  204. package/dist/vanilla.d.ts.map +1 -0
  205. package/dist/vanilla.js +903 -0
  206. package/dist/vanilla.js.map +1 -0
  207. package/openapi.json +13779 -0
  208. package/package.json +204 -0
  209. package/src/adapters-revalidate.ts +88 -0
  210. package/src/alpha.ts +89 -0
  211. package/src/analytics-core.ts +175 -0
  212. package/src/analytics-server.ts +99 -0
  213. package/src/angular/biab-form.component.ts +1443 -0
  214. package/src/angular/index.ts +26 -0
  215. package/src/attribution-logo.ts +5 -0
  216. package/src/auth-handler.ts +352 -0
  217. package/src/cli.ts +2517 -0
  218. package/src/client.ts +3578 -0
  219. package/src/collections.ts +101 -0
  220. package/src/contracts.ts +3390 -0
  221. package/src/data-model-schema.ts +4042 -0
  222. package/src/distribution.ts +73 -0
  223. package/src/element.ts +321 -0
  224. package/src/enums.ts +65 -0
  225. package/src/errors.ts +338 -0
  226. package/src/forms-core/autocomplete.ts +97 -0
  227. package/src/forms-core/business-function.ts +209 -0
  228. package/src/forms-core/calculation.ts +167 -0
  229. package/src/forms-core/controller.ts +922 -0
  230. package/src/forms-core/elements.ts +86 -0
  231. package/src/forms-core/email-domains.ts +68 -0
  232. package/src/forms-core/file-rules.ts +123 -0
  233. package/src/forms-core/formula.ts +1339 -0
  234. package/src/forms-core/index.ts +122 -0
  235. package/src/forms-core/units.ts +308 -0
  236. package/src/forms-core/us-states.ts +68 -0
  237. package/src/forms-core/validation.ts +1037 -0
  238. package/src/forms.ts +63 -0
  239. package/src/gallery-types.ts +31 -0
  240. package/src/graphql.ts +295 -0
  241. package/src/index.ts +505 -0
  242. package/src/marketing-schema.ts +395 -0
  243. package/src/mcp.ts +108 -0
  244. package/src/native.ts +73 -0
  245. package/src/next-revalidate.ts +124 -0
  246. package/src/parallel-pages.ts +192 -0
  247. package/src/payment-icons.ts +205 -0
  248. package/src/proxy.ts +173 -0
  249. package/src/qwik.tsx +1234 -0
  250. package/src/react-analytics.tsx +76 -0
  251. package/src/react-attribution.tsx +192 -0
  252. package/src/react-marketing.tsx +338 -0
  253. package/src/react.tsx +5495 -0
  254. package/src/reserved-paths.ts +65 -0
  255. package/src/revalidate-verify.ts +98 -0
  256. package/src/sdk.ts +1671 -0
  257. package/src/seo.ts +488 -0
  258. package/src/socials.ts +230 -0
  259. package/src/solid.tsx +1466 -0
  260. package/src/static.ts +21 -0
  261. package/src/styles/biab-forms.css +484 -0
  262. package/src/svelte/BiabForm.svelte +1069 -0
  263. package/src/svelte/context.ts +57 -0
  264. package/src/svelte/index.ts +79 -0
  265. package/src/url-pattern.ts +153 -0
  266. package/src/vanilla.ts +1290 -0
  267. package/src/vue/BiabForm.vue +1538 -0
  268. package/src/vue/index.ts +119 -0
@@ -0,0 +1,103 @@
1
+ /**
2
+ * Calculation/Math form-element runtime — the bridge between a form's
3
+ * "calculation" field and the Business Functions engine.
4
+ *
5
+ * A calculation field computes a value from OTHER fields in the same form,
6
+ * either by an **inline formula** (mode "formula") or by referencing a saved
7
+ * **business function** (mode "function"). Input variables are bound to source
8
+ * fields via `inputMap` (variable name → source field id). The result is the
9
+ * field's submitted value; for a multi-output function, `outputKey` selects
10
+ * which exported variable to surface (default: the function's first output).
11
+ *
12
+ * Sensitivity: a calculation that references a `sensitive` function MUST run
13
+ * server-only (its formula/def is never published). This module is pure and
14
+ * environment-agnostic — the CALLER decides whether to run it (the client skips
15
+ * sensitive calcs and shows a placeholder; the server always computes the
16
+ * authoritative value on submit).
17
+ *
18
+ * Pure + isomorphic (no DB, no React). The SDK mirrors it.
19
+ */
20
+ import { runBusinessFunction, } from "./business-function.js";
21
+ import { runFormula, } from "./formula.js";
22
+ /** Coerce an arbitrary source-field value into something the engine accepts. */
23
+ function toFormulaValue(raw) {
24
+ if (raw === null || raw === undefined || raw === "")
25
+ return undefined;
26
+ if (typeof raw === "number" || typeof raw === "boolean")
27
+ return raw;
28
+ if (typeof raw === "string")
29
+ return raw;
30
+ if (typeof raw === "object" && !Array.isArray(raw))
31
+ return raw;
32
+ return String(raw);
33
+ }
34
+ /** Apply display formatting (prefix/suffix/decimals) for rendering. Pure. */
35
+ export function formatCalcValue(value, display) {
36
+ if (value === null || value === undefined)
37
+ return "";
38
+ let body;
39
+ if (typeof value === "number" &&
40
+ display?.decimals !== undefined &&
41
+ Number.isFinite(value)) {
42
+ body = value.toFixed(display.decimals);
43
+ }
44
+ else if (typeof value === "object") {
45
+ body = JSON.stringify(value);
46
+ }
47
+ else {
48
+ body = String(value);
49
+ }
50
+ return `${display?.prefix ?? ""}${body}${display?.suffix ?? ""}`;
51
+ }
52
+ /**
53
+ * Compute a calculation field. `resolveField(fieldId)` returns the current
54
+ * value of a source field. Never throws — returns `{ ok:false, error }` on a
55
+ * bad config or evaluation error.
56
+ */
57
+ export function computeCalculation(config, resolveField, ctx = {}) {
58
+ const bindings = config.inputMap ?? [];
59
+ if (config.mode === "function") {
60
+ const def = config.functionId
61
+ ? ctx.functionsById?.[config.functionId]
62
+ : undefined;
63
+ if (!def) {
64
+ return {
65
+ ok: false,
66
+ value: null,
67
+ error: "Referenced function not found.",
68
+ };
69
+ }
70
+ const rawInputs = {};
71
+ for (const b of bindings) {
72
+ rawInputs[b.variable] = resolveField(b.fieldId);
73
+ }
74
+ const run = runBusinessFunction(def, rawInputs, ctx.evalOptions);
75
+ const key = config.outputKey ?? def.outputs[0]?.key;
76
+ const value = key !== undefined && key in run.outputs ? run.outputs[key] : null;
77
+ const result = {
78
+ ok: run.ok,
79
+ value: value ?? null,
80
+ outputs: run.outputs,
81
+ };
82
+ if (!run.ok) {
83
+ result.error = run.issues
84
+ .map((i) => `${i.scope}/${i.key}: ${i.reason}`)
85
+ .join("; ");
86
+ }
87
+ return result;
88
+ }
89
+ // mode "formula" (default)
90
+ const formula = config.formula?.trim();
91
+ if (!formula) {
92
+ return { ok: false, value: null, error: "No formula." };
93
+ }
94
+ const vars = {};
95
+ for (const b of bindings) {
96
+ vars[b.variable] = toFormulaValue(resolveField(b.fieldId));
97
+ }
98
+ const r = runFormula(formula, vars, ctx.evalOptions);
99
+ if (!r.ok)
100
+ return { ok: false, value: null, error: r.error };
101
+ return { ok: true, value: r.value };
102
+ }
103
+ //# sourceMappingURL=calculation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"calculation.js","sourceRoot":"","sources":["../../src/forms-core/calculation.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,249 @@
1
+ /**
2
+ * createFormController — the framework-agnostic observable store that drives
3
+ * every `<BiabForm>` binding (React / Vue / Svelte / Solid / Qwik / Angular /
4
+ * web-component / vanilla).
5
+ *
6
+ * It owns ALL of the form's runtime state and behaviour:
7
+ * - working values (+ seeded defaults), condition-aware visible fields,
8
+ * - field-level validation errors (mirrored from the server's rules),
9
+ * - multi-step ("consecutive") navigation + progress,
10
+ * - concurrent-reveal gating inside groups,
11
+ * - submission lifecycle (submitting / result),
12
+ * - file uploads via the SDK.
13
+ *
14
+ * Bindings stay dumb: subscribe to `snapshot()`, render by field `type` using
15
+ * the `biab-*` class convention (light DOM, no shadow root, so consumer CSS
16
+ * cascades), and call `setValue` / `next` / `back` / `submit` / `uploadFile` /
17
+ * `reset`. The store is a tiny subscribe/notify observable — no framework
18
+ * reactivity primitives leak in.
19
+ *
20
+ * Data flows entirely through the SDK: it calls `client.forms.schema(slug)` to
21
+ * load and `client.forms.submit(slug, data, opts)` to submit, so auth, caching,
22
+ * revalidation, HMAC, retries, and CRM fan-out all stay invisible inside
23
+ * biab-dev. SSR callers can hand a pre-fetched schema instead of a client.
24
+ */
25
+ import type { FormFieldDef, FormFileValue, FormRenderSettings, FormSchema, FormSubmitResult } from "../sdk.js";
26
+ import { concurrentRevealCount, evalCondition, type FormConditionRule, type FormCoreField, type FormData, findMissingRequired, isNodeVisible, type MissingField, seedInitialData } from "./validation.js";
27
+ export type { FormCoreField, FormData, MissingField } from "./validation.js";
28
+ /** Per-field validation error surfaced to the binding (`id` → message). */
29
+ export interface FieldError {
30
+ id: string;
31
+ label: string;
32
+ message: string;
33
+ }
34
+ /**
35
+ * A file the visitor picked but hasn't uploaded — uploads are DEFERRED to
36
+ * `submit()`. A binding stores these in the field's value (an array mixing
37
+ * `PendingFileValue` + already-uploaded `FormFileValue`); `submit()` flushes
38
+ * the pending ones to R2, replacing each with its uploaded record. Deferring
39
+ * means an abandoned form never orphans an object and a failed upload surfaces
40
+ * as a submit error rather than vanishing.
41
+ */
42
+ export interface PendingFileValue {
43
+ pending: true;
44
+ file: File | Blob;
45
+ name: string;
46
+ size: number;
47
+ }
48
+ export declare function isPendingFileValue(v: unknown): v is PendingFileValue;
49
+ /** Provenance + recipient passthrough for the underlying `forms.submit`. */
50
+ export interface FormSubmitOptions {
51
+ submitterEmail?: string;
52
+ submitterName?: string;
53
+ /** Validate on the server but store nothing (no side effects). */
54
+ dryRun?: boolean;
55
+ /** Lead-source provenance (e.g. "facebook", "google-ads:summer"). */
56
+ source?: string;
57
+ referrer?: string;
58
+ metadata?: Record<string, unknown>;
59
+ }
60
+ /**
61
+ * The slice of the SDK client the form controller actually needs. Any object exposing a
62
+ * `forms` resource with `schema` / `submit` / `uploadFile` satisfies it — the
63
+ * full `BiabClient` from `createBiabClient()`, or a thin same-origin proxy that
64
+ * forwards to `/api/biab/forms/*` (the pattern every starter template uses so the
65
+ * bearer key never reaches the browser).
66
+ *
67
+ * It lives here rather than in `react.tsx` because `forms-core` is the layer
68
+ * that consumes it — solid, qwik, svelte, vanilla and the custom element all
69
+ * run this controller, and none of them should reach through React for a type.
70
+ * `react.tsx` re-exports the name, so the public API is unchanged.
71
+ */
72
+ export interface BiabFormsClient {
73
+ forms: {
74
+ schema(slug: string): Promise<FormSchema>;
75
+ submit(slug: string, data: Record<string, unknown>, opts?: FormSubmitOptions): Promise<FormSubmitResult>;
76
+ uploadFile?(slug: string, fieldId: string, file: File | Blob, opts?: {
77
+ filename?: string;
78
+ }): Promise<FormFileValue>;
79
+ /** Open booking slots for an auto-mode `schedule` field. */
80
+ scheduleSlots?(slug: string, input: {
81
+ fieldId: string;
82
+ from: Date;
83
+ to: Date;
84
+ }): Promise<{
85
+ slots: Array<{
86
+ startAt: string;
87
+ }>;
88
+ }>;
89
+ };
90
+ }
91
+ export interface CreateFormControllerOptions {
92
+ /**
93
+ * The SDK client. Required unless `schema` is supplied (SSR / pre-fetched).
94
+ * When both are given, `client` is still used for `submit` / `uploadFile`.
95
+ *
96
+ * Typed as `BiabFormsClient` — the `forms` surface — rather than the whole
97
+ * `BiabClient`, because that is all this controller ever touches. Demanding
98
+ * the full client was what forced `client as never` at the React call site:
99
+ * the hook resolves a forms-shaped client from a provider or a token, which
100
+ * is not a `BiabClient` and never needed to be. A full `BiabClient` still
101
+ * satisfies this structurally, so existing callers are unaffected.
102
+ */
103
+ client?: BiabFormsClient;
104
+ /** Form slug. Required when loading via `client`; optional with a pre-fetched
105
+ * `schema` that already carries its own `slug`. */
106
+ slug?: string;
107
+ /**
108
+ * Pre-fetched schema (SSR / RSC). When provided, `load()` resolves
109
+ * synchronously against it instead of hitting the network. `submit` /
110
+ * `uploadFile` still require `client`.
111
+ */
112
+ schema?: FormSchema;
113
+ /**
114
+ * Default submit options merged into every `submit()` call (the call's own
115
+ * options win per-key).
116
+ */
117
+ submitOptions?: FormSubmitOptions;
118
+ /**
119
+ * Called after a successful submit (result.ok === true). Fires before the
120
+ * final snapshot notify so a binding can read the result in the same tick.
121
+ */
122
+ onSuccess?: (result: Extract<FormSubmitResult, {
123
+ ok: true;
124
+ }>) => void;
125
+ /** Called after a failed submit (result.ok === false). */
126
+ onError?: (result: Extract<FormSubmitResult, {
127
+ ok: false;
128
+ }>) => void;
129
+ }
130
+ export type FormStatus = "idle" | "loading" | "ready" | "error";
131
+ export interface FormSnapshot {
132
+ /** Lifecycle of the schema load. `ready` once fields are available. */
133
+ status: FormStatus;
134
+ /** Set when `status === "error"` (schema load failed). */
135
+ loadError: string | null;
136
+ /** The loaded schema (null until `ready`). */
137
+ schema: FormSchema | null;
138
+ /** Flat public field defs from the schema (convenience; the tree is `fields`). */
139
+ fieldDefs: FormFieldDef[];
140
+ /** The nested field tree to render (the authoritative render source). */
141
+ fields: FormCoreField[];
142
+ /** Resolved render settings (animation / steps / progress) with defaults. */
143
+ settings: ResolvedFormSettings;
144
+ /** Org icon URL when the form opted into `showOrgIcon`, else null. */
145
+ orgIcon: string | null;
146
+ /** Form title, when present. */
147
+ title: string | null;
148
+ /** Form description, when present. */
149
+ description: string | null;
150
+ /** Working values, keyed by field `id`. */
151
+ values: FormData;
152
+ /** Field-level validation errors, keyed by field `id` (for O(1) lookup). */
153
+ errors: Record<string, FieldError>;
154
+ /** Ordered list of current errors (same data as `errors`, render-friendly). */
155
+ errorList: FieldError[];
156
+ /** Steps: each entry is the field subtree for one step. In single-page mode
157
+ * there is exactly one step containing every field. */
158
+ steps: FormCoreField[][];
159
+ /** Zero-based index of the active step (clamped to a valid range). */
160
+ step: number;
161
+ /** Total number of steps (`steps.length`). */
162
+ stepCount: number;
163
+ /** True when on the first step. */
164
+ isFirstStep: boolean;
165
+ /** True when on the last step. */
166
+ isLastStep: boolean;
167
+ /** The field subtree for the active step (already condition-pruned for the
168
+ * top level — bindings still skip hidden `condition_block`s as they recurse). */
169
+ visibleFields: FormCoreField[];
170
+ /** 0–1 completion fraction = (step + 1) / stepCount. */
171
+ progress: number;
172
+ /** Whole-percent form of `progress` (0–100), convenient for width styles. */
173
+ progressPercent: number;
174
+ /** True when the active step has no missing-required / regex problems —
175
+ * drives the Next button's disabled state. */
176
+ canAdvance: boolean;
177
+ /** True when the WHOLE form passes required/regex checks — drives Submit. */
178
+ canSubmit: boolean;
179
+ /** Nav direction of the last step change (`true` = forward) — for slide anims. */
180
+ forward: boolean;
181
+ /** True while a `submit()` round-trip is in flight. */
182
+ submitting: boolean;
183
+ /** True while ANY field is uploading a file. */
184
+ uploading: boolean;
185
+ /** The most recent submit result (null until the first submit). */
186
+ result: FormSubmitResult | null;
187
+ /** True after a successful submit (result.ok === true). */
188
+ submitted: boolean;
189
+ }
190
+ /** Render settings after applying defaults. */
191
+ export interface ResolvedFormSettings {
192
+ animation: NonNullable<FormRenderSettings["animation"]>;
193
+ isConsecutive: boolean;
194
+ showProgress: boolean;
195
+ progressStyle: NonNullable<FormRenderSettings["progressStyle"]>;
196
+ /** Warn before abandoning a dirty, unsubmitted form (undefined = off). */
197
+ exitConfirm?: {
198
+ enabled?: boolean;
199
+ message?: string;
200
+ };
201
+ }
202
+ export interface FormController {
203
+ /** Load (or adopt the pre-fetched) schema and seed initial values. Idempotent:
204
+ * safe to call again to re-fetch. Resolves once the schema is `ready` or
205
+ * `error`. */
206
+ load(): Promise<void>;
207
+ /** The current immutable snapshot. Cheap; returns the same object until the
208
+ * next mutation. */
209
+ snapshot(): FormSnapshot;
210
+ /** Subscribe to snapshot changes. Returns an unsubscribe fn. The callback is
211
+ * NOT invoked on subscribe — read `snapshot()` for the initial value. */
212
+ subscribe(callback: (snapshot: FormSnapshot) => void): () => void;
213
+ /** Set one field's value (keyed by field `id`). Clears that field's error and
214
+ * recomputes condition-driven visibility / advance gating. */
215
+ setValue(id: string, value: unknown): void;
216
+ /** Advance to the next step. No-op (and surfaces step errors) when the current
217
+ * step has missing-required / invalid fields, or already on the last step. */
218
+ next(): void;
219
+ /** Go back one step. No-op on the first step. */
220
+ back(): void;
221
+ /** Jump to a specific step index (clamped). Validates nothing — use for a
222
+ * progress-indicator click-back. */
223
+ goToStep(index: number): void;
224
+ /**
225
+ * Validate the whole form, then submit via the SDK. Populates `errors` and
226
+ * returns early (without a network call) when local validation fails. Always
227
+ * resolves to a `FormSubmitResult` (never throws for an expected failure).
228
+ */
229
+ submit(options?: FormSubmitOptions): Promise<FormSubmitResult>;
230
+ /**
231
+ * Upload one file for a `file_upload` field via the SDK, append the resulting
232
+ * `FormFileValue` to that field's value array, and return it. Throws on
233
+ * plan-gate / transfer failure (mirrors `client.forms.uploadFile`).
234
+ */
235
+ uploadFile(fieldId: string, file: File | Blob, opts?: {
236
+ filename?: string;
237
+ }): Promise<FormFileValue>;
238
+ /** Re-run validation against the current values and publish `errors`. Returns
239
+ * the missing/invalid list (empty when valid). */
240
+ validate(): MissingField[];
241
+ /** Reset values to seeded defaults, clear errors / result, go to step 0. */
242
+ reset(): void;
243
+ /** Stop notifying and drop all subscribers. */
244
+ destroy(): void;
245
+ }
246
+ export declare function createFormController(options: CreateFormControllerOptions): FormController;
247
+ export type { FormConditionRule };
248
+ export { concurrentRevealCount, evalCondition, findMissingRequired, isNodeVisible, seedInitialData, };
249
+ //# sourceMappingURL=controller.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"controller.d.ts","sourceRoot":"","sources":["../../src/forms-core/controller.ts"],"names":[],"mappings":"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"}