@object-ui/plugin-form 17.6.0 → 17.7.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 +4187 -0
- package/README.md +376 -44
- package/dist/DrawerForm.d.ts +30 -2
- package/dist/DrawerForm.d.ts.map +1 -1
- package/dist/EmbeddableForm.d.ts.map +1 -1
- package/dist/FormAnalytics.d.ts.map +1 -1
- package/dist/LineItemsPanel.d.ts +6 -3
- package/dist/LineItemsPanel.d.ts.map +1 -1
- package/dist/MasterDetailForm.d.ts +31 -10
- package/dist/MasterDetailForm.d.ts.map +1 -1
- package/dist/ModalForm.d.ts +48 -4
- package/dist/ModalForm.d.ts.map +1 -1
- package/dist/ObjectForm.d.ts.map +1 -1
- package/dist/SplitForm.d.ts +37 -2
- package/dist/SplitForm.d.ts.map +1 -1
- package/dist/TabbedForm.d.ts +65 -3
- package/dist/TabbedForm.d.ts.map +1 -1
- package/dist/WizardForm.d.ts +143 -38
- package/dist/WizardForm.d.ts.map +1 -1
- package/dist/autoLayout.d.ts +12 -3
- package/dist/autoLayout.d.ts.map +1 -1
- package/dist/closedAffordanceNotice.d.ts +14 -0
- package/dist/closedAffordanceNotice.d.ts.map +1 -0
- package/dist/customFieldsMerge.d.ts +29 -0
- package/dist/customFieldsMerge.d.ts.map +1 -0
- package/dist/deriveMasterDetail.d.ts +32 -8
- package/dist/deriveMasterDetail.d.ts.map +1 -1
- package/dist/fieldGroups.d.ts +176 -0
- package/dist/fieldGroups.d.ts.map +1 -1
- package/dist/fieldWriteGate.d.ts +116 -0
- package/dist/fieldWriteGate.d.ts.map +1 -0
- package/dist/flatFields.d.ts +11 -2
- package/dist/flatFields.d.ts.map +1 -1
- package/dist/formChrome.d.ts +55 -0
- package/dist/formChrome.d.ts.map +1 -0
- package/dist/index.d.ts +124 -26
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3435 -2093
- package/dist/index.umd.cjs +1 -1
- package/dist/initialRecord.d.ts +72 -0
- package/dist/initialRecord.d.ts.map +1 -0
- package/dist/loadFailure.d.ts +28 -0
- package/dist/loadFailure.d.ts.map +1 -0
- package/dist/masterDetailTx.d.ts.map +1 -1
- package/dist/occSave.d.ts +6 -1
- package/dist/occSave.d.ts.map +1 -1
- package/dist/recordInvalidation.d.ts +33 -0
- package/dist/recordInvalidation.d.ts.map +1 -0
- package/dist/recordReadGate.d.ts +34 -0
- package/dist/recordReadGate.d.ts.map +1 -0
- package/dist/sanitize.d.ts +187 -5
- package/dist/sanitize.d.ts.map +1 -1
- package/dist/schemaDefaults.d.ts +27 -6
- package/dist/schemaDefaults.d.ts.map +1 -1
- package/dist/sectionFields.d.ts +56 -2
- package/dist/sectionFields.d.ts.map +1 -1
- package/dist/sectionGroups.d.ts +62 -0
- package/dist/sectionGroups.d.ts.map +1 -0
- package/dist/sectionPredicateDiagnostic.d.ts +38 -0
- package/dist/sectionPredicateDiagnostic.d.ts.map +1 -0
- package/dist/submitTarget.d.ts +119 -0
- package/dist/submitTarget.d.ts.map +1 -0
- package/dist/successBehavior.d.ts +44 -25
- package/dist/successBehavior.d.ts.map +1 -1
- package/dist/thankYouRedirectCountdown.d.ts +1 -1
- package/dist/uploadGate.d.ts +35 -0
- package/dist/uploadGate.d.ts.map +1 -0
- package/dist/writePayload.d.ts +68 -0
- package/dist/writePayload.d.ts.map +1 -0
- package/package.json +12 -11
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ObjectUI
|
|
3
|
+
* Copyright (c) 2024-present ObjectStack Inc.
|
|
4
|
+
*
|
|
5
|
+
* This source code is licensed under the MIT license found in the
|
|
6
|
+
* LICENSE file in the root directory of this source tree.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* The opening record an `object-form`-shaped schema authors through its two
|
|
10
|
+
* seed keys — `initialValues` and its alternate spelling `initialData`
|
|
11
|
+
* (objectui#9760).
|
|
12
|
+
*
|
|
13
|
+
* ## The defect this replaces
|
|
14
|
+
*
|
|
15
|
+
* Every presentation arm used to choose between the two keys as WHOLE OBJECTS:
|
|
16
|
+
*
|
|
17
|
+
* ```ts
|
|
18
|
+
* schema.initialData || schema.initialValues
|
|
19
|
+
* ```
|
|
20
|
+
*
|
|
21
|
+
* `||` tests the object, never its size, and `{}` is truthy. So an author who
|
|
22
|
+
* prefilled three fields through `initialValues` and added a one-member
|
|
23
|
+
* `initialData` lost the other two, and an author whose `initialData` computed
|
|
24
|
+
* to an EMPTY object — the shape a `?? {}` producer hands over when it has
|
|
25
|
+
* nothing to contribute — got a completely blank form where a populated
|
|
26
|
+
* `initialValues` sat right beside it. No warning, no empty state, no
|
|
27
|
+
* diagnostic: the form simply opened blank where it used to open seeded.
|
|
28
|
+
*
|
|
29
|
+
* Nothing declared ever said that. The registration calls `initialData` an
|
|
30
|
+
* "alternate spelling of `initialValues` … read FIRST", which is a statement of
|
|
31
|
+
* PRECEDENCE — the reading a per-member merge implements — and is what an
|
|
32
|
+
* author gets here now.
|
|
33
|
+
*
|
|
34
|
+
* ## Why it is one function rather than a corrected expression per arm
|
|
35
|
+
*
|
|
36
|
+
* The `||` was spelled at every read site of every presentation arm — the set a
|
|
37
|
+
* `git grep` for this module's name now enumerates — and the two spellings
|
|
38
|
+
* around it were not even the same: the create branches passed the chosen
|
|
39
|
+
* object into `seedCreateValues` (which layers the object schema's declared
|
|
40
|
+
* `defaultValue`s underneath it) while the rest installed it directly with a
|
|
41
|
+
* trailing `|| {}`. Two expressions free to drift are how one arm comes to
|
|
42
|
+
* answer "which spelling wins" differently from its neighbour, which is a
|
|
43
|
+
* question no author can even ask of a JSON schema. One function cannot drift.
|
|
44
|
+
*
|
|
45
|
+
* ## The contract
|
|
46
|
+
*
|
|
47
|
+
* `initialData` wins PER MEMBER, `initialValues` supplies every member it says
|
|
48
|
+
* nothing about, and the result is always a fresh plain object — never `null`,
|
|
49
|
+
* never `undefined`, never either authored object by reference. Callers may
|
|
50
|
+
* therefore spread it, hand it to `seedCreateValues` as the caller layer, or
|
|
51
|
+
* install it as form state without a `|| {}` tail.
|
|
52
|
+
*
|
|
53
|
+
* An explicit `null` MEMBER is preserved, on both sides: a caller writing
|
|
54
|
+
* `{ status: null }` is saying "open this control blank", which is a value and
|
|
55
|
+
* not an absence — the same reading `seedCreateValues`' docblock takes of the
|
|
56
|
+
* seed as a whole. Only a missing or nullish KEY contributes nothing.
|
|
57
|
+
*/
|
|
58
|
+
/** The two seed keys, as every presentation arm's schema declares them. */
|
|
59
|
+
export interface InitialRecordSchemaLike {
|
|
60
|
+
/** Values to prefill in `create` mode. */
|
|
61
|
+
initialValues?: Record<string, any> | null;
|
|
62
|
+
/** Alternate spelling of `initialValues`, read FIRST — i.e. per member it wins. */
|
|
63
|
+
initialData?: Record<string, any> | null;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* The record a form opens with, merged per member with `initialData` on top.
|
|
67
|
+
*
|
|
68
|
+
* Returns a fresh object (never shared with either input, never nullish), so
|
|
69
|
+
* every caller can install or spread it unconditionally.
|
|
70
|
+
*/
|
|
71
|
+
export declare function resolveInitialRecord(schema: InitialRecordSchemaLike | null | undefined): Record<string, any>;
|
|
72
|
+
//# sourceMappingURL=initialRecord.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"initialRecord.d.ts","sourceRoot":"","sources":["../src/initialRecord.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiDG;AAEH,2EAA2E;AAC3E,MAAM,WAAW,uBAAuB;IACtC,0CAA0C;IAC1C,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,CAAC;IAC3C,mFAAmF;IACnF,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,CAAC;CAC1C;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,uBAAuB,GAAG,IAAI,GAAG,SAAS,GACjD,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAErB"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { Dispatch, MutableRefObject, SetStateAction } from 'react';
|
|
2
|
+
/** The two reads a record form makes before it can draw. */
|
|
3
|
+
export type LoadSource = 'schema' | 'record';
|
|
4
|
+
/** The latest failure of each read, or `null` when its current run has not failed. */
|
|
5
|
+
export type LoadFailures = Readonly<Record<LoadSource, Error | null>>;
|
|
6
|
+
/** Neither read has failed. */
|
|
7
|
+
export declare const NO_LOAD_FAILURES: LoadFailures;
|
|
8
|
+
/** The number of the latest run of each read. Held in a ref: nothing renders from it. */
|
|
9
|
+
export type LoadRunSeq = Record<LoadSource, number>;
|
|
10
|
+
/** One run of one read. Each method is a no-op once a newer run of that read has begun. */
|
|
11
|
+
export interface LoadRun {
|
|
12
|
+
/** This run failed: its read's failure becomes `err`. */
|
|
13
|
+
fail(err: unknown): void;
|
|
14
|
+
/** This run committed what it read: its read's failure, if any, is cleared. */
|
|
15
|
+
commit(): void;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Number a new run of `source` and hand back its two writes. Call it once per
|
|
19
|
+
* run of the fetch effect, synchronously in the effect body, so the number
|
|
20
|
+
* moves when the effect does rather than when a read happens to settle.
|
|
21
|
+
*/
|
|
22
|
+
export declare function beginLoadRun(seqRef: MutableRefObject<LoadRunSeq>, setFailures: Dispatch<SetStateAction<LoadFailures>>, source: LoadSource): LoadRun;
|
|
23
|
+
/**
|
|
24
|
+
* The failure the error screen reports, or `null` when the form may draw. The
|
|
25
|
+
* schema's comes first: without it the fields the record fills are unknown.
|
|
26
|
+
*/
|
|
27
|
+
export declare function shownLoadFailure(failures: LoadFailures): Error | null;
|
|
28
|
+
//# sourceMappingURL=loadFailure.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loadFailure.d.ts","sourceRoot":"","sources":["../src/loadFailure.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,OAAO,KAAK,EAAE,QAAQ,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,OAAO,CAAC;AAExE,4DAA4D;AAC5D,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAE7C,sFAAsF;AACtF,MAAM,MAAM,YAAY,GAAG,QAAQ,CAAC,MAAM,CAAC,UAAU,EAAE,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC;AAEtE,+BAA+B;AAC/B,eAAO,MAAM,gBAAgB,EAAE,YAA6C,CAAC;AAE7E,yFAAyF;AACzF,MAAM,MAAM,UAAU,GAAG,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;AAEpD,2FAA2F;AAC3F,MAAM,WAAW,OAAO;IACtB,yDAAyD;IACzD,IAAI,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI,CAAC;IACzB,+EAA+E;IAC/E,MAAM,IAAI,IAAI,CAAC;CAChB;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAC1B,MAAM,EAAE,gBAAgB,CAAC,UAAU,CAAC,EACpC,WAAW,EAAE,QAAQ,CAAC,cAAc,CAAC,YAAY,CAAC,CAAC,EACnD,MAAM,EAAE,UAAU,GACjB,OAAO,CAYT;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,YAAY,GAAG,KAAK,GAAG,IAAI,CAErE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"masterDetailTx.d.ts","sourceRoot":"","sources":["../src/masterDetailTx.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"masterDetailTx.d.ts","sourceRoot":"","sources":["../src/masterDetailTx.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,kBAAkB,CAAC;AAKlE,eAAO,MAAM,IAAI,GAAI,KAAK,GAAG,KAAG,MAAM,GAAG,SACsB,CAAC;AAEhE;qDACqD;AACrD,MAAM,MAAM,WAAW,GAAG;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;CAAE,GAAG,IAAI,GAAG,SAAS,CAAC;AA+B9E,MAAM,WAAW,OAAO;IACtB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,CAAC;IAChC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,CAAC;IAChC,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED;;;;GAIG;AACH,MAAM,WAAW,gBAAgB;IAC/B,WAAW,EAAE,MAAM,CAAC;IACpB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,CAAC;IAC5B;8EAC0E;IAC1E,WAAW,CAAC,EAAE,WAAW,CAAC;CAC3B;AAED,kFAAkF;AAClF,MAAM,WAAW,oBAAqB,SAAQ,gBAAgB;IAC5D,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,CAAC;CACjC;AAED;;;;;GAKG;AACH,MAAM,MAAM,OAAO,GAAG,yBAAyB,CAAC;AAIhD;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,iBAAiB,CAAC,EAAE,MAAM,GAAG,OAAO,CAMxF;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CACpC,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC/B,OAAO,EAAE,gBAAgB,EAAE,GAC1B,OAAO,EAAE,CAWX;AAED;;;;;;GAMG;AACH,wBAAgB,0BAA0B,CACxC,YAAY,EAAE,MAAM,EACpB,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC/B,OAAO,EAAE,oBAAoB,EAAE,GAC9B,OAAO,EAAE,CAwCX;AAED,wBAAgB,QAAQ,CACtB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,EAC/B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,GAC7B,OAAO,CAST;AAED,6DAA6D;AAC7D,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAM1E"}
|
package/dist/occSave.d.ts
CHANGED
|
@@ -17,7 +17,9 @@
|
|
|
17
17
|
* forms were the only link in the chain not sending it.
|
|
18
18
|
*
|
|
19
19
|
* `useOccSave` centralises the guarded write:
|
|
20
|
-
* 1. `update` is issued with `ifMatch` = the `updated_at` the form read
|
|
20
|
+
* 1. `update` is issued with `ifMatch` = the `updated_at` the form read —
|
|
21
|
+
* or, once this hook has itself saved that record, the version its last
|
|
22
|
+
* successful write returned (objectui#10565; see `versionToSend`).
|
|
21
23
|
* 2. On `409 CONCURRENT_UPDATE` a dialog offers **Keep editing** (stay in
|
|
22
24
|
* the form, draft intact) or **Overwrite** (retry re-keyed to the
|
|
23
25
|
* server's `currentVersion` — "I know it changed, mine wins").
|
|
@@ -60,6 +62,9 @@ export interface OccSaveArgs {
|
|
|
60
62
|
/**
|
|
61
63
|
* The record as the form read it (`findOne` result) — supplies the
|
|
62
64
|
* `updated_at` version token. Optional: without it the write is unguarded.
|
|
65
|
+
* It decides WHETHER the write is guarded; after this hook's own save of
|
|
66
|
+
* the same record it no longer decides WHICH version is sent (see
|
|
67
|
+
* `versionToSend`).
|
|
63
68
|
*/
|
|
64
69
|
baseRecord?: unknown;
|
|
65
70
|
}
|
package/dist/occSave.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"occSave.d.ts","sourceRoot":"","sources":["../src/occSave.tsx"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"occSave.d.ts","sourceRoot":"","sources":["../src/occSave.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AA8B/B;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAGhE;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAI/D;AAED,MAAM,MAAM,cAAc;AACxB,+DAA+D;AAC7D;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,GAAG,CAAA;CAAE;AAClC,6EAA6E;GAC3E;IAAE,MAAM,EAAE,WAAW,CAAA;CAAE,CAAC;AAE5B,MAAM,WAAW,WAAW;IAC1B,UAAU,EAAE,GAAG,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAC;IAC1B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC7B;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AA0ED;;;;;;;GAOG;AACH,wBAAgB,UAAU,IAAI;IAC5B,WAAW,EAAE,CAAC,IAAI,EAAE,WAAW,KAAK,OAAO,CAAC,cAAc,CAAC,CAAC;IAC5D,cAAc,EAAE,KAAK,CAAC,SAAS,CAAC;CACjC,CAmIA"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ObjectUI
|
|
3
|
+
* Copyright (c) 2024-present ObjectStack Inc.
|
|
4
|
+
*
|
|
5
|
+
* This source code is licensed under the MIT license found in the
|
|
6
|
+
* LICENSE file in the root directory of this source tree.
|
|
7
|
+
*/
|
|
8
|
+
export interface RecordInvalidation {
|
|
9
|
+
/**
|
|
10
|
+
* Bumped once per re-read this form decides to run. The record read effect
|
|
11
|
+
* names it in its dependency list; nothing else reads it.
|
|
12
|
+
*/
|
|
13
|
+
refetch: number;
|
|
14
|
+
/**
|
|
15
|
+
* The form renderer's `onDirtyChange`. A host with dirty state of its own
|
|
16
|
+
* composes this with it; `false` replays a held re-read.
|
|
17
|
+
*/
|
|
18
|
+
onDirtyChange: (dirty: boolean) => void;
|
|
19
|
+
/**
|
|
20
|
+
* This form's edit landed: what it shows is what the server holds. Clears
|
|
21
|
+
* dirty and replays a held re-read once (the write's own bus echo included).
|
|
22
|
+
*/
|
|
23
|
+
saved: () => void;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* @param objectName the object the form reads
|
|
27
|
+
* @param recordId the record it reads
|
|
28
|
+
* @param readsRecord whether it reads one at all — edit or view mode with a
|
|
29
|
+
* `recordId`, and (for the default arm) no inline field source. When `false`
|
|
30
|
+
* the bus is not subscribed to and `refetch` never moves.
|
|
31
|
+
*/
|
|
32
|
+
export declare function useRecordInvalidation(objectName: string | undefined, recordId: string | number | undefined, readsRecord: boolean): RecordInvalidation;
|
|
33
|
+
//# sourceMappingURL=recordInvalidation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recordInvalidation.d.ts","sourceRoot":"","sources":["../src/recordInvalidation.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AA6CH,MAAM,WAAW,kBAAkB;IACjC;;;OAGG;IACH,OAAO,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,aAAa,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IACxC;;;OAGG;IACH,KAAK,EAAE,MAAM,IAAI,CAAC;CACnB;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CACnC,UAAU,EAAE,MAAM,GAAG,SAAS,EAC9B,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,EACrC,WAAW,EAAE,OAAO,GACnB,kBAAkB,CAuCpB"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ObjectUI
|
|
3
|
+
* Copyright (c) 2024-present ObjectStack Inc.
|
|
4
|
+
*
|
|
5
|
+
* This source code is licensed under the MIT license found in the
|
|
6
|
+
* LICENSE file in the root directory of this source tree.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* The first-record-read gate, shared by the two overlay containers
|
|
10
|
+
* (`DrawerForm`, objectui#10190; `ModalForm`, objectui#10659).
|
|
11
|
+
*
|
|
12
|
+
* Each container builds its fields and reads its record in two effects, and
|
|
13
|
+
* both key on `objectSchema`. The commit that publishes the schema therefore
|
|
14
|
+
* runs both, fetch first: the fetch effect enters the loading state and fires
|
|
15
|
+
* `findOne`, and a fields effect that ended the loading state unconditionally
|
|
16
|
+
* then won. That painted an empty, EDITABLE form while the read was in flight,
|
|
17
|
+
* and the landing record replaced whatever had been typed. The save that
|
|
18
|
+
* followed compared the record with itself and sent it whole, with its
|
|
19
|
+
* original values.
|
|
20
|
+
*
|
|
21
|
+
* So the fields effect ends the loading state only when this answers `false`.
|
|
22
|
+
* A load the fetch effect started is ended by the fetch effect. The condition
|
|
23
|
+
* mirrors that effect's own branches: create mode, no `recordId`, or no
|
|
24
|
+
* `dataSource` never read a record. `loadedRecordId` is the id of the record
|
|
25
|
+
* the form currently holds, which the fetch effect sets when its read lands,
|
|
26
|
+
* so this covers the FIRST load and a record swap alike.
|
|
27
|
+
*/
|
|
28
|
+
export declare function isRecordReadOutstanding(state: {
|
|
29
|
+
mode?: string;
|
|
30
|
+
recordId?: string | number;
|
|
31
|
+
dataSource: unknown;
|
|
32
|
+
loadedRecordId: string | number | undefined;
|
|
33
|
+
}): boolean;
|
|
34
|
+
//# sourceMappingURL=recordReadGate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recordReadGate.d.ts","sourceRoot":"","sources":["../src/recordReadGate.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE;IAC7C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC3B,UAAU,EAAE,OAAO,CAAC;IACpB,cAAc,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;CAC7C,GAAG,OAAO,CAOV"}
|
package/dist/sanitize.d.ts
CHANGED
|
@@ -6,18 +6,200 @@
|
|
|
6
6
|
* LICENSE file in the root directory of this source tree.
|
|
7
7
|
*/
|
|
8
8
|
/**
|
|
9
|
-
*
|
|
9
|
+
* The refused-field roster: every field name the SERVER owns on write.
|
|
10
|
+
*
|
|
11
|
+
* ## What it is
|
|
12
|
+
*
|
|
13
|
+
* The framework's `applySystemFields` stamps these columns onto every business
|
|
14
|
+
* object — record identity, audit provenance (`created_*` / `updated_*`), and
|
|
15
|
+
* the reassignable ownership / tenancy FKs (`owner_id`,
|
|
16
|
+
* `owning_business_unit_id`, `organization_id`, `tenant_id`, `company_id`,
|
|
17
|
+
* `space`). They are not author-declared business data, and a form may never
|
|
18
|
+
* write one.
|
|
19
|
+
*
|
|
20
|
+
* ## Why one roster, and why it is THIS roster
|
|
21
|
+
*
|
|
22
|
+
* `filterSystemFields` in `autoLayout.ts` reads the same set to decide what an
|
|
23
|
+
* auto-laid-out form RENDERS, in create and edit mode alike. The two readings
|
|
24
|
+
* are deliberately the same object, because the invariant they express is one
|
|
25
|
+
* invariant: **a form never writes a field it refuses to render.** Spelling the
|
|
26
|
+
* refusal separately at each call site is how they drifted — the render side
|
|
27
|
+
* had dropped `owner_id` since it was written, while the write side had not, so
|
|
28
|
+
* an edit form that showed the user two business inputs still sent back every
|
|
29
|
+
* ownership and audit column it had read (objectui#10108).
|
|
30
|
+
*
|
|
31
|
+
* That drift is not a cosmetic one. The platform refuses a write to a
|
|
32
|
+
* system-managed ownership column unless the caller holds the transfer grant
|
|
33
|
+
* (`allowTransfer` / `modifyAllRecords`), and it cannot tell a round-trip of
|
|
34
|
+
* the value it just served from an attempted ownership transfer. So a form
|
|
35
|
+
* echoing an UNCHANGED `owner_id` back is a 403 for every role that does not
|
|
36
|
+
* hold the grant — which, for a line-entry role, is the whole point of the
|
|
37
|
+
* role. The master-detail save sends its operations as one atomic batch, so a
|
|
38
|
+
* single echoed column refuses the entire save.
|
|
39
|
+
*
|
|
40
|
+
* ## What is deliberately NOT here
|
|
41
|
+
*
|
|
42
|
+
* The lifecycle bookkeeping columns (`locked`, `instance_state`, `deleted`,
|
|
43
|
+
* `is_deleted`) are left out. They are plausibly author-writable — a workflow
|
|
44
|
+
* or an admin form that drives record state is writing business meaning, not
|
|
45
|
+
* echoing provenance — and nothing has measured them refusing a write. Adding
|
|
46
|
+
* one here on the strength of the pattern alone would silently drop a value a
|
|
47
|
+
* form was asked to persist, which is the failure direction this module must
|
|
48
|
+
* not take.
|
|
49
|
+
*
|
|
50
|
+
* ⚠️ A name list alone cannot close the class: the NEXT injected column the
|
|
51
|
+
* platform adds will not be in it. {@link sanitizeFormData} therefore branches
|
|
52
|
+
* on the spec `system` flag first whenever a field definition is available —
|
|
53
|
+
* that flag is the registry's own mark on everything it injects, and
|
|
54
|
+
* `isSystemManagedField` in `@object-ui/types` reads the same one. This roster
|
|
55
|
+
* is the fallback for metadata that arrives without the flag.
|
|
56
|
+
*/
|
|
57
|
+
export declare const SERVER_OWNED_FIELD_NAMES: ReadonlySet<string>;
|
|
58
|
+
/**
|
|
59
|
+
* Strip server-owned and computed fields from a form payload before sending
|
|
10
60
|
* it to `dataSource.create()` / `dataSource.update()`.
|
|
11
61
|
*
|
|
12
|
-
* - Drops
|
|
62
|
+
* - Drops every name in {@link SERVER_OWNED_FIELD_NAMES}.
|
|
63
|
+
* - When `objectSchema` is provided, drops any field the spec marks
|
|
64
|
+
* `system: true` — the registry's own mark on the columns it injects, so a
|
|
65
|
+
* column added to the platform after this module was written is refused
|
|
66
|
+
* without anyone editing the roster.
|
|
13
67
|
* - When `objectSchema` is provided, drops fields that are flagged as
|
|
14
|
-
* `computed` / `
|
|
15
|
-
*
|
|
68
|
+
* `computed` / `readOnly` or whose type is in {@link COMPUTED_FIELD_TYPES}.
|
|
69
|
+
* A `formula` key is NOT a flag this reads (objectui#11070 round 6): every
|
|
70
|
+
* `type: 'formula'` field is already dropped by its type, and
|
|
71
|
+
* `@objectstack/spec`'s `FieldSchema` refuses `formula` by name on every
|
|
72
|
+
* field type (renaming it to `expression`), so no served definition can use
|
|
73
|
+
* it to mark some other type computed.
|
|
16
74
|
* - When `objectSchema` is provided, also drops keys that don't appear in
|
|
17
75
|
* `objectSchema.fields` at all (these are typically server-projected
|
|
18
76
|
* relationships or flattened lookups like `full_name`).
|
|
77
|
+
* - When `options.canEdit` is provided, drops every field that predicate
|
|
78
|
+
* refuses — the CALLER's field-level security, which no schema can answer.
|
|
79
|
+
*
|
|
80
|
+
* The two server-owned branches are separate on purpose and neither subsumes
|
|
81
|
+
* the other: the name roster fires with no schema at all (an inline form passes
|
|
82
|
+
* `null`), and the `system` flag fires for a name the roster has never heard
|
|
83
|
+
* of.
|
|
84
|
+
*
|
|
85
|
+
* ## Why field-level security arrives as a PREDICATE, not as more schema
|
|
86
|
+
*
|
|
87
|
+
* The branches above are properties of the OBJECT: the same for every caller,
|
|
88
|
+
* readable off metadata this function is already handed. Field-level security
|
|
89
|
+
* is a property of the CALLER — `score` is writable for one principal and
|
|
90
|
+
* refused for the next, on the identical object — so it cannot be read off
|
|
91
|
+
* `objectSchema` and must not be re-derived here. `fieldWriteGate` in
|
|
92
|
+
* `./fieldWriteGate` adapts the ONE resolver that owns that answer
|
|
93
|
+
* (`checkField(object, field, 'write')` in `@object-ui/permissions`) into this
|
|
94
|
+
* predicate. It arrives here, at the single outbound filter, rather than as a
|
|
95
|
+
* strip loop after each container's call, because every such loop is a copy
|
|
96
|
+
* that can be forgotten — and one of the three containers had forgotten it
|
|
97
|
+
* (`80c54122e`).
|
|
19
98
|
*/
|
|
20
99
|
export declare function sanitizeFormData(data: Record<string, any>, objectSchema?: {
|
|
21
100
|
fields?: Record<string, any>;
|
|
22
|
-
} | null
|
|
101
|
+
} | null, options?: {
|
|
102
|
+
canEdit?: (fieldName: string) => boolean;
|
|
103
|
+
}): Record<string, any>;
|
|
104
|
+
/**
|
|
105
|
+
* Whether two payload values are the SAME stored value — the one comparison
|
|
106
|
+
* every dirty-field diff in this package uses: the master-detail child rows in
|
|
107
|
+
* `masterDetailTx.ts` (objectui#10108) and the edit form's own record
|
|
108
|
+
* (objectui#10156). ⛔ Do not write a second equality rule beside it; two rules
|
|
109
|
+
* would drift, and the one that drifted towards "equal" would drop edits.
|
|
110
|
+
*
|
|
111
|
+
* ⚠️ The comparison is deliberately asymmetric in its failure direction. Saying
|
|
112
|
+
* "changed" about an equal pair costs one redundant column on the wire; saying
|
|
113
|
+
* "unchanged" about a changed pair DISCARDS the user's edit, silently, with a
|
|
114
|
+
* 200 back. So every case this cannot settle confidently reads as changed.
|
|
115
|
+
*
|
|
116
|
+
* The rule, pair by pair:
|
|
117
|
+
*
|
|
118
|
+
* - The same value (`===`) is equal.
|
|
119
|
+
* - `null` and `undefined` are one blank — the only two blanks a form
|
|
120
|
+
* round-trip actually interchanges. `''` is NOT a blank here: `null` and
|
|
121
|
+
* `''` read as different, and so do `undefined` and `''`.
|
|
122
|
+
* - Numbers never equal strings: `1000` and `'1000'` read as different.
|
|
123
|
+
* - Two `Date`s are equal only when both hold the same finite time. A `Date`
|
|
124
|
+
* and a date STRING read as different, and so do two date strings in
|
|
125
|
+
* different formats (`'2026-01-02'` and `'2026-01-02T00:00:00Z'`).
|
|
126
|
+
* - Two objects or arrays are equal only when they serialize identically. A
|
|
127
|
+
* reordered key or array element reads as changed, which is the safe side.
|
|
128
|
+
* - A lookup's id and its expanded object (`'a1'` and `{ id: 'a1', … }`) read
|
|
129
|
+
* as different: one is a string and the other an object.
|
|
130
|
+
* - Anything else is different, including `NaN` against itself.
|
|
131
|
+
*/
|
|
132
|
+
export declare function isSameStoredValue(a: unknown, b: unknown): boolean;
|
|
133
|
+
/**
|
|
134
|
+
* The subset of `next` that differs from the loaded snapshot `prev` — the
|
|
135
|
+
* DIRTY fields, and only those, judged by {@link isSameStoredValue}.
|
|
136
|
+
*
|
|
137
|
+
* An update that carries an unchanged column is not free: the platform refuses
|
|
138
|
+
* a write to a system-managed ownership column unless the caller holds the
|
|
139
|
+
* transfer grant, and it cannot tell a round-trip of the value it just served
|
|
140
|
+
* from an attempted transfer. A master-detail save commits as ONE atomic batch,
|
|
141
|
+
* so one such column on any row refuses every row (objectui#10108).
|
|
142
|
+
* `sanitizeFormData` already refuses the columns the server owns by name;
|
|
143
|
+
* sending only what the user actually changed is the half that does not depend
|
|
144
|
+
* on a roster being complete.
|
|
145
|
+
*/
|
|
146
|
+
export declare function changedFields(next: Record<string, any>, prev: Record<string, any>): Record<string, any>;
|
|
147
|
+
/**
|
|
148
|
+
* The record an edit form READ from its data source, tagged with the object
|
|
149
|
+
* and record it was read for (objectui#10156).
|
|
150
|
+
*
|
|
151
|
+
* It is the baseline an edit save diffs against, and it is held by the form
|
|
152
|
+
* component that performed the read — never passed in by a host. A record a
|
|
153
|
+
* caller supplied (`initialData`, inline `customFields`) is a prefill, not the
|
|
154
|
+
* row as stored, so no snapshot is taken for it and its save sends every field.
|
|
155
|
+
*/
|
|
156
|
+
export interface LoadedRecordSnapshot {
|
|
157
|
+
objectName: string;
|
|
158
|
+
recordId: string;
|
|
159
|
+
record: Record<string, unknown>;
|
|
160
|
+
}
|
|
161
|
+
/** The three facts of a form schema that decide whether a snapshot applies. */
|
|
162
|
+
export interface EditSaveTarget {
|
|
163
|
+
mode?: string;
|
|
164
|
+
objectName: string;
|
|
165
|
+
recordId?: string | number | null;
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Take the snapshot for a record just read with `findOne`, or `null` when the
|
|
169
|
+
* read returned nothing usable.
|
|
170
|
+
*/
|
|
171
|
+
export declare function snapshotLoadedRecord(target: EditSaveTarget, data: unknown): LoadedRecordSnapshot | null;
|
|
172
|
+
/**
|
|
173
|
+
* The payload an EDIT save writes: only the fields that differ from the record
|
|
174
|
+
* the form loaded (objectui#10156).
|
|
175
|
+
*
|
|
176
|
+
* `payload` is the output of {@link sanitizeFormData}. Every case that cannot
|
|
177
|
+
* be settled resolves towards SENDING, because a false "clean" drops the user's
|
|
178
|
+
* edit and the server still answers 200:
|
|
179
|
+
*
|
|
180
|
+
* - Not an edit, or no snapshot was read for this object and record (a create,
|
|
181
|
+
* a caller-supplied record, a record swap still in flight) → `payload`
|
|
182
|
+
* unchanged, every field sent.
|
|
183
|
+
* - A snapshot applies → the fields {@link changedFields} reports. Fields the
|
|
184
|
+
* form itself moved after the load — a cascade clear, a clear-on-hide, a
|
|
185
|
+
* value the form computed — differ from the loaded record, so they are sent.
|
|
186
|
+
* - The diff is EMPTY → `payload` unchanged. A save with nothing changed stays
|
|
187
|
+
* the request it has always been: the same write, the same OCC guard and a
|
|
188
|
+
* real server record for `onSuccess`. Emitting no request instead would
|
|
189
|
+
* report success for a save no server saw, and that is the one outcome a
|
|
190
|
+
* wrong baseline must never be able to produce.
|
|
191
|
+
*/
|
|
192
|
+
export declare function dirtyEditPayload(payload: Record<string, unknown>, snapshot: LoadedRecordSnapshot | null | undefined, target: EditSaveTarget): Record<string, unknown>;
|
|
193
|
+
/**
|
|
194
|
+
* The snapshot after an edit save SUCCEEDED: the fields just written, laid over
|
|
195
|
+
* the record as read.
|
|
196
|
+
*
|
|
197
|
+
* A form that stays mounted after a save must not diff its next save against
|
|
198
|
+
* the row as FIRST read. Changing a field and then changing it back to the
|
|
199
|
+
* value first read would compare equal to that stale baseline and be dropped,
|
|
200
|
+
* while the server still holds the first save's value. Advancing the baseline
|
|
201
|
+
* by what the server accepted closes that. A snapshot read for another record
|
|
202
|
+
* is returned untouched.
|
|
203
|
+
*/
|
|
204
|
+
export declare function advanceLoadedRecord(snapshot: LoadedRecordSnapshot | null | undefined, target: EditSaveTarget, written: Record<string, unknown>): LoadedRecordSnapshot | null;
|
|
23
205
|
//# sourceMappingURL=sanitize.d.ts.map
|
package/dist/sanitize.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sanitize.d.ts","sourceRoot":"","sources":["../src/sanitize.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;
|
|
1
|
+
{"version":3,"file":"sanitize.d.ts","sourceRoot":"","sources":["../src/sanitize.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgDG;AACH,eAAO,MAAM,wBAAwB,EAAE,WAAW,CAAC,MAAM,CAcvD,CAAC;AAeH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACzB,YAAY,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;CAAE,GAAG,IAAI,EACtD,OAAO,CAAC,EAAE;IAAE,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAA;CAAE,GACrD,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAiCrB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,GAAG,OAAO,CAajE;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,aAAa,CAC3B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACzB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GACxB,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAMrB;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,oBAAoB;IACnC,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACjC;AAED,+EAA+E;AAC/E,MAAM,WAAW,cAAc;IAC7B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;CACnC;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,cAAc,EACtB,IAAI,EAAE,OAAO,GACZ,oBAAoB,GAAG,IAAI,CAQ7B;AAcD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChC,QAAQ,EAAE,oBAAoB,GAAG,IAAI,GAAG,SAAS,EACjD,MAAM,EAAE,cAAc,GACrB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAMzB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,oBAAoB,GAAG,IAAI,GAAG,SAAS,EACjD,MAAM,EAAE,cAAc,EACtB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC/B,oBAAoB,GAAG,IAAI,CAK7B"}
|
package/dist/schemaDefaults.d.ts
CHANGED
|
@@ -1,12 +1,33 @@
|
|
|
1
1
|
import { isRuntimeDefault } from '@object-ui/core';
|
|
2
2
|
export { isRuntimeDefault };
|
|
3
|
-
/**
|
|
4
|
-
|
|
3
|
+
/**
|
|
4
|
+
* An object schema as the data source serves it (`{ fields: { [name]: def } }`),
|
|
5
|
+
* narrowed to the four field members THIS module's rule reads.
|
|
6
|
+
*
|
|
7
|
+
* Exported and published (objectui#7324) because `omitServerResolvedDefaults`
|
|
8
|
+
* is published and this is its second parameter: a host with its own form
|
|
9
|
+
* renderer has to hold that schema in a variable or a prop, and until now it
|
|
10
|
+
* could not name the variable's type. Structural typing meant such a host
|
|
11
|
+
* still compiled by writing the shape out by hand — which is a copy of a
|
|
12
|
+
* producer-owned shape in every consumer, invisible to every gate until the
|
|
13
|
+
* producer's shape moves.
|
|
14
|
+
*
|
|
15
|
+
* `FieldDefaults`, not `ObjectSchema`: `deriveMasterDetail.ts` holds a
|
|
16
|
+
* different shape that used to carry the same `ObjectSchemaLike` name, and the
|
|
17
|
+
* two are NOT interchangeable — see `ChildObjectSchemaLike` there. This one is
|
|
18
|
+
* the stricter of the pair (its field values are pinned, not `any`), so a
|
|
19
|
+
* value legal here is legal there but not the reverse.
|
|
20
|
+
*
|
|
21
|
+
* NOT `@object-ui/types`' `ObjectSchemaMetadata`: that type requires `name`
|
|
22
|
+
* and requires a `type` on every field. `isCurrentUserSeedField` below reads
|
|
23
|
+
* the target as `reference`, the one spelling the spec declares and ObjectUI
|
|
24
|
+
* reads (objectui#11070 round 4).
|
|
25
|
+
*/
|
|
26
|
+
export interface FieldDefaultsSchemaLike {
|
|
5
27
|
fields?: Record<string, {
|
|
6
28
|
defaultValue?: unknown;
|
|
7
29
|
type?: unknown;
|
|
8
30
|
reference?: unknown;
|
|
9
|
-
reference_to?: unknown;
|
|
10
31
|
} | undefined>;
|
|
11
32
|
}
|
|
12
33
|
/**
|
|
@@ -100,7 +121,7 @@ export declare function isRequiredInForm(field: {
|
|
|
100
121
|
* Returns a fresh object (never shared), and `{}` for a missing/!object schema
|
|
101
122
|
* so callers can spread it unconditionally.
|
|
102
123
|
*/
|
|
103
|
-
export declare function schemaDefaultValues(objectSchema:
|
|
124
|
+
export declare function schemaDefaultValues(objectSchema: FieldDefaultsSchemaLike | null | undefined, ctx?: SeedContext): Record<string, unknown>;
|
|
104
125
|
/**
|
|
105
126
|
* The initial values a CREATE form opens with: the schema's static defaults,
|
|
106
127
|
* overlaid with whatever the caller supplied.
|
|
@@ -110,7 +131,7 @@ export declare function schemaDefaultValues(objectSchema: ObjectSchemaLike | nul
|
|
|
110
131
|
* carrying state forward), and an explicit `null` from a caller is a real
|
|
111
132
|
* "leave this blank", not an absence.
|
|
112
133
|
*/
|
|
113
|
-
export declare function seedCreateValues(objectSchema:
|
|
134
|
+
export declare function seedCreateValues(objectSchema: FieldDefaultsSchemaLike | null | undefined, initial?: Record<string, unknown> | null, ctx?: SeedContext): Record<string, unknown>;
|
|
114
135
|
/**
|
|
115
136
|
* Drop the fields a CREATE payload must leave to the producer (#4069).
|
|
116
137
|
*
|
|
@@ -138,5 +159,5 @@ export declare function seedCreateValues(objectSchema: ObjectSchemaLike | null |
|
|
|
138
159
|
* column there is a deliberate removal, and dropping the key would silently
|
|
139
160
|
* discard the user's edit.
|
|
140
161
|
*/
|
|
141
|
-
export declare function omitServerResolvedDefaults(data: Record<string, unknown>, objectSchema:
|
|
162
|
+
export declare function omitServerResolvedDefaults(data: Record<string, unknown>, objectSchema: FieldDefaultsSchemaLike | null | undefined): Record<string, unknown>;
|
|
142
163
|
//# sourceMappingURL=schemaDefaults.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schemaDefaults.d.ts","sourceRoot":"","sources":["../src/schemaDefaults.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmEG;AAEH,OAAO,EAAwB,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAQzE,OAAO,EAAE,gBAAgB,EAAE,CAAC;AAE5B
|
|
1
|
+
{"version":3,"file":"schemaDefaults.d.ts","sourceRoot":"","sources":["../src/schemaDefaults.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmEG;AAEH,OAAO,EAAwB,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAQzE,OAAO,EAAE,gBAAgB,EAAE,CAAC;AAE5B;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,WAAW,uBAAuB;IACtC,MAAM,CAAC,EAAE,MAAM,CACb,MAAM,EACN;QAAE,YAAY,CAAC,EAAE,OAAO,CAAC;QAAC,IAAI,CAAC,EAAE,OAAO,CAAC;QAAC,SAAS,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,SAAS,CAC5E,CAAC;CACH;AAED;;;;GAIG;AACH,MAAM,WAAW,WAAW;IAC1B;;;;;OAKG;IACH,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/B;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,OAAO,GAAG,OAAO,CAGrD;AAED;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,IAAI,GAAG,SAAS,GACpE,OAAO,CAET;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE;IAAE,QAAQ,CAAC,EAAE,OAAO,CAAC;IAAC,YAAY,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,IAAI,GAAG,SAAS,EACxE,YAAY,EAAE,OAAO,GACpB,OAAO,CAIT;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CACjC,YAAY,EAAE,uBAAuB,GAAG,IAAI,GAAG,SAAS,EACxD,GAAG,CAAC,EAAE,WAAW,GAChB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAyBzB;AAqBD;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAC9B,YAAY,EAAE,uBAAuB,GAAG,IAAI,GAAG,SAAS,EACxD,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,EACxC,GAAG,CAAC,EAAE,WAAW,GAChB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAEzB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,0BAA0B,CACxC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,YAAY,EAAE,uBAAuB,GAAG,IAAI,GAAG,SAAS,GACvD,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAUzB"}
|
package/dist/sectionFields.d.ts
CHANGED
|
@@ -26,7 +26,48 @@ export interface SectionFieldsContext {
|
|
|
26
26
|
* passes it.
|
|
27
27
|
*/
|
|
28
28
|
fieldLabel: (objectName: string, fieldName: string, fallback: string) => string;
|
|
29
|
+
/**
|
|
30
|
+
* The authored inline members (`schema.customFields`). A member naming the
|
|
31
|
+
* field a section entry names is that entry's BASE definition, in place of
|
|
32
|
+
* the one generated from the object schema — the precedence `ObjectForm`'s
|
|
33
|
+
* default arm resolves its section members with (`findCustomFieldMember`,
|
|
34
|
+
* objectui#10254). Only the base moves: the entry's own overrides still
|
|
35
|
+
* apply on top, by the rules below. Omitted or empty → every base is
|
|
36
|
+
* generated, as before.
|
|
37
|
+
*/
|
|
38
|
+
customFields?: readonly FormField[] | null;
|
|
39
|
+
/**
|
|
40
|
+
* The parent field POOL the section resolves its members against, for the
|
|
41
|
+
* one caller that has one: `ObjectForm`'s default arm (`SimpleObjectForm`),
|
|
42
|
+
* whose pool is built from top-level `fields` (or the object) merged with
|
|
43
|
+
* `customFields` (objectui#10475).
|
|
44
|
+
*
|
|
45
|
+
* When set, {@link buildSectionFields} still walks the section's entries in
|
|
46
|
+
* AUTHORED order and applies each entry's overrides by the same rules as
|
|
47
|
+
* every other arm; two things change, both the pool's to decide:
|
|
48
|
+
*
|
|
49
|
+
* - membership — an entry naming a field the pool does not hold is
|
|
50
|
+
* dropped. That is objectui#9884's INTERSECTION of `fields` and
|
|
51
|
+
* `sections`; the caller emits its warning
|
|
52
|
+
* (`warnSectionMemberExcludedByFields`), this module only drops;
|
|
53
|
+
* - the BASE — the pooled field is what a name string draws and what a
|
|
54
|
+
* spec entry's overrides are written onto (a copy), in place of
|
|
55
|
+
* `fromObjectSchema` / the member lookup. The pool already resolved the
|
|
56
|
+
* member-over-generated precedence, and its generated fields carry the
|
|
57
|
+
* default arm's own per-field facts (the lock on a computed `formula` /
|
|
58
|
+
* `summary` / `auto_number` field, the input type, the step), which only
|
|
59
|
+
* LAYOUT and per-entry overrides may move. The managed-object lock is
|
|
60
|
+
* not one of them: every arm applies it after this builder, in
|
|
61
|
+
* `gateFormFields` (objectui#10612).
|
|
62
|
+
*
|
|
63
|
+
* An already-built runtime FormField entry (shape 3) is its own definition
|
|
64
|
+
* with or without a pool; the pool decides only whether it is drawn.
|
|
65
|
+
* Omitted → no pool: every entry is drawn, from the bases above.
|
|
66
|
+
*/
|
|
67
|
+
pool?: readonly FormField[] | null;
|
|
29
68
|
}
|
|
69
|
+
export declare function warnUnresolvedTopLevelField(entry: unknown, objectName: string): void;
|
|
70
|
+
export declare function warnSectionMemberExcludedByFields(memberName: string, objectName: string, sectionLabel?: string): void;
|
|
30
71
|
/**
|
|
31
72
|
* Build a runtime FormField from object-schema metadata for `fieldName`.
|
|
32
73
|
*
|
|
@@ -36,13 +77,26 @@ export interface SectionFieldsContext {
|
|
|
36
77
|
* costs.
|
|
37
78
|
*/
|
|
38
79
|
export declare function fromObjectSchema(fieldName: string, ctx: SectionFieldsContext): FormField;
|
|
80
|
+
/**
|
|
81
|
+
* The field name a section entry resolves to — the identity rule of the three
|
|
82
|
+
* shapes above, spelled once: a string is the name; a spec entry's identity is
|
|
83
|
+
* its `field` STRING; an already-built runtime FormField's is its `name`.
|
|
84
|
+
* `undefined` when the entry names nothing.
|
|
85
|
+
*/
|
|
86
|
+
export declare function sectionEntryName(fieldDef: unknown): string | undefined;
|
|
39
87
|
/**
|
|
40
88
|
* Normalize one section field definition (string | spec object | runtime
|
|
41
89
|
* FormField) into a runtime FormField with a guaranteed `name`.
|
|
42
90
|
*/
|
|
43
91
|
export declare function normalizeSectionField(fieldDef: string | Record<string, any>, ctx: SectionFieldsContext): FormField;
|
|
44
|
-
/**
|
|
92
|
+
/**
|
|
93
|
+
* Normalize every field def in a section, in the section's AUTHORED order.
|
|
94
|
+
*
|
|
95
|
+
* With a {@link SectionFieldsContext.pool}, an entry naming a field the pool
|
|
96
|
+
* does not hold is dropped, and a pooled field is the base the entry starts
|
|
97
|
+
* from; the order stays the section's own either way (objectui#10475).
|
|
98
|
+
*/
|
|
45
99
|
export declare function buildSectionFields(section: {
|
|
46
|
-
fields
|
|
100
|
+
fields?: Array<string | Record<string, any>>;
|
|
47
101
|
}, ctx: SectionFieldsContext): FormField[];
|
|
48
102
|
//# sourceMappingURL=sectionFields.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sectionFields.d.ts","sourceRoot":"","sources":["../src/sectionFields.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH
|
|
1
|
+
{"version":3,"file":"sectionFields.d.ts","sourceRoot":"","sources":["../src/sectionFields.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAMlD,MAAM,WAAW,oBAAoB;IACnC,2EAA2E;IAC3E,YAAY,EAAE,GAAG,CAAC;IAClB,0CAA0C;IAC1C,UAAU,EAAE,MAAM,CAAC;IACnB,iCAAiC;IACjC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,sDAAsD;IACtD,IAAI,CAAC,EAAE,QAAQ,GAAG,MAAM,GAAG,MAAM,CAAC;IAClC;;;;;;;OAOG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;;;;;OAOG;IACH,UAAU,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,MAAM,CAAC;IAChF;;;;;;;;OAQG;IACH,YAAY,CAAC,EAAE,SAAS,SAAS,EAAE,GAAG,IAAI,CAAC;IAC3C;;;;;;;;;;;;;;;;;;;;;;;;;;;OA2BG;IACH,IAAI,CAAC,EAAE,SAAS,SAAS,EAAE,GAAG,IAAI,CAAC;CACpC;AA0FD,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI,CAepF;AAkCD,wBAAgB,iCAAiC,CAC/C,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,EAClB,YAAY,CAAC,EAAE,MAAM,GACpB,IAAI,CAaN;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,oBAAoB,GAAG,SAAS,CAgCxF;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAMtE;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACtC,GAAG,EAAE,oBAAoB,GACxB,SAAS,CAEX;AAwHD;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE;IAAE,MAAM,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAA;CAAE,EACzD,GAAG,EAAE,oBAAoB,GACxB,SAAS,EAAE,CAmBb"}
|