@object-ui/plugin-form 17.5.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.
Files changed (78) hide show
  1. package/CHANGELOG.md +4841 -0
  2. package/README.md +772 -77
  3. package/dist/DrawerForm.d.ts +30 -2
  4. package/dist/DrawerForm.d.ts.map +1 -1
  5. package/dist/EmbeddableForm.d.ts.map +1 -1
  6. package/dist/FormAnalytics.d.ts.map +1 -1
  7. package/dist/LineItemsPanel.d.ts +6 -3
  8. package/dist/LineItemsPanel.d.ts.map +1 -1
  9. package/dist/MasterDetailForm.d.ts +31 -10
  10. package/dist/MasterDetailForm.d.ts.map +1 -1
  11. package/dist/ModalForm.d.ts +48 -4
  12. package/dist/ModalForm.d.ts.map +1 -1
  13. package/dist/ObjectForm.d.ts +18 -2
  14. package/dist/ObjectForm.d.ts.map +1 -1
  15. package/dist/SplitForm.d.ts +37 -2
  16. package/dist/SplitForm.d.ts.map +1 -1
  17. package/dist/TabbedForm.d.ts +65 -3
  18. package/dist/TabbedForm.d.ts.map +1 -1
  19. package/dist/WizardForm.d.ts +149 -11
  20. package/dist/WizardForm.d.ts.map +1 -1
  21. package/dist/autoLayout.d.ts +12 -3
  22. package/dist/autoLayout.d.ts.map +1 -1
  23. package/dist/closedAffordanceNotice.d.ts +14 -0
  24. package/dist/closedAffordanceNotice.d.ts.map +1 -0
  25. package/dist/customFieldsMerge.d.ts +29 -0
  26. package/dist/customFieldsMerge.d.ts.map +1 -0
  27. package/dist/deriveMasterDetail.d.ts +33 -9
  28. package/dist/deriveMasterDetail.d.ts.map +1 -1
  29. package/dist/fieldGroups.d.ts +176 -0
  30. package/dist/fieldGroups.d.ts.map +1 -1
  31. package/dist/fieldWriteGate.d.ts +116 -0
  32. package/dist/fieldWriteGate.d.ts.map +1 -0
  33. package/dist/flatFields.d.ts +30 -0
  34. package/dist/flatFields.d.ts.map +1 -0
  35. package/dist/formChrome.d.ts +55 -0
  36. package/dist/formChrome.d.ts.map +1 -0
  37. package/dist/index.d.ts +131 -25
  38. package/dist/index.d.ts.map +1 -1
  39. package/dist/index.js +3676 -1967
  40. package/dist/index.umd.cjs +1 -1
  41. package/dist/initialRecord.d.ts +72 -0
  42. package/dist/initialRecord.d.ts.map +1 -0
  43. package/dist/loadFailure.d.ts +28 -0
  44. package/dist/loadFailure.d.ts.map +1 -0
  45. package/dist/masterDetailTx.d.ts.map +1 -1
  46. package/dist/occSave.d.ts +6 -1
  47. package/dist/occSave.d.ts.map +1 -1
  48. package/dist/recordInvalidation.d.ts +33 -0
  49. package/dist/recordInvalidation.d.ts.map +1 -0
  50. package/dist/recordReadGate.d.ts +34 -0
  51. package/dist/recordReadGate.d.ts.map +1 -0
  52. package/dist/sanitize.d.ts +187 -5
  53. package/dist/sanitize.d.ts.map +1 -1
  54. package/dist/schemaDefaults.d.ts +51 -30
  55. package/dist/schemaDefaults.d.ts.map +1 -1
  56. package/dist/sectionFields.d.ts +65 -2
  57. package/dist/sectionFields.d.ts.map +1 -1
  58. package/dist/sectionGroups.d.ts +62 -0
  59. package/dist/sectionGroups.d.ts.map +1 -0
  60. package/dist/sectionPredicateDiagnostic.d.ts +38 -0
  61. package/dist/sectionPredicateDiagnostic.d.ts.map +1 -0
  62. package/dist/submitRedirect.d.ts +148 -0
  63. package/dist/submitRedirect.d.ts.map +1 -0
  64. package/dist/submitRedirectNavigation.d.ts +82 -0
  65. package/dist/submitRedirectNavigation.d.ts.map +1 -0
  66. package/dist/submitTarget.d.ts +119 -0
  67. package/dist/submitTarget.d.ts.map +1 -0
  68. package/dist/successBehavior.d.ts +44 -8
  69. package/dist/successBehavior.d.ts.map +1 -1
  70. package/dist/thankYouRedirectCountdown.d.ts +17 -0
  71. package/dist/thankYouRedirectCountdown.d.ts.map +1 -0
  72. package/dist/thankYouRedirectNavigation.d.ts +111 -0
  73. package/dist/thankYouRedirectNavigation.d.ts.map +1 -0
  74. package/dist/uploadGate.d.ts +35 -0
  75. package/dist/uploadGate.d.ts.map +1 -0
  76. package/dist/writePayload.d.ts +68 -0
  77. package/dist/writePayload.d.ts.map +1 -0
  78. package/package.json +13 -12
@@ -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;AAGlE,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;AAiB9E,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,CAqBX;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"}
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
  }
@@ -1 +1 @@
1
- {"version":3,"file":"occSave.d.ts","sourceRoot":"","sources":["../src/occSave.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AA6B/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;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAeD;;;;;;;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,CAyFA"}
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"}
@@ -6,18 +6,200 @@
6
6
  * LICENSE file in the root directory of this source tree.
7
7
  */
8
8
  /**
9
- * Strip server-managed and computed fields from a form payload before sending
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 well-known server-owned keys (id, created_at, organization_id, …).
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` / `formula` / `readOnly` or whose type is in
15
- * {@link COMPUTED_FIELD_TYPES}.
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): Record<string, any>;
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
@@ -1 +1 @@
1
- {"version":3,"file":"sanitize.d.ts","sourceRoot":"","sources":["../src/sanitize.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AA+BH;;;;;;;;;;;GAWG;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,GACrD,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAwBrB"}
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"}
@@ -1,34 +1,49 @@
1
+ import { isRuntimeDefault } from '@object-ui/core';
2
+ export { isRuntimeDefault };
1
3
  /**
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.
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).
7
25
  */
8
- /** An object schema as the data source serves it (`{ fields: { [name]: def } }`). */
9
- interface ObjectSchemaLike {
26
+ export interface FieldDefaultsSchemaLike {
10
27
  fields?: Record<string, {
11
28
  defaultValue?: unknown;
29
+ type?: unknown;
30
+ reference?: unknown;
12
31
  } | undefined>;
13
32
  }
14
33
  /**
15
- * Is this declared `defaultValue` a RUNTIME INSTRUCTION the server resolves per
16
- * insert, rather than a literal value?
17
- *
18
- * True for the `DEFAULT_VALUE_TOKENS` family (`'NOW()'` / `'current_user'`) and
19
- * for CEL/template Expression envelopes. This is THE classifier for "the
20
- * producer owns this field's create value" — both consumers in this package
21
- * read it, and neither may grow a second copy:
22
- *
23
- * 1. seeding (#4047 / #4068) — such a default is not seeded, because putting
24
- * the literal text `NOW()` into a datetime input and submitting it
25
- * suppresses the very resolution the declaration asked for;
26
- * 2. the create-mode `required` rule (#4069) — see {@link isRequiredInForm}.
27
- *
28
- * The two are the same fact seen twice: a field whose value the server supplies
29
- * is neither seedable nor missing.
34
+ * The session facts create-form seeding may draw on (#5683). Callers thread it
35
+ * from `usePermissions()`; every key is optional so existing call sites keep
36
+ * compiling and behaving unchanged until they opt in.
30
37
  */
31
- export declare function isRuntimeDefault(v: unknown): boolean;
38
+ export interface SeedContext {
39
+ /**
40
+ * The acting user's id (`usePermissions().userId`), or null/undefined when
41
+ * unknown — no provider, anonymous, or still loading. Unknown seeds nothing:
42
+ * the field stays empty and OMITTED from the payload, which is the case the
43
+ * engine's own `current_user` resolution handles at insert.
44
+ */
45
+ currentUserId?: string | null;
46
+ }
32
47
  /**
33
48
  * Can this declared `defaultValue` be used as a form's initial value as-is?
34
49
  *
@@ -85,9 +100,16 @@ export declare function isCreateFormMode(form: {
85
100
  * user really is not required to provide the value. Surfacing what the server
86
101
  * WILL supply is issue #4069's option B, a separate follow-up card.
87
102
  *
88
- * Deliberately NOT extended to `requiredWhen` (the conditional-required CEL
89
- * rule): that is resolved downstream in the form renderer against the live
90
- * record, outside this package.
103
+ * The CONDITIONAL spelling (`requiredWhen`) reaches the same verdict, ruled
104
+ * identically in #4085 — but it cannot be decided here, because it is resolved
105
+ * downstream against the live record. It is suppressed in the one evaluator
106
+ * that resolves it, `resolveFieldRuleState`, which reads the same fact off
107
+ * `@object-ui/core`'s `isServerOwnedValue` (and therefore the same
108
+ * {@link isRuntimeDefault} classifier this function reads). That evaluator
109
+ * subsumes this function on every path that threads the fact; this static
110
+ * answer stays because it is also the one the containers publish as the
111
+ * FormField's `required` flag, and because it is what re-runs when a form VIEW
112
+ * restates `required` over the object field (see `normalizeSectionField`).
91
113
  */
92
114
  export declare function isRequiredInForm(field: {
93
115
  required?: unknown;
@@ -99,7 +121,7 @@ export declare function isRequiredInForm(field: {
99
121
  * Returns a fresh object (never shared), and `{}` for a missing/!object schema
100
122
  * so callers can spread it unconditionally.
101
123
  */
102
- export declare function schemaDefaultValues(objectSchema: ObjectSchemaLike | null | undefined): Record<string, unknown>;
124
+ export declare function schemaDefaultValues(objectSchema: FieldDefaultsSchemaLike | null | undefined, ctx?: SeedContext): Record<string, unknown>;
103
125
  /**
104
126
  * The initial values a CREATE form opens with: the schema's static defaults,
105
127
  * overlaid with whatever the caller supplied.
@@ -109,7 +131,7 @@ export declare function schemaDefaultValues(objectSchema: ObjectSchemaLike | nul
109
131
  * carrying state forward), and an explicit `null` from a caller is a real
110
132
  * "leave this blank", not an absence.
111
133
  */
112
- export declare function seedCreateValues(objectSchema: ObjectSchemaLike | null | undefined, initial?: Record<string, unknown> | null): Record<string, unknown>;
134
+ export declare function seedCreateValues(objectSchema: FieldDefaultsSchemaLike | null | undefined, initial?: Record<string, unknown> | null, ctx?: SeedContext): Record<string, unknown>;
113
135
  /**
114
136
  * Drop the fields a CREATE payload must leave to the producer (#4069).
115
137
  *
@@ -137,6 +159,5 @@ export declare function seedCreateValues(objectSchema: ObjectSchemaLike | null |
137
159
  * column there is a deliberate removal, and dropping the key would silently
138
160
  * discard the user's edit.
139
161
  */
140
- export declare function omitServerResolvedDefaults(data: Record<string, unknown>, objectSchema: ObjectSchemaLike | null | undefined): Record<string, unknown>;
141
- export {};
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;AAgEH,qFAAqF;AACrF,UAAU,gBAAgB;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,YAAY,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,SAAS,CAAC,CAAC;CACjE;AAkBD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,OAAO,GAAG,OAAO,CAEpD;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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;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,CAAC,YAAY,EAAE,gBAAgB,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAS9G;AAED;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAC9B,YAAY,EAAE,gBAAgB,GAAG,IAAI,GAAG,SAAS,EACjD,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,GACvC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAEzB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,0BAA0B,CACxC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,YAAY,EAAE,gBAAgB,GAAG,IAAI,GAAG,SAAS,GAChD,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAUzB"}
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"}