@object-ui/plugin-form 17.7.0 → 18.0.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 (41) hide show
  1. package/CHANGELOG.md +804 -0
  2. package/README.md +148 -38
  3. package/dist/DrawerForm.d.ts +13 -2
  4. package/dist/DrawerForm.d.ts.map +1 -1
  5. package/dist/LineItemsPanel.d.ts.map +1 -1
  6. package/dist/MasterDetailForm.d.ts +49 -29
  7. package/dist/MasterDetailForm.d.ts.map +1 -1
  8. package/dist/ModalForm.d.ts +13 -2
  9. package/dist/ModalForm.d.ts.map +1 -1
  10. package/dist/ObjectForm.d.ts.map +1 -1
  11. package/dist/SplitForm.d.ts +13 -2
  12. package/dist/SplitForm.d.ts.map +1 -1
  13. package/dist/TabbedForm.d.ts +11 -3
  14. package/dist/TabbedForm.d.ts.map +1 -1
  15. package/dist/WizardForm.d.ts +5 -3
  16. package/dist/WizardForm.d.ts.map +1 -1
  17. package/dist/autoLayout.d.ts +101 -5
  18. package/dist/autoLayout.d.ts.map +1 -1
  19. package/dist/deriveMasterDetail.d.ts +53 -24
  20. package/dist/deriveMasterDetail.d.ts.map +1 -1
  21. package/dist/fieldGroups.d.ts +14 -1
  22. package/dist/fieldGroups.d.ts.map +1 -1
  23. package/dist/fieldWriteGate.d.ts +31 -11
  24. package/dist/fieldWriteGate.d.ts.map +1 -1
  25. package/dist/index.d.ts +32 -7
  26. package/dist/index.d.ts.map +1 -1
  27. package/dist/index.js +2206 -1896
  28. package/dist/index.umd.cjs +1 -1
  29. package/dist/initialFieldFocus.d.ts +23 -0
  30. package/dist/initialFieldFocus.d.ts.map +1 -0
  31. package/dist/sanitize.d.ts +88 -3
  32. package/dist/sanitize.d.ts.map +1 -1
  33. package/dist/schemaDefaults.d.ts +80 -6
  34. package/dist/schemaDefaults.d.ts.map +1 -1
  35. package/dist/sectionFields.d.ts +17 -6
  36. package/dist/sectionFields.d.ts.map +1 -1
  37. package/dist/submitTarget.d.ts +17 -0
  38. package/dist/submitTarget.d.ts.map +1 -1
  39. package/dist/writePayload.d.ts +24 -5
  40. package/dist/writePayload.d.ts.map +1 -1
  41. package/package.json +10 -10
@@ -0,0 +1,23 @@
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 control, in document order, that a user can edit in the first
10
+ * field row that has one. `null` while no field row is drawn (the body is
11
+ * loading) or when every field is read-only (a view-mode form).
12
+ */
13
+ export declare function findFirstEditableField(root: ParentNode): HTMLElement | null;
14
+ /**
15
+ * The `onOpenAutoFocus` / `onCloseAutoFocus` pair for a dialog content whose
16
+ * body loads after it opens. Pass both to the dialog content; the observer the
17
+ * open handler may start is stopped on close, on the next open and on unmount.
18
+ */
19
+ export declare function useInitialFieldFocus(): {
20
+ onOpenAutoFocus: (event: Event) => void;
21
+ onCloseAutoFocus: (event: Event) => void;
22
+ };
23
+ //# sourceMappingURL=initialFieldFocus.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"initialFieldFocus.d.ts","sourceRoot":"","sources":["../src/initialFieldFocus.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAmDH;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,UAAU,GAAG,WAAW,GAAG,IAAI,CAO3E;AAeD;;;;GAIG;AACH,wBAAgB,oBAAoB,IAAI;IACtC,eAAe,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IACxC,gBAAgB,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CAC1C,CAmEA"}
@@ -15,7 +15,18 @@
15
15
  * the reassignable ownership / tenancy FKs (`owner_id`,
16
16
  * `owning_business_unit_id`, `organization_id`, `tenant_id`, `company_id`,
17
17
  * `space`). They are not author-declared business data, and a form may never
18
- * write one.
18
+ * echo one back.
19
+ *
20
+ * One of them is also a value a user may set: the record's owner. The spec
21
+ * declares `owner_id` `system` but NOT `readonly`, because ownership is
22
+ * transferable from a form. It stays in this roster — an untouched owner is
23
+ * still never sent, and an auto-laid-out form still never renders it — and an
24
+ * EDIT adds it back only when the user changed it against the record the form
25
+ * read ({@link dirtyEditPayload}, objectui#12205), and a CREATE only when the
26
+ * user picked it against the values the form opened with
27
+ * ({@link createOwnerPayload}, objectui#12359). The rest of the family is
28
+ * not reassignable from a form: the spec declares the business-unit and tenant
29
+ * anchors `readonly`, so they stay refused even when they differ.
19
30
  *
20
31
  * ## Why one roster, and why it is THIS roster
21
32
  *
@@ -77,6 +88,12 @@ export declare const SERVER_OWNED_FIELD_NAMES: ReadonlySet<string>;
77
88
  * - When `options.canEdit` is provided, drops every field that predicate
78
89
  * refuses — the CALLER's field-level security, which no schema can answer.
79
90
  *
91
+ * Its output never carries the owner. An edit's changed owner is judged after
92
+ * this, against the record the form read, by {@link dirtyEditPayload}
93
+ * (objectui#12205), and a create's picked owner against the values the form
94
+ * opened with, by {@link createOwnerPayload} (objectui#12359) — the two places
95
+ * that can tell a user's pick from an echo.
96
+ *
80
97
  * The two server-owned branches are separate on purpose and neither subsumes
81
98
  * the other: the name roster fires with no schema at all (an inline form passes
82
99
  * `null`), and the `system` flag fires for a name the roster has never heard
@@ -90,7 +107,8 @@ export declare const SERVER_OWNED_FIELD_NAMES: ReadonlySet<string>;
90
107
  * refused for the next, on the identical object — so it cannot be read off
91
108
  * `objectSchema` and must not be re-derived here. `fieldWriteGate` in
92
109
  * `./fieldWriteGate` adapts the ONE resolver that owns that answer
93
- * (`checkField(object, field, 'write')` in `@object-ui/permissions`) into this
110
+ * (`checkField` in `@object-ui/permissions`, asked the question the form's
111
+ * mode reads from the affordance-to-grant map — objectui#12082) into this
94
112
  * predicate. It arrives here, at the single outbound filter, rather than as a
95
113
  * strip loop after each container's call, because every such loop is a copy
96
114
  * that can be forgotten — and one of the three containers had forgotten it
@@ -188,8 +206,75 @@ export declare function snapshotLoadedRecord(target: EditSaveTarget, data: unkno
188
206
  * real server record for `onSuccess`. Emitting no request instead would
189
207
  * report success for a save no server saw, and that is the one outcome a
190
208
  * wrong baseline must never be able to produce.
209
+ *
210
+ * ## The owner (objectui#12205)
211
+ *
212
+ * `payload` never carries the owner: `sanitizeFormData` drops it, because the
213
+ * platform refuses an echoed owner from every role without the transfer grant
214
+ * and cannot tell an echo from a transfer (objectui#10108). That drop also
215
+ * swallowed a REAL reassignment or clear — the form closed as if it saved and
216
+ * the record kept its owner. This is the one place that can tell the two
217
+ * apart, so `owner` hands it the values the form holds and the strip's own
218
+ * inputs, and the owner is added to the diff when, and only when:
219
+ *
220
+ * - a snapshot applies — with none, nothing proves the owner changed, so it
221
+ * stays off the wire exactly as before;
222
+ * - the form holds a value for it (`undefined` is not a clear; a clear is
223
+ * `null`) and {@link changedFields} reports it against the record read;
224
+ * - everything else `sanitizeFormData` asks still allows it: the caller's
225
+ * field-level security, the object declaring it, and it not being
226
+ * `readonly` or computed.
227
+ *
228
+ * The server stays the authority: a role without the transfer grant is refused
229
+ * with a 403, which the form shows as its error. A caller that passes no
230
+ * `owner` gets the diff it always got.
231
+ */
232
+ export declare function dirtyEditPayload(payload: Record<string, unknown>, snapshot: LoadedRecordSnapshot | null | undefined, target: EditSaveTarget, owner?: EditOwnerSource | null): Record<string, unknown>;
233
+ /**
234
+ * The payload a CREATE save writes: `payload`, plus the owner when the user
235
+ * picked one on this New form (objectui#12359).
236
+ *
237
+ * `payload` is the output of {@link sanitizeFormData}, which never carries the
238
+ * owner. Before this, a New form that rendered Owner let the user pick a user,
239
+ * showed the pick, and then saved the record under the creator with no error.
240
+ *
241
+ * "Picked" means the same thing it means on an edit, judged against the values
242
+ * the form OPENED with instead of a record it read: `seed` is the create
243
+ * form's opening values (`seedCreateValues` — the declared defaults, a
244
+ * `current_user` default resolved to the acting user, and any caller-supplied
245
+ * initial values). So the owner is added when, and only when:
246
+ *
247
+ * - the caller hands a `seed` — with none, nothing proves the user set the
248
+ * owner, so it stays off the wire exactly as before;
249
+ * - the form holds a value for it (`undefined` is not a pick) and
250
+ * {@link changedFields} reports it against `seed`. An owner the form was
251
+ * seeded with and the user left alone — the creator from a `current_user`
252
+ * default, or a caller's prefill — is NOT a pick, and is never sent
253
+ * (objectui#10108);
254
+ * - everything else {@link sanitizeFormData} asks still allows it: the
255
+ * caller's field-level security, the object declaring it, and it not being
256
+ * `readonly` or computed.
257
+ *
258
+ * The client does not guess whether the caller may assign another owner. The
259
+ * server judges it: an insert naming another user is refused without the
260
+ * transfer grant (`allowTransfer` / `modifyAllRecords`), and the form shows
261
+ * that refusal as its error. A caller that passes no `owner` gets `payload`.
191
262
  */
192
- export declare function dirtyEditPayload(payload: Record<string, unknown>, snapshot: LoadedRecordSnapshot | null | undefined, target: EditSaveTarget): Record<string, unknown>;
263
+ export declare function createOwnerPayload(payload: Record<string, unknown>, seed: Record<string, unknown> | null | undefined, owner?: EditOwnerSource | null): Record<string, unknown>;
264
+ /**
265
+ * What a save hands {@link dirtyEditPayload} (an edit) or
266
+ * {@link createOwnerPayload} (a create) so it can judge the owner.
267
+ */
268
+ export interface EditOwnerSource {
269
+ /** The values the form holds — BEFORE `sanitizeFormData`, which drops the owner. */
270
+ values: Record<string, unknown>;
271
+ /** The definition `payload` was sanitized against (`null` for inline members). */
272
+ objectSchema?: {
273
+ fields?: Record<string, unknown>;
274
+ } | null;
275
+ /** The field-level verdict `payload` was sanitized with. */
276
+ canEdit?: (fieldName: string) => boolean;
277
+ }
193
278
  /**
194
279
  * The snapshot after an edit save SUCCEEDED: the fields just written, laid over
195
280
  * the record as read.
@@ -1 +1 @@
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
+ {"version":3,"file":"sanitize.d.ts","sourceRoot":"","sources":["../src/sanitize.ts"],"names":[],"mappings":"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"}
@@ -2,7 +2,12 @@ import { isRuntimeDefault } from '@object-ui/core';
2
2
  export { isRuntimeDefault };
3
3
  /**
4
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.
5
+ * narrowed to `defaultValue` and the two members the `current_user` seed reads
6
+ * (`type`, `reference`). The keys the option-list fallback reads
7
+ * (objectui#11914) sit on the package-local `SeedFieldLike` below instead: the
8
+ * one published function that reads them, `optionListDefault`, names its own
9
+ * `OptionListFieldLike` (objectui#13049), and every member added here is
10
+ * published surface somebody then has to keep.
6
11
  *
7
12
  * Exported and published (objectui#7324) because `omitServerResolvedDefaults`
8
13
  * is published and this is its second parameter: a host with its own form
@@ -30,6 +35,41 @@ export interface FieldDefaultsSchemaLike {
30
35
  reference?: unknown;
31
36
  } | undefined>;
32
37
  }
38
+ /**
39
+ * One field as the SEEDING half of this module reads it: the published
40
+ * {@link FieldDefaultsSchemaLike} member set plus the two keys the option-list
41
+ * fallback reads (objectui#11914) — `options`, and `multiple` for the arity.
42
+ *
43
+ * Package-local, and derived from the published type rather than restating
44
+ * it: seeding is not on the package entry (`schemaDefaultValues` and
45
+ * `seedCreateValues` are withheld, see `index.tsx`), so the keys only it reads
46
+ * stay off the published shape, whose members are pinned to what the
47
+ * published pair reads (`parameterTypesNameable-7324.test.ts`). Every value of
48
+ * the published type is still a value of this one.
49
+ */
50
+ type SeedFieldLike = NonNullable<NonNullable<FieldDefaultsSchemaLike['fields']>[string]> & {
51
+ options?: unknown;
52
+ multiple?: unknown;
53
+ };
54
+ /**
55
+ * One field as {@link optionListDefault} reads it: the option list and the two
56
+ * arity inputs, nothing else (objectui#13049).
57
+ *
58
+ * Published because `optionListDefault` is, and a consumer must be able to
59
+ * name what it passes (objectui#7324). Its own shape rather than a widening of
60
+ * {@link FieldDefaultsSchemaLike}, whose members are pinned to what the
61
+ * published `omitServerResolvedDefaults` / `isRequiredInForm` pair reads. A
62
+ * served object field is assignable to it as it arrives.
63
+ */
64
+ export interface OptionListFieldLike {
65
+ type?: unknown;
66
+ multiple?: unknown;
67
+ options?: unknown;
68
+ }
69
+ /** An object schema as the seeding half reads it — see {@link SeedFieldLike}. */
70
+ interface SeedSchemaLike {
71
+ fields?: Record<string, SeedFieldLike | undefined>;
72
+ }
33
73
  /**
34
74
  * The session facts create-form seeding may draw on (#5683). Callers thread it
35
75
  * from `usePermissions()`; every key is optional so existing call sites keep
@@ -97,8 +137,10 @@ export declare function isCreateFormMode(form: {
97
137
  *
98
138
  * Note this drops the required MARKER (and `aria-required`) too, since both are
99
139
  * driven by this one boolean — which is the honest reading: in create mode the
100
- * user really is not required to provide the value. Surfacing what the server
101
- * WILL supply is issue #4069's option B, a separate follow-up card.
140
+ * user really is not required to provide the value. The form renderer says
141
+ * THAT the server supplies it — "Set automatically when saved." under the
142
+ * empty control (objectui#12108), keyed on the same classifier. Previewing
143
+ * WHAT it will supply is issue #4069's option B, still a separate card.
102
144
  *
103
145
  * The CONDITIONAL spelling (`requiredWhen`) reaches the same verdict, ruled
104
146
  * identically in #4085 — but it cannot be decided here, because it is resolved
@@ -116,12 +158,44 @@ export declare function isRequiredInForm(field: {
116
158
  defaultValue?: unknown;
117
159
  } | null | undefined, isCreateForm: boolean): boolean;
118
160
  /**
119
- * The static `defaultValue`s an object schema declares, as a form-values patch.
161
+ * The static defaults an object schema declares, as a form-values patch: each
162
+ * field's `defaultValue`, or — for a field that declares none — the option its
163
+ * option list marks `default: true` ({@link optionListDefault}).
120
164
  *
121
165
  * Returns a fresh object (never shared), and `{}` for a missing/!object schema
122
166
  * so callers can spread it unconditionally.
123
167
  */
124
- export declare function schemaDefaultValues(objectSchema: FieldDefaultsSchemaLike | null | undefined, ctx?: SeedContext): Record<string, unknown>;
168
+ export declare function schemaDefaultValues(objectSchema: SeedSchemaLike | null | undefined, ctx?: SeedContext): Record<string, unknown>;
169
+ /**
170
+ * The value a field's option list declares as its initial value — the option
171
+ * marked `default: true` — or `undefined` when it marks none (objectui#11914).
172
+ *
173
+ * The client reading of `ObjectQL.resolveOptionDefault` (objectstack#7246),
174
+ * rule for rule, so a create form preselects exactly what omitting the field
175
+ * would store:
176
+ *
177
+ * - **Only `default === true`, on the canonical key.** The authoring aliases
178
+ * (`isDefault`, `selected`) are normalized by `SelectOptionSchema` before
179
+ * metadata is served, and the engine reads the canonical key alone.
180
+ * - **A marked option with no value declares nothing** and is skipped.
181
+ * - **Single-valued: the FIRST marked option wins** — the schema does not
182
+ * dedupe the flag, so declaration order decides.
183
+ * - **Multi-valued: every marked option, as an array** — even one, since the
184
+ * field stores an array. Arity is `@objectstack/spec`'s `isMultiValueField`,
185
+ * the one predicate the engine asks too (`declaredMultiValued`), ⛔ never a
186
+ * raw `multiple` read: `multiselect` stores an array without the flag.
187
+ *
188
+ * Not gated on `type: 'select'`, as the engine's is not: `options` is a
189
+ * field-level key, and a field the server defaults must not open empty here.
190
+ *
191
+ * Applies only to a field that declares no `defaultValue` — the caller's gate,
192
+ * not this function's: {@link schemaDefaultValues} reaches it through
193
+ * `dv == null`, the engine's own presence test, and so must every other
194
+ * reader. Published on the package entry for the SECOND form renderer, the
195
+ * console's public form page (objectui#13049), so both renderers seed from
196
+ * this one reading instead of two.
197
+ */
198
+ export declare function optionListDefault(field: OptionListFieldLike | null | undefined): unknown;
125
199
  /**
126
200
  * The initial values a CREATE form opens with: the schema's static defaults,
127
201
  * overlaid with whatever the caller supplied.
@@ -131,7 +205,7 @@ export declare function schemaDefaultValues(objectSchema: FieldDefaultsSchemaLik
131
205
  * carrying state forward), and an explicit `null` from a caller is a real
132
206
  * "leave this blank", not an absence.
133
207
  */
134
- export declare function seedCreateValues(objectSchema: FieldDefaultsSchemaLike | null | undefined, initial?: Record<string, unknown> | null, ctx?: SeedContext): Record<string, unknown>;
208
+ export declare function seedCreateValues(objectSchema: SeedSchemaLike | null | undefined, initial?: Record<string, unknown> | null, ctx?: SeedContext): Record<string, unknown>;
135
209
  /**
136
210
  * Drop the fields a CREATE payload must leave to the producer (#4069).
137
211
  *
@@ -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;;;;;;;;;;;;;;;;;;;;;;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"}
1
+ {"version":3,"file":"schemaDefaults.d.ts","sourceRoot":"","sources":["../src/schemaDefaults.ts"],"names":[],"mappings":"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"}
@@ -44,7 +44,9 @@ export interface SectionFieldsContext {
44
44
  *
45
45
  * When set, {@link buildSectionFields} still walks the section's entries in
46
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:
47
+ * every other arm; for a NAME-ONLY entry — shape (1) or (2), which names a
48
+ * field and leaves its definition to be resolved — two things change, both
49
+ * the pool's to decide:
48
50
  *
49
51
  * - membership — an entry naming a field the pool does not hold is
50
52
  * dropped. That is objectui#9884's INTERSECTION of `fields` and
@@ -60,8 +62,15 @@ export interface SectionFieldsContext {
60
62
  * not one of them: every arm applies it after this builder, in
61
63
  * `gateFormFields` (objectui#10612).
62
64
  *
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
+ * An already-built runtime FormField entry (shape 3) carrying its own
66
+ * `name` is its own definition, and the pool decides NOTHING about it: it is
67
+ * drawn whatever the pool holds, exactly as the pool-less arms draw it
68
+ * (objectui#11615). The intersection catches a NAME the object does not
69
+ * declare or `fields` does not list — a typo, a stale name — and an entry
70
+ * that declares itself names nothing to resolve, so dropping it guarded
71
+ * nothing and made this arm the one that skipped what the other five drew.
72
+ * "Self-describing" is `isInlineFieldDef` (`submitTarget.ts`), the one
73
+ * predicate the submit-target rule already reads.
65
74
  * Omitted → no pool: every entry is drawn, from the bases above.
66
75
  */
67
76
  pool?: readonly FormField[] | null;
@@ -92,9 +101,11 @@ export declare function normalizeSectionField(fieldDef: string | Record<string,
92
101
  /**
93
102
  * Normalize every field def in a section, in the section's AUTHORED order.
94
103
  *
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).
104
+ * With a {@link SectionFieldsContext.pool}, a name-only entry naming a field
105
+ * the pool does not hold is dropped, and a pooled field is the base the entry
106
+ * starts from; a self-describing inline entry is drawn as it stands, pooled
107
+ * or not (objectui#11615); the order stays the section's own either way
108
+ * (objectui#10475).
98
109
  */
99
110
  export declare function buildSectionFields(section: {
100
111
  fields?: Array<string | Record<string, any>>;
@@ -1 +1 @@
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"}
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;AAOlD,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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAoCG;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,CAmCxF;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;AA+HD;;;;;;;;GAQG;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,CAyBb"}
@@ -78,6 +78,23 @@ export interface InlineFieldSource {
78
78
  customFields?: unknown;
79
79
  sections?: unknown;
80
80
  }
81
+ /**
82
+ * `normalizeSectionField`'s shape (3): an already-built runtime `FormField`,
83
+ * carrying its own `name`, needing no object schema to resolve.
84
+ *
85
+ * A STRING `field` is the disambiguator for shape (2), the spec
86
+ * `FormFieldSchema` — there `field` is the field NAME; on a runtime `FormField`
87
+ * the `field` slot holds the metadata OBJECT. A missing `name` is not treated as
88
+ * inline either: shape 3 without one is what used to crash the form renderer on
89
+ * `name.split('.')`, so it is malformed rather than self-describing.
90
+ *
91
+ * Exported because it is also what `buildSectionFields` (`sectionFields.ts`)
92
+ * asks of a section entry before its parent field pool may drop it
93
+ * (objectui#11615): a self-describing entry is drawn whatever the pool holds,
94
+ * as the pool-less arms draw it. One predicate, so "inline enough to need no
95
+ * adapter" and "inline enough to need no pool" cannot drift apart.
96
+ */
97
+ export declare function isInlineFieldDef(def: unknown): boolean;
81
98
  /**
82
99
  * Whether the author declared the form's fields inline, i.e. the form is a
83
100
  * self-contained collector whose `onSuccess` is the write.
@@ -1 +1 @@
1
- {"version":3,"file":"submitTarget.d.ts","sourceRoot":"","sources":["../src/submitTarget.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmEG;AAEH,gFAAgF;AAChF,MAAM,WAAW,iBAAiB;IAChC,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAkCD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAI/E;AAED;;;GAGG;AACH,eAAO,MAAM,wBAAwB,4EACsC,CAAC;AAE5E;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,mBAAmB,IAAI,KAAK,CAE3C"}
1
+ {"version":3,"file":"submitTarget.d.ts","sourceRoot":"","sources":["../src/submitTarget.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmEG;AAEH,gFAAgF;AAChF,MAAM,WAAW,iBAAiB;IAChC,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAItD;AAkBD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAI/E;AAED;;;GAGG;AACH,eAAO,MAAM,wBAAwB,4EACsC,CAAC;AAE5E;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,mBAAmB,IAAI,KAAK,CAE3C"}
@@ -18,11 +18,25 @@ export interface FormWriteSources {
18
18
  canEdit: FieldWriteGate | undefined;
19
19
  /** The record this form read for the record it edits (objectui#10156). */
20
20
  snapshot: LoadedRecordSnapshot | null | undefined;
21
+ /**
22
+ * On a create, the values the form OPENED with — its `seedCreateValues`
23
+ * result (objectui#12359). An owner the user picked against it is written,
24
+ * and one the form was seeded with and the user left alone is not. Ignored
25
+ * on an edit.
26
+ *
27
+ * Required, so a layout cannot forget it and silently drop a pick again —
28
+ * which is how every create writer behaved before. `null` says there is no
29
+ * opening value to judge against: no pick can then be told from a seed, so
30
+ * the owner stays off the wire.
31
+ */
32
+ createBaseline: Record<string, unknown> | null;
21
33
  }
22
34
  export interface FormWritePayloads {
23
35
  /**
24
36
  * Every value the form may write, as the form now holds it: stripped of what
25
- * a form never writes and, on a create, of the fields the producer owns.
37
+ * a form never writes and, on a create, of the fields the producer owns. On
38
+ * a create it also carries an owner the user picked (objectui#12359), since
39
+ * a create writes `payload` itself.
26
40
  */
27
41
  payload: Record<string, unknown>;
28
42
  /**
@@ -41,11 +55,16 @@ export interface FormWritePayloads {
41
55
  * (objectui#10108), computed / formula / read-only columns, keys the object
42
56
  * does not declare, and every field the caller's field-level security
43
57
  * refuses (`canEdit`, `80c54122e`).
44
- * 2. On a create, `omitServerResolvedDefaults` drops an empty field whose
45
- * runtime default the producer resolves (#4069).
58
+ * 2. On a create, `createOwnerPayload` adds back an owner the user picked
59
+ * against {@link FormWriteSources.createBaseline} (objectui#12359), and then
60
+ * `omitServerResolvedDefaults` drops an empty field whose runtime default
61
+ * the producer resolves (#4069).
46
62
  * 3. On an edit, `dirtyEditPayload` keeps only the fields that differ from the
47
63
  * record the form read (objectui#10156), and sends the whole of step 1's
48
- * result when it cannot settle that.
64
+ * result when it cannot settle that. It is handed the values too, so an
65
+ * owner the user changed is written while an untouched one is not
66
+ * (objectui#12205): on an edit only `writePayload` can carry it, never
67
+ * `payload`.
49
68
  *
50
69
  * ## Why it is one function
51
70
  *
@@ -64,5 +83,5 @@ export interface FormWritePayloads {
64
83
  * would drop the value the author asked for. The server-owned roster and the
65
84
  * field-level verdict still apply, because neither needs a definition.
66
85
  */
67
- export declare function formWritePayload(values: Record<string, unknown>, form: FormWriteTarget, { objectSchema, canEdit, snapshot }: FormWriteSources): FormWritePayloads;
86
+ export declare function formWritePayload(values: Record<string, unknown>, form: FormWriteTarget, { objectSchema, canEdit, snapshot, createBaseline }: FormWriteSources): FormWritePayloads;
68
87
  //# sourceMappingURL=writePayload.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"writePayload.d.ts","sourceRoot":"","sources":["../src/writePayload.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAGL,KAAK,oBAAoB,EAC1B,MAAM,YAAY,CAAC;AAEpB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAEvD,8DAA8D;AAC9D,MAAM,WAAW,eAAe;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;IAClC,6DAA6D;IAC7D,YAAY,CAAC,EAAE,SAAS,OAAO,EAAE,GAAG,IAAI,CAAC;CAC1C;AAED,yDAAyD;AACzD,MAAM,WAAW,gBAAgB;IAC/B,yEAAyE;IACzE,YAAY,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC,CAAA;KAAE,GAAG,IAAI,GAAG,SAAS,CAAC;IAClG,uEAAuE;IACvE,OAAO,EAAE,cAAc,GAAG,SAAS,CAAC;IACpC,0EAA0E;IAC1E,QAAQ,EAAE,oBAAoB,GAAG,IAAI,GAAG,SAAS,CAAC;CACnD;AAED,MAAM,WAAW,iBAAiB;IAChC;;;OAGG;IACH,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC;;;;;OAKG;IACH,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACvC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,IAAI,EAAE,eAAe,EACrB,EAAE,YAAY,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,gBAAgB,GACpD,iBAAiB,CAanB"}
1
+ {"version":3,"file":"writePayload.d.ts","sourceRoot":"","sources":["../src/writePayload.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAIL,KAAK,oBAAoB,EAC1B,MAAM,YAAY,CAAC;AAEpB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAEvD,8DAA8D;AAC9D,MAAM,WAAW,eAAe;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;IAClC,6DAA6D;IAC7D,YAAY,CAAC,EAAE,SAAS,OAAO,EAAE,GAAG,IAAI,CAAC;CAC1C;AAED,yDAAyD;AACzD,MAAM,WAAW,gBAAgB;IAC/B,yEAAyE;IACzE,YAAY,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC,CAAA;KAAE,GAAG,IAAI,GAAG,SAAS,CAAC;IAClG,uEAAuE;IACvE,OAAO,EAAE,cAAc,GAAG,SAAS,CAAC;IACpC,0EAA0E;IAC1E,QAAQ,EAAE,oBAAoB,GAAG,IAAI,GAAG,SAAS,CAAC;IAClD;;;;;;;;;;OAUG;IACH,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;CAChD;AAED,MAAM,WAAW,iBAAiB;IAChC;;;;;OAKG;IACH,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC;;;;;OAKG;IACH,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACvC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,IAAI,EAAE,eAAe,EACrB,EAAE,YAAY,EAAE,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,EAAE,gBAAgB,GACpE,iBAAiB,CAmBnB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@object-ui/plugin-form",
3
- "version": "17.7.0",
3
+ "version": "18.0.0",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "description": "Form plugin for Object UI",
@@ -15,15 +15,15 @@
15
15
  }
16
16
  },
17
17
  "dependencies": {
18
- "@objectstack/spec": "^17.0.0",
18
+ "@objectstack/spec": "^18.0.0",
19
19
  "lucide-react": "^1.43.0",
20
- "@object-ui/components": "17.7.0",
21
- "@object-ui/core": "17.7.0",
22
- "@object-ui/fields": "17.7.0",
23
- "@object-ui/i18n": "17.7.0",
24
- "@object-ui/permissions": "17.7.0",
25
- "@object-ui/react": "17.7.0",
26
- "@object-ui/types": "17.7.0"
20
+ "@object-ui/components": "18.0.0",
21
+ "@object-ui/core": "18.0.0",
22
+ "@object-ui/fields": "18.0.0",
23
+ "@object-ui/i18n": "18.0.0",
24
+ "@object-ui/permissions": "18.0.0",
25
+ "@object-ui/react": "18.0.0",
26
+ "@object-ui/types": "18.0.0"
27
27
  },
28
28
  "peerDependencies": {
29
29
  "react": "^18.0.0 || ^19.0.0",
@@ -35,7 +35,7 @@
35
35
  "typescript": "^6.0.3",
36
36
  "vite": "^8.2.1",
37
37
  "vite-plugin-dts": "^5.0.3",
38
- "@object-ui/data-objectstack": "17.7.0",
38
+ "@object-ui/data-objectstack": "18.0.0",
39
39
  "@object-ui/test-support": "17.4.0"
40
40
  },
41
41
  "keywords": [