jsonisch 0.1.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.
- package/CHANGELOG.md +7 -0
- package/LICENSE +21 -0
- package/README.md +218 -0
- package/dist/form-ref-BEri3JKv.js +1123 -0
- package/dist/form-ref-D_xHSaqL.d.ts +994 -0
- package/dist/handle-submit-CD3WY9gW.js +208 -0
- package/dist/handle-submit-Dk7QW3_q.d.ts +34 -0
- package/dist/index.d.ts +724 -0
- package/dist/index.js +1521 -0
- package/dist/plugin/index.d.ts +188 -0
- package/dist/plugin/index.js +4 -0
- package/dist/plugin-BCsAE8RK.d.ts +612 -0
- package/dist/plugin-Qka-vaO1.js +1545 -0
- package/dist/react/index.d.ts +476 -0
- package/dist/react/index.js +456 -0
- package/docs/decode-fork.md +24 -0
- package/docs/plugin-lifecycle.md +44 -0
- package/docs/rerender-history.md +61 -0
- package/docs/wire-shapes.md +70 -0
- package/package.json +87 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,724 @@
|
|
|
1
|
+
import { C as flattenSourceRow, D as derivation, F as AmountOrPercentEnvelope, G as CalcParseResult, H as EstimateMeta, K as DerivationMode, L as EntryMeta, M as ValidateFormInputConfig, N as ValidationResult, R as EntryMode, S as computeBag, V as EstimateEnvelope, W as CalcEngine, _ as bagger, b as ComputeBagOptions, c as CheckDefinition, d as ChecksConfig, f as Finding, h as SeverityConfig, i as formulaCheck, j as envelopes, l as CheckInstanceConfig, m as Severity, n as replaceCheckInstances, p as FormulaOptions, q as DerivedState, r as UNEVALUABLE_MESSAGE_ID, s as CheckContext, t as checks, u as CheckScope, w as visibility, x as collectionKeys, y as BaggerOptions, z as Envelope } from "./plugin-BCsAE8RK.js";
|
|
2
|
+
import { A as VisibleWhen, C as FieldErrors, G as JsonSchema, K as Path, M as ControlKind, N as inferControl, _ as WireContract, a as InternalFormStore, g as PluginsInput, i as FormValidator, j as VisibleWhenOp, o as ValidationIssue, q as PathSegment, r as FormConfig, s as ValidationMode, t as FormRef, w as FieldKind, x as ContainerInput } from "./form-ref-D_xHSaqL.js";
|
|
3
|
+
import { n as handleSubmit, t as SubmitHandler } from "./handle-submit-Dk7QW3_q.js";
|
|
4
|
+
|
|
5
|
+
//#region src/core/form/create-form-store.d.ts
|
|
6
|
+
/**
|
|
7
|
+
* The default empty input of a form. Required string fields start as an
|
|
8
|
+
* empty string, while every other type starts as `undefined`.
|
|
9
|
+
*/
|
|
10
|
+
declare const DEFAULT_EMPTY_INPUT: Record<string, unknown>;
|
|
11
|
+
/**
|
|
12
|
+
* The default root-record alias (`FormConfig.rootRecordAlias`). The
|
|
13
|
+
* store's resolved value is the one home at runtime; this default
|
|
14
|
+
* exists so store-less readers (`computeBag`) resolve identically.
|
|
15
|
+
*/
|
|
16
|
+
declare const DEFAULT_ROOT_RECORD_ALIAS = "record";
|
|
17
|
+
/**
|
|
18
|
+
* Creates a new internal form store from the provided configuration: walks
|
|
19
|
+
* the JSON-Schema once and builds the field-store tree (`kind:
|
|
20
|
+
* array|object|value`), with the schema as the allow-list — `initialInput`
|
|
21
|
+
* keys not declared in the schema never enter form state.
|
|
22
|
+
*
|
|
23
|
+
* Plugins are resolved and their state containers created BEFORE the walk,
|
|
24
|
+
* so the walk can dispatch `buildScope` for every array-item object it
|
|
25
|
+
* creates (a row wired by the walk behaves exactly like one built later by
|
|
26
|
+
* an insert). The ROOT scope is dispatched after the walk, in plugin array
|
|
27
|
+
* order — for the standard trio that means envelopes (the estimate pin's
|
|
28
|
+
* mode signal) before derivation before visibility.
|
|
29
|
+
*
|
|
30
|
+
* @param config The form configuration.
|
|
31
|
+
*
|
|
32
|
+
* @returns The internal form store.
|
|
33
|
+
*/
|
|
34
|
+
declare function createFormStore(config: FormConfig): InternalFormStore;
|
|
35
|
+
//#endregion
|
|
36
|
+
//#region src/methods/apply-baseline.d.ts
|
|
37
|
+
/**
|
|
38
|
+
* Configuration for `applyBaseline`.
|
|
39
|
+
*/
|
|
40
|
+
interface ApplyBaselineConfig {
|
|
41
|
+
/**
|
|
42
|
+
* Fresh off-form values (canonical rows, the read-only eval scope) to
|
|
43
|
+
* adopt in the same batch as the baseline, so formula fields recompute
|
|
44
|
+
* once against a consistent snapshot. Omit to keep the current values.
|
|
45
|
+
*/
|
|
46
|
+
readonly offFormValues?: Record<string, unknown> | undefined;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Rebases a live form on a fresh server-loaded record — after a save or a
|
|
50
|
+
* revalidate, the store adopts the record as its new baseline instead of
|
|
51
|
+
* being torn down and rebuilt: the record decodes through the `x-column`
|
|
52
|
+
* codec (envelope fields keep their kind-discriminated shape for
|
|
53
|
+
* the plugin rebase), clean fields
|
|
54
|
+
* take the new server value, dirty fields keep the user's in-flight edit
|
|
55
|
+
* re-diffed against the new baseline (an edit equal to the fresh server
|
|
56
|
+
* value becomes clean), and a later `reset()` returns to the NEW baseline.
|
|
57
|
+
* Array membership follows the same rule: unchanged membership adopts the
|
|
58
|
+
* server rows — by `id` when the item schema has usable ids, otherwise
|
|
59
|
+
* positionally — and surviving rows keep their identity. Unmatched clean
|
|
60
|
+
* locals drop; unmatched dirty locals append after the server prefix
|
|
61
|
+
* (field-level dirty still enables Save). Locally changed membership wins,
|
|
62
|
+
* with rows still rebasing content by server `id` where ids exist.
|
|
63
|
+
*
|
|
64
|
+
* It is NOT conflict resolution — two people editing the same field stays
|
|
65
|
+
* last-write-wins. A nullish record is a no-op (nothing to rebase on).
|
|
66
|
+
*
|
|
67
|
+
* For flat-JSONB surfaces without column routing, pass the bag as
|
|
68
|
+
* `{ data: bag }` (the `decodeRecord` convention).
|
|
69
|
+
*
|
|
70
|
+
* @param form The form store to rebase.
|
|
71
|
+
* @param record The fresh server record (`{ …columns, data? }`).
|
|
72
|
+
* @param config Rebase options (e.g. fresh off-form values).
|
|
73
|
+
*/
|
|
74
|
+
declare function applyBaseline(form: FormRef, record: Record<string, unknown> | null | undefined, config?: ApplyBaselineConfig): void;
|
|
75
|
+
//#endregion
|
|
76
|
+
//#region src/methods/array-ops.d.ts
|
|
77
|
+
/**
|
|
78
|
+
* Configuration for inserting an array item.
|
|
79
|
+
*/
|
|
80
|
+
interface InsertConfig {
|
|
81
|
+
/**
|
|
82
|
+
* The index to insert the new item at. Appends to the end when omitted.
|
|
83
|
+
*/
|
|
84
|
+
readonly at?: number | undefined;
|
|
85
|
+
/**
|
|
86
|
+
* The initial input value for the new item.
|
|
87
|
+
*/
|
|
88
|
+
readonly initialInput?: unknown;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Inserts a new item into the array field at the given path. All items at
|
|
92
|
+
* or after the insertion point shift up by one index, and their full state
|
|
93
|
+
* (values, errors, touched/dirty flags, elements) shifts with them.
|
|
94
|
+
*
|
|
95
|
+
* @param form The form store containing the array field.
|
|
96
|
+
* @param path The path to the array field.
|
|
97
|
+
* @param config The insert configuration.
|
|
98
|
+
*/
|
|
99
|
+
declare function insert(form: FormRef, path: Path, config?: InsertConfig): void;
|
|
100
|
+
/**
|
|
101
|
+
* Removes the item at the given index from the array field at the given
|
|
102
|
+
* path. All items after it shift down by one index with their full state.
|
|
103
|
+
*
|
|
104
|
+
* @param form The form store containing the array field.
|
|
105
|
+
* @param path The path to the array field.
|
|
106
|
+
* @param at The index of the item to remove.
|
|
107
|
+
*/
|
|
108
|
+
declare function remove(form: FormRef, path: Path, at: number): void;
|
|
109
|
+
/**
|
|
110
|
+
* Moves the item at one index to another within the array field at the
|
|
111
|
+
* given path. All items between the two indices shift accordingly with
|
|
112
|
+
* their full state.
|
|
113
|
+
*
|
|
114
|
+
* @param form The form store containing the array field.
|
|
115
|
+
* @param path The path to the array field.
|
|
116
|
+
* @param from The index of the item to move.
|
|
117
|
+
* @param to The index to move the item to.
|
|
118
|
+
*/
|
|
119
|
+
declare function move(form: FormRef, path: Path, from: number, to: number): void;
|
|
120
|
+
/**
|
|
121
|
+
* Swaps two items in the array field at the given path by exchanging their
|
|
122
|
+
* positions and their full state.
|
|
123
|
+
*
|
|
124
|
+
* @param form The form store containing the array field.
|
|
125
|
+
* @param path The path to the array field.
|
|
126
|
+
* @param at The index of the first item.
|
|
127
|
+
* @param and The index of the second item.
|
|
128
|
+
*/
|
|
129
|
+
declare function swap(form: FormRef, path: Path, at: number, and: number): void;
|
|
130
|
+
//#endregion
|
|
131
|
+
//#region src/methods/errors.d.ts
|
|
132
|
+
/**
|
|
133
|
+
* Sets or clears the error messages of the field at the given path, or the
|
|
134
|
+
* form-level (root) errors when no path is given. Useful for custom errors
|
|
135
|
+
* that do not come from schema validation (e.g. a failed server action).
|
|
136
|
+
*
|
|
137
|
+
* @param form The form store to set errors on.
|
|
138
|
+
* @param errors The error messages, or `null` to clear.
|
|
139
|
+
* @param path The path to the field (omit for form-level errors).
|
|
140
|
+
*/
|
|
141
|
+
declare function setErrors(form: FormRef, errors: FieldErrors, path?: Path): void;
|
|
142
|
+
/**
|
|
143
|
+
* Retrieves the error messages of the field at the given path, or the
|
|
144
|
+
* form-level (root) errors when no path is given. Does NOT include
|
|
145
|
+
* descendants — use `getDeepErrors` for a subtree.
|
|
146
|
+
*
|
|
147
|
+
* @param form The form store to read errors from.
|
|
148
|
+
* @param path The path to the field (omit for form-level errors).
|
|
149
|
+
*
|
|
150
|
+
* @returns The error messages, or `null`.
|
|
151
|
+
*/
|
|
152
|
+
declare function getErrors(form: FormRef, path?: Path): FieldErrors;
|
|
153
|
+
/**
|
|
154
|
+
* Retrieves every error message of the field at the given path and all its
|
|
155
|
+
* descendants (the entire form when no path is given), in depth-first
|
|
156
|
+
* order. Form-level errors are included. This is what a checks panel sits
|
|
157
|
+
* on — it surfaces errors of fields that are not currently rendered.
|
|
158
|
+
*
|
|
159
|
+
* @param form The form store to read errors from.
|
|
160
|
+
* @param path The path to scope to (omit for the whole form).
|
|
161
|
+
*
|
|
162
|
+
* @returns The error messages, or `null` if none exist.
|
|
163
|
+
*/
|
|
164
|
+
declare function getDeepErrors(form: FormRef, path?: Path): FieldErrors;
|
|
165
|
+
/**
|
|
166
|
+
* One deep-error entry: the erroring field's path and its messages.
|
|
167
|
+
*/
|
|
168
|
+
interface DeepErrorEntry {
|
|
169
|
+
/**
|
|
170
|
+
* The path to the erroring field (`[]` for form-level errors).
|
|
171
|
+
*/
|
|
172
|
+
readonly path: Path;
|
|
173
|
+
/**
|
|
174
|
+
* The error messages of the field.
|
|
175
|
+
*/
|
|
176
|
+
readonly errors: [string, ...string[]];
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Retrieves every erroring field of the subtree at the given path (the
|
|
180
|
+
* entire form when no path is given) as `{ path, errors }` entries in
|
|
181
|
+
* depth-first order.
|
|
182
|
+
*
|
|
183
|
+
* @param form The form store to read errors from.
|
|
184
|
+
* @param path The path to scope to (omit for the whole form).
|
|
185
|
+
*
|
|
186
|
+
* @returns The deep error entries (empty when none exist).
|
|
187
|
+
*/
|
|
188
|
+
declare function getDeepErrorEntries(form: FormRef, path?: Path): DeepErrorEntry[];
|
|
189
|
+
//#endregion
|
|
190
|
+
//#region src/methods/focus.d.ts
|
|
191
|
+
/**
|
|
192
|
+
* Focuses the first focusable element of the field at the given path.
|
|
193
|
+
* Detached, disabled or hidden elements are skipped.
|
|
194
|
+
*
|
|
195
|
+
* @param form The form store containing the field.
|
|
196
|
+
* @param path The path to the field to focus.
|
|
197
|
+
*/
|
|
198
|
+
declare function focus(form: FormRef, path: Path): void;
|
|
199
|
+
//#endregion
|
|
200
|
+
//#region src/methods/get-dirty-input.d.ts
|
|
201
|
+
/**
|
|
202
|
+
* Retrieves only the dirty input values of the field at the given path, or
|
|
203
|
+
* the entire form when no path is given. Arrays are treated as atomic and
|
|
204
|
+
* returned in full if any item is dirty, while object keys without a dirty
|
|
205
|
+
* descendant are omitted. Returns `undefined` if nothing in the inspected
|
|
206
|
+
* subtree is dirty.
|
|
207
|
+
*
|
|
208
|
+
* @param form The form store to retrieve dirty input from.
|
|
209
|
+
* @param path The path to the field (omit for the whole form).
|
|
210
|
+
*
|
|
211
|
+
* @returns The dirty input, or `undefined`.
|
|
212
|
+
*/
|
|
213
|
+
declare function getDirtyInput(form: FormRef, path?: Path): unknown;
|
|
214
|
+
//#endregion
|
|
215
|
+
//#region src/methods/get-dirty-paths.d.ts
|
|
216
|
+
/**
|
|
217
|
+
* Returns the paths to the dirty fields of the form (or of the subtree at
|
|
218
|
+
* the given path). Arrays are treated as atomic and contribute only their
|
|
219
|
+
* own path if any item is dirty; object branches are recursed into, and a
|
|
220
|
+
* container that flipped dirty itself (e.g. nullish → present) emits its
|
|
221
|
+
* own path only when no descendant already covers it.
|
|
222
|
+
*
|
|
223
|
+
* @param form The form store to inspect.
|
|
224
|
+
* @param path The path to scope to (omit for the whole form).
|
|
225
|
+
*
|
|
226
|
+
* @returns The list of paths to the dirty fields.
|
|
227
|
+
*/
|
|
228
|
+
declare function getDirtyPaths(form: FormRef, path?: Path): Path[];
|
|
229
|
+
//#endregion
|
|
230
|
+
//#region src/methods/get-input.d.ts
|
|
231
|
+
/**
|
|
232
|
+
* Retrieves the current input value of the field at the given path, or the
|
|
233
|
+
* entire form when no path is given. The tree is the allow-list, so the
|
|
234
|
+
* result only ever contains declared fields.
|
|
235
|
+
*
|
|
236
|
+
* @param form The form store to retrieve input from.
|
|
237
|
+
* @param path The path to the field (omit for the whole form).
|
|
238
|
+
*
|
|
239
|
+
* @returns The input value.
|
|
240
|
+
*/
|
|
241
|
+
declare function getInput(form: FormRef, path?: Path): unknown;
|
|
242
|
+
//#endregion
|
|
243
|
+
//#region src/methods/pick-dirty.d.ts
|
|
244
|
+
/**
|
|
245
|
+
* Picks only the dirty parts of the given value, using the form's dirty
|
|
246
|
+
* fields as a structural mask while reading from the SUPPLIED value (e.g. a
|
|
247
|
+
* validated output), not the form's own input. Arrays are treated as atomic
|
|
248
|
+
* and object keys without a dirty descendant are omitted. Returns
|
|
249
|
+
* `undefined` if no field is dirty or no dirty key is present in the value.
|
|
250
|
+
*
|
|
251
|
+
* Envelope leaves (estimate/amount-or-percent) emit their COMPLETE
|
|
252
|
+
* kind envelope — the plugin wraps the supplied
|
|
253
|
+
* value with its meta half, and a leaf whose only change is plugin state
|
|
254
|
+
* (a mode flip) still emits.
|
|
255
|
+
*
|
|
256
|
+
* @param form The form store providing the dirty mask.
|
|
257
|
+
* @param from The value to filter down to its dirty parts.
|
|
258
|
+
*
|
|
259
|
+
* @returns The dirty parts of the value, or `undefined`.
|
|
260
|
+
*/
|
|
261
|
+
declare function pickDirty(form: FormRef, from: Record<string, unknown>): Record<string, unknown> | undefined;
|
|
262
|
+
//#endregion
|
|
263
|
+
//#region src/methods/reset.d.ts
|
|
264
|
+
/**
|
|
265
|
+
* Configuration for resetting a form or field.
|
|
266
|
+
*/
|
|
267
|
+
interface ResetConfig {
|
|
268
|
+
/**
|
|
269
|
+
* The path to the field to reset. Leave undefined to reset the entire
|
|
270
|
+
* form.
|
|
271
|
+
*/
|
|
272
|
+
readonly path?: Path | undefined;
|
|
273
|
+
/**
|
|
274
|
+
* The new initial input to reset to. An EXPLICIT `undefined` resets the
|
|
275
|
+
* baseline to the empty input; an OMITTED key keeps the existing
|
|
276
|
+
* baseline — the two are distinguished by key presence.
|
|
277
|
+
*/
|
|
278
|
+
readonly initialInput?: unknown;
|
|
279
|
+
/**
|
|
280
|
+
* Whether to keep the current input values. Defaults to `false`.
|
|
281
|
+
*/
|
|
282
|
+
readonly keepInput?: boolean | undefined;
|
|
283
|
+
/**
|
|
284
|
+
* Whether to keep the touched state. Defaults to `false`.
|
|
285
|
+
*/
|
|
286
|
+
readonly keepTouched?: boolean | undefined;
|
|
287
|
+
/**
|
|
288
|
+
* Whether to keep the edited state. Defaults to `false`.
|
|
289
|
+
*/
|
|
290
|
+
readonly keepEdited?: boolean | undefined;
|
|
291
|
+
/**
|
|
292
|
+
* Whether to keep the error messages. Defaults to `false`.
|
|
293
|
+
*/
|
|
294
|
+
readonly keepErrors?: boolean | undefined;
|
|
295
|
+
/**
|
|
296
|
+
* Whether to keep the submitted state (form reset only). Defaults to
|
|
297
|
+
* `false`.
|
|
298
|
+
*/
|
|
299
|
+
readonly keepSubmitted?: boolean | undefined;
|
|
300
|
+
}
|
|
301
|
+
/**
|
|
302
|
+
* Resets a specific field or the entire form to its initial state, with
|
|
303
|
+
* fine-grained control over which state to preserve via the `keep*` flags.
|
|
304
|
+
* When `initialInput` is provided it replaces the reset baseline first.
|
|
305
|
+
*
|
|
306
|
+
* @param form The form store to reset.
|
|
307
|
+
* @param config The reset configuration.
|
|
308
|
+
*/
|
|
309
|
+
declare function reset(form: FormRef, config?: ResetConfig): void;
|
|
310
|
+
//#endregion
|
|
311
|
+
//#region src/methods/set-entry.d.ts
|
|
312
|
+
/**
|
|
313
|
+
* Sets the entry mode of an amount-or-percent field (enter a dollar
|
|
314
|
+
* amount, or a percent of the percent basis). Dirties the meta half; the
|
|
315
|
+
* field's own value — always the resolved dollar amount — is the widget's
|
|
316
|
+
* to convert and write.
|
|
317
|
+
*
|
|
318
|
+
* @param form The form store containing the field.
|
|
319
|
+
* @param path The path to the amount-or-percent field.
|
|
320
|
+
* @param mode The entry mode.
|
|
321
|
+
*/
|
|
322
|
+
declare function setEntryMode(form: FormRef, path: Path, mode: EntryMode): void;
|
|
323
|
+
/**
|
|
324
|
+
* Sets the percent basis of an amount-or-percent field (the root-level field key
|
|
325
|
+
* the percent is taken of). Dirties the meta half; keeping the resolved
|
|
326
|
+
* dollar amount constant against the new basis is the widget's job.
|
|
327
|
+
*
|
|
328
|
+
* @param form The form store containing the field.
|
|
329
|
+
* @param path The path to the amount-or-percent field.
|
|
330
|
+
* @param percentBasis The basis field key.
|
|
331
|
+
*/
|
|
332
|
+
declare function setPercentBasis(form: FormRef, path: Path, percentBasis: string): void;
|
|
333
|
+
//#endregion
|
|
334
|
+
//#region src/methods/set-input.d.ts
|
|
335
|
+
/**
|
|
336
|
+
* Sets the input value of the field at the given path (or the entire form
|
|
337
|
+
* for an empty path), updating touched, edited and dirty state, and
|
|
338
|
+
* triggers validation when the form's validation mode requires it. Throws
|
|
339
|
+
* on a path not declared in the schema.
|
|
340
|
+
*
|
|
341
|
+
* @param form The form store to set input on.
|
|
342
|
+
* @param path The path to the field (`[]` for the whole form).
|
|
343
|
+
* @param input The new input value.
|
|
344
|
+
*/
|
|
345
|
+
declare function setInput(form: FormRef, path: Path, input: unknown): void;
|
|
346
|
+
//#endregion
|
|
347
|
+
//#region src/methods/set-mode.d.ts
|
|
348
|
+
/**
|
|
349
|
+
* Options for `setMode`.
|
|
350
|
+
*/
|
|
351
|
+
interface SetModeOptions {
|
|
352
|
+
/**
|
|
353
|
+
* The flip timestamp (ISO-8601) stamped into the meta half's
|
|
354
|
+
* `lastFlippedAt`. Defaults to the current time; inject for
|
|
355
|
+
* deterministic tests.
|
|
356
|
+
*/
|
|
357
|
+
readonly now?: string | undefined;
|
|
358
|
+
}
|
|
359
|
+
/**
|
|
360
|
+
* Flips an estimate field between its two modes — the ONLY supported mode
|
|
361
|
+
* writer (a raw `mode` signal write skips value seeding and the flip
|
|
362
|
+
* timestamp):
|
|
363
|
+
*
|
|
364
|
+
* - `estimate` → `formula`: the current input is preserved as the meta
|
|
365
|
+
* half's `manualValue` and the field computes again. The derived value
|
|
366
|
+
* is NOT written into the input — derived values are outputs; the
|
|
367
|
+
* server recompute pass is their author.
|
|
368
|
+
* - `formula` → `estimate`: the manual value is seeded from the last
|
|
369
|
+
* formula result (estimate-first chronology: when you stop trusting the
|
|
370
|
+
* formula you start from its current value and adjust), which marks the
|
|
371
|
+
* value dirty like any user edit.
|
|
372
|
+
*
|
|
373
|
+
* Either flip dirties the meta half (`lastFlippedAt` stamped), so a flip
|
|
374
|
+
* with no other edit still produces a payload.
|
|
375
|
+
*
|
|
376
|
+
* Works at any depth: an estimate field inside an array row has its own
|
|
377
|
+
* envelope slot, built from the row's envelope. The throw is reserved
|
|
378
|
+
* for a field that genuinely has none — a non-estimate control, or a form
|
|
379
|
+
* without the envelopes plugin.
|
|
380
|
+
*
|
|
381
|
+
* @param form The form store containing the field.
|
|
382
|
+
* @param path The path to the estimate field.
|
|
383
|
+
* @param mode The target mode (a no-op when already current).
|
|
384
|
+
* @param options Flip options (e.g. an injected timestamp).
|
|
385
|
+
*/
|
|
386
|
+
declare function setMode(form: FormRef, path: Path, mode: DerivationMode, options?: SetModeOptions): void;
|
|
387
|
+
//#endregion
|
|
388
|
+
//#region src/methods/set-off-form-values.d.ts
|
|
389
|
+
/**
|
|
390
|
+
* Replaces the form's off-form values (the read-only eval scope formula
|
|
391
|
+
* resolution falls back to). One signal write: every formula field reading
|
|
392
|
+
* off-form values re-resolves once — the LOS-470 `BpsBaseSync` behavior as
|
|
393
|
+
* a store property. `applyBaseline` performs the same
|
|
394
|
+
* write on reconcile, batched with the value rebase.
|
|
395
|
+
*
|
|
396
|
+
* @param form The form store.
|
|
397
|
+
* @param values The new off-form values.
|
|
398
|
+
*/
|
|
399
|
+
declare function setOffFormValues(form: FormRef, values: Record<string, unknown>): void;
|
|
400
|
+
//#endregion
|
|
401
|
+
//#region src/methods/validate.d.ts
|
|
402
|
+
/**
|
|
403
|
+
* Validates the entire form input with the injected validator, routing each
|
|
404
|
+
* issue to its field's `errors` signal. Optionally focuses the first field
|
|
405
|
+
* with an error.
|
|
406
|
+
*
|
|
407
|
+
* @param form The form store to validate.
|
|
408
|
+
* @param config The validation configuration.
|
|
409
|
+
*
|
|
410
|
+
* @returns The validation result.
|
|
411
|
+
*/
|
|
412
|
+
declare function validate(form: FormRef, config?: ValidateFormInputConfig): ValidationResult;
|
|
413
|
+
//#endregion
|
|
414
|
+
//#region src/core/codec/decode-record.d.ts
|
|
415
|
+
/**
|
|
416
|
+
* Options for `decodeRecord`.
|
|
417
|
+
*/
|
|
418
|
+
interface DecodeRecordOptions {
|
|
419
|
+
/**
|
|
420
|
+
* Envelope wire contracts keyed by control kind — the form store's
|
|
421
|
+
* `pluginDriver.envelopes`, or `envelopeContracts([envelopesWire])` on
|
|
422
|
+
* the server. An envelope-control field reads its WHOLE envelope from
|
|
423
|
+
* the `data` bag (falling back to the bare column value for a field
|
|
424
|
+
* whose meta was never persisted); core unwraps the value half at the
|
|
425
|
+
* leaf, and the owning plugin re-reads the meta half from the same raw.
|
|
426
|
+
*/
|
|
427
|
+
envelopes?: ReadonlyMap<string, WireContract>;
|
|
428
|
+
}
|
|
429
|
+
/**
|
|
430
|
+
* Decodes a nested server record into the form's `initialInput` shape,
|
|
431
|
+
* routing each declared root property by its `x-column` geometry:
|
|
432
|
+
* `x-column: true` fields read from a real record column (a top-level
|
|
433
|
+
* record key), everything else reads from the record's `data` JSONB bag.
|
|
434
|
+
*
|
|
435
|
+
* The schema is the allow-list — only declared property keys are read, so
|
|
436
|
+
* undeclared record keys (including prototype-pollution keys) never enter
|
|
437
|
+
* the result. Nested values pass through as-is; the store walk applies the
|
|
438
|
+
* allow-list recursively when the result becomes `initialInput`, and
|
|
439
|
+
* unwraps envelope leaves (`{ kind, value?, mode, … }`) through the
|
|
440
|
+
* registered wire contracts.
|
|
441
|
+
*
|
|
442
|
+
* For flat-JSONB surfaces without column routing (e.g. workflow form
|
|
443
|
+
* tasks), pass the bag as `{ data: bag }`.
|
|
444
|
+
*
|
|
445
|
+
* @param schema The form's JSON-Schema (object schema with properties).
|
|
446
|
+
* @param record The server record (`{ …columns, data? }`).
|
|
447
|
+
* @param options Decode options (envelope wire contracts).
|
|
448
|
+
*
|
|
449
|
+
* @returns The decoded initial input, or `undefined` for a nullish record.
|
|
450
|
+
*/
|
|
451
|
+
declare function decodeRecord(schema: JsonSchema, record: Record<string, unknown> | null | undefined, options?: DecodeRecordOptions): Record<string, unknown> | undefined;
|
|
452
|
+
//#endregion
|
|
453
|
+
//#region src/core/codec/encode-dirty.d.ts
|
|
454
|
+
/**
|
|
455
|
+
* The save payload partitioned by record geometry: real table columns and
|
|
456
|
+
* `data` JSONB bag entries. Envelope fields (kind-discriminated union)
|
|
457
|
+
* always land WHOLE in `data`; an `x-column: true` envelope field also
|
|
458
|
+
* mirrors its value half into `columns` (a write-through scalar for SQL
|
|
459
|
+
* and list pages — the bag stays the source of truth).
|
|
460
|
+
*/
|
|
461
|
+
interface EncodedDirty {
|
|
462
|
+
columns: Record<string, unknown>;
|
|
463
|
+
data: Record<string, unknown>;
|
|
464
|
+
}
|
|
465
|
+
/**
|
|
466
|
+
* Options for `encodeDirty`.
|
|
467
|
+
*/
|
|
468
|
+
interface EncodeDirtyOptions {
|
|
469
|
+
/**
|
|
470
|
+
* The real table columns that exist (server-side drizzle column keys).
|
|
471
|
+
* When provided, an `x-column: true` key with no matching real column is
|
|
472
|
+
* DROPPED instead of routed to `columns` — a schema declaring a column
|
|
473
|
+
* that does not exist is an undeclared write path, and one bad key must
|
|
474
|
+
* not fail the whole save (mirrors `partitionAssetRow`).
|
|
475
|
+
*/
|
|
476
|
+
knownColumns?: ReadonlySet<string>;
|
|
477
|
+
/**
|
|
478
|
+
* The plugins' static wire contracts (`[envelopesWire, derivationWire]`
|
|
479
|
+
* for the standard trio). This function is isomorphic — the server
|
|
480
|
+
* assembles the same list from the same exported descriptors, with no
|
|
481
|
+
* form store anywhere (D7). Without contracts every declared value
|
|
482
|
+
* passes through bare.
|
|
483
|
+
*/
|
|
484
|
+
wire?: readonly WireContract[];
|
|
485
|
+
}
|
|
486
|
+
/**
|
|
487
|
+
* Builds the envelope-control lookup from a wire list.
|
|
488
|
+
*/
|
|
489
|
+
declare function envelopeContracts(wire: readonly WireContract[] | undefined): ReadonlyMap<string, WireContract>;
|
|
490
|
+
/**
|
|
491
|
+
* Encodes a dirty-values object (the `pickDirty`/`getDirtyInput` result)
|
|
492
|
+
* into the save payload, partitioning each root key by its `x-column`
|
|
493
|
+
* geometry: `x-column: true` fields become column updates, everything else
|
|
494
|
+
* lands in the `data` bag. Undeclared keys — including prototype-pollution
|
|
495
|
+
* keys — are dropped: the schema is the allow-list at the write boundary
|
|
496
|
+
* too.
|
|
497
|
+
*
|
|
498
|
+
* Wire contracts carry each plugin's persistence policy (behavior
|
|
499
|
+
* relocated verbatim from LOS-461, not redesigned): `skipValue` drops a
|
|
500
|
+
* formula value (the server recompute is its only author), and an
|
|
501
|
+
* envelope contract's `encode` normalizes the outgoing envelope (an
|
|
502
|
+
* estimate value persists exactly when its meta pins `mode: "estimate"`).
|
|
503
|
+
*
|
|
504
|
+
* @param schema The form's JSON-Schema (object schema with properties).
|
|
505
|
+
* @param dirty The dirty values, or `undefined` when nothing is dirty.
|
|
506
|
+
* @param options Encoding options (column set, wire contracts).
|
|
507
|
+
*
|
|
508
|
+
* @returns The partitioned payload, or `undefined` when nothing survives.
|
|
509
|
+
*/
|
|
510
|
+
declare function encodeDirty(schema: JsonSchema, dirty: Record<string, unknown> | null | undefined, options?: EncodeDirtyOptions): EncodedDirty | undefined;
|
|
511
|
+
//#endregion
|
|
512
|
+
//#region src/core/derivation/merge-collection-rows.d.ts
|
|
513
|
+
/**
|
|
514
|
+
* Merge a collection's canonical rows (the read model — full server rows
|
|
515
|
+
* with calc fields pre-evaluated, delivered via `offFormValues`) with the
|
|
516
|
+
* live form rows (the write model the user edits) for formula evaluation.
|
|
517
|
+
*
|
|
518
|
+
* Membership comes from the LIVE rows, so rows added or removed during the
|
|
519
|
+
* form session are respected. Each live row is enriched from the canonical
|
|
520
|
+
* row with the same `id`: live keys win (an explicit `null` means the user
|
|
521
|
+
* cleared the field), canonical fills everything the live row doesn't
|
|
522
|
+
* carry — core columns the write model never holds.
|
|
523
|
+
*
|
|
524
|
+
* One home for collection overlay (app re-exports this). The merged result
|
|
525
|
+
* is for evaluation only; it is never written back into form state.
|
|
526
|
+
*/
|
|
527
|
+
declare function mergeCollectionRows(canonicalRows: ReadonlyArray<Record<string, unknown>>, liveRows: unknown): Array<Record<string, unknown>>;
|
|
528
|
+
//#endregion
|
|
529
|
+
//#region src/core/relation/relation-config.d.ts
|
|
530
|
+
/**
|
|
531
|
+
* The relation config a select/multiselect control may carry. Read
|
|
532
|
+
* straight off the schema node at render time; jsonisch's `inferControl`
|
|
533
|
+
* already classified the node select/multiselect, so this only decides
|
|
534
|
+
* WHICH picker renders and with what search filters.
|
|
535
|
+
*
|
|
536
|
+
* Core home — bagger() classifies collections with this; host widgets
|
|
537
|
+
* import it from the package root.
|
|
538
|
+
*/
|
|
539
|
+
interface RelationConfig {
|
|
540
|
+
/**
|
|
541
|
+
* The related domain: `entity` | `contact` | `participant` | `party` |
|
|
542
|
+
* `asset` (from the `schema://<target>` ref or the `x-relation` target).
|
|
543
|
+
*/
|
|
544
|
+
target: string;
|
|
545
|
+
/**
|
|
546
|
+
* Whether the field holds many rows. Explicit `multiple` wins over the
|
|
547
|
+
* node's type — legacy data has array-typed nodes that render a single
|
|
548
|
+
* picker (e.g. loan.assignee).
|
|
549
|
+
*/
|
|
550
|
+
many: boolean;
|
|
551
|
+
/**
|
|
552
|
+
* The participant role the picker searches for (drives placeholder,
|
|
553
|
+
* trait filter fallback, and the add-button label).
|
|
554
|
+
*/
|
|
555
|
+
role?: string | undefined;
|
|
556
|
+
/**
|
|
557
|
+
* The trait slugs filtering the search.
|
|
558
|
+
*/
|
|
559
|
+
traits?: string[] | undefined;
|
|
560
|
+
/**
|
|
561
|
+
* Restricts search to entities that are members of the entity picked in
|
|
562
|
+
* this sibling field (e.g. closingContact within lendingBranch).
|
|
563
|
+
*/
|
|
564
|
+
parent?: string | undefined;
|
|
565
|
+
/**
|
|
566
|
+
* Mock search data (docs/demo surfaces only).
|
|
567
|
+
*/
|
|
568
|
+
useMockData?: boolean | undefined;
|
|
569
|
+
/**
|
|
570
|
+
* The per-row nested sub-schema (stage-configured "fields on this
|
|
571
|
+
* record"; the stage loader injects it into `items`).
|
|
572
|
+
*/
|
|
573
|
+
items?: JsonSchema | undefined;
|
|
574
|
+
}
|
|
575
|
+
/**
|
|
576
|
+
* Reads a node's relation config, or `undefined` for a plain enum
|
|
577
|
+
* select/multiselect. Two schema forms:
|
|
578
|
+
* 1. Canonical — `$ref: schema://<target>` (one) or array of that ref
|
|
579
|
+
* (many); widget extras ride as sibling keys.
|
|
580
|
+
* 2. Vendor — `x-relation` namespace or flat `x-relation-target`;
|
|
581
|
+
* cardinality follows the node's `type` unless `multiple` overrides.
|
|
582
|
+
*/
|
|
583
|
+
declare function readRelationConfig(schema: JsonSchema): RelationConfig | undefined;
|
|
584
|
+
/**
|
|
585
|
+
* Maps a relation target to the party autocomplete's kind hint. The widget
|
|
586
|
+
* only knows `entity` / `contact` / undefined (= search both); join-table
|
|
587
|
+
* targets (`participant`, `party`) stay open.
|
|
588
|
+
*/
|
|
589
|
+
declare function targetToKind(target: string): "entity" | "contact" | undefined;
|
|
590
|
+
/**
|
|
591
|
+
* The sibling field a contact picker is scoped to (`memberOfEntityId`).
|
|
592
|
+
*
|
|
593
|
+
* Explicit `x-relation-parent` always wins. When it is missing — the live
|
|
594
|
+
* artifact schema never carried the key — a contact relation whose traits
|
|
595
|
+
* include exactly one sibling entity relation's role is scoped to that
|
|
596
|
+
* sibling (LOS-860: titleOfficer traits `["title-company"]` → titleCompany).
|
|
597
|
+
* Two matches is ambiguous, so no parent is invented.
|
|
598
|
+
*/
|
|
599
|
+
declare function relationParentFieldName(schema: JsonSchema, path: readonly (string | number)[], relation: RelationConfig): string | undefined;
|
|
600
|
+
/**
|
|
601
|
+
* The row-identity contract for a relation target. A relation whose item
|
|
602
|
+
* schema declares NO properties never reaches `withRelationRowIdentity` —
|
|
603
|
+
* its rows are a value leaf holding the whole object, with no allow-list to
|
|
604
|
+
* thin them — so a host feeding such a relation from a canonical record
|
|
605
|
+
* must project the rows against this same set itself.
|
|
606
|
+
*/
|
|
607
|
+
declare function relationRowIdentityProps(target: string): Record<string, JsonSchema>;
|
|
608
|
+
/**
|
|
609
|
+
* Returns a schema whose multi-row relation item schemas additionally
|
|
610
|
+
* declare the row-identity keys (stage-configured keys win on collision).
|
|
611
|
+
* Apply to the STORE schema only — rendering iterates the configured keys
|
|
612
|
+
* and skips hidden controls.
|
|
613
|
+
*/
|
|
614
|
+
declare function withRelationRowIdentity(schema: JsonSchema): JsonSchema;
|
|
615
|
+
//#endregion
|
|
616
|
+
//#region src/core/dirty.d.ts
|
|
617
|
+
/**
|
|
618
|
+
* Returns whether a value is semantically empty: `undefined`, `null`, the
|
|
619
|
+
* empty string, or `NaN` (what a cleared number input parses to). These are
|
|
620
|
+
* all "no value entered" and must never make a field dirty against each
|
|
621
|
+
* other — the core semantic-dirty promise.
|
|
622
|
+
*/
|
|
623
|
+
declare function isEmptyish(value: unknown): boolean;
|
|
624
|
+
/**
|
|
625
|
+
* Semantic, empty-aware equality between two leaf inputs: equal when both
|
|
626
|
+
* are semantically empty (`null` ≡ `undefined` ≡ `""` ≡ `NaN`) or deeply
|
|
627
|
+
* structurally equal.
|
|
628
|
+
*/
|
|
629
|
+
declare function isSemanticEqual(a: unknown, b: unknown): boolean;
|
|
630
|
+
/**
|
|
631
|
+
* Semantic equality between two container presence sentinels: `true` only
|
|
632
|
+
* equals `true`; `null` and `undefined` (absent container) are equivalent.
|
|
633
|
+
*/
|
|
634
|
+
declare function isPresenceEqual(a: ContainerInput, b: ContainerInput): boolean;
|
|
635
|
+
//#endregion
|
|
636
|
+
//#region src/plugins/derivation/resolve-scope-value.d.ts
|
|
637
|
+
/**
|
|
638
|
+
* Resolves a single scalar key through the canonical scope precedence —
|
|
639
|
+
* the same order the derivation plugin evaluates formula dependencies in:
|
|
640
|
+
* the form value wins (a formula field resolves through its derived
|
|
641
|
+
* signal, so the read is always fresh; an erroring formula resolves
|
|
642
|
+
* `undefined`, never a stale number), `offFormValues` fills what the form
|
|
643
|
+
* does not hold (an off-stage field still resolves from the canonical record).
|
|
644
|
+
*
|
|
645
|
+
* For widget-side scalar reads (e.g. an amount-or-percent field resolving
|
|
646
|
+
* its percent basis). Collection overlay semantics stay inside the
|
|
647
|
+
* derivation plugin — this helper is for scalars.
|
|
648
|
+
*
|
|
649
|
+
* @param internalFormStore The form store.
|
|
650
|
+
* @param key The root-level field key to resolve.
|
|
651
|
+
*
|
|
652
|
+
* @returns The resolved value, or `undefined`.
|
|
653
|
+
*/
|
|
654
|
+
declare function resolveScopeValue(internalFormStore: InternalFormStore, key: string): unknown;
|
|
655
|
+
/**
|
|
656
|
+
* Resolves a single scalar key in the scope of the field at `path` — the
|
|
657
|
+
* path-aware sibling of `resolveScopeValue`, and the read a widget owned by
|
|
658
|
+
* a field should use:
|
|
659
|
+
*
|
|
660
|
+
* - inside an array row, the ROW's scope (live siblings in the same row →
|
|
661
|
+
* the canonical row from `offFormValues` matched by `id` → the parent
|
|
662
|
+
* root record under the form's `rootRecordAlias`), so a per-row formula's inputs are ITS
|
|
663
|
+
* row's values;
|
|
664
|
+
* - anywhere else, the document scope (`resolveScopeValue`).
|
|
665
|
+
*
|
|
666
|
+
* The same precedence the derivation graph evaluates the field's own
|
|
667
|
+
* formula in, so a widget can never display an input the value was not
|
|
668
|
+
* computed from.
|
|
669
|
+
*
|
|
670
|
+
* @param internalFormStore The form store.
|
|
671
|
+
* @param path The path of the field whose scope to resolve in.
|
|
672
|
+
* @param key The identifier to resolve.
|
|
673
|
+
*
|
|
674
|
+
* @returns The resolved value, or `undefined`.
|
|
675
|
+
*/
|
|
676
|
+
declare function resolveScopeValueAt(internalFormStore: InternalFormStore, path: Path, key: string): unknown;
|
|
677
|
+
//#endregion
|
|
678
|
+
//#region src/plugins/envelopes/wire.d.ts
|
|
679
|
+
/** Discriminator of a persisted estimate / amount-or-percent envelope. */
|
|
680
|
+
type EnvelopeKind = "estimate" | "amount-or-percent";
|
|
681
|
+
/**
|
|
682
|
+
* Returns whether a raw persisted entry is an envelope: an object whose
|
|
683
|
+
* `kind` is `estimate` or `amount-or-percent`. Anything else — including
|
|
684
|
+
* the bare scalars every non-envelope field persists — is a bare value.
|
|
685
|
+
*/
|
|
686
|
+
declare function isEnvelope(raw: unknown): raw is Record<string, unknown>;
|
|
687
|
+
/**
|
|
688
|
+
* Wraps an estimate field's halves into its envelope. The value key is
|
|
689
|
+
* OMITTED when `value` is `undefined` (formula mode ships
|
|
690
|
+
* `{ kind: "estimate", mode: "formula" }` and lets the server recompute
|
|
691
|
+
* author the value half).
|
|
692
|
+
*/
|
|
693
|
+
declare function wrapEstimate(value: unknown, meta: EstimateMeta): unknown;
|
|
694
|
+
/**
|
|
695
|
+
* Wraps an amount-or-percent field's halves into its envelope. Always
|
|
696
|
+
* complete — an envelope is one bag key, so a partial write would clobber
|
|
697
|
+
* the persisted other half.
|
|
698
|
+
*/
|
|
699
|
+
declare function wrapAmountOrPercent(value: unknown, meta: EntryMeta): unknown;
|
|
700
|
+
/**
|
|
701
|
+
* The envelopes plugin's STATIC wire contract — isomorphic by
|
|
702
|
+
* construction: the server imports this same object for save routing
|
|
703
|
+
* (`encodeDirty`), the recompute pass, and engine-less readers
|
|
704
|
+
* (changelog, list pages), with no form store anywhere (D7).
|
|
705
|
+
*
|
|
706
|
+
* Envelope shape: estimate fields persist
|
|
707
|
+
* `{ kind: "estimate", value?, mode, manualValue?, lastFlippedAt? }`,
|
|
708
|
+
* amount-or-percent fields
|
|
709
|
+
* `{ kind: "amount-or-percent", value, mode, basis? }`.
|
|
710
|
+
* Wire `mode` uses settled names (`estimate`/`formula`, `amount`/`percent`).
|
|
711
|
+
* Only these two controls grow the envelope; scalars stay bare.
|
|
712
|
+
*/
|
|
713
|
+
declare const envelopesWire: WireContract;
|
|
714
|
+
//#endregion
|
|
715
|
+
//#region src/plugins/derivation/wire.d.ts
|
|
716
|
+
/**
|
|
717
|
+
* The derivation plugin's STATIC wire contract: a `formula` value is
|
|
718
|
+
* ALWAYS server-recomputed — a client payload only carries a stale echo of
|
|
719
|
+
* the last-rendered result, so `encodeDirty` drops it. (The estimate-pin
|
|
720
|
+
* policy lives on `envelopesWire.encode` — the envelope owns it.)
|
|
721
|
+
*/
|
|
722
|
+
declare const derivationWire: WireContract;
|
|
723
|
+
//#endregion
|
|
724
|
+
export { type AmountOrPercentEnvelope, type ApplyBaselineConfig, type BaggerOptions, type CalcEngine, type CalcParseResult, type CheckContext, type CheckDefinition, type CheckInstanceConfig, type CheckScope, type ChecksConfig, type ComputeBagOptions, type ControlKind, DEFAULT_EMPTY_INPUT, DEFAULT_ROOT_RECORD_ALIAS, type DecodeRecordOptions, type DeepErrorEntry, type DerivationMode, type DerivedState, type EncodeDirtyOptions, type EncodedDirty, type EntryMeta, type EntryMode, type Envelope, type EnvelopeKind, type EstimateEnvelope, type EstimateMeta, type FieldErrors, type FieldKind, type Finding, type FormConfig, type FormRef, type FormValidator, type FormulaOptions, type InsertConfig, type JsonSchema, type Path, type PathSegment, type PluginsInput, type RelationConfig, type ResetConfig, type SetModeOptions, type Severity, type SeverityConfig, type SubmitHandler, UNEVALUABLE_MESSAGE_ID, type ValidateFormInputConfig, type ValidationIssue, type ValidationMode, type ValidationResult, type VisibleWhen, type VisibleWhenOp, applyBaseline, bagger, checks, collectionKeys, computeBag, createFormStore, decodeRecord, derivation, derivationWire, encodeDirty, envelopeContracts, envelopes, envelopesWire, flattenSourceRow, focus, formulaCheck, getDeepErrorEntries, getDeepErrors, getDirtyInput, getDirtyPaths, getErrors, getInput, handleSubmit, inferControl, insert, isEmptyish, isEnvelope, isPresenceEqual, isSemanticEqual, mergeCollectionRows, move, pickDirty, readRelationConfig, relationParentFieldName, relationRowIdentityProps, remove, replaceCheckInstances, reset, resolveScopeValue, resolveScopeValueAt, setEntryMode, setErrors, setInput, setMode, setOffFormValues, setPercentBasis, swap, targetToKind, validate, visibility, withRelationRowIdentity, wrapAmountOrPercent, wrapEstimate };
|