diff --git a/.changeset/12626-spec-next-2.md b/.changeset/12626-spec-next-2.md new file mode 100644 index 0000000000..e6fbf04003 --- /dev/null +++ b/.changeset/12626-spec-next-2.md @@ -0,0 +1,22 @@ +--- +"@object-ui/app-shell": minor +"@object-ui/types": minor +"@object-ui/core": minor +"@object-ui/plugin-calendar": minor +"@object-ui/plugin-designer": minor +"@object-ui/plugin-detail": minor +"@object-ui/plugin-kanban": minor +"@object-ui/console": minor +"@object-ui/runner": minor +--- + +Resolve `@objectstack/*` `18.0.0-next.2` (objectui#12626). + +The console and the runner bundle `18.0.0-next.2`. `@object-ui/types` and `@object-ui/app-shell` now declare `@objectstack/spec` `^18.0.0-next.2`; the other packages keep `^18.0.0-next.1`, which already admits it. + +**The record dialog opens bounded on desktop for every object.** A create, edit or child record dialog on an object with many fields used to open as a 95vw task canvas. `@objectstack/spec` `18.0.0-next.2` derives a bounded modal for it on desktop and keeps the full-screen sheet on a phone, and the console now takes that answer directly. + +**Accept sets that narrow with it.** `@object-ui/types` validates a page through the spec's own page checks, so its faces (`safeValidateSchema` and `StrictAnyComponentSchema`) now refuse what `18.0.0-next.2` refuses. Each was accepted before: + +- On a `kind: 'full'` page, a region whose `name` the page's `template` does not place (with the default template: anything but `header`, `sidebar`, `main`, `aside` and `footer`), and a second region for a slot another region already fills. The renderer stacked such a region under `main` at full width. Rename it to a slot the template places, or choose the `dashboard` template, which lays every other region out as a grid cell. +- `isDefault: true` on a page whose `type` is its page kind (`record`, `home` or `utility`) unless it is a `record` page bound to an `object`. Delete the key; an app's landing page is its first navigation item. diff --git a/apps/console/src/__tests__/registry-inputs-spec-parity.test.ts b/apps/console/src/__tests__/registry-inputs-spec-parity.test.ts index 648a6d0777..a01bced8c6 100644 --- a/apps/console/src/__tests__/registry-inputs-spec-parity.test.ts +++ b/apps/console/src/__tests__/registry-inputs-spec-parity.test.ts @@ -2966,11 +2966,11 @@ const MEMBER_PINS: Record = { }, 'object-grid.data': { file: 'packages/plugin-grid/src/__tests__/gridDataInputContract.test.ts', - pins: 'The `object` arm is `ViewDataSchema` discriminated on `provider`: each of the three providers parses and the retired `api` one is refused (spec 18.0.0-next.1, objectui#12370), none of them is an array, the declaration is one shape across both registered tags so the alias cannot drift, and it is pinned at compile time too (objectui#5090).', + pins: 'The `object` arm is `ViewDataSchema` discriminated on `provider`: each of the three providers parses and the retired `api` one is refused (spec 18.0.0-next.2, objectui#12370), none of them is an array, the declaration is one shape across both registered tags so the alias cannot drift, and it is pinned at compile time too (objectui#5090).', }, 'object-grid.conditionalFormatting': { file: 'packages/plugin-grid/src/__tests__/gridRowDecorationMembers-8071.test.tsx', - pins: 'The members read inside ONE formatting rule, asserted on the `style` attribute of the `` the grid paints. THREE alternative predicate members with a PRECEDENCE between them — one rule carrying `condition`, `expression` and the native `field`/`operator`/`value` triple, each naming a DIFFERENT row, is decided by `condition`; drop it and `expression` decides; drop that and the triple does — so a renderer reading any two of them as equivalent is red in a specific direction rather than merely unpinned. FOUR style members, and the sharp one is a RENAME: `backgroundColor` and `borderColor` keep their authored names on the way to the DOM while `textColor` is read as the CSS `color`, so keeping the authored spelling hands React a key it silently drops — same rules, same background, the text colour gone with nothing thrown. `style` is pinned as the BASE the three colour members override rather than replace (a non-colour member of it survives alongside the override). Two rule-list facts complete it: FIRST-MATCH-WINS with no merge (the second matching rule\'s own `textColor` never lands) and a rule carrying NO predicate member is SKIPPED rather than read as always-true, with the rule after it still deciding. ⚠️ Since objectui#11533 the AUTHORED member is ONE dialect, `{ condition, style }`: `expression`, the native triple and the three top-level colour members are refused by name on `ObjectGridSchema` and the list view (`packages/types/src/__tests__/grid-list-view-conditional-formatting-11533.test.ts`), so the rows that write them pin STORED-rule reads, which the resolver keeps as compatibility arms; a last block pins the two facts side by side — the stored native rule refused at authoring and painted at render, with its respelling painting the same row. The registration is an `array` arm; the installed spec row (18.0.0-next.1, re-measured by objectui#12030, objectui#12370) takes the list view\'s own `{ condition, style }` rule and refuses the native members and any other key, so the spec fixes the AUTHORED shape and the read site is the rest of the member contract, the stored-rule compatibility arms included (objectui#8071 slice 12).', + pins: 'The members read inside ONE formatting rule, asserted on the `style` attribute of the `` the grid paints. THREE alternative predicate members with a PRECEDENCE between them — one rule carrying `condition`, `expression` and the native `field`/`operator`/`value` triple, each naming a DIFFERENT row, is decided by `condition`; drop it and `expression` decides; drop that and the triple does — so a renderer reading any two of them as equivalent is red in a specific direction rather than merely unpinned. FOUR style members, and the sharp one is a RENAME: `backgroundColor` and `borderColor` keep their authored names on the way to the DOM while `textColor` is read as the CSS `color`, so keeping the authored spelling hands React a key it silently drops — same rules, same background, the text colour gone with nothing thrown. `style` is pinned as the BASE the three colour members override rather than replace (a non-colour member of it survives alongside the override). Two rule-list facts complete it: FIRST-MATCH-WINS with no merge (the second matching rule\'s own `textColor` never lands) and a rule carrying NO predicate member is SKIPPED rather than read as always-true, with the rule after it still deciding. ⚠️ Since objectui#11533 the AUTHORED member is ONE dialect, `{ condition, style }`: `expression`, the native triple and the three top-level colour members are refused by name on `ObjectGridSchema` and the list view (`packages/types/src/__tests__/grid-list-view-conditional-formatting-11533.test.ts`), so the rows that write them pin STORED-rule reads, which the resolver keeps as compatibility arms; a last block pins the two facts side by side — the stored native rule refused at authoring and painted at render, with its respelling painting the same row. The registration is an `array` arm; the installed spec row (18.0.0-next.2, re-measured by objectui#12030, objectui#12370, objectui#12626) takes the list view\'s own `{ condition, style }` rule and refuses the native members and any other key, so the spec fixes the AUTHORED shape and the read site is the rest of the member contract, the stored-rule compatibility arms included (objectui#8071 slice 12).', }, 'object-grid.operations': { file: 'packages/plugin-grid/src/__tests__/gridOperationsMembers-8071.test.tsx', @@ -3046,7 +3046,7 @@ const MEMBER_PINS: Record = { }, 'object-kanban.conditionalFormatting': { file: 'packages/plugin-kanban/src/__tests__/ObjectKanban.structuredMembersReachTheirSinks-8313.test.tsx', - pins: 'Members are card STYLE RULES in ONE dialect since objectui#11522, the spec list view\'s `{ condition, style }`, and it reaches the sink: a rule colours the matching card and only it, a second rule aimed at the other card does the same, and the whole `style` map arrives, with the sibling card in the same render as the live non-matching control so a green cannot come from two unstyled cards agreeing. The retired native `{ field, operator, value }` and flat-colour dialects are refused by name on the types side (`packages/types/src/__tests__/kanban-conditional-formatting.test.ts`); these rows are their respellings, painting the same cards. ⛔ NOT an identity pin and not a wire pin: `ObjectKanban.tsx` never names this key at all (measured zero, against nine for `cardFields` in the same file) — it rides the `{ ...schema }` spread into `KanbanRenderer`, which forwards it to `KanbanImpl`\'s `getCardStyles`. That makes the pin load-bearing in a way the others are not: an edit replacing that spread with an explicit key list drops the key silently and nothing else in the repo would notice. The installed spec row (18.0.0-next.1, re-measured by objectui#12030, objectui#12370) takes the list view\'s own `{ condition, style }` rule, so the spec fixes the authored shape and the read site is the rest of the member contract (objectui#8313).', + pins: 'Members are card STYLE RULES in ONE dialect since objectui#11522, the spec list view\'s `{ condition, style }`, and it reaches the sink: a rule colours the matching card and only it, a second rule aimed at the other card does the same, and the whole `style` map arrives, with the sibling card in the same render as the live non-matching control so a green cannot come from two unstyled cards agreeing. The retired native `{ field, operator, value }` and flat-colour dialects are refused by name on the types side (`packages/types/src/__tests__/kanban-conditional-formatting.test.ts`); these rows are their respellings, painting the same cards. ⛔ NOT an identity pin and not a wire pin: `ObjectKanban.tsx` never names this key at all (measured zero, against nine for `cardFields` in the same file) — it rides the `{ ...schema }` spread into `KanbanRenderer`, which forwards it to `KanbanImpl`\'s `getCardStyles`. That makes the pin load-bearing in a way the others are not: an edit replacing that spread with an explicit key list drops the key silently and nothing else in the repo would notice. The installed spec row (18.0.0-next.2, re-measured by objectui#12030, objectui#12370, objectui#12626) takes the list view\'s own `{ condition, style }` rule, so the spec fixes the authored shape and the read site is the rest of the member contract (objectui#8313).', }, 'object-kanban.data': { file: 'packages/plugin-kanban/src/__tests__/ObjectKanban.structuredMembersReachTheirSinks-8313.test.tsx', diff --git a/e2e/live/ci/backend.env b/e2e/live/ci/backend.env index 2a69478f33..6bd1f57137 100644 --- a/e2e/live/ci/backend.env +++ b/e2e/live/ci/backend.env @@ -14,7 +14,7 @@ # # This file declares exactly ONE @objectstack pin, and that is the whole # design: the commit is derived from it, see below. -OBJECTSTACK_VERSION=18.0.0-next.1 +OBJECTSTACK_VERSION=18.0.0-next.2 # There is deliberately no OBJECTSTACK_REF key here. The objectstack-ai/objectstack # commit the showcase app metadata is sparse-checked-out from is DERIVED at diff --git a/packages/app-shell/package.json b/packages/app-shell/package.json index 4ff8bccc9a..08b20fdcdd 100644 --- a/packages/app-shell/package.json +++ b/packages/app-shell/package.json @@ -91,7 +91,7 @@ "@object-ui/types": "workspace:*", "@objectstack/formula": "^18.0.0-next.1", "@objectstack/lint": "^18.0.0-next.1", - "@objectstack/spec": "^18.0.0-next.1", + "@objectstack/spec": "^18.0.0-next.2", "@sentry/react": "^10.70.0", "jsonc-parser": "^3.3.1", "lucide-react": "^1.43.0", diff --git a/packages/app-shell/src/console/AppContent.tsx b/packages/app-shell/src/console/AppContent.tsx index 91e724d1d8..c8a8a7d5d2 100644 --- a/packages/app-shell/src/console/AppContent.tsx +++ b/packages/app-shell/src/console/AppContent.tsx @@ -33,7 +33,7 @@ import { useTrackRouteAsRecent } from '../hooks/useTrackRouteAsRecent.js'; import { useHomePath } from '../hooks/useHomePath.js'; import { useSignedInUserLocale } from '../hooks/useUserLocale.js'; import { resolveRecordFormTarget, resolveFormViewLayout, resolveNavigateCreateUrl, resolveNavigateEditUrl, resolvePostCreateTarget, recordFormCreateValues, readRecordFormCreateValues, RECORD_FORM_CREATE_VALUES_STATE } from '../utils/recordFormNavigation.js'; -import { deriveRecordSurface, deriveRecordFlowSurface, type RecordFlowSurface } from '@object-ui/plugin-view'; +import { deriveRecordSurface, deriveRecordFlowSurface } from '@object-ui/plugin-view'; import { RECORD_FORM_PARAM, RECORD_FORM_OBJECT_PARAM, RECORD_FORM_LINK_PARAM } from '../urlParams.js'; import { appRouteSegment, matchAppBySegment } from '../utils/appRoute.js'; import { resolveHref, type NavTemplateContext } from '@object-ui/layout'; @@ -102,36 +102,6 @@ interface AppContentProps { extraRoutesNoApp?: ReactNode; } -/** - * INTERIM — objectui#12521, ruled in comment 6205068311 (the maintainer's - * 「可以,12521 走快速方案」), the early outcome of letter B (6203721639). - * - * `deriveRecordFlowSurface` answers `size: 'full'` for a field-heavy create / - * edit / child-create / child-edit flow (objectstack-ai/objectstack#2604 D1), - * and the record dialog below spreads that into `modalSize: 'full'`: a 95vw - * task canvas on desktop. Letter B moves the bound into the protocol — on - * desktop a field-heavy task flow derives a bounded modal, `size: 'auto'` — - * through objectstack-ai/objectstack#23734. This gives the installed - * derivation's answer that shape early, so `ModalForm`'s own bounded default - * (`lg` / `xl`, never `full`) sizes the dialog until that spec is installed. - * - * Desktop only, with no posture check of its own: this host calls the - * derivation with no `viewport`, so the answer it receives is the desktop - * one, and the phone presentation is `ModalForm`'s full-screen sheet below - * `sm`, which no `modalSize` reaches (every size class is `sm:`-prefixed). - * Only the derived default changes: a `modalSize` handed to `ModalForm` is - * used as written. - * - * EXIT: once objectui installs an `@objectstack/spec` carrying - * objectstack-ai/objectstack#23734, delete this function and call - * `deriveRecordFlowSurface` directly at its one call site. The pin - * `AppContent.recordDialogInterimBound-12521.test.tsx` fails on that bump and - * names this deletion. - */ -function interimBoundedTaskFlowSurface(surface: RecordFlowSurface): RecordFlowSurface { - return surface.size === 'full' ? { ...surface, size: 'auto' } : surface; -} - /** * Bridges the global chat's "Review N change(s)" affordance (ADR-0033 Phase B) * to the metadata designer. The chat publishes a review target on `assistantBus`; @@ -1220,20 +1190,20 @@ export function AppContent({ extraRoutes, extraRoutesNoApp }: AppContentProps = ...(!editingRecord && (formLinkValues ?? overlayCreateValues) ? { initialValues: formLinkValues ?? overlayCreateValues } : {}), - // objectstack-ai/objectstack#2604 D1: create/edit follow the flow-surface derivation — - // field-heavy → full-screen modal, which the objectui#12521 - // interim bounds on desktop until the spec derives it - // (`interimBoundedTaskFlowSurface`); light objects keep the - // auto-sized modal (ModalForm's bounded default when - // modalSize is unset). Derived default only — anything spread - // later (form view layout) would win. Child tasks size to the - // CHILD object's def. - ...(interimBoundedTaskFlowSurface(deriveRecordFlowSurface( + // objectstack-ai/objectstack#2604 D1: create/edit follow the flow-surface derivation. + // This host calls it with no `viewport`, so it gets the desktop + // answer: a bounded modal (`size: 'auto'`, ModalForm's bounded + // default when modalSize is unset) for field-heavy and light + // objects alike (objectstack-ai/objectstack#23734, objectui#12592); + // a phone gets ModalForm's full-screen sheet below `sm`. Derived + // default only — anything spread later (form view layout) would + // win. Child tasks size to the CHILD object's def. + ...(deriveRecordFlowSurface( formObjectDef, isChildFormTask ? (editingRecord ? 'child-edit' : 'child-create') : (editingRecord ? 'edit' : 'create'), - )).size === 'full' + ).size === 'full' ? { modalSize: 'full' as const } : {}), // Honor the object's DEFAULT FORM VIEW: curated sections (field diff --git a/packages/app-shell/src/console/__tests__/AppContent.recordDialogInterimBound-12521.test.tsx b/packages/app-shell/src/console/__tests__/AppContent.recordDialogInterimBound-12521.test.tsx index 7d151eb1f5..61d0aea633 100644 --- a/packages/app-shell/src/console/__tests__/AppContent.recordDialogInterimBound-12521.test.tsx +++ b/packages/app-shell/src/console/__tests__/AppContent.recordDialogInterimBound-12521.test.tsx @@ -7,30 +7,26 @@ */ /** - * objectui#12521 — the console's record dialog on a field-heavy object opens - * bounded on desktop, as an INTERIM with a pinned exit (ruled in comment - * 6205068311, the early outcome of letter B, 6203721639). + * objectui#12521 / objectui#12592 — the console's record dialog on a + * field-heavy object opens bounded on desktop, as the installed + * `@objectstack/spec` derives it. * * `deriveRecordFlowSurface` (installed `@objectstack/spec`, re-exported by - * `@object-ui/plugin-view`, the import `AppContent` uses) answers - * `size: 'full'` for a create / edit / child task flow on an object with - * `RECORD_SURFACE_PAGE_THRESHOLD` or more authorable fields, and `AppContent` - * spread that into `modalSize: 'full'`: a 95vw dialog. Letter B makes the spec - * derive a bounded modal on desktop instead (objectstack-ai/objectstack#23734); - * until objectui installs that spec, `AppContent`'s module-private - * `interimBoundedTaskFlowSurface` gives the derivation's answer that shape, so - * `ModalForm`'s own bounded default sizes the dialog. + * `@object-ui/plugin-view`, the import `AppContent` uses) answers a create / + * edit / child task flow on an object with `RECORD_SURFACE_PAGE_THRESHOLD` or + * more authorable fields with a bounded modal on desktop, `size: 'auto'`, and + * keeps `size: 'full'` for a phone (objectstack-ai/objectstack#23734, letter B + * of objectui#12521). `AppContent` calls it with no `viewport` and spreads only + * a `full` answer into `modalSize`, so `ModalForm`'s own bounded default sizes + * the dialog. objectui#12521 bounded the dialog with an interim of its own + * until that spec was installed; objectui#12592 deleted it on the bump to + * `18.0.0-next.2`, and this file pins the derivation's answer in its place. * * Measured from a real `AppContent` mount (the `AppContent.createSeed-12291` * harness): the global record-form modal records the schema it is handed and, * where a cell reads the dialog itself, renders the real `ModalForm`. A * dialog's width is its `sm:max-w-*` class; jsdom evaluates no media query, so * "below `sm`" is read as the classes that carry no responsive prefix. - * - * Direction, written before the run: with the interim removed (the call site - * back on the bare derivation), the desktop cells and the EXIT cell RED (the - * schema carries `modalSize: 'full'`, the dialog `sm:max-w-[95vw]`); the - * authored-size CONTROL and the phone cell GREEN on both sides. */ import '@testing-library/jest-dom/vitest'; @@ -198,7 +194,7 @@ beforeEach(() => { }); afterEach(cleanup); -describe('objectui#12521 interim — a desktop task flow on a field-heavy object opens bounded', () => { +describe('objectui#12521 — a desktop task flow on a field-heavy object opens bounded', () => { it('the object is field-heavy: the installed derivation pages it', () => { expect(deriveRecordSurface(HEAVY)).toBe('page'); }); @@ -228,7 +224,7 @@ describe('objectui#12521 interim — a desktop task flow on a field-heavy object const bounded = belowSm(await dialogOnScreen()); cleanup(); - // What the console handed before the interim: the derivation's `full`. + // What the console handed before letter B: the derivation's `full`. const full = belowSm(await renderDialog({ ...schema, modalSize: 'full' })); expect(bounded).toEqual(full); @@ -246,21 +242,16 @@ describe('objectui#12521 interim — a desktop task flow on a field-heavy object }); }); -describe('objectui#12521 interim — EXIT', () => { - it('retires when the installed spec bounds the field-heavy desktop task flow itself', async () => { - // The import `AppContent` uses, called the way it calls it: no viewport. - const derived = deriveRecordFlowSurface(HEAVY, 'create'); - expect( - derived.size, - 'The installed @objectstack/spec no longer derives `size: \'full\'` for a field-heavy desktop ' - + 'task flow: objectstack-ai/objectstack#23734 is installed. Delete the interim ' - + '`interimBoundedTaskFlowSurface` in packages/app-shell/src/console/AppContent.tsx, call ' - + '`deriveRecordFlowSurface` directly at its call site, and delete this file ' - + '(objectui#12521, interim ruled in comment 6205068311).', - ).toBe('full'); - - // While the spec still answers `full`, the interim is what bounds the dialog. - const schema = await openFlow('create'); - expect(schema.modalSize).toBeUndefined(); +describe('objectui#12592 — the installed derivation bounds the field-heavy task flow itself', () => { + it.each(['create', 'edit', 'child-create', 'child-edit'] as const)( + '%s on desktop: a bounded modal overlay, size auto', + (flow) => { + // The import `AppContent` uses, called the way it calls it: no viewport. + expect(deriveRecordFlowSurface(HEAVY, flow)).toEqual({ container: 'overlay', surface: 'modal', size: 'auto' }); + }, + ); + + it('CONTROL: on a phone the same flow derives the full-screen modal', () => { + expect(deriveRecordFlowSurface(HEAVY, 'create', { viewport: 'mobile' }).size).toBe('full'); }); }); diff --git a/packages/app-shell/src/views/metadata-admin/celAuthoring.ts b/packages/app-shell/src/views/metadata-admin/celAuthoring.ts index 5a3ec27023..5cc6f024c9 100644 --- a/packages/app-shell/src/views/metadata-admin/celAuthoring.ts +++ b/packages/app-shell/src/views/metadata-admin/celAuthoring.ts @@ -428,7 +428,7 @@ function loadRowCanon(): Promise { * not re-derived — and the engine's own message ships with it. * * ⚠️ The reason is NOT that the engine's message refuses a `record.` - * rewrite. Measured against the installed 18.0.0-next.1 (objectui#12030, objectui#12370), it mostly PRESCRIBES one: the + * rewrite. Measured against the installed 18.0.0-next.2 (objectui#12030, objectui#12370, objectui#12626), it mostly PRESCRIBES one: the * `current_user` text CONTAINS "To gate on record state, rewrite the predicate * against `record`." — one of the three remedies it offers, and NOT where it * ends (measured: `includes` true, `endsWith` false; every covered slot's text diff --git a/packages/app-shell/src/views/metadata-admin/inspectors/FlowNodeInspector.declaredDefault.test.tsx b/packages/app-shell/src/views/metadata-admin/inspectors/FlowNodeInspector.declaredDefault.test.tsx index 15ed782f1d..bc8f88a209 100644 --- a/packages/app-shell/src/views/metadata-admin/inspectors/FlowNodeInspector.declaredDefault.test.tsx +++ b/packages/app-shell/src/views/metadata-admin/inspectors/FlowNodeInspector.declaredDefault.test.tsx @@ -381,7 +381,7 @@ describe('boolean: a declared defaultValue seeds the control (objectui#8451, arm // ⇒ `screen.waitForInput` is the offline undeclared boolean that sentence // says does not exist — and it is undeclared CORRECTLY, so ⛔ do not read // this as an objectui#9277-class omission waiting to be declared. Measured - // on the installed `@objectstack/spec` (18.0.0-next.1, objectui#12030, objectui#12370): `waitForInput` is typed + // on the installed `@objectstack/spec` (18.0.0-next.2, objectui#12030, objectui#12370, objectui#12626): `waitForInput` is typed // `z.boolean().optional()` with no `.default(...)`, so an omitted key // materialises nothing and there is no spec answer for a declaration to // mirror. Declaring one here would invent a default the runtime does not diff --git a/packages/app-shell/src/views/metadata-admin/inspectors/flowSingleBrace-12329.test.tsx b/packages/app-shell/src/views/metadata-admin/inspectors/flowSingleBrace-12329.test.tsx index 586cca0dc8..c1cba0a131 100644 --- a/packages/app-shell/src/views/metadata-admin/inspectors/flowSingleBrace-12329.test.tsx +++ b/packages/app-shell/src/views/metadata-admin/inspectors/flowSingleBrace-12329.test.tsx @@ -6,7 +6,7 @@ * * objectstack#19939 S7 deleted the engine's single-brace resolver: a value slot * refuses a `{…}` token, a text slot reads `{{ }}` holes, and every other flow - * string is a literal. The installed spec (`18.0.0-next.1`) publishes no + * string is a literal. The installed spec (`18.0.0-next.2`) publishes no * `xExpression: 'template'` mark. So the picker has two spellings left — the * bare reference and the `{{ }}` hole — and a literal position has no picker. * diff --git a/packages/app-shell/src/views/metadata-admin/previews/flow-canvas-seeds.saveErrors-10948.test.tsx b/packages/app-shell/src/views/metadata-admin/previews/flow-canvas-seeds.saveErrors-10948.test.tsx index 2323de5a07..aa7ab3f1ab 100644 --- a/packages/app-shell/src/views/metadata-admin/previews/flow-canvas-seeds.saveErrors-10948.test.tsx +++ b/packages/app-shell/src/views/metadata-admin/previews/flow-canvas-seeds.saveErrors-10948.test.tsx @@ -2,7 +2,7 @@ /** * objectui#10948 — what the designer's live `FlowSchema` pass says about a node - * the author has ADDED but not yet configured, on the installed spec (18.0.0-next.1). + * the author has ADDED but not yet configured, on the installed spec (18.0.0-next.2). * * Spec 17.5.0 carries objectstack#20316 (a node config key its executor * contract requires, left out, and a decision branch with no `label`, are diff --git a/packages/core/src/evaluator/optionRules.ts b/packages/core/src/evaluator/optionRules.ts index ac187cca28..daaf077f18 100644 --- a/packages/core/src/evaluator/optionRules.ts +++ b/packages/core/src/evaluator/optionRules.ts @@ -118,7 +118,7 @@ export function resolveVisibleOptions( * This is deliberately NOT the lenient renderer fallback AGENTS.md #0.1 * forbids. That rule governs metadata the contract REFUSES ("if the metadata * is off-spec, fix it at the producer"); an empty label is metadata the - * contract ACCEPTS. Measured on the installed `@objectstack/spec` 18.0.0-next.1, + * contract ACCEPTS. Measured on the installed `@objectstack/spec` 18.0.0-next.2, * `SelectOptionSchema`: * * { value: 'low', label: 'Low' } -> ACCEPT (lit control) diff --git a/packages/plugin-calendar/src/ObjectCalendar.tsx b/packages/plugin-calendar/src/ObjectCalendar.tsx index 3471f51fb1..4067e539d5 100644 --- a/packages/plugin-calendar/src/ObjectCalendar.tsx +++ b/packages/plugin-calendar/src/ObjectCalendar.tsx @@ -1428,7 +1428,7 @@ export const ObjectCalendar: React.FC = ({ * * `@objectstack/spec`'s `CalendarConfigSchema` is a `strictObject` whose ONE * required key is `startDateField`; `titleField` is optional. Re-measured on - * the installed 18.0.0-next.1 (objectui#12030, objectui#12370), three legs: `{}` and `{ titleField: 't' }` both fail + * the installed 18.0.0-next.2 (objectui#12030, objectui#12370, objectui#12626), three legs: `{}` and `{ titleField: 't' }` both fail * `invalid_type` at `startDateField`, and `{ startDateField: 'd' }` parses * CLEAN. The spec's own note on that schema names THIS renderer as the * reason — `resolveTitle` above takes an explicit `titleField` when present diff --git a/packages/plugin-calendar/src/__tests__/calendarUnionReads-8651.test.tsx b/packages/plugin-calendar/src/__tests__/calendarUnionReads-8651.test.tsx index c05c77928c..af5fe73b72 100644 --- a/packages/plugin-calendar/src/__tests__/calendarUnionReads-8651.test.tsx +++ b/packages/plugin-calendar/src/__tests__/calendarUnionReads-8651.test.tsx @@ -179,7 +179,7 @@ const LEDGERED_OTHER_CARD_READS: readonly string[] = []; * `ObjectCalendarSchema` and must stay so. * * ⚠️ The ground is NOT that the spec singles these two out. MEASURED on - * installed `@objectstack/spec` 18.0.0-next.1: `ComponentPropsMap['object-calendar']` + * installed `@objectstack/spec` 18.0.0-next.2: `ComponentPropsMap['object-calendar']` * is STRICT and declares exactly ten flat members — `calendar` `data` * `defaultView` `filter` `loading` `locale` `navigation` `objectName` `sort` * `staticData` (nine through 17.4.0; 17.5.0 added `navigation`) — diff --git a/packages/plugin-designer/src/MetadataFieldsPage.tsx b/packages/plugin-designer/src/MetadataFieldsPage.tsx index be93fd6fae..499604f3fa 100644 --- a/packages/plugin-designer/src/MetadataFieldsPage.tsx +++ b/packages/plugin-designer/src/MetadataFieldsPage.tsx @@ -184,7 +184,7 @@ function isDesignerAuthorableType(raw: unknown): raw is DesignerFieldType { * ## Why reading the retired spelling is a RENAME here and not a laundering * * `@objectstack/spec` treats the two as one key under two spellings and says - * so in the refusal itself. Measured on the installed 18.0.0-next.1 (objectui#12030, objectui#12370): + * so in the refusal itself. Measured on the installed 18.0.0-next.2 (objectui#12030, objectui#12370, objectui#12626): * * FieldSchema.safeParse({ type: 'lookup', label: 'L', referenceTo: 'account' }) * => success = false diff --git a/packages/plugin-detail/src/index.tsx b/packages/plugin-detail/src/index.tsx index c511f49ad4..ff56ef265e 100644 --- a/packages/plugin-detail/src/index.tsx +++ b/packages/plugin-detail/src/index.tsx @@ -966,7 +966,7 @@ ComponentRegistry.register('alert', RecordAlertRenderer, { // through `pickLocalized`, which is exactly what these descriptions teach. // Declaring the map arm therefore adds no shape the block does not already // honour; it stops the manifest gate warning `type-mismatch` on the - // recommended write. (The row DOES exist as of the installed 18.0.0-next.1 — read + // recommended write. (The row DOES exist as of the installed 18.0.0-next.2 — read // for `visible` below, objectui#9100 — so the "no entry" reading is stale; // these two arms are unaffected either way.) { name: 'title', type: ['string', 'object'], description: 'Accepts an inline translation map ({ en, "zh-CN", … })' }, @@ -974,7 +974,7 @@ ComponentRegistry.register('alert', RecordAlertRenderer, { // objectui#9100 — the spec accepts three arms here and the renderer now // resolves all three, so a single `'string'` was the declaration-narrower- // than-the-contract family of objectui#4581, one layer up. Measured on the - // INSTALLED `@objectstack/spec` 18.0.0-next.1 (`dist/ui/index.d.ts`, the + // INSTALLED `@objectstack/spec` 18.0.0-next.2 (`dist/ui/index.d.ts`, the // `ComponentPropsMap['record:alert']` row): `visible` is // `boolean | string | { dialect: 'cel'|'cron'|'template', source?, … }`, // and `renderers/record-alert.tsx` hands whichever arrives to diff --git a/packages/plugin-form/src/__tests__/formSectionGroupReference-7051.test.tsx b/packages/plugin-form/src/__tests__/formSectionGroupReference-7051.test.tsx index 7ffa47f9ad..32b6a3154c 100644 --- a/packages/plugin-form/src/__tests__/formSectionGroupReference-7051.test.tsx +++ b/packages/plugin-form/src/__tests__/formSectionGroupReference-7051.test.tsx @@ -448,7 +448,7 @@ describe('objectui#7051 — resolveSectionGroupReferences', () => { /** * ⭐ The second axis. The card asks that group-owned presentation keys beside * `group`, and `group` on a wizard step, not be SILENTLY accepted. Measured - * against the installed `@objectstack/spec` (18.0.0-next.1): both are refused at PARSE + * against the installed `@objectstack/spec` (18.0.0-next.2): both are refused at PARSE * — a stronger door than the lint that objectui#8497 concluded owns EXISTENCE * checking, and a different one. So authored metadata carrying either never * reaches this renderer at all; the renderer's own reports above exist for the diff --git a/packages/plugin-form/src/__tests__/masterDetailDetailsMembers-8071.test.tsx b/packages/plugin-form/src/__tests__/masterDetailDetailsMembers-8071.test.tsx index 334984a849..c882557c56 100644 --- a/packages/plugin-form/src/__tests__/masterDetailDetailsMembers-8071.test.tsx +++ b/packages/plugin-form/src/__tests__/masterDetailDetailsMembers-8071.test.tsx @@ -504,7 +504,7 @@ type SpecDetailEntry = NonNullable[numbe * The config IS the spec's entry minus `sortField`, by reference * (objectui#11396): a member the spec adds, drops or retypes lands on the * config with no hand edit, and a hand-written restatement that drifts is red - * here before it is red anywhere else. The installed 18.0.0-next.1 entry carries a + * here before it is red anywhere else. The installed 18.0.0-next.2 entry carries a * `retiredKey()` tombstone for `sortField` (objectstack-ai/objectstack#21589); * 17.6.0 declared it as a string, and the subtraction removes the key either * way. ⛔ No row here pins which of the two shapes the spec has; the `Spec Main diff --git a/packages/plugin-gantt/src/readme-navigation-example.test.ts b/packages/plugin-gantt/src/readme-navigation-example.test.ts index d710defe6e..0e91176421 100644 --- a/packages/plugin-gantt/src/readme-navigation-example.test.ts +++ b/packages/plugin-gantt/src/readme-navigation-example.test.ts @@ -79,7 +79,7 @@ * * WARNING: `declaredMembers()` cannot derive that key's retirement. When this * was written the spec in the lockfile (17.4.0) still DECLARED `view` as a live - * member. The installed `@objectstack/spec` 18.0.0-next.1 lands it as a tombstone, + * member. The installed `@objectstack/spec` 18.0.0-next.2 lands it as a tombstone, * as 17.5.0 through 17.7.0 did (objectui#11073 measured it, objectui#11438, * objectui#11717 and objectui#12030 again: a `never` * schema, and `{ view: 'detail' }` is diff --git a/packages/plugin-kanban/src/index.tsx b/packages/plugin-kanban/src/index.tsx index 358d0520f8..fd50b45246 100644 --- a/packages/plugin-kanban/src/index.tsx +++ b/packages/plugin-kanban/src/index.tsx @@ -549,7 +549,7 @@ export const ObjectKanbanRenderer: React.FC<{ schema: any; [key: string]: any }> * ## Why these keys were added * * `@objectstack/spec`'s `ComponentPropsMap['object-kanban']` carries FIFTEEN - * top-level keys on the installed 18.0.0-next.1 pin, fourteen of them live, the + * top-level keys on the installed 18.0.0-next.2 pin, fourteen of them live, the * same set as 17.5.0 through 17.7.0: 17.5.0 * added `navigation` and turned `quickAdd` into a tombstone (typed `never`, * refused by name — objectui#8285's ruled retirement, landed). This list diff --git a/packages/plugin-view/src/recordSurface.test.ts b/packages/plugin-view/src/recordSurface.test.ts index 6133b890fc..09e5f28d17 100644 --- a/packages/plugin-view/src/recordSurface.test.ts +++ b/packages/plugin-view/src/recordSurface.test.ts @@ -70,9 +70,20 @@ describe('deriveRecordFlowSurface (#2604 mirror)', () => { }); }); - it('task flows never route: heavy → full-screen modal overlay', () => { + // objectstack-ai/objectstack#23734 (letter B of objectui#12521, objectui#12592): on desktop a + // field-heavy task flow derives a BOUNDED modal; only a phone keeps the full-screen one (below). + // The spec keeps no full-screen split for a form with an embedded child or line-items table. + it('task flows never route: heavy → bounded modal overlay on desktop', () => { for (const flow of TASK_FLOWS) { expect(deriveRecordFlowSurface(heavy, flow)).toEqual({ + container: 'overlay', surface: 'modal', size: 'auto', + }); + } + }); + + it('heavy task flows on mobile: the full-screen modal', () => { + for (const flow of TASK_FLOWS) { + expect(deriveRecordFlowSurface(heavy, flow, { viewport: 'mobile' })).toEqual({ container: 'overlay', surface: 'modal', size: 'full', }); } @@ -98,7 +109,7 @@ describe('deriveRecordFlowSurface (#2604 mirror)', () => { it('child-* flows size to the def they are given (the child), independent of any parent', () => { expect(deriveRecordFlowSurface(objWithFields(3), 'child-create').surface).toBe('drawer'); expect(deriveRecordFlowSurface(objWithFields(40), 'child-edit')).toEqual({ - container: 'overlay', surface: 'modal', size: 'full', + container: 'overlay', surface: 'modal', size: 'auto', }); }); }); diff --git a/packages/types/package.json b/packages/types/package.json index 1304fc8b11..9b708563e4 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -93,7 +93,7 @@ "directory": "packages/types" }, "dependencies": { - "@objectstack/spec": "^18.0.0-next.1", + "@objectstack/spec": "^18.0.0-next.2", "zod": "^4.6.1" }, "devDependencies": { diff --git a/packages/types/src/__tests__/chartconfig-aria-retired-4044.test.ts b/packages/types/src/__tests__/chartconfig-aria-retired-4044.test.ts index 18f5cfc09e..a9efdd4345 100644 --- a/packages/types/src/__tests__/chartconfig-aria-retired-4044.test.ts +++ b/packages/types/src/__tests__/chartconfig-aria-retired-4044.test.ts @@ -30,7 +30,7 @@ * - **TypeScript.** `complex.ts` re-typed `chartConfig` as `any`, so an * authored `aria` compiled. The member now takes `aria` from the spec's own * input type, which is the spec's retired-key type (the branded `[REMOVED]` - * mark at the pinned 18.0.0-next.1 and on objectstack `main`, bare `undefined` + * mark at the pinned 18.0.0-next.2 and on objectstack `main`, bare `undefined` * through 17.5.0; both * spellings are `retired-key-type.ts`'s), so an authored value is a compile * error. diff --git a/packages/types/src/__tests__/dashboard-aria-retired-contract-twins.test.ts b/packages/types/src/__tests__/dashboard-aria-retired-contract-twins.test.ts index f8deb03a0b..4071dd2b1b 100644 --- a/packages/types/src/__tests__/dashboard-aria-retired-contract-twins.test.ts +++ b/packages/types/src/__tests__/dashboard-aria-retired-contract-twins.test.ts @@ -29,7 +29,7 @@ * objectui#9736 closed that half. The interface now extends the spec's own * `Dashboard` input type (`Omit< Dashboard, … >` over the exclusion list its * mirror reads), so it inherits the spec's tombstone as a DECLARED member typed - * as the spec's retired key (the branded `[REMOVED]` mark at the pinned 18.0.0-next.1 + * as the spec's retired key (the branded `[REMOVED]` mark at the pinned 18.0.0-next.2 * and on objectstack `main`, bare `undefined` through 17.5.0) — `aria` is back in the declared key * set, but only as a refusal, * and an authored value is a compile error: the same verdict the Zod twin gives @@ -52,7 +52,7 @@ describe('the TS interface declares `aria` only as the spec tombstone (objectui# it('`aria` is declared, typed as the spec\'s retired key; the neighbours it stood beside still are', () => { // Type-level pins, erased at runtime. `aria` is a DECLARED key again — the // spec projection carries the tombstone — and its type admits no value: - // the branded `[REMOVED]` mark at the pinned 18.0.0-next.1 and on objectstack + // the branded `[REMOVED]` mark at the pinned 18.0.0-next.2 and on objectstack // `main`, bare `undefined` through 17.5.0 (both spellings are // `retired-key-type.ts`'s, objectui#11330). const ariaDeclared: 'aria' extends Declared ? true : false = true; diff --git a/packages/types/src/__tests__/imported-defaults-8317.test.ts b/packages/types/src/__tests__/imported-defaults-8317.test.ts index e7c58a3661..83a9bc30ea 100644 --- a/packages/types/src/__tests__/imported-defaults-8317.test.ts +++ b/packages/types/src/__tests__/imported-defaults-8317.test.ts @@ -143,6 +143,8 @@ import { checkPageRequiresKind, checkPageSlotPair, checkPageComponentViewData, + checkPageRegionPlacement, + checkPageDefaultPlacement, VIEW_METADATA_MEMBERS as SpecViewMetadataMembers, } from '@objectstack/spec/ui'; import { @@ -706,6 +708,11 @@ describe('the import boundary strips every imported default (objectui#8317)', () // `PageSchema` (the retired `api` provider under `regions` / `slots`), re-attached on // `PageNodeSchema` and `PageKindNodeSchema` under the same ruling. ['checkPageComponentViewData', checkPageComponentViewData], + // objectui#12626: the two page checks `@objectstack/spec` 18.0.0-next.2 adds to + // `PageSchema` — region placement by `template`, re-attached on `PageNodeSchema` and + // `PageKindNodeSchema`, and `isDefault` placement, on `PageKindNodeSchema` only. + ['checkPageRegionPlacement', checkPageRegionPlacement], + ['checkPageDefaultPlacement', checkPageDefaultPlacement], ]); /** diff --git a/packages/types/src/__tests__/object-view-unmirrored-keys-7779.test.ts b/packages/types/src/__tests__/object-view-unmirrored-keys-7779.test.ts index f9c56332cb..2a89f8e57c 100644 --- a/packages/types/src/__tests__/object-view-unmirrored-keys-7779.test.ts +++ b/packages/types/src/__tests__/object-view-unmirrored-keys-7779.test.ts @@ -339,7 +339,7 @@ const NAMED_VIEW_ABSENT_CONTROL = 'stickyHeader'; /** * The protocol's own member set for a named list view — `ObjectListViewSchema`'s - * shape, off `@objectstack/spec` as installed (18.0.0-next.1). ⛔ Not a copy of the + * shape, off `@objectstack/spec` as installed (18.0.0-next.2). ⛔ Not a copy of the * objectui face and ⛔ not a hand list: it is read off the schema object, so a * spec bump that moves a key moves this. */ diff --git a/packages/types/src/__tests__/record-details-top-level-9040.test.ts b/packages/types/src/__tests__/record-details-top-level-9040.test.ts index 13b7edbf59..8849a2cd1a 100644 --- a/packages/types/src/__tests__/record-details-top-level-9040.test.ts +++ b/packages/types/src/__tests__/record-details-top-level-9040.test.ts @@ -174,7 +174,7 @@ type _KeyofStillResolvesOnThisInterface = Expect< /** * The contract's face, untouched by this removal: the tombstone accepts nothing. * Its type is the spec's retired-key type — the branded `[REMOVED]` mark at the - * pinned 18.0.0-next.1 and on objectstack `main`, + * pinned 18.0.0-next.2 and on objectstack `main`, * bare `undefined` through 17.5.0 — and the helper accepts * exactly those two spellings (objectui#11330). */ diff --git a/packages/types/src/__tests__/spec-object-refinements-7715.test.ts b/packages/types/src/__tests__/spec-object-refinements-7715.test.ts index a4a49895f3..2948bef76d 100644 --- a/packages/types/src/__tests__/spec-object-refinements-7715.test.ts +++ b/packages/types/src/__tests__/spec-object-refinements-7715.test.ts @@ -211,6 +211,67 @@ describe('objectui#12370 — the Page retired-`api` view-data refusal reaches ob }); }); +describe('objectui#12626 — the Page region-placement refusal reaches objectui', () => { + const regions = (...names: string[]) => names.map((name) => ({ name, components: [] })); + + it.each([ + ['a region the default template does not place', { regions: regions('main', 'left_sidebar') }, 'regions.1.name'], + ['a second region for a filled slot', { regions: regions('main', 'Main') }, 'regions.1.name'], + ['a region `header-sidebar-main` does not place', { template: 'header-sidebar-main', regions: regions('main', 'aside') }, 'regions.1.name'], + ])('%s: the spec refuses it, and objectui refuses with the spec\'s own issue on both page nodes', (_label, extra, at) => { + const spec = SpecPageSchema.safeParse(specPage(extra)); + expect(spec.success).toBe(false); + const specIssue = spec.error!.issues.find((i) => i.path.join('.') === at); + expect(specIssue?.code).toBe('custom'); + + // The `page` node through its own schema and the published door, and the page-kind node + // (`type: 'home'`) through the published door. + const kindNode = { ...extra, type: 'home' }; + for (const r of [PageNodeSchema.safeParse(pageNode(extra)), safeValidateSchema(pageNode(extra)), safeValidateSchema(kindNode)]) { + expect(r.success).toBe(false); + const issues = r.error!.issues.map((i) => ({ code: i.code, path: i.path.join('.'), message: i.message })); + expect(issues).toContainEqual({ code: 'custom', path: at, message: specIssue!.message }); + } + }); + + it('controls: placed regions, any region on the open-grid `dashboard` template, and a non-`full` kind pass on both doors', () => { + for (const extra of [ + { regions: regions('header', 'main', 'aside', 'footer') }, + { template: 'dashboard', regions: regions('header', 'kpis', 'pipeline') }, + { kind: 'slotted', regions: regions('left_sidebar') }, + ]) { + expect(SpecPageSchema.safeParse(specPage(extra)).success).toBe(true); + expect(PageNodeSchema.safeParse(pageNode(extra)).success).toBe(true); + expect(safeValidateSchema(pageNode(extra)).success).toBe(true); + } + }); +}); + +describe('objectui#12626 — the Page `isDefault` placement refusal reaches the page-kind node, and only there', () => { + it('a `home` page with `isDefault`: the spec refuses at `isDefault`, and the kind node refuses with the spec\'s own issue', () => { + const extra = { type: 'home', isDefault: true }; + const spec = SpecPageSchema.safeParse(specPage(extra)); + expect(spec.success).toBe(false); + const specIssue = spec.error!.issues.find((i) => i.path.join('.') === 'isDefault'); + expect(specIssue?.code).toBe('custom'); + + const r = safeValidateSchema(extra); + expect(r.success).toBe(false); + expect(r.error!.issues.map((i) => ({ code: i.code, path: i.path.join('.'), message: i.message }))) + .toContainEqual({ code: 'custom', path: 'isDefault', message: specIssue!.message }); + }); + + it('controls: a bound record page with `isDefault` passes on the spec and the kind node, and the `page` node does not judge it', () => { + const bound = { type: 'record', object: 'account', isDefault: true }; + expect(SpecPageSchema.safeParse(specPage(bound)).success).toBe(true); + expect(safeValidateSchema(bound).success).toBe(true); + // The `page` node's `type` is the discriminator, so the check is not attached there: + // the same `isDefault` on a `page` node is not refused at `isDefault`. + const r = PageNodeSchema.safeParse(pageNode({ object: 'account', isDefault: true })); + expect(r.success).toBe(true); + }); +}); + // ── The census: every object-level check the spec runs is accounted for ───── /** @@ -255,13 +316,26 @@ const SITES = [ // `checkPageComponentViewData` joined at 18.0.0-next.1 (objectstack#23419) and was attached // by objectui#12370: it reads `slots` (by reference) and `regions`, whose components this // node's union already judges; measured in its describe block above. - attached: ['checkPageSourceCompleteness', 'checkPageRequiresKind', 'checkPageSlotPair', 'checkPageComponentViewData'], + // `checkPageRegionPlacement` joined at 18.0.0-next.2 and was attached by objectui#12626: it + // reads `kind` and `template` (by reference) and each region's `name`, which objectui's own + // region carries with the meaning `page.tsx` places it by; measured in its describe block above. + attached: [ + 'checkPageSourceCompleteness', + 'checkPageRequiresKind', + 'checkPageSlotPair', + 'checkPageComponentViewData', + 'checkPageRegionPlacement', + ], // `checkPagePrintComposition` joined at 18 (the `print` page, ruling B′ on objectstack#8346). // It reads `type` and `regions`, and this node carries NEITHER by reference: both are in // `PAGE_SPEC_EXCLUDED`, `type` being the component discriminator (`'page'`, or a page kind // on the kind node) and `regions` objectui's own `PageNodeRegionSchema` — so it is not // attachable here, the measurement `checkListViewPageMount` had on the list-view site. - notAttachable: ['checkPagePrintComposition'], + // `checkPageDefaultPlacement` joined at 18.0.0-next.2. It judges `isDefault` by the page's + // `type`, which on this node is the component discriminator `'page'`, so attached it would + // refuse every `isDefault`; `PageKindNodeSchema`, whose `type` is the page kind, attaches it + // (objectui#12626, measured in its describe block above). + notAttachable: ['checkPagePrintComposition', 'checkPageDefaultPlacement'], }, { site: 'ListViewSchema (objectql.zod.ts)', diff --git a/packages/types/src/field-types.ts b/packages/types/src/field-types.ts index 9a1824475c..05ea4b272a 100644 --- a/packages/types/src/field-types.ts +++ b/packages/types/src/field-types.ts @@ -25,7 +25,7 @@ import type { Field as SpecField } from '@objectstack/spec/data'; * sibling field names, or `{ field, param }` entries mapping a sibling onto the * remote query parameter a dependent lookup filters by. * - * Measured on the installed `@objectstack/spec` (18.0.0-next.1), `FieldSchema` declares + * Measured on the installed `@objectstack/spec` (18.0.0-next.2), `FieldSchema` declares * `dependsOn` as an OPTIONAL ARRAY of `string | { field, param? }` — never a * bare string. That is deliberately narrower than `DependsOnInput` (`form.ts`), * the shape the widget prop `FieldWidgetComponentProps.dependsOn` and @@ -343,7 +343,7 @@ export interface MarkdownFieldMetadata extends BaseFieldMetadata { * annotated literal rejected. Follows the `TextareaFieldMetadata` precedent. * * A DECLARED spec key as of `@objectstack/spec` 17.3.0, which implements that - * same ruling. Measured on the installed `@objectstack/spec` 18.0.0-next.1: + * same ruling. Measured on the installed `@objectstack/spec` 18.0.0-next.2: * `FieldSchema` ACCEPTS `rows` on all four of textarea/markdown/html/ * richtext, as an integer of at least 1 — a non-integer answers * `invalid_type` and 0 answers `too_small`, so "declared" does not mean "any @@ -664,7 +664,7 @@ export interface SelectOptionMetadata extends SelectOptionBase { * * A DECLARED `SelectOptionSchema` key as of `@objectstack/spec` 17.3.0, * which implements the objectui#6153 half of that ruling. Measured on the - * installed `@objectstack/spec` 18.0.0-next.1: an option carrying `description` + * installed `@objectstack/spec` 18.0.0-next.2: an option carrying `description` * is ACCEPTED, as a string (a non-string answers `invalid_type`; the empty * string is valid), and a field whose `options` carry it parses whole. ⇒ it * may now be written into authored object metadata, which is the point of diff --git a/packages/types/src/objectql.ts b/packages/types/src/objectql.ts index d8fcd77c0e..389bc78bfa 100644 --- a/packages/types/src/objectql.ts +++ b/packages/types/src/objectql.ts @@ -4219,7 +4219,7 @@ export interface ObjectCalendarSchema extends BaseSchema { * (the spec's own `ObjectCalendarPropsSchema`) declares * `z.array(z.unknown()).optional()`, described *"Pre-fetched records — skips * the internal fetch"*. - * MEASURED on the installed artifact at `@objectstack/spec` 18.0.0-next.1 — the + * MEASURED on the installed artifact at `@objectstack/spec` 18.0.0-next.2 — the * version this repository's `pnpm-lock.yaml` resolves — through the published * `@objectstack/spec/ui` entry point: the provider block returns * `success=false` with `expected: 'array'` at `path: ['data']`, the array diff --git a/packages/types/src/record-components.ts b/packages/types/src/record-components.ts index 7968b6d5c5..203c42ec64 100644 --- a/packages/types/src/record-components.ts +++ b/packages/types/src/record-components.ts @@ -107,7 +107,7 @@ export interface RecordDetailsComponentProps { * It was `number` here until objectui#8604, which is the wrong PRIMITIVE * TYPE, not merely a wider range: `{ columns: 2 }` compiled locally and the * contract refused it at publish with `invalid_value` at `columns` (measured - * on the installed pin, 18.0.0-next.1, against a control — `columns: '2'` — that + * on the installed pin, 18.0.0-next.2, against a control — `columns: '2'` — that * parses green on the same instrument). Contract-first (Commandment #0.1): * the code moves to the contract's spelling, and today's `columns: 2` * authors are the defect surfacing rather than collateral damage. @@ -358,7 +358,7 @@ export interface RecordHighlightsComponentProps { * `RecordHighlightsProps.fields[]`'s object arm declares exactly * `name`/`label`/`type`/`readonly` and carries a `never` catchall, i.e. it is * `$strict`: an unlisted key is REFUSED, not stripped, and the refusal takes - * the WHOLE document with it. Measured on the installed pin, 18.0.0-next.1, + * the WHOLE document with it. Measured on the installed pin, 18.0.0-next.2, * `RecordHighlightsProps.safeParse({ fields: [{ name: 'x', icon: 'star' }] })` * is RED with `invalid_union` at `fields.0`. So `{ name: 'amount', icon: * 'dollar-sign' }` type-checked here and was refused at the door — a green @@ -390,7 +390,7 @@ export interface RecordHighlightsComponentProps { * `z.enum(['horizontal','vertical'])` behind a `.default('horizontal')`). * * It offered a third value, `grid`, until objectui#9187, and the contract - * never accepted it: measured on the installed pin, 18.0.0-next.1, + * never accepted it: measured on the installed pin, 18.0.0-next.2, * `RecordHighlightsProps.safeParse({ fields: ['name'], layout: 'grid' })` is * RED with `invalid_value` at `layout`. So `{ layout: 'grid' }` type-checked * here and was refused at the door — a green local build and a rejection at diff --git a/packages/types/src/zod/layout.zod.ts b/packages/types/src/zod/layout.zod.ts index bd56d5345c..53fdc88552 100644 --- a/packages/types/src/zod/layout.zod.ts +++ b/packages/types/src/zod/layout.zod.ts @@ -23,6 +23,8 @@ import { PageTypeSchema as SpecPageTypeSchema, PageVariableSchema as SpecPageVariableSchema, checkPageComponentViewData, + checkPageDefaultPlacement, + checkPageRegionPlacement, checkPageRequiresKind, checkPageSlotPair, checkPageSourceCompleteness, @@ -1360,8 +1362,17 @@ export const PageNodeSchema = BaseSchema.extend(SpecPageFields.shape).extend({ // `regions` or `slots` whose `properties.data` names the retired `api` // provider is refused at that `properties.data.provider`, with the // retirement message (`checkPageComponentViewData`, objectstack#23419, the - // spec's 18.0.0-next.1; attached by objectui#12370). - // The spec exports all four and all four are attached here as-is: the first + // spec's 18.0.0-next.1; attached by objectui#12370); + // - on a `kind: 'full'` page, a region whose `name` the page's `template` + // does not place, or a second region for a slot already filled, is + // refused at `regions.N.name` (`checkPageRegionPlacement`, the spec's + // 18.0.0-next.2; attached by objectui#12626). It reads `kind`, `template` + // (both by reference) and each region's `name`, which this node's own + // {@link PageNodeRegionSchema} carries with the same meaning: `page.tsx` + // in `@object-ui/components` places a region by its lowercased `name`, as + // the check does, so the refusal names exactly the region the renderer + // stacks under `main`. + // The spec's `PageSchema` carries seven; these five are attached here as-is: the first // three read `kind`, `source`, `requires` and `slots`, which this node carries // by reference — none is in {@link PAGE_SPEC_EXCLUDED} nor overridden above. // `checkPageComponentViewData` reads `slots` and `regions`. `slots` is carried @@ -1372,15 +1383,20 @@ export const PageNodeSchema = BaseSchema.extend(SpecPageFields.shape).extend({ // the `object-grid` arm already refuses the `api` provider there; the check // walks any object tree and judges only a node's `type` and `properties.data`, // so attaching it over this node's regions adds no second rule (measured in - // `__tests__/spec-object-refinements-7715.test.ts`). The spec's fifth page check, `checkPagePrintComposition`, + // `__tests__/spec-object-refinements-7715.test.ts`). The sixth, `checkPagePrintComposition`, // reads `type` and `regions` as the PAGE's own, which this node does NOT carry - // by reference, so it is not attached; the census below records why. + // by reference, so it is not attached; the census below records why. The + // seventh, `checkPageDefaultPlacement` (18.0.0-next.2), judges `isDefault` by + // the page's `type`, and on this node `type` is the component discriminator + // (`'page'`), so attached here it would refuse every `isDefault`; it is + // attached on {@link PageKindNodeSchema} below, whose `type` IS the page kind. // `__tests__/spec-object-refinements-7715.test.ts` re-derives the count, so a // check the spec adds to `PageSchema` later reddens there. .superRefine(checkPageSourceCompleteness) .superRefine(checkPageRequiresKind) .superRefine(checkPageSlotPair) - .superRefine(checkPageComponentViewData); + .superRefine(checkPageComponentViewData) + .superRefine(checkPageRegionPlacement); /** * The spec page KINDS a node may carry in `type` (objectui#11440): `record`, @@ -1428,10 +1444,12 @@ const { type: _pageNodeTypeLiteral, ...PAGE_NODE_MEMBERS } = PageNodeSchema.shap * member is {@link PageNodeSchema}'s own, by reference, and that node already * takes the spec's `PageSchema` fields by reference through * {@link SpecPageFields}. Its four refusals (`actions`, `breadcrumbs`, - * `maxWidth`, `padding`), the `body` refusal and the spec's four attachable + * `maxWidth`, `padding`), the `body` refusal and the spec's five attachable * object-level checks (`source`, `requires` by `kind`, the `details` / - * `tabs` slot pair, and the retired `api` view data under `regions` / `slots`) - * come with it. `regions` stays the node's own + * `tabs` slot pair, the retired `api` view data under `regions` / `slots`, + * and region placement by `template`) come with it. The spec's + * `isDefault` placement check is attached here only: it reads the page + * kind from `type`, which this node carries and the `page` node does not. `regions` stays the node's own * {@link PageNodeRegionSchema}, so each region component is judged by this * union at every depth, as on `page`. * @@ -1442,7 +1460,10 @@ export const PageKindNodeSchema: PageKindNodeSchemaType = BaseSchema.extend({ ...PAGE_NODE_MEMBERS, type: PAGE_KIND_NODE_TYPE.describe('The spec page kind — `record`, `home` or `utility` (`@objectstack/spec` `PageTypeSchema`)'), }).superRefine(checkPageSourceCompleteness).superRefine(checkPageRequiresKind).superRefine(checkPageSlotPair) - .superRefine(checkPageComponentViewData); + .superRefine(checkPageComponentViewData).superRefine(checkPageRegionPlacement) + // On this node `type` is the spec page kind, the field the spec's + // `checkPageDefaultPlacement` judges `isDefault` by (objectui#12626). + .superRefine(checkPageDefaultPlacement); /** * The TYPE of {@link PageKindNodeSchema}, written out BY REFERENCE to the diff --git a/packages/types/src/zod/objectql.zod.ts b/packages/types/src/zod/objectql.zod.ts index 3ab40585e7..976dd1a5fd 100644 --- a/packages/types/src/zod/objectql.zod.ts +++ b/packages/types/src/zod/objectql.zod.ts @@ -1758,7 +1758,7 @@ const KanbanConfig = stripImportedDefaults(SpecListViewSchema).shape.kanban.unwr * `@objectstack/spec` 17.4.0 (the version in the lockfile then) rather than * reading it — RE-RUN on 17.5.0 (objectui#11073), whose answer moved, as the * last bullet says, RE-RUN on 17.6.0 (objectui#11438), on 17.7.0 (objectui#11717), - * and again on the installed 18.0.0-next.1 (objectui#12030, objectui#12370), each of which answers + * and again on the installed 18.0.0-next.2 (objectui#12030, objectui#12370, objectui#12626), each of which answers * every bullet below as 17.5.0 did: * * - `CalendarConfigSchema`'s `strictObject` options carry `surface` and @@ -1783,7 +1783,7 @@ const KanbanConfig = stripImportedDefaults(SpecListViewSchema).shape.kanban.unwr * prescribes neither. `endField` still draws no hint, and a one-char typo * still resolves by distance (`titleFeld` → `titleField`) — all three * measured on 17.5.0, again on 17.6.0 (objectui#11438), on 17.7.0 - * (objectui#11717), and again on the installed 18.0.0-next.1 (objectui#12030, objectui#12370). + * (objectui#11717), and again on the installed 18.0.0-next.2 (objectui#12030, objectui#12370, objectui#12626). * * ⇒ through 17.4.0 a generic typo-distance suggester picked the wrong sibling. * It was not a declaration, it contradicted no declaration, and ⛔ no upstream diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 35c92a15ed..33771caf46 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -35,7 +35,7 @@ importers: version: link:packages/test-support '@objectstack/spec': specifier: ^18.0.0-next.1 - version: 18.0.0-next.1(ai@7.0.65(zod@4.6.5)) + version: 18.0.0-next.2(ai@7.0.65(zod@4.6.7)) '@playwright/test': specifier: ^1.62.1 version: 1.62.1 @@ -273,13 +273,13 @@ importers: version: link:../../packages/types '@objectstack/client': specifier: ^18.0.0-next.1 - version: 18.0.0-next.1(ai@7.0.65(zod@4.6.5)) + version: 18.0.0-next.2(ai@7.0.65(zod@4.6.7)) '@objectstack/lint': specifier: ^18.0.0-next.1 - version: 18.0.0-next.1(ai@7.0.65(zod@4.6.5)) + version: 18.0.0-next.2(ai@7.0.65(zod@4.6.7)) '@objectstack/spec': specifier: ^18.0.0-next.1 - version: 18.0.0-next.1(ai@7.0.65(zod@4.6.5)) + version: 18.0.0-next.2(ai@7.0.65(zod@4.6.7)) '@tailwindcss/postcss': specifier: ^4.3.3 version: 4.3.3 @@ -417,16 +417,16 @@ importers: version: link:../../packages/types '@objectstack/spec': specifier: ^18.0.0-next.1 - version: 18.0.0-next.1(ai@7.0.65(zod@4.6.5)) + version: 18.0.0-next.2(ai@7.0.65(zod@4.6.7)) fumadocs-core: specifier: 16.15.4 - version: 16.15.4(@mdx-js/mdx@3.1.1)(@tanstack/react-router@1.170.8(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(@types/estree-jsx@1.0.5)(@types/hast@3.0.5)(@types/mdast@4.0.4)(@types/react@19.2.18)(lucide-react@1.43.0(react@19.2.8))(next@16.3.6(@babel/core@7.29.7)(@opentelemetry/api@1.9.1)(@playwright/test@1.62.1)(@types/node@26.2.0)(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react-dom@19.2.8(react@19.2.8))(react-router@7.18.2(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react@19.2.8)(zod@4.6.5) + version: 16.15.4(@mdx-js/mdx@3.1.1)(@tanstack/react-router@1.170.8(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(@types/estree-jsx@1.0.5)(@types/hast@3.0.5)(@types/mdast@4.0.4)(@types/react@19.2.18)(lucide-react@1.43.0(react@19.2.8))(next@16.3.6(@babel/core@7.29.7)(@opentelemetry/api@1.9.1)(@playwright/test@1.62.1)(@types/node@26.2.0)(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react-dom@19.2.8(react@19.2.8))(react-router@7.18.2(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react@19.2.8)(zod@4.6.7) fumadocs-mdx: specifier: 15.2.3 - version: 15.2.3(@types/mdast@4.0.4)(@types/mdx@2.0.14)(@types/react@19.2.18)(fumadocs-core@16.15.4(@mdx-js/mdx@3.1.1)(@tanstack/react-router@1.170.8(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(@types/estree-jsx@1.0.5)(@types/hast@3.0.5)(@types/mdast@4.0.4)(@types/react@19.2.18)(lucide-react@1.43.0(react@19.2.8))(next@16.3.6(@babel/core@7.29.7)(@opentelemetry/api@1.9.1)(@playwright/test@1.62.1)(@types/node@26.2.0)(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react-dom@19.2.8(react@19.2.8))(react-router@7.18.2(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react@19.2.8)(zod@4.6.5))(next@16.3.6(@babel/core@7.29.7)(@opentelemetry/api@1.9.1)(@playwright/test@1.62.1)(@types/node@26.2.0)(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react@19.2.8)(rolldown@1.2.7)(vite@8.2.2(@types/node@26.2.0)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.12)(yaml@2.9.0)) + version: 15.2.3(@types/mdast@4.0.4)(@types/mdx@2.0.14)(@types/react@19.2.18)(fumadocs-core@16.15.4(@mdx-js/mdx@3.1.1)(@tanstack/react-router@1.170.8(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(@types/estree-jsx@1.0.5)(@types/hast@3.0.5)(@types/mdast@4.0.4)(@types/react@19.2.18)(lucide-react@1.43.0(react@19.2.8))(next@16.3.6(@babel/core@7.29.7)(@opentelemetry/api@1.9.1)(@playwright/test@1.62.1)(@types/node@26.2.0)(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react-dom@19.2.8(react@19.2.8))(react-router@7.18.2(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react@19.2.8)(zod@4.6.7))(next@16.3.6(@babel/core@7.29.7)(@opentelemetry/api@1.9.1)(@playwright/test@1.62.1)(@types/node@26.2.0)(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react@19.2.8)(rolldown@1.2.7)(vite@8.2.2(@types/node@26.2.0)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.12)(yaml@2.9.0)) fumadocs-ui: specifier: 16.15.4 - version: 16.15.4(@types/mdx@2.0.14)(@types/react-dom@19.2.4(@types/react@19.2.18))(@types/react@19.2.18)(fumadocs-core@16.15.4(@mdx-js/mdx@3.1.1)(@tanstack/react-router@1.170.8(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(@types/estree-jsx@1.0.5)(@types/hast@3.0.5)(@types/mdast@4.0.4)(@types/react@19.2.18)(lucide-react@1.43.0(react@19.2.8))(next@16.3.6(@babel/core@7.29.7)(@opentelemetry/api@1.9.1)(@playwright/test@1.62.1)(@types/node@26.2.0)(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react-dom@19.2.8(react@19.2.8))(react-router@7.18.2(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react@19.2.8)(zod@4.6.5))(next@16.3.6(@babel/core@7.29.7)(@opentelemetry/api@1.9.1)(@playwright/test@1.62.1)(@types/node@26.2.0)(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react-dom@19.2.8(react@19.2.8))(react@19.2.8)(tailwindcss@4.3.3) + version: 16.15.4(@types/mdx@2.0.14)(@types/react-dom@19.2.4(@types/react@19.2.18))(@types/react@19.2.18)(fumadocs-core@16.15.4(@mdx-js/mdx@3.1.1)(@tanstack/react-router@1.170.8(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(@types/estree-jsx@1.0.5)(@types/hast@3.0.5)(@types/mdast@4.0.4)(@types/react@19.2.18)(lucide-react@1.43.0(react@19.2.8))(next@16.3.6(@babel/core@7.29.7)(@opentelemetry/api@1.9.1)(@playwright/test@1.62.1)(@types/node@26.2.0)(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react-dom@19.2.8(react@19.2.8))(react-router@7.18.2(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react@19.2.8)(zod@4.6.7))(next@16.3.6(@babel/core@7.29.7)(@opentelemetry/api@1.9.1)(@playwright/test@1.62.1)(@types/node@26.2.0)(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react-dom@19.2.8(react@19.2.8))(react@19.2.8)(tailwindcss@4.3.3) lucide-react: specifier: ^1.43.0 version: 1.43.0(react@19.2.8) @@ -775,13 +775,13 @@ importers: version: link:../types '@objectstack/formula': specifier: ^18.0.0-next.1 - version: 18.0.0-next.1(ai@7.0.65(zod@4.6.5)) + version: 18.0.0-next.2(ai@7.0.65(zod@4.6.7)) '@objectstack/lint': specifier: ^18.0.0-next.1 - version: 18.0.0-next.1(ai@7.0.65(zod@4.6.5)) + version: 18.0.0-next.2(ai@7.0.65(zod@4.6.7)) '@objectstack/spec': - specifier: ^18.0.0-next.1 - version: 18.0.0-next.1(ai@7.0.65(zod@4.6.5)) + specifier: ^18.0.0-next.2 + version: 18.0.0-next.2(ai@7.0.65(zod@4.6.7)) '@sentry/react': specifier: ^10.70.0 version: 10.70.0(react@19.2.8) @@ -799,7 +799,7 @@ importers: version: 2.0.8(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) zod: specifier: ^4.6.1 - version: 4.6.5 + version: 4.6.7 devDependencies: '@object-ui/plugin-calendar': specifier: workspace:* @@ -872,7 +872,7 @@ importers: dependencies: '@objectstack/spec': specifier: ^18.0.0-next.1 - version: 18.0.0-next.1(ai@7.0.65(zod@4.6.5)) + version: 18.0.0-next.2(ai@7.0.65(zod@4.6.7)) better-auth: specifier: ^1.7.2 version: 1.7.2(@opentelemetry/api@1.9.1)(better-sqlite3@12.9.0)(mongodb@7.2.0(socks@2.8.9))(next@16.3.6(@babel/core@7.29.7)(@opentelemetry/api@1.9.1)(@playwright/test@1.62.1)(@types/node@26.2.0)(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react-dom@19.2.8(react@19.2.8))(react@19.2.8)(vitest@4.1.10) @@ -903,7 +903,7 @@ importers: version: link:../types '@objectstack/spec': specifier: ^18.0.0-next.1 - version: 18.0.0-next.1(ai@7.0.65(zod@4.6.5)) + version: 18.0.0-next.2(ai@7.0.65(zod@4.6.7)) '@tailwindcss/postcss': specifier: ^4.3.3 version: 4.3.3 @@ -971,7 +971,7 @@ importers: devDependencies: '@objectstack/spec': specifier: ^18.0.0-next.1 - version: 18.0.0-next.1(ai@7.0.65(zod@4.6.5)) + version: 18.0.0-next.2(ai@7.0.65(zod@4.6.7)) '@types/react': specifier: 19.2.18 version: 19.2.18 @@ -1007,7 +1007,7 @@ importers: version: link:../types '@objectstack/spec': specifier: ^18.0.0-next.1 - version: 18.0.0-next.1(ai@7.0.65(zod@4.6.5)) + version: 18.0.0-next.2(ai@7.0.65(zod@4.6.7)) '@radix-ui/react-accordion': specifier: ^1.2.20 version: 1.2.20(@types/react-dom@19.2.4(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) @@ -1182,7 +1182,7 @@ importers: version: 5.0.3(@microsoft/api-extractor@7.58.2(@types/node@26.2.0))(esbuild@0.28.2)(rolldown@1.2.7)(rollup@4.62.2)(typescript@6.0.3)(vite@8.2.2(@types/node@26.2.0)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.12)(yaml@2.9.0)) zod: specifier: ^4.4.3 - version: 4.6.5 + version: 4.6.7 packages/core: dependencies: @@ -1191,10 +1191,10 @@ importers: version: link:../types '@objectstack/formula': specifier: ^18.0.0-next.1 - version: 18.0.0-next.1(ai@7.0.65(zod@4.6.5)) + version: 18.0.0-next.2(ai@7.0.65(zod@4.6.7)) '@objectstack/spec': specifier: ^18.0.0-next.1 - version: 18.0.0-next.1(ai@7.0.65(zod@4.6.5)) + version: 18.0.0-next.2(ai@7.0.65(zod@4.6.7)) devDependencies: '@object-ui/test-support': specifier: workspace:* @@ -1250,10 +1250,10 @@ importers: version: link:../types '@objectstack/client': specifier: ^18.0.0-next.1 - version: 18.0.0-next.1(ai@7.0.65(zod@4.6.5)) + version: 18.0.0-next.2(ai@7.0.65(zod@4.6.7)) '@objectstack/spec': specifier: ^18.0.0-next.1 - version: 18.0.0-next.1(ai@7.0.65(zod@4.6.5)) + version: 18.0.0-next.2(ai@7.0.65(zod@4.6.7)) devDependencies: '@object-ui/test-support': specifier: workspace:* @@ -1293,7 +1293,7 @@ importers: version: link:../types '@objectstack/spec': specifier: ^18.0.0-next.1 - version: 18.0.0-next.1(ai@7.0.65(zod@4.6.5)) + version: 18.0.0-next.2(ai@7.0.65(zod@4.6.7)) lucide-react: specifier: ^1.43.0 version: 1.43.0(react@19.2.8) @@ -1397,7 +1397,7 @@ importers: version: link:../types '@objectstack/spec': specifier: ^18.0.0-next.1 - version: 18.0.0-next.1(ai@7.0.65(zod@4.6.5)) + version: 18.0.0-next.2(ai@7.0.65(zod@4.6.7)) lucide-react: specifier: ^1.43.0 version: 1.43.0(react@19.2.8) @@ -1438,7 +1438,7 @@ importers: devDependencies: '@objectstack/spec': specifier: ^18.0.0-next.1 - version: 18.0.0-next.1(ai@7.0.65(zod@4.6.5)) + version: 18.0.0-next.2(ai@7.0.65(zod@4.6.7)) '@types/react': specifier: 19.2.18 version: 19.2.18 @@ -1459,7 +1459,7 @@ importers: version: link:../types '@objectstack/spec': specifier: ^18.0.0-next.1 - version: 18.0.0-next.1(ai@7.0.65(zod@4.6.5)) + version: 18.0.0-next.2(ai@7.0.65(zod@4.6.7)) devDependencies: '@types/react': specifier: 19.2.18 @@ -1622,7 +1622,7 @@ importers: version: link:../test-support '@objectstack/spec': specifier: ^18.0.0-next.1 - version: 18.0.0-next.1(ai@7.0.65(zod@4.6.5)) + version: 18.0.0-next.2(ai@7.0.65(zod@4.6.7)) '@types/react': specifier: 19.2.18 version: 19.2.18 @@ -1646,7 +1646,7 @@ importers: dependencies: '@ai-sdk/react': specifier: ^4.0.68 - version: 4.0.68(react@19.2.8)(zod@4.6.5) + version: 4.0.68(react@19.2.8)(zod@4.6.7) '@object-ui/components': specifier: workspace:* version: link:../components @@ -1664,7 +1664,7 @@ importers: version: link:../types '@objectstack/spec': specifier: ^18.0.0-next.1 - version: 18.0.0-next.1(ai@7.0.65(zod@4.6.5)) + version: 18.0.0-next.2(ai@7.0.65(zod@4.6.7)) '@radix-ui/react-slot': specifier: ^1.3.3 version: 1.3.3(@types/react@19.2.18)(react@19.2.8) @@ -1673,7 +1673,7 @@ importers: version: 1.2.6(@types/react@19.2.18)(react@19.2.8) ai: specifier: ^7.0.65 - version: 7.0.65(zod@4.6.5) + version: 7.0.65(zod@4.6.7) class-variance-authority: specifier: ^0.7.1 version: 0.7.1 @@ -1755,7 +1755,7 @@ importers: version: link:../types '@objectstack/spec': specifier: ^18.0.0-next.1 - version: 18.0.0-next.1(ai@7.0.65(zod@4.6.5)) + version: 18.0.0-next.2(ai@7.0.65(zod@4.6.7)) lucide-react: specifier: ^1.43.0 version: 1.43.0(react@19.2.8) @@ -1825,7 +1825,7 @@ importers: version: link:../types '@objectstack/spec': specifier: ^18.0.0-next.1 - version: 18.0.0-next.1(ai@7.0.65(zod@4.6.5)) + version: 18.0.0-next.2(ai@7.0.65(zod@4.6.7)) clsx: specifier: ^2.1.1 version: 2.1.1 @@ -1877,7 +1877,7 @@ importers: version: link:../i18n '@objectstack/spec': specifier: ^18.0.0-next.1 - version: 18.0.0-next.1(ai@7.0.65(zod@4.6.5)) + version: 18.0.0-next.2(ai@7.0.65(zod@4.6.7)) lucide-react: specifier: ^1.43.0 version: 1.43.0(react@19.2.8) @@ -2002,7 +2002,7 @@ importers: version: link:../types '@objectstack/spec': specifier: ^18.0.0-next.1 - version: 18.0.0-next.1(ai@7.0.65(zod@4.6.5)) + version: 18.0.0-next.2(ai@7.0.65(zod@4.6.7)) lucide-react: specifier: ^1.43.0 version: 1.43.0(react@19.2.8) @@ -2063,7 +2063,7 @@ importers: version: link:../types '@objectstack/spec': specifier: ^18.0.0-next.1 - version: 18.0.0-next.1(ai@7.0.65(zod@4.6.5)) + version: 18.0.0-next.2(ai@7.0.65(zod@4.6.7)) lucide-react: specifier: ^1.43.0 version: 1.43.0(react@19.2.8) @@ -2133,7 +2133,7 @@ importers: version: link:../types '@objectstack/spec': specifier: ^18.0.0-next.1 - version: 18.0.0-next.1(ai@7.0.65(zod@4.6.5)) + version: 18.0.0-next.2(ai@7.0.65(zod@4.6.7)) '@tanstack/react-virtual': specifier: ^3.14.9 version: 3.14.9(react-dom@19.2.8(react@19.2.8))(react@19.2.8) @@ -2307,7 +2307,7 @@ importers: version: link:../types '@objectstack/spec': specifier: ^18.0.0-next.1 - version: 18.0.0-next.1(ai@7.0.65(zod@4.6.5)) + version: 18.0.0-next.2(ai@7.0.65(zod@4.6.7)) '@types/react': specifier: 19.2.18 version: 19.2.18 @@ -2484,7 +2484,7 @@ importers: version: link:../test-support '@objectstack/spec': specifier: ^18.0.0-next.1 - version: 18.0.0-next.1(ai@7.0.65(zod@4.6.5)) + version: 18.0.0-next.2(ai@7.0.65(zod@4.6.7)) '@types/node': specifier: ^26.2.0 version: 26.2.0 @@ -2532,7 +2532,7 @@ importers: version: link:../types '@objectstack/spec': specifier: ^18.0.0-next.1 - version: 18.0.0-next.1(ai@7.0.65(zod@4.6.5)) + version: 18.0.0-next.2(ai@7.0.65(zod@4.6.7)) class-variance-authority: specifier: ^0.7.1 version: 0.7.1 @@ -2544,7 +2544,7 @@ importers: version: 19.2.8(react@19.2.8) zod: specifier: ^4.4.3 - version: 4.6.5 + version: 4.6.7 devDependencies: '@object-ui/data-objectstack': specifier: workspace:* @@ -2602,7 +2602,7 @@ importers: version: link:../types '@objectstack/spec': specifier: ^18.0.0-next.1 - version: 18.0.0-next.1(ai@7.0.65(zod@4.6.5)) + version: 18.0.0-next.2(ai@7.0.65(zod@4.6.7)) lucide-react: specifier: ^1.43.0 version: 1.43.0(react@19.2.8) @@ -2675,7 +2675,7 @@ importers: version: link:../types '@objectstack/spec': specifier: ^18.0.0-next.1 - version: 18.0.0-next.1(ai@7.0.65(zod@4.6.5)) + version: 18.0.0-next.2(ai@7.0.65(zod@4.6.7)) class-variance-authority: specifier: ^0.7.1 version: 0.7.1 @@ -2740,7 +2740,7 @@ importers: version: link:../types '@objectstack/spec': specifier: ^18.0.0-next.1 - version: 18.0.0-next.1(ai@7.0.65(zod@4.6.5)) + version: 18.0.0-next.2(ai@7.0.65(zod@4.6.7)) react: specifier: 19.2.8 version: 19.2.8 @@ -2805,7 +2805,7 @@ importers: devDependencies: '@objectstack/spec': specifier: ^18.0.0-next.1 - version: 18.0.0-next.1(ai@7.0.65(zod@4.6.5)) + version: 18.0.0-next.2(ai@7.0.65(zod@4.6.7)) '@tailwindcss/postcss': specifier: ^4.3.3 version: 4.3.3 @@ -2847,13 +2847,13 @@ importers: version: link:../types '@objectstack/spec': specifier: ^18.0.0-next.1 - version: 18.0.0-next.1(ai@7.0.65(zod@4.6.5)) + version: 18.0.0-next.2(ai@7.0.65(zod@4.6.7)) packages/test-support: devDependencies: '@objectstack/spec': specifier: ^18.0.0-next.1 - version: 18.0.0-next.1(ai@7.0.65(zod@4.6.5)) + version: 18.0.0-next.2(ai@7.0.65(zod@4.6.7)) '@types/node': specifier: ^26.2.0 version: 26.2.0 @@ -2862,16 +2862,16 @@ importers: version: 6.0.3 zod: specifier: ^4.4.3 - version: 4.6.5 + version: 4.6.7 packages/types: dependencies: '@objectstack/spec': - specifier: ^18.0.0-next.1 - version: 18.0.0-next.1(ai@7.0.65(zod@4.6.5)) + specifier: ^18.0.0-next.2 + version: 18.0.0-next.2(ai@7.0.65(zod@4.6.7)) zod: specifier: ^4.6.1 - version: 4.6.5 + version: 4.6.7 devDependencies: '@object-ui/test-support': specifier: workspace:* @@ -4121,12 +4121,15 @@ packages: resolution: {integrity: sha512-qmqWa0Fx1xn3irQy8MyuAKUs8e3CdwMJOujaPkM8gx5v/V7RcLhTjBU0/uL2kdhmROpW+5WG1FD98O441kkvQQ==} hasBin: true - '@microsoft/tsdoc-config@0.18.1': - resolution: {integrity: sha512-9brPoVdfN9k9g0dcWkFeA7IH9bbcttzDJlXvkf8b2OBzd5MueR1V2wkKBL0abn0otvmkHJC6aapBOTJDDeMCZg==} + '@microsoft/tsdoc-config@0.18.3': + resolution: {integrity: sha512-0I0rGXo1eJziw3EEErkDS9p/0RzBcyOiV+zbSDqOZTeURmhtut+WIvpih0LM5g+ZpZ9SyFxDfkhAcl/r8e2zGw==} '@microsoft/tsdoc@0.16.0': resolution: {integrity: sha512-xgAyonlVVS+q7Vc7qLW0UrJU7rSFcETRWsqdXZtjzRU8dF+6CkozTK4V4y1LwOX7j8r/vHphjDeMeGI4tNGeGA==} + '@microsoft/tsdoc@0.17.1': + resolution: {integrity: sha512-VHyYyyoH63jFoO3shpw9Zfijk5v/9p/VrClW35z0/q6ooK7sSmxpzOkS4iZPxs3vO4XtBW4H38HRAKkAMIK7DA==} + '@modelcontextprotocol/sdk@1.30.0': resolution: {integrity: sha512-xKd8OIzlqNzcqcNumGAa6g+PW2kjD5vrpcKOnfldAUPP3j7lnqMPwlTXQm8gF+UwH72z0lqaRbjr9hqGz0eITA==} engines: {node: '>=18'} @@ -4147,8 +4150,8 @@ packages: react: 19.2.8 react-dom: 19.2.8 - '@mongodb-js/saslprep@1.5.2': - resolution: {integrity: sha512-UBvCBdPHAmiiDNEpD2ORBGzna4qYr06fLELfGDPW3/KZ9uLK+cGT9npAc/x/6/8SLzdbILMuc3HWFQ0FvJMhCw==} + '@mongodb-js/saslprep@1.6.1': + resolution: {integrity: sha512-D4CQtk9IwjCLAvCf1xvHEod3960q8XMUzfmdRU9qjUNlHnesGuTOvJcOTaPm9koZ1caUKA2aTbszZiAkcmSgmg==} '@mswjs/interceptors@0.41.9': resolution: {integrity: sha512-VVPPgHyQ6ShqnrmDWuxjmUIsO9gWyOZFmuOfLd9LfBGQJwZfy0gvv9pbHSJuoFNIYC7ZDX9aoFwowjcdSC4E8w==} @@ -4229,26 +4232,26 @@ packages: resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} engines: {node: '>= 8'} - '@objectstack/client@18.0.0-next.1': - resolution: {integrity: sha512-3KlwtJUTV7yrtWeTqs/z19iWURmoKd5smuOY/KN7a82Ffll3GDliju25Nh6JOdF4UmuJtfaoblygflS/U+tgpw==} + '@objectstack/client@18.0.0-next.2': + resolution: {integrity: sha512-17d28OcMqU0QkauexCzOtR6O8kRuiUm2iVo/M1gn8iIZ4+K4JMzt69szVE4Se1IQ6EBoJZ+pWOf/xgt1efF0gA==} engines: {node: '>=22.0.0'} - '@objectstack/core@18.0.0-next.1': - resolution: {integrity: sha512-+d+tGi0lWeIMC3TjI6leyDYt3uVlpthifwjsgXMWl1jjMNdD8Pw3Uc2Q7QipmrVXj3CcINKEH0cri5SCYIeNPw==} + '@objectstack/core@18.0.0-next.2': + resolution: {integrity: sha512-K5ZnDtUGt7UrY6ZS9UVI1okcYaiVDTdxj7I7Hw5wznFqThlZmREFETWIHr1OGnIiRElInB9bsjteVBfC+zUh5w==} engines: {node: '>=22.0.0'} - '@objectstack/formula@18.0.0-next.1': - resolution: {integrity: sha512-acgpTRlVuRkNHyVr+gaaKK9AhNhihyFM658qiYxMxZy0ynWHbOMTjJq6/3X18HSsWbgdAc68OILu3QJcf8Rr2g==} + '@objectstack/formula@18.0.0-next.2': + resolution: {integrity: sha512-zbrGzFNfn4+cjuCkpzRukEIniKuAaRaQGpoIa055uzBk0k/7Wn01gclC02rmFSTuwTyhvTshijkQBVYd8Y1grw==} - '@objectstack/lint@18.0.0-next.1': - resolution: {integrity: sha512-/Ae71Tv3Nfk3xzBKMwZdGt89e32lI0+rnqHKWjuO5ZlcCvpZLIA3qPEvydwrsQV7ep7iYEjVG35cthgD/YbafQ==} + '@objectstack/lint@18.0.0-next.2': + resolution: {integrity: sha512-Gx7YTMnw6YVtWtH2ISNNNd696WhoegBIUYmc25w7bxJ3voswRwcovEOXFt22SW9RzRolARkNhPsJU/Pz2c4Egg==} engines: {node: '>=22.0.0'} - '@objectstack/sdui-parser@18.0.0-next.1': - resolution: {integrity: sha512-Jc6brfLZjz3dFss3G4Qu0jTCASIKipCUM13I5v+/Tw/cClqMbFntkudbaDEbo588+WOnqf3gLtuvghabK3/kNA==} + '@objectstack/sdui-parser@18.0.0-next.2': + resolution: {integrity: sha512-D1TvInAAcdIVmDDeHdQhe+FWbFNIsJp05sC1qoKrUKhgYQCDrg/O14w1wqAyl2aqubd7STSxx9iBPzUurlVZEA==} - '@objectstack/spec@18.0.0-next.1': - resolution: {integrity: sha512-pDNzwgJz1/SzVr1K7WGA3kDIR/rBVrA/K8UpVIw2P4SWJ1ONdxVy/K3+IZzl2MC3/+ye1ChePbQFw9i4gvAhFg==} + '@objectstack/spec@18.0.0-next.2': + resolution: {integrity: sha512-cOENas5Zq1Vlum3AhiJVhoWRfZyJkcW2nhB3TuL+Ic5psP02DrWz4vEEqD12Ngp0wrcADCCuKFiIzXHoZ4qb0A==} engines: {node: '>=22.0.0'} peerDependencies: ai: ^7.0.0 @@ -4256,8 +4259,8 @@ packages: ai: optional: true - '@objectstack/types@18.0.0-next.1': - resolution: {integrity: sha512-Mjulyi0JgLMT16Qf014sK6L/QufOzfQZe7yjVFHyiO9umDDCMA59s2hA4GsYdbOSNyS/YV2WBi3NAupjSX84NA==} + '@objectstack/types@18.0.0-next.2': + resolution: {integrity: sha512-ScT2JGBHqOElmFLKC9aj4t6oSa9BBYdgqznar6YQY31vMahivILGF6ZHBCyRz4EBGa2lXyFbY9MjKeaVJ4Cy0w==} engines: {node: '>=22.0.0'} '@open-draft/deferred-promise@2.2.0': @@ -6492,8 +6495,8 @@ packages: brace-expansion@2.1.4: resolution: {integrity: sha512-hGfVzPxthbf3+2yjg/RBs60cB0FhqBS/zvdV/4wn4/BmN0bNMMHPc4V/BbFieqf1TKAGGAHnY4eSjajCl0f2Xg==} - brace-expansion@5.0.9: - resolution: {integrity: sha512-ScQ4IuvIEF1TMlP7Zt+vjJ//9zlPb2SDcxWxM3bk8s6t6GGdJ7KO1dCcTidOPJKePW30LE/2cT7wCyPho9/Wxg==} + brace-expansion@5.0.12: + resolution: {integrity: sha512-YovQ3rzhaLMIrDjNDMkNS01tea93qhEhG5xy8f6+R0l+dw3Ki+5sCoIoI942iuLZTHWogWktgwVDhU09iNEimQ==} engines: {node: 20 || >=22} braces@3.0.3: @@ -6505,8 +6508,8 @@ packages: engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true - bson@7.3.2: - resolution: {integrity: sha512-1w0ra+ho1cuE+w8jzwgzTFIimFtCfZeCoOsvIPQg6uyFCsp8M29U7bNNf5GrFh88TXbYg1g3TyKUGpd6O7q6zA==} + bson@7.3.3: + resolution: {integrity: sha512-oz3LwE3qGEhTCSyhzQRLY3Bj1NLOsjFMf6tcmY5J8M+3R7EVcmoBfSHWvjUK3yXCLDUsGpIuB3aQL4nDZ1EV/g==} engines: {node: '>=20.19.0'} buffer-crc32@0.2.13: @@ -7144,8 +7147,8 @@ packages: resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} engines: {node: '>= 4'} - dompurify@3.4.15: - resolution: {integrity: sha512-EUBjM+B+lkDE41iE82DDSCfkoPGfXx8IxFxPMjNzm/Uk4xDet77rTN9wqlxlVg71kK7XGuUMv6wUxJUwwv+Xyw==} + dompurify@3.4.17: + resolution: {integrity: sha512-B/pSlYVHQ58kqISD/yDjuJ1yfzI34m1gF4lAod2bwSRhiN4K5Cl3H8Af7hqB2PmTL911tdEudnnXn5FnhRoz0w==} domutils@3.2.2: resolution: {integrity: sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==} @@ -7472,8 +7475,8 @@ packages: fast-string-width@3.0.2: resolution: {integrity: sha512-gX8LrtNEI5hq8DVUfRQMbr5lpaS4nMIWV+7XEbXk2b8kiQIizgnlr12B4dA3ZEx3308ze0O4Q1R+cHts8kyUJg==} - fast-uri@3.1.7: - resolution: {integrity: sha512-dOvZVzjdZdz7phd9v6jCbwxrBW3fK6n8Rc0CtdmM4bumzMnxywBYhuph6J819RRw/ku+rLbelwfMunktuzVVHg==} + fast-uri@3.1.8: + resolution: {integrity: sha512-GZMtZUTNRpOVIECoXwLNZS5xUGE+mVNbTB8h/7Rwh2TFWcBQiPzTgyZi05BF9UMZKkLJv8XBRJTlU7zg8+ZfMg==} fast-wrap-ansi@0.2.2: resolution: {integrity: sha512-7F2Fl+TjRSenLqlU3UjSH0iyqopqoZIu7eZVpEirP2g1GtWa2G/ecEmBdgz31+Mxr+ELclgg6sokpSFIQiZ02Q==} @@ -8055,8 +8058,8 @@ packages: is-arrayish@0.2.1: resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} - is-core-module@2.16.2: - resolution: {integrity: sha512-evOr8xfXKxE6qSR0hSXL2r3sd7ALj8+7jQEUvPYcm5sgZFdJ+AYzT6yNmJenvIYQBgIGwfwz08sL8zoL7yq2BA==} + is-core-module@2.17.0: + resolution: {integrity: sha512-J/vG0zBCbIKOQFfufSwyXdMrsohyJIUNkrnmo6WZGzoM7tr/lsbfW5b2BvisL6zsyMzK9UxV9L6c7AoFbyXHOA==} engines: {node: '>= 0.4'} is-decimal@2.0.1: @@ -9819,8 +9822,8 @@ packages: resolve-protobuf-schema@2.1.0: resolution: {integrity: sha512-kI5ffTiZWmJaS/huM8wZfEMer1eRd7oJQhDuxeCLe3t7N7mX3z94CN0xPxBQxFYQTSNz9T0i+v6inKqSdK8xrQ==} - resolve@1.22.12: - resolution: {integrity: sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA==} + resolve@1.22.13: + resolution: {integrity: sha512-Dj/cW9zBV2aRj6XzCxuGIs3ESZKv02jixne3q6jFZYZ3/Tg09gHHviSMDL4kObh9pqSahdRHEnDoaP2gn8YLhA==} engines: {node: '>= 0.4'} hasBin: true @@ -9947,14 +9950,14 @@ packages: resolution: {integrity: sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==} engines: {node: '>= 18'} - seroval-plugins@1.6.7: - resolution: {integrity: sha512-4Nk35ttD3DTDJW4hgw5StsVAPeU6qnDFnULAouw6tQ7oLTV/ICXrWpsXo2EE52eSP2joUMazbVf52mFEcADqRw==} + seroval-plugins@1.6.9: + resolution: {integrity: sha512-kiDK/Tb8IWZ61WEU8pA2PDmAuw37gKph9Y77OZlD56mg0Y2g0Bg7gZ1HeHhs5d40w+nRoUq/wj08V26ilbez9g==} engines: {node: '>=10'} peerDependencies: seroval: ^1.0 - seroval@1.6.7: - resolution: {integrity: sha512-AeDcLh0yO2SFm9W71essgnSzLV9DI8ZH0x0knXn2DMnUZj728mpLbxjlbB6IqKCmqh8JA3cEqRyGoNkt584JcQ==} + seroval@1.6.9: + resolution: {integrity: sha512-UeEzHwAK+yl0YLbsvROV1t5yMYEwZZ0CfKYxDvUgS2fO9Vxdf8djqVIB+OuVpuawRNPqw68LE1Du/GMsW2ZPqA==} engines: {node: '>=10'} serve-static@1.16.3: @@ -10670,8 +10673,8 @@ packages: peerDependencies: react: 19.2.8 - use-sync-external-store@1.6.0: - resolution: {integrity: sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==} + use-sync-external-store@1.7.0: + resolution: {integrity: sha512-6L+EeigHMQhdaIPNIFUKwfWJSwWFQ8gJbJ2DLOs5sDIegTwR9fRxvnM3uciHKjIZhFz+KAv2emhWMRvDmMcY8A==} peerDependencies: react: 19.2.8 @@ -11041,8 +11044,8 @@ packages: zod@3.25.76: resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==} - zod@4.6.5: - resolution: {integrity: sha512-v5l/aFXZQeai4awLbOpSoHecE9UiMrnfx75tEXLjNonXVARxQ5mOeipTjROUchszUNCqnE+hqAMujRsRHsut2Q==} + zod@4.6.7: + resolution: {integrity: sha512-g8W2D2kU6a8untc053fX1uVBKzM7yqAxW/3zwk83+6RyF2+SKOuV+c0wBDhUwzV1PaGapmZH+rmcUzPf+3CGwg==} zwitch@2.0.4: resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} @@ -11051,39 +11054,39 @@ snapshots: '@adobe/css-tools@4.5.0': {} - '@ai-sdk/gateway@4.0.52(zod@4.6.5)': + '@ai-sdk/gateway@4.0.52(zod@4.6.7)': dependencies: '@ai-sdk/provider': 4.0.7 - '@ai-sdk/provider-utils': 5.0.27(zod@4.6.5) + '@ai-sdk/provider-utils': 5.0.27(zod@4.6.7) '@vercel/oidc': 3.2.0 - zod: 4.6.5 + zod: 4.6.7 - '@ai-sdk/mcp@2.0.31(zod@4.6.5)': + '@ai-sdk/mcp@2.0.31(zod@4.6.7)': dependencies: '@ai-sdk/provider': 4.0.7 - '@ai-sdk/provider-utils': 5.0.27(zod@4.6.5) + '@ai-sdk/provider-utils': 5.0.27(zod@4.6.7) pkce-challenge: 5.0.1 - zod: 4.6.5 + zod: 4.6.7 - '@ai-sdk/provider-utils@5.0.27(zod@4.6.5)': + '@ai-sdk/provider-utils@5.0.27(zod@4.6.7)': dependencies: '@ai-sdk/provider': 4.0.7 '@standard-schema/spec': 1.1.0 '@workflow/serde': 4.1.0 eventsource-parser: 3.1.1 undici: 7.29.0 - zod: 4.6.5 + zod: 4.6.7 '@ai-sdk/provider@4.0.7': dependencies: json-schema: 0.4.0 - '@ai-sdk/react@4.0.68(react@19.2.8)(zod@4.6.5)': + '@ai-sdk/react@4.0.68(react@19.2.8)(zod@4.6.7)': dependencies: - '@ai-sdk/mcp': 2.0.31(zod@4.6.5) + '@ai-sdk/mcp': 2.0.31(zod@4.6.7) '@ai-sdk/provider': 4.0.7 - '@ai-sdk/provider-utils': 5.0.27(zod@4.6.5) - ai: 7.0.65(zod@4.6.5) + '@ai-sdk/provider-utils': 5.0.27(zod@4.6.7) + ai: 7.0.65(zod@4.6.7) react: 19.2.8 swr: 2.5.1(react@19.2.8) throttleit: 2.1.0 @@ -11395,52 +11398,52 @@ snapshots: '@bcoe/v8-coverage@1.0.2': {} - '@better-auth/core@1.7.2(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.5))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.0)': + '@better-auth/core@1.7.2(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.7))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.0)': dependencies: '@better-auth/utils': 0.4.2 '@better-fetch/fetch': 1.3.1 '@opentelemetry/semantic-conventions': 1.43.0 '@standard-schema/spec': 1.1.0 - better-call: 1.4.0(zod@4.6.5) + better-call: 1.4.0(zod@4.6.7) jose: 6.2.9 kysely: 0.29.5 nanostores: 1.5.0 - zod: 4.6.5 + zod: 4.6.7 optionalDependencies: '@opentelemetry/api': 1.9.1 - '@better-auth/drizzle-adapter@1.7.2(@better-auth/core@1.7.2(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.5))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.0))(@better-auth/utils@0.4.2)': + '@better-auth/drizzle-adapter@1.7.2(@better-auth/core@1.7.2(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.7))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.0))(@better-auth/utils@0.4.2)': dependencies: - '@better-auth/core': 1.7.2(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.5))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.0) + '@better-auth/core': 1.7.2(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.7))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.0) '@better-auth/utils': 0.4.2 - '@better-auth/kysely-adapter@1.7.2(@better-auth/core@1.7.2(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.5))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.0))(@better-auth/utils@0.4.2)(kysely@0.29.5)': + '@better-auth/kysely-adapter@1.7.2(@better-auth/core@1.7.2(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.7))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.0))(@better-auth/utils@0.4.2)(kysely@0.29.5)': dependencies: - '@better-auth/core': 1.7.2(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.5))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.0) + '@better-auth/core': 1.7.2(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.7))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.0) '@better-auth/utils': 0.4.2 optionalDependencies: kysely: 0.29.5 - '@better-auth/memory-adapter@1.7.2(@better-auth/core@1.7.2(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.5))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.0))(@better-auth/utils@0.4.2)': + '@better-auth/memory-adapter@1.7.2(@better-auth/core@1.7.2(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.7))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.0))(@better-auth/utils@0.4.2)': dependencies: - '@better-auth/core': 1.7.2(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.5))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.0) + '@better-auth/core': 1.7.2(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.7))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.0) '@better-auth/utils': 0.4.2 - '@better-auth/mongo-adapter@1.7.2(@better-auth/core@1.7.2(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.5))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.0))(@better-auth/utils@0.4.2)(mongodb@7.2.0(socks@2.8.9))': + '@better-auth/mongo-adapter@1.7.2(@better-auth/core@1.7.2(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.7))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.0))(@better-auth/utils@0.4.2)(mongodb@7.2.0(socks@2.8.9))': dependencies: - '@better-auth/core': 1.7.2(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.5))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.0) + '@better-auth/core': 1.7.2(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.7))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.0) '@better-auth/utils': 0.4.2 optionalDependencies: mongodb: 7.2.0(socks@2.8.9) - '@better-auth/prisma-adapter@1.7.2(@better-auth/core@1.7.2(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.5))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.0))(@better-auth/utils@0.4.2)': + '@better-auth/prisma-adapter@1.7.2(@better-auth/core@1.7.2(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.7))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.0))(@better-auth/utils@0.4.2)': dependencies: - '@better-auth/core': 1.7.2(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.5))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.0) + '@better-auth/core': 1.7.2(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.7))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.0) '@better-auth/utils': 0.4.2 - '@better-auth/telemetry@1.7.2(@better-auth/core@1.7.2(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.5))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.0))(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)': + '@better-auth/telemetry@1.7.2(@better-auth/core@1.7.2(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.7))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.0))(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)': dependencies: - '@better-auth/core': 1.7.2(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.5))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.0) + '@better-auth/core': 1.7.2(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.7))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.0) '@better-auth/utils': 0.4.2 '@better-fetch/fetch': 1.3.1 @@ -12205,7 +12208,7 @@ snapshots: '@microsoft/api-extractor-model@7.33.6(@types/node@26.2.0)': dependencies: '@microsoft/tsdoc': 0.16.0 - '@microsoft/tsdoc-config': 0.18.1 + '@microsoft/tsdoc-config': 0.18.3 '@rushstack/node-core-library': 5.22.0(@types/node@26.2.0) transitivePeerDependencies: - '@types/node' @@ -12215,7 +12218,7 @@ snapshots: dependencies: '@microsoft/api-extractor-model': 7.33.6(@types/node@26.2.0) '@microsoft/tsdoc': 0.16.0 - '@microsoft/tsdoc-config': 0.18.1 + '@microsoft/tsdoc-config': 0.18.3 '@rushstack/node-core-library': 5.22.0(@types/node@26.2.0) '@rushstack/rig-package': 0.7.2 '@rushstack/terminal': 0.22.5(@types/node@26.2.0) @@ -12223,7 +12226,7 @@ snapshots: diff: 8.0.4 lodash: 4.18.1 minimatch: 10.2.3 - resolve: 1.22.12 + resolve: 1.22.13 semver: 7.5.4 source-map: 0.6.1 typescript: 5.9.3 @@ -12231,17 +12234,20 @@ snapshots: - '@types/node' optional: true - '@microsoft/tsdoc-config@0.18.1': + '@microsoft/tsdoc-config@0.18.3': dependencies: - '@microsoft/tsdoc': 0.16.0 + '@microsoft/tsdoc': 0.17.1 ajv: 8.18.0 jju: 1.4.0 - resolve: 1.22.12 + resolve: 1.22.13 optional: true '@microsoft/tsdoc@0.16.0': optional: true + '@microsoft/tsdoc@0.17.1': + optional: true + '@modelcontextprotocol/sdk@1.30.0(zod@3.25.76)': dependencies: '@hono/node-server': 2.1.1(hono@4.13.2) @@ -12275,7 +12281,7 @@ snapshots: react: 19.2.8 react-dom: 19.2.8(react@19.2.8) - '@mongodb-js/saslprep@1.5.2': + '@mongodb-js/saslprep@1.6.1': dependencies: sparse-bitfield: 3.0.3 optional: true @@ -12331,33 +12337,33 @@ snapshots: '@nodelib/fs.scandir': 2.1.5 fastq: 1.20.1 - '@objectstack/client@18.0.0-next.1(ai@7.0.65(zod@4.6.5))': + '@objectstack/client@18.0.0-next.2(ai@7.0.65(zod@4.6.7))': dependencies: - '@objectstack/core': 18.0.0-next.1(ai@7.0.65(zod@4.6.5)) - '@objectstack/spec': 18.0.0-next.1(ai@7.0.65(zod@4.6.5)) + '@objectstack/core': 18.0.0-next.2(ai@7.0.65(zod@4.6.7)) + '@objectstack/spec': 18.0.0-next.2(ai@7.0.65(zod@4.6.7)) transitivePeerDependencies: - ai - '@objectstack/core@18.0.0-next.1(ai@7.0.65(zod@4.6.5))': + '@objectstack/core@18.0.0-next.2(ai@7.0.65(zod@4.6.7))': dependencies: - '@objectstack/spec': 18.0.0-next.1(ai@7.0.65(zod@4.6.5)) - '@objectstack/types': 18.0.0-next.1(ai@7.0.65(zod@4.6.5)) - zod: 4.6.5 + '@objectstack/spec': 18.0.0-next.2(ai@7.0.65(zod@4.6.7)) + '@objectstack/types': 18.0.0-next.2(ai@7.0.65(zod@4.6.7)) + zod: 4.6.7 transitivePeerDependencies: - ai - '@objectstack/formula@18.0.0-next.1(ai@7.0.65(zod@4.6.5))': + '@objectstack/formula@18.0.0-next.2(ai@7.0.65(zod@4.6.7))': dependencies: '@marcbachmann/cel-js': 8.0.0 - '@objectstack/spec': 18.0.0-next.1(ai@7.0.65(zod@4.6.5)) + '@objectstack/spec': 18.0.0-next.2(ai@7.0.65(zod@4.6.7)) transitivePeerDependencies: - ai - '@objectstack/lint@18.0.0-next.1(ai@7.0.65(zod@4.6.5))': + '@objectstack/lint@18.0.0-next.2(ai@7.0.65(zod@4.6.7))': dependencies: - '@objectstack/formula': 18.0.0-next.1(ai@7.0.65(zod@4.6.5)) - '@objectstack/sdui-parser': 18.0.0-next.1 - '@objectstack/spec': 18.0.0-next.1(ai@7.0.65(zod@4.6.5)) + '@objectstack/formula': 18.0.0-next.2(ai@7.0.65(zod@4.6.7)) + '@objectstack/sdui-parser': 18.0.0-next.2 + '@objectstack/spec': 18.0.0-next.2(ai@7.0.65(zod@4.6.7)) ajv: 8.20.0 ajv-formats: 3.0.1(ajv@8.20.0) sucrase: 3.35.1 @@ -12365,18 +12371,18 @@ snapshots: transitivePeerDependencies: - ai - '@objectstack/sdui-parser@18.0.0-next.1': {} + '@objectstack/sdui-parser@18.0.0-next.2': {} - '@objectstack/spec@18.0.0-next.1(ai@7.0.65(zod@4.6.5))': + '@objectstack/spec@18.0.0-next.2(ai@7.0.65(zod@4.6.7))': dependencies: pg-connection-string: 2.14.0 - zod: 4.6.5 + zod: 4.6.7 optionalDependencies: - ai: 7.0.65(zod@4.6.5) + ai: 7.0.65(zod@4.6.7) - '@objectstack/types@18.0.0-next.1(ai@7.0.65(zod@4.6.5))': + '@objectstack/types@18.0.0-next.2(ai@7.0.65(zod@4.6.7))': dependencies: - '@objectstack/spec': 18.0.0-next.1(ai@7.0.65(zod@4.6.5)) + '@objectstack/spec': 18.0.0-next.2(ai@7.0.65(zod@4.6.7)) transitivePeerDependencies: - ai @@ -13202,7 +13208,7 @@ snapshots: fs-extra: 11.3.6 import-lazy: 4.0.0 jju: 1.4.0 - resolve: 1.22.12 + resolve: 1.22.13 semver: 7.5.4 optionalDependencies: '@types/node': 26.2.0 @@ -13215,7 +13221,7 @@ snapshots: '@rushstack/rig-package@0.7.2': dependencies: - resolve: 1.22.12 + resolve: 1.22.13 strip-json-comments: 3.1.1 optional: true @@ -13581,7 +13587,7 @@ snapshots: '@tanstack/store': 0.9.3 react: 19.2.8 react-dom: 19.2.8(react@19.2.8) - use-sync-external-store: 1.6.0(react@19.2.8) + use-sync-external-store: 1.7.0(react@19.2.8) optional: true '@tanstack/react-virtual@3.14.9(react-dom@19.2.8(react@19.2.8))(react@19.2.8)': @@ -13594,8 +13600,8 @@ snapshots: dependencies: '@tanstack/history': 1.162.0 cookie-es: 3.1.1 - seroval: 1.6.7 - seroval-plugins: 1.6.7(seroval@1.6.7) + seroval: 1.6.9 + seroval-plugins: 1.6.9(seroval@1.6.9) optional: true '@tanstack/store@0.9.3': @@ -14336,12 +14342,12 @@ snapshots: agent-base@7.1.4: {} - ai@7.0.65(zod@4.6.5): + ai@7.0.65(zod@4.6.7): dependencies: - '@ai-sdk/gateway': 4.0.52(zod@4.6.5) + '@ai-sdk/gateway': 4.0.52(zod@4.6.7) '@ai-sdk/provider': 4.0.7 - '@ai-sdk/provider-utils': 5.0.27(zod@4.6.5) - zod: 4.6.5 + '@ai-sdk/provider-utils': 5.0.27(zod@4.6.7) + zod: 4.6.7 ajv-draft-04@1.0.0(ajv@8.18.0): optionalDependencies: @@ -14371,7 +14377,7 @@ snapshots: ajv@8.18.0: dependencies: fast-deep-equal: 3.1.3 - fast-uri: 3.1.7 + fast-uri: 3.1.8 json-schema-traverse: 1.0.0 require-from-string: 2.0.2 optional: true @@ -14379,7 +14385,7 @@ snapshots: ajv@8.20.0: dependencies: fast-deep-equal: 3.1.3 - fast-uri: 3.1.7 + fast-uri: 3.1.8 json-schema-traverse: 1.0.0 require-from-string: 2.0.2 @@ -14522,23 +14528,23 @@ snapshots: better-auth@1.7.2(@opentelemetry/api@1.9.1)(better-sqlite3@12.9.0)(mongodb@7.2.0(socks@2.8.9))(next@16.3.6(@babel/core@7.29.7)(@opentelemetry/api@1.9.1)(@playwright/test@1.62.1)(@types/node@26.2.0)(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react-dom@19.2.8(react@19.2.8))(react@19.2.8)(vitest@4.1.10): dependencies: - '@better-auth/core': 1.7.2(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.5))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.0) - '@better-auth/drizzle-adapter': 1.7.2(@better-auth/core@1.7.2(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.5))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.0))(@better-auth/utils@0.4.2) - '@better-auth/kysely-adapter': 1.7.2(@better-auth/core@1.7.2(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.5))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.0))(@better-auth/utils@0.4.2)(kysely@0.29.5) - '@better-auth/memory-adapter': 1.7.2(@better-auth/core@1.7.2(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.5))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.0))(@better-auth/utils@0.4.2) - '@better-auth/mongo-adapter': 1.7.2(@better-auth/core@1.7.2(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.5))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.0))(@better-auth/utils@0.4.2)(mongodb@7.2.0(socks@2.8.9)) - '@better-auth/prisma-adapter': 1.7.2(@better-auth/core@1.7.2(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.5))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.0))(@better-auth/utils@0.4.2) - '@better-auth/telemetry': 1.7.2(@better-auth/core@1.7.2(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.5))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.0))(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1) + '@better-auth/core': 1.7.2(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.7))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.0) + '@better-auth/drizzle-adapter': 1.7.2(@better-auth/core@1.7.2(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.7))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.0))(@better-auth/utils@0.4.2) + '@better-auth/kysely-adapter': 1.7.2(@better-auth/core@1.7.2(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.7))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.0))(@better-auth/utils@0.4.2)(kysely@0.29.5) + '@better-auth/memory-adapter': 1.7.2(@better-auth/core@1.7.2(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.7))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.0))(@better-auth/utils@0.4.2) + '@better-auth/mongo-adapter': 1.7.2(@better-auth/core@1.7.2(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.7))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.0))(@better-auth/utils@0.4.2)(mongodb@7.2.0(socks@2.8.9)) + '@better-auth/prisma-adapter': 1.7.2(@better-auth/core@1.7.2(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.7))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.0))(@better-auth/utils@0.4.2) + '@better-auth/telemetry': 1.7.2(@better-auth/core@1.7.2(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.7))(jose@6.2.9)(kysely@0.29.5)(nanostores@1.5.0))(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1) '@better-auth/utils': 0.4.2 '@better-fetch/fetch': 1.3.1 '@noble/ciphers': 2.3.0 '@noble/hashes': 2.3.0 - better-call: 1.4.0(zod@4.6.5) + better-call: 1.4.0(zod@4.6.7) defu: 6.1.7 jose: 6.2.9 kysely: 0.29.5 nanostores: 1.5.0 - zod: 4.6.5 + zod: 4.6.7 optionalDependencies: better-sqlite3: 12.9.0 mongodb: 7.2.0(socks@2.8.9) @@ -14550,14 +14556,14 @@ snapshots: - '@cloudflare/workers-types' - '@opentelemetry/api' - better-call@1.4.0(zod@4.6.5): + better-call@1.4.0(zod@4.6.7): dependencies: '@better-auth/utils': 0.5.0 '@better-fetch/fetch': 1.3.1 rou3: 0.9.2 set-cookie-parser: 3.1.2 optionalDependencies: - zod: 4.6.5 + zod: 4.6.7 better-sqlite3@12.9.0: dependencies: @@ -14637,7 +14643,7 @@ snapshots: dependencies: balanced-match: 1.0.2 - brace-expansion@5.0.9: + brace-expansion@5.0.12: dependencies: balanced-match: 4.0.4 @@ -14653,7 +14659,7 @@ snapshots: node-releases: 2.0.53 update-browserslist-db: 1.3.1(browserslist@4.28.8) - bson@7.3.2: + bson@7.3.3: optional: true buffer-crc32@0.2.13: {} @@ -15258,7 +15264,7 @@ snapshots: dependencies: domelementtype: 2.3.0 - dompurify@3.4.15: + dompurify@3.4.17: optionalDependencies: '@types/trusted-types': 2.0.7 @@ -15456,8 +15462,8 @@ snapshots: '@babel/parser': 7.29.8 eslint: 10.8.1(jiti@2.7.0) hermes-parser: 0.25.1 - zod: 4.6.5 - zod-validation-error: 4.0.2(zod@4.6.5) + zod: 4.6.7 + zod-validation-error: 4.0.2(zod@4.6.7) transitivePeerDependencies: - supports-color @@ -15751,7 +15757,7 @@ snapshots: dependencies: fast-string-truncated-width: 3.0.3 - fast-uri@3.1.7: {} + fast-uri@3.1.8: {} fast-wrap-ansi@0.2.2: dependencies: @@ -15893,7 +15899,7 @@ snapshots: mkdirp: 0.5.6 rimraf: 2.7.1 - fumadocs-core@16.15.4(@mdx-js/mdx@3.1.1)(@tanstack/react-router@1.170.8(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(@types/estree-jsx@1.0.5)(@types/hast@3.0.5)(@types/mdast@4.0.4)(@types/react@19.2.18)(lucide-react@1.43.0(react@19.2.8))(next@16.3.6(@babel/core@7.29.7)(@opentelemetry/api@1.9.1)(@playwright/test@1.62.1)(@types/node@26.2.0)(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react-dom@19.2.8(react@19.2.8))(react-router@7.18.2(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react@19.2.8)(zod@4.6.5): + fumadocs-core@16.15.4(@mdx-js/mdx@3.1.1)(@tanstack/react-router@1.170.8(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(@types/estree-jsx@1.0.5)(@types/hast@3.0.5)(@types/mdast@4.0.4)(@types/react@19.2.18)(lucide-react@1.43.0(react@19.2.8))(next@16.3.6(@babel/core@7.29.7)(@opentelemetry/api@1.9.1)(@playwright/test@1.62.1)(@types/node@26.2.0)(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react-dom@19.2.8(react@19.2.8))(react-router@7.18.2(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react@19.2.8)(zod@4.6.7): dependencies: '@fumari/image-size': 0.1.0 estree-util-value-to-estree: 3.5.0 @@ -15926,18 +15932,18 @@ snapshots: react: 19.2.8 react-dom: 19.2.8(react@19.2.8) react-router: 7.18.2(react-dom@19.2.8(react@19.2.8))(react@19.2.8) - zod: 4.6.5 + zod: 4.6.7 transitivePeerDependencies: - supports-color - fumadocs-mdx@15.2.3(@types/mdast@4.0.4)(@types/mdx@2.0.14)(@types/react@19.2.18)(fumadocs-core@16.15.4(@mdx-js/mdx@3.1.1)(@tanstack/react-router@1.170.8(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(@types/estree-jsx@1.0.5)(@types/hast@3.0.5)(@types/mdast@4.0.4)(@types/react@19.2.18)(lucide-react@1.43.0(react@19.2.8))(next@16.3.6(@babel/core@7.29.7)(@opentelemetry/api@1.9.1)(@playwright/test@1.62.1)(@types/node@26.2.0)(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react-dom@19.2.8(react@19.2.8))(react-router@7.18.2(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react@19.2.8)(zod@4.6.5))(next@16.3.6(@babel/core@7.29.7)(@opentelemetry/api@1.9.1)(@playwright/test@1.62.1)(@types/node@26.2.0)(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react@19.2.8)(rolldown@1.2.7)(vite@8.2.2(@types/node@26.2.0)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.12)(yaml@2.9.0)): + fumadocs-mdx@15.2.3(@types/mdast@4.0.4)(@types/mdx@2.0.14)(@types/react@19.2.18)(fumadocs-core@16.15.4(@mdx-js/mdx@3.1.1)(@tanstack/react-router@1.170.8(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(@types/estree-jsx@1.0.5)(@types/hast@3.0.5)(@types/mdast@4.0.4)(@types/react@19.2.18)(lucide-react@1.43.0(react@19.2.8))(next@16.3.6(@babel/core@7.29.7)(@opentelemetry/api@1.9.1)(@playwright/test@1.62.1)(@types/node@26.2.0)(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react-dom@19.2.8(react@19.2.8))(react-router@7.18.2(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react@19.2.8)(zod@4.6.7))(next@16.3.6(@babel/core@7.29.7)(@opentelemetry/api@1.9.1)(@playwright/test@1.62.1)(@types/node@26.2.0)(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react@19.2.8)(rolldown@1.2.7)(vite@8.2.2(@types/node@26.2.0)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.12)(yaml@2.9.0)): dependencies: '@mdx-js/mdx': 3.1.1 '@standard-schema/spec': 1.1.0 chokidar: 5.0.0 esbuild: 0.28.2 estree-util-value-to-estree: 3.5.0 - fumadocs-core: 16.15.4(@mdx-js/mdx@3.1.1)(@tanstack/react-router@1.170.8(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(@types/estree-jsx@1.0.5)(@types/hast@3.0.5)(@types/mdast@4.0.4)(@types/react@19.2.18)(lucide-react@1.43.0(react@19.2.8))(next@16.3.6(@babel/core@7.29.7)(@opentelemetry/api@1.9.1)(@playwright/test@1.62.1)(@types/node@26.2.0)(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react-dom@19.2.8(react@19.2.8))(react-router@7.18.2(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react@19.2.8)(zod@4.6.5) + fumadocs-core: 16.15.4(@mdx-js/mdx@3.1.1)(@tanstack/react-router@1.170.8(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(@types/estree-jsx@1.0.5)(@types/hast@3.0.5)(@types/mdast@4.0.4)(@types/react@19.2.18)(lucide-react@1.43.0(react@19.2.8))(next@16.3.6(@babel/core@7.29.7)(@opentelemetry/api@1.9.1)(@playwright/test@1.62.1)(@types/node@26.2.0)(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react-dom@19.2.8(react@19.2.8))(react-router@7.18.2(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react@19.2.8)(zod@4.6.7) github-slugger: 2.0.0 magic-string: 1.2.0 mdast-util-mdx: 3.0.0 @@ -15951,7 +15957,7 @@ snapshots: vfile: 6.0.3 yaml: 2.9.0 yuku-analyzer: 0.8.7 - zod: 4.6.5 + zod: 4.6.7 optionalDependencies: '@types/mdast': 4.0.4 '@types/mdx': 2.0.14 @@ -15963,7 +15969,7 @@ snapshots: transitivePeerDependencies: - supports-color - fumadocs-ui@16.15.4(@types/mdx@2.0.14)(@types/react-dom@19.2.4(@types/react@19.2.18))(@types/react@19.2.18)(fumadocs-core@16.15.4(@mdx-js/mdx@3.1.1)(@tanstack/react-router@1.170.8(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(@types/estree-jsx@1.0.5)(@types/hast@3.0.5)(@types/mdast@4.0.4)(@types/react@19.2.18)(lucide-react@1.43.0(react@19.2.8))(next@16.3.6(@babel/core@7.29.7)(@opentelemetry/api@1.9.1)(@playwright/test@1.62.1)(@types/node@26.2.0)(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react-dom@19.2.8(react@19.2.8))(react-router@7.18.2(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react@19.2.8)(zod@4.6.5))(next@16.3.6(@babel/core@7.29.7)(@opentelemetry/api@1.9.1)(@playwright/test@1.62.1)(@types/node@26.2.0)(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react-dom@19.2.8(react@19.2.8))(react@19.2.8)(tailwindcss@4.3.3): + fumadocs-ui@16.15.4(@types/mdx@2.0.14)(@types/react-dom@19.2.4(@types/react@19.2.18))(@types/react@19.2.18)(fumadocs-core@16.15.4(@mdx-js/mdx@3.1.1)(@tanstack/react-router@1.170.8(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(@types/estree-jsx@1.0.5)(@types/hast@3.0.5)(@types/mdast@4.0.4)(@types/react@19.2.18)(lucide-react@1.43.0(react@19.2.8))(next@16.3.6(@babel/core@7.29.7)(@opentelemetry/api@1.9.1)(@playwright/test@1.62.1)(@types/node@26.2.0)(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react-dom@19.2.8(react@19.2.8))(react-router@7.18.2(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react@19.2.8)(zod@4.6.7))(next@16.3.6(@babel/core@7.29.7)(@opentelemetry/api@1.9.1)(@playwright/test@1.62.1)(@types/node@26.2.0)(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react-dom@19.2.8(react@19.2.8))(react@19.2.8)(tailwindcss@4.3.3): dependencies: '@fuma-translate/react': 1.0.2(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) '@fumadocs/tailwind': 0.1.1(tailwindcss@4.3.3) @@ -15979,7 +15985,7 @@ snapshots: '@radix-ui/react-tabs': 1.1.21(@types/react-dom@19.2.4(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) class-variance-authority: 0.7.1 cnfast: 0.1.0 - fumadocs-core: 16.15.4(@mdx-js/mdx@3.1.1)(@tanstack/react-router@1.170.8(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(@types/estree-jsx@1.0.5)(@types/hast@3.0.5)(@types/mdast@4.0.4)(@types/react@19.2.18)(lucide-react@1.43.0(react@19.2.8))(next@16.3.6(@babel/core@7.29.7)(@opentelemetry/api@1.9.1)(@playwright/test@1.62.1)(@types/node@26.2.0)(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react-dom@19.2.8(react@19.2.8))(react-router@7.18.2(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react@19.2.8)(zod@4.6.5) + fumadocs-core: 16.15.4(@mdx-js/mdx@3.1.1)(@tanstack/react-router@1.170.8(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(@types/estree-jsx@1.0.5)(@types/hast@3.0.5)(@types/mdast@4.0.4)(@types/react@19.2.18)(lucide-react@1.43.0(react@19.2.8))(next@16.3.6(@babel/core@7.29.7)(@opentelemetry/api@1.9.1)(@playwright/test@1.62.1)(@types/node@26.2.0)(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react-dom@19.2.8(react@19.2.8))(react-router@7.18.2(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react@19.2.8)(zod@4.6.7) lucide-react: 1.43.0(react@19.2.8) motion: 13.2.0(react-dom@19.2.8(react@19.2.8))(react@19.2.8) next-themes: 0.4.6(react-dom@19.2.8(react@19.2.8))(react@19.2.8) @@ -16401,7 +16407,7 @@ snapshots: is-arrayish@0.2.1: {} - is-core-module@2.16.2: + is-core-module@2.17.0: dependencies: hasown: 2.0.4 optional: true @@ -17134,7 +17140,7 @@ snapshots: d3-sankey: 0.12.3 dagre-d3-es: 7.0.14 dayjs: 1.11.23 - dompurify: 3.4.15 + dompurify: 3.4.17 es-toolkit: 1.52.0 fastdom: 1.0.12 katex: 0.16.47 @@ -17443,12 +17449,12 @@ snapshots: minimatch@10.2.3: dependencies: - brace-expansion: 5.0.9 + brace-expansion: 5.0.12 optional: true minimatch@10.2.6: dependencies: - brace-expansion: 5.0.9 + brace-expansion: 5.0.12 minimatch@3.1.5: dependencies: @@ -17478,7 +17484,7 @@ snapshots: monaco-editor@0.55.1: dependencies: - dompurify: 3.4.15 + dompurify: 3.4.17 marked: 14.0.0 mongodb-connection-string-url@7.0.2: @@ -17489,8 +17495,8 @@ snapshots: mongodb@7.2.0(socks@2.8.9): dependencies: - '@mongodb-js/saslprep': 1.5.2 - bson: 7.3.2 + '@mongodb-js/saslprep': 1.6.1 + bson: 7.3.3 mongodb-connection-string-url: 7.0.2 optionalDependencies: socks: 2.8.9 @@ -18076,7 +18082,7 @@ snapshots: html-parse-stringify: 4.0.1 i18next: 26.4.0(typescript@6.0.3) react: 19.2.8 - use-sync-external-store: 1.6.0(react@19.2.8) + use-sync-external-store: 1.7.0(react@19.2.8) optionalDependencies: react-dom: 19.2.8(react@19.2.8) typescript: 6.0.3 @@ -18118,7 +18124,7 @@ snapshots: dependencies: '@types/use-sync-external-store': 0.0.6 react: 19.2.8 - use-sync-external-store: 1.6.0(react@19.2.8) + use-sync-external-store: 1.7.0(react@19.2.8) optionalDependencies: '@types/react': 19.2.18 redux: 5.0.1 @@ -18236,7 +18242,7 @@ snapshots: react-redux: 9.3.0(@types/react@19.2.18)(react@19.2.8)(redux@5.0.1) reselect: 5.2.0 tiny-invariant: 1.3.3 - use-sync-external-store: 1.6.0(react@19.2.8) + use-sync-external-store: 1.7.0(react@19.2.8) victory-vendor: 37.3.6 transitivePeerDependencies: - '@types/react' @@ -18414,10 +18420,10 @@ snapshots: dependencies: protocol-buffers-schema: 3.6.1 - resolve@1.22.12: + resolve@1.22.13: dependencies: es-errors: 1.3.0 - is-core-module: 2.16.2 + is-core-module: 2.17.0 path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 optional: true @@ -18609,12 +18615,12 @@ snapshots: transitivePeerDependencies: - supports-color - seroval-plugins@1.6.7(seroval@1.6.7): + seroval-plugins@1.6.9(seroval@1.6.9): dependencies: - seroval: 1.6.7 + seroval: 1.6.9 optional: true - seroval@1.6.7: + seroval@1.6.9: optional: true serve-static@1.16.3: @@ -19023,7 +19029,7 @@ snapshots: dependencies: dequal: 2.0.3 react: 19.2.8 - use-sync-external-store: 1.6.0(react@19.2.8) + use-sync-external-store: 1.7.0(react@19.2.8) symbol-tree@3.2.4: {} @@ -19422,7 +19428,7 @@ snapshots: dependencies: react: 19.2.8 - use-sync-external-store@1.6.0(react@19.2.8): + use-sync-external-store@1.7.0(react@19.2.8): dependencies: react: 19.2.8 @@ -19831,12 +19837,12 @@ snapshots: dependencies: zod: 3.25.76 - zod-validation-error@4.0.2(zod@4.6.5): + zod-validation-error@4.0.2(zod@4.6.7): dependencies: - zod: 4.6.5 + zod: 4.6.7 zod@3.25.76: {} - zod@4.6.5: {} + zod@4.6.7: {} zwitch@2.0.4: {} diff --git a/scripts/__tests__/check-lockfile-integrity.test.ts b/scripts/__tests__/check-lockfile-integrity.test.ts index 00c0f29555..70393bd209 100644 --- a/scripts/__tests__/check-lockfile-integrity.test.ts +++ b/scripts/__tests__/check-lockfile-integrity.test.ts @@ -90,7 +90,7 @@ describe('green on main — the negative control', () => { * ⛔ It cannot be produced by running the resolver, and that impossibility is * the card's central claim: every workspace range on `@objectstack/*` is a * floating range that a fresh resolve satisfies with the newest release — `^18.0.0-next.1` - * resolving 18.0.0-next.1 today (objectui#12030, objectui#12370; `^17.x` and 17.4.0 when this sample was + * resolving 18.0.0-next.2 today (objectui#12030, objectui#12370, objectui#12626; `^17.x` and 17.4.0 when this sample was * written), so no fresh resolve can pick 17.2.0. The sample is therefore a transformation of the real lockfile * reproducing the identity facts measured on PRs #7053 / #7058 — the family * down to 17.2.0, and `@objectstack/spec` resolved at BOTH versions. @@ -98,15 +98,15 @@ describe('green on main — the negative control', () => { function sampleA(): string { let out = realLock; for (const pkg of ['client', 'core', 'formula', 'lint', 'sdui-parser']) { - out = out.replace(new RegExp(`(@objectstack/${pkg}@)18\\.0\\.0-next\\.1`, 'g'), '$117.2.0'); + out = out.replace(new RegExp(`(@objectstack/${pkg}@)18\\.0\\.0-next\\.2`, 'g'), '$117.2.0'); } - const specKey = " '@objectstack/spec@18.0.0-next.1(ai@7.0.65(zod@4.6.5))':"; + const specKey = " '@objectstack/spec@18.0.0-next.2(ai@7.0.65(zod@4.6.7))':"; expect(out, 'the spec snapshot key moved — rebuild this sample before trusting it').toContain( specKey, ); return out.replace( specKey, - " '@objectstack/spec@17.2.0(ai@7.0.65(zod@4.6.5))':\n dependencies:\n zod: 4.6.5\n" + + " '@objectstack/spec@17.2.0(ai@7.0.65(zod@4.6.7))':\n dependencies:\n zod: 4.6.7\n" + specKey, ); } @@ -124,15 +124,15 @@ function sampleA(): string { function sampleB(): string { let out = realLock; const forked = [ - " '@objectstack/spec@18.0.0-next.1(ai@7.0.65(zod@4.6.5))':", - " '@objectstack/formula@18.0.0-next.1(ai@7.0.65(zod@4.6.5))':", - " ai@7.0.65(zod@4.6.5):", + " '@objectstack/spec@18.0.0-next.2(ai@7.0.65(zod@4.6.7))':", + " '@objectstack/formula@18.0.0-next.2(ai@7.0.65(zod@4.6.7))':", + " ai@7.0.65(zod@4.6.7):", ]; for (const key of forked) { expect(out, `snapshot key moved: ${key}`).toContain(key); - out = out.replace(key, `${key.replace('zod@4.6.5', 'zod@4.5.4')}\n dependencies: {}\n${key}`); + out = out.replace(key, `${key.replace('zod@4.6.7', 'zod@4.5.4')}\n dependencies: {}\n${key}`); } - const zodKey = ' zod@4.6.5: {}'; + const zodKey = ' zod@4.6.7: {}'; expect(out).toContain(zodKey); return out.replace(zodKey, `${zodKey}\n zod@4.5.4: {}`); } @@ -180,7 +180,7 @@ describe('cause 2 — a declared dependency forks with no version moving (object expect(zod, 'the gate must not be blind to objectui#8333').toBeTruthy(); // ⛔ 2 -> 3, not 1 -> 2. Both cards say "forks a single-copy dependency"; // measured on `main`, zod is ALREADY two copies (3.25.76 + 4.4.3 then; - // 3.25.76 + 4.6.5 since objectui#11073, re-measured), so a + // 3.25.76 + 4.6.5 since objectui#11073, 3.25.76 + 4.6.7 since objectui#12626, re-measured), so a // rule keyed on "was one, is now two" would be green here. expect(zod?.baseCount).toBe(2); expect(zod?.headCount).toBe(3); @@ -191,7 +191,7 @@ describe('cause 2 — a declared dependency forks with no version moving (object expect(spec?.headCount).toBe(2); // This is #8326's exact bundling mechanism — two real paths, nothing // dedupes them — arriving with no version change anywhere. - expect(spec?.head.every((k) => k.includes('@18.0.0-next.1'))).toBe(true); + expect(spec?.head.every((k) => k.includes('@18.0.0-next.2'))).toBe(true); }); }); diff --git a/scripts/check-eager-closure-budget.mjs b/scripts/check-eager-closure-budget.mjs index 3e5afd94c2..cec7c54a92 100644 --- a/scripts/check-eager-closure-budget.mjs +++ b/scripts/check-eager-closure-budget.mjs @@ -1948,7 +1948,47 @@ export const PER_CHUNK_GZIP_CEILINGS = Object.freeze({ // on MAX_EAGER_CLOSURE_GZIP_BYTES). Headroom 23,719 bytes = 0.26x // REGRESSION_THIS_GATE_MUST_CATCH_BYTES over the baseline below — what this // key had on `main` at `cea429b` before the payback, kept to the byte. - 'vendor-objectstack': 1_536_409, + // + // ⚠️ RAISED by objectui#12626 (2026-10-16), the `@objectstack/*` + // 18.0.0-next.2 bump, under the claim seat's ruling A on that card's PR + // (objectui#12648), from 1,536,409 by exactly the measured +19,296 bytes. + // + // WHAT THE BYTES ARE — one container, one instrument: `CI=true pnpm --filter + // @object-ui/console exec vite build` in each tree, reading + // `apps/console/dist/eager-closure.json`. The control is `8a8bcf3d`, `main` + // and the branch's merge-base, with `@objectstack/*` 18.0.0-next.1 and zod + // 4.6.5 resolved, in a worktree of its own. The branch is `2043710f` + // (next.2; the lockfile's dedupe moves zod to 4.6.7). A third build is the + // branch tree with every `zod@4.6.7` link pointed at 4.6.5 for the build, + // then restored, which splits zod's share out. Gzipped bytes: + // + // | chunk | `8a8bcf3d` | branch, zod 4.6.5 | `2043710f` | delta | + // |-----------------------|-----------:|------------------:|-----------:|-------:| + // | `vendor-objectstack` | 1,536,365 | 1,555,533 | 1,555,661 | +19,296 | + // | `ui-components` | 288,804 | 288,762 | 288,761 | -43 | + // | `framework` | 76,333 | 76,336 | 76,337 | +4 | + // | `i18n-locale-en` | 46,678 | 46,678 | 46,678 | 0 | + // | ⇒ aggregate | 3,170,311 | 3,189,413 | 3,189,564 | +19,253 | + // + // +19,168 are `@objectstack/*` 18.0.0-next.2 and +128 are the zod + // 4.6.5 -> 4.6.7 patch. zod already lived in this chunk on `main` (its version + // marker is in both builds' `vendor-objectstack`) and grew in place: no + // chunk lost bytes to it and no package joined the group. All 70 eager + // chunks are the same names in both builds. + // + // WHAT THEY BUY: the console's client-side validation answering as the + // 18.0.0-next.2 server does — its page region-placement and `isDefault` + // placement checks, the `AdminScope` tombstones and its schemas — and the + // spec's bounded task-flow derivation the record dialog now takes directly + // (objectui#12592). ⛔ It is NOT a new console capability. + // + // Headroom stays at the 44 bytes `main` had over its own reading + // (1,536,409 - 1,536,365), and this ceiling minus the baseline below stays at + // 23,719, both moved by the same amount. ⛔ Not moved: the aggregate + // MAX_EAGER_CLOSURE_GZIP_BYTES (it passed on the branch, 3114.8 / 3119.4 KB), + // BASELINE and REGRESSION_THIS_GATE_MUST_CATCH_BYTES. No exemption was added + // and no import was made lazy. + 'vendor-objectstack': 1_555_705, // ⭐ LOWERED, and RE-KEYED, by objectui#7479 — this line used to read // `'i18n-locales': 465_000` and budget TEN catalogues. Nine of them are // `import()`ed on demand now, so the chunk that name pointed at no longer @@ -2179,7 +2219,13 @@ export const PER_CHUNK_BASELINE = Object.freeze({ // payback), which superseded objectui#11101's `4acbea07` reading of 1,670,964, which superseded objectui#11073's // `048e7f6` reading of 1,703,690 (landed on `main` as `81f8498`), which // superseded objectui#7122's `34a1578ef` reading of 1,235,029. - 'vendor-objectstack': 1_512_690, + // + // Moved with its ceiling by objectui#12626 (2026-10-16), from 1,512,690 by + // the same measured +19,296 bytes (the table on that key of + // PER_CHUNK_GZIP_CEILINGS). ⚠️ So this is no longer one build's reading: it + // is the `5488ae7` reading plus the next.2 bump's measured delta, which + // keeps the ceiling-minus-baseline gap this key carried. + 'vendor-objectstack': 1_531_986, // `755d34a5f` (objectui#7479) — the SAME console build as // BASELINE above, so the two are directly comparable, and the same instrument // and container as the control build it is subtracted from. It supersedes