Skip to content

omitServerResolvedDefaults is unreachable outside @object-ui/plugin-form, so a second renderer has to compose its two predicates by hand #6059

Description

@yinlianghui

Observation recorded while implementing #5883. Not a defect in behaviour — nothing is currently wrong on either chain — but it is the structural reason the fix for #5883 could not simply call the sibling function, and it will be the same reason for the next renderer.

Measured on origin/main5a06beda4.

What is not reachable

packages/plugin-form/src/schemaDefaults.ts owns omitServerResolvedDefaults — the "drop the keys a CREATE payload must leave to the producer" rule, whose docblock states the pairing with isRequiredInForm outright. Five call sites inside that package use it (ObjectForm, ModalForm, DrawerForm, TabbedForm, SplitForm, WizardForm).

Nothing outside the package can:

  • packages/plugin-form/package.json publishes exports for . alone;
  • the root module packages/plugin-form/src/index.tsx re-exports ObjectForm, FormSection, the six containers, autoLayout and deriveMasterDetail — and not schemaDefaults. seedCreateValues, isCreateFormMode, isRequiredInForm, schemaDefaultValues, isSeedableDefault, SeedContext and omitServerResolvedDefaults are all module-private in that sense.

So the helper has no spelling an importing package can write.

Why it matters

The console's apps/console/src/components/FormPage.tsx is the second form renderer in this repo, and it has now needed the same rule twice: #5727 for the seeding half and #5883 for the submit half. Both times the answer was to import the CLASSIFIERS from @object-ui/core (isRuntimeDefault, isMissingForRequired) and apply them locally, because the composed helper is out of reach.

That is safe — the classifiers are genuinely shared, @object-ui/core is where they live for exactly this reason (validation/server-owned-value.ts says so), and plugin-kanban plus @object-ui/components' form renderer read them the same way. It is also how omitServerResolvedDefaults itself is built. But it means the COMPOSITION — "runtime default AND missing, on create only" — now exists in two places even though neither predicate does, and the #4047 / #4068 / #4069 / #4085 / #5683 / #5727 / #5883 chain is seven cards of one renderer being behind the other.

Options, not a recommendation

  1. Publish omitServerResolvedDefaults (and possibly isRequiredInForm / seedCreateValues) from @object-ui/plugin-form's root, and have the console call it. Cost: it widens a plugin package's published surface, and makes the console's form page import a heavy React widget package for a pure function.
  2. Move the composed helper down to @object-ui/core beside the two predicates it is made of, and have plugin-form re-export it — the same move requiredWhen + a runtime defaultValue still deadlocks a create form (the conditional half of #4069) #4085 already made for isRuntimeDefault when a third consumer appeared.
  3. Leave it. Two call sites composing two shared predicates is not drift as long as the predicates stay shared; the thing that must not fork has not forked.

Filed for triage rather than acted on: option 2 changes a published package's surface and option 1 changes a dependency edge, neither of which belongs in a console bug fix.

Related: #5883, #5727, #4085, #4069, #4068, #4047, #5683.

Metadata

Metadata

Assignees

No one assigned

    Labels

    domain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatpm:queue

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions