diff --git a/.changeset/12030-console-bundles-spec-18.md b/.changeset/12030-console-bundles-spec-18.md index a2b0df40cf..cf036d5435 100644 --- a/.changeset/12030-console-bundles-spec-18.md +++ b/.changeset/12030-console-bundles-spec-18.md @@ -3,4 +3,4 @@ "@object-ui/runner": minor --- -The console and the runner bundles are built against `@objectstack/*` 18.0.0-next.0 (objectui#12030). In both, the `@objectstack/*` ranges are `devDependencies`, but each package is an app build whose published `dist` bundles them, together with the `@object-ui/*` packages it compiles from source. So the shipped console and runner now carry the 18 prerelease line and the `@object-ui/*` changes that follow it. +The console and the runner bundles are built against `@objectstack/*` 18.0.0-next.0 (objectui#12030), and 18.0.0-next.1 since objectui#12370. In both, the `@objectstack/*` ranges are `devDependencies`, but each package is an app build whose published `dist` bundles them, together with the `@object-ui/*` packages it compiles from source. So the shipped console and runner now carry the 18 prerelease line and the `@object-ui/*` changes that follow it. diff --git a/.changeset/12030-objectstack-next-18.md b/.changeset/12030-objectstack-next-18.md index 94e36325c7..f75d5d8fe7 100644 --- a/.changeset/12030-objectstack-next-18.md +++ b/.changeset/12030-objectstack-next-18.md @@ -25,9 +25,9 @@ Depend on the `@objectstack/*` 18 prerelease line (objectui#12030). -Every `@objectstack/*` range these packages declare in `dependencies` or `peerDependencies` moves from `^17.x` to `^18.0.0-next.0`, the `next` prerelease of `@objectstack/*` 18. +Every `@objectstack/*` range these packages declare in `dependencies` or `peerDependencies` moves from `^17.x` to `^18.0.0-next.0`, the `next` prerelease of `@objectstack/*` 18 (raised to `^18.0.0-next.1` by objectui#12370 before release). -**Breaking for consumers:** an install that resolves `@objectstack/spec` (or `@objectstack/client`, `@objectstack/formula`, `@objectstack/lint`) 17.x no longer satisfies these ranges. A consumer must move its own `@objectstack/*` packages to the 18 line, starting with `18.0.0-next.0`, at the same time as it takes this release. +**Breaking for consumers:** an install that resolves `@objectstack/spec` (or `@objectstack/client`, `@objectstack/formula`, `@objectstack/lint`) 17.x no longer satisfies these ranges. A consumer must move its own `@objectstack/*` packages to the 18 line, starting with `18.0.0-next.1` (objectui#12370), at the same time as it takes this release. **objectui's own surface moves with it:** diff --git a/.changeset/12370-spec-next-1.md b/.changeset/12370-spec-next-1.md new file mode 100644 index 0000000000..6ea9d9ac34 --- /dev/null +++ b/.changeset/12370-spec-next-1.md @@ -0,0 +1,38 @@ +--- +"@object-ui/app-shell": minor +"@object-ui/auth": minor +"@object-ui/cli": minor +"@object-ui/components": minor +"@object-ui/core": minor +"@object-ui/data-objectstack": minor +"@object-ui/fields": minor +"@object-ui/layout": minor +"@object-ui/permissions": minor +"@object-ui/plugin-chatbot": minor +"@object-ui/plugin-dashboard": minor +"@object-ui/plugin-designer": minor +"@object-ui/plugin-detail": minor +"@object-ui/plugin-form": minor +"@object-ui/plugin-gantt": minor +"@object-ui/plugin-grid": minor +"@object-ui/plugin-list": minor +"@object-ui/plugin-timeline": minor +"@object-ui/plugin-tree": minor +"@object-ui/plugin-view": minor +"@object-ui/react": minor +"@object-ui/types": minor +"@object-ui/console": minor +"@object-ui/runner": minor +--- + +Depend on `@objectstack/*` `18.0.0-next.1` (objectui#12370). + +Every `@objectstack/*` range these packages declare moves from `^18.0.0-next.0` to `^18.0.0-next.1`; the console and the runner bundle `18.0.0-next.1`. A consumer moves its own `@objectstack/*` packages to `18.0.0-next.1` with this release. + +**Accept sets that narrow with it.** `@object-ui/types` validates page action rows and view data bindings through the spec's own rows, so its faces (`safeValidateSchema` and `StrictAnyComponentSchema`) now refuse what `18.0.0-next.1` refuses. Each was accepted on `18.0.0-next.0`: + +- `onSuccess` on an `action:button` / `action:icon` row, or an `action:group` / `action:menu` member, whose executor is the `url`, `navigation`, `modal`, `flow` or `form` built-in, or that has no executor at all. Write the hop on an `api` or `script` action (or a host handler name), or drop it. +- `onSuccess` beside `operation: 'update'`, and an `onSuccess` block carrying a key outside `{ navigate, openIn }`. +- `actionType: 'navigation'` on a row (and `type: 'navigation'` on a container member): write `'url'`. +- A `url` executor's `target` that is not openable, judged on the executor the runner runs, including a row whose `name` selects it. +- A view `data` binding with `provider: 'api'`: bind the object or static rows; an API call is the page element's binding. diff --git a/QUICK_REFERENCE.md b/QUICK_REFERENCE.md index 181eafc2db..7f8b2b1014 100644 --- a/QUICK_REFERENCE.md +++ b/QUICK_REFERENCE.md @@ -126,9 +126,9 @@ behind (objectui#5394 — that had happened once per release, three times). - **Version:** 17.7.0 (the version every `@object-ui/*` manifest carries — they are one `fixed` group in `.changeset/config.json`, so a release moves all of them together) -- **Spec:** `@objectstack/spec` ^18.0.0-next.0 (declared by the root `package.json` and by +- **Spec:** `@objectstack/spec` ^18.0.0-next.1 (declared by the root `package.json` and by `apps/console/package.json`) -- **Client:** `@objectstack/client` ^18.0.0-next.0 (declared by `apps/console/package.json` +- **Client:** `@objectstack/client` ^18.0.0-next.1 (declared by `apps/console/package.json` and `packages/data-objectstack/package.json`) - **Node.js:** ≥ 22.13 (see root `engines.node`) - **pnpm:** ≥ 10 (the workspace pins `pnpm@10.31.0` via `packageManager`) diff --git a/apps/console/package.json b/apps/console/package.json index f81889ba13..1e2e3833b1 100644 --- a/apps/console/package.json +++ b/apps/console/package.json @@ -91,9 +91,9 @@ "@object-ui/react": "workspace:*", "@object-ui/test-support": "workspace:*", "@object-ui/types": "workspace:*", - "@objectstack/client": "^18.0.0-next.0", - "@objectstack/lint": "^18.0.0-next.0", - "@objectstack/spec": "^18.0.0-next.0", + "@objectstack/client": "^18.0.0-next.1", + "@objectstack/lint": "^18.0.0-next.1", + "@objectstack/spec": "^18.0.0-next.1", "@tailwindcss/postcss": "^4.3.3", "@tailwindcss/typography": "^0.5.20", "@testing-library/jest-dom": "^7.0.1", 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 df2f13f7d1..6e670807eb 100644 --- a/apps/console/src/__tests__/registry-inputs-spec-parity.test.ts +++ b/apps/console/src/__tests__/registry-inputs-spec-parity.test.ts @@ -1507,6 +1507,13 @@ const UNPUBLISHED_EXEMPTIONS: Record = { // entire justification for this exemption — it always was sufficient alone. 'record:reference_rail.entries': 'An array of {objectName, relationshipField, title, limit, displayField} objects; `inputs` is a flat scalar carrier and cannot express it. Newly judged rather than newly missing — @objectstack/spec 17.1.0 added record:reference_rail to ComponentPropsMap, and the registration (the reference_rail register call in plugin-detail/src/index.tsx) has always published only `hideEmpty` — the 17.1.0 pin, objectui#5328. The flat-carrier shape limit is the entire reason: the `icon` divergence that once also blocked an entries editor was settled by Option B (maintainer 2026-08-22, objectui#5494).', + // objectui#12370 (the 18.0.0-next.1 bump): objectstack#23205 declares `parentDataSource` on + // `record:related_list`, the parent record bound by a query of its own, for objectui#12294. The + // spec's own description opens "[PLANNED — not yet rendered]", and no renderer here reads it + // (`git grep parentDataSource -- packages` finds no read site), so publishing it now would + // advertise configuration the platform drops. objectui#12294 owns wiring and declaring it. + 'record:related_list.parentDataSource': + 'Declared by @objectstack/spec 18.0.0-next.1 (objectstack#23205) as PLANNED, not yet rendered: the parent record of a related list bound by its own query. No renderer here reads it yet; objectui#12294 wires the record blocks to their bound row and declares it on the registration.', /* * ⚠️ THE 17.5.0 BOOKINGS — objectui#11111 decision 3 = B (record 5902351047). @@ -2940,11 +2947,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 four providers parses, 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.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).', }, '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.0, re-measured by objectui#12030) 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.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).', }, 'object-grid.operations': { file: 'packages/plugin-grid/src/__tests__/gridOperationsMembers-8071.test.tsx', @@ -3020,7 +3027,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.0, re-measured by objectui#12030) 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.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).', }, 'object-kanban.data': { file: 'packages/plugin-kanban/src/__tests__/ObjectKanban.structuredMembersReachTheirSinks-8313.test.tsx', diff --git a/apps/site/package.json b/apps/site/package.json index 2373af3fce..4f5b528362 100644 --- a/apps/site/package.json +++ b/apps/site/package.json @@ -32,7 +32,7 @@ "@object-ui/plugin-view": "workspace:*", "@object-ui/react": "workspace:*", "@object-ui/types": "workspace:*", - "@objectstack/spec": "^18.0.0-next.0", + "@objectstack/spec": "^18.0.0-next.1", "fumadocs-core": "16.15.4", "fumadocs-mdx": "15.2.3", "fumadocs-ui": "16.15.4", diff --git a/e2e/live/ci/backend.env b/e2e/live/ci/backend.env index 6975d165b6..2a69478f33 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.0 +OBJECTSTACK_VERSION=18.0.0-next.1 # 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/package.json b/package.json index d615cbd6c8..b4703fd2d3 100644 --- a/package.json +++ b/package.json @@ -143,7 +143,7 @@ "@changesets/cli": "^3.0.0", "@eslint/js": "^10.0.1", "@object-ui/test-support": "workspace:*", - "@objectstack/spec": "^18.0.0-next.0", + "@objectstack/spec": "^18.0.0-next.1", "@playwright/test": "^1.62.1", "@testing-library/dom": "^10.4.1", "@testing-library/jest-dom": "^7.0.1", diff --git a/packages/app-shell/package.json b/packages/app-shell/package.json index 024be7430b..4ff8bccc9a 100644 --- a/packages/app-shell/package.json +++ b/packages/app-shell/package.json @@ -89,9 +89,9 @@ "@object-ui/providers": "workspace:*", "@object-ui/react": "workspace:*", "@object-ui/types": "workspace:*", - "@objectstack/formula": "^18.0.0-next.0", - "@objectstack/lint": "^18.0.0-next.0", - "@objectstack/spec": "^18.0.0-next.0", + "@objectstack/formula": "^18.0.0-next.1", + "@objectstack/lint": "^18.0.0-next.1", + "@objectstack/spec": "^18.0.0-next.1", "@sentry/react": "^10.70.0", "jsonc-parser": "^3.3.1", "lucide-react": "^1.43.0", diff --git a/packages/app-shell/src/views/metadata-admin/celAuthoring.ts b/packages/app-shell/src/views/metadata-admin/celAuthoring.ts index c2554be7d9..5a3ec27023 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.0 (objectui#12030), it mostly PRESCRIBES one: the + * rewrite. Measured against the installed 18.0.0-next.1 (objectui#12030, objectui#12370), 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 7d197cf984..15ed782f1d 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.0, objectui#12030): `waitForInput` is typed + // on the installed `@objectstack/spec` (18.0.0-next.1, objectui#12030, objectui#12370): `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/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 b4961415c3..cc8d704b98 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.0). + * the author has ADDED but not yet configured, on the installed spec (18.0.0-next.1). * * 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/auth/package.json b/packages/auth/package.json index c37030323d..5a38dad2af 100644 --- a/packages/auth/package.json +++ b/packages/auth/package.json @@ -37,7 +37,7 @@ "react": "^18.0.0 || ^19.0.0" }, "dependencies": { - "@objectstack/spec": "^18.0.0-next.0", + "@objectstack/spec": "^18.0.0-next.1", "better-auth": "^1.7.2" }, "devDependencies": { diff --git a/packages/cli/package.json b/packages/cli/package.json index ac488ae329..cc80a4f76d 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -56,7 +56,7 @@ "@object-ui/components": "workspace:*", "@object-ui/react": "workspace:*", "@object-ui/types": "workspace:*", - "@objectstack/spec": "^18.0.0-next.0", + "@objectstack/spec": "^18.0.0-next.1", "@tailwindcss/postcss": "^4.3.3", "@types/glob": "^9.0.0", "@vitejs/plugin-react": "^6.0.5", diff --git a/packages/collaboration/package.json b/packages/collaboration/package.json index 990a9c97c1..b4441601b2 100644 --- a/packages/collaboration/package.json +++ b/packages/collaboration/package.json @@ -41,7 +41,7 @@ "@object-ui/types": "workspace:*" }, "devDependencies": { - "@objectstack/spec": "^18.0.0-next.0", + "@objectstack/spec": "^18.0.0-next.1", "@types/react": "19.2.18", "react": "19.2.8", "typescript": "^6.0.3", diff --git a/packages/components/package.json b/packages/components/package.json index 989dde646b..df83bbf222 100644 --- a/packages/components/package.json +++ b/packages/components/package.json @@ -39,7 +39,7 @@ "@object-ui/react-runtime": "workspace:*", "@object-ui/sdui-parser": "workspace:*", "@object-ui/types": "workspace:*", - "@objectstack/spec": "^18.0.0-next.0", + "@objectstack/spec": "^18.0.0-next.1", "@radix-ui/react-accordion": "^1.2.20", "@radix-ui/react-alert-dialog": "^1.1.23", "@radix-ui/react-aspect-ratio": "^1.1.15", diff --git a/packages/core/package.json b/packages/core/package.json index cc12a97153..8d7ae89718 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -32,8 +32,8 @@ }, "dependencies": { "@object-ui/types": "workspace:*", - "@objectstack/formula": "^18.0.0-next.0", - "@objectstack/spec": "^18.0.0-next.0" + "@objectstack/formula": "^18.0.0-next.1", + "@objectstack/spec": "^18.0.0-next.1" }, "devDependencies": { "@object-ui/test-support": "workspace:*", diff --git a/packages/core/src/evaluator/optionRules.ts b/packages/core/src/evaluator/optionRules.ts index 72da23d1fb..ac187cca28 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.0, + * contract ACCEPTS. Measured on the installed `@objectstack/spec` 18.0.0-next.1, * `SelectOptionSchema`: * * { value: 'low', label: 'Low' } -> ACCEPT (lit control) diff --git a/packages/data-objectstack/package.json b/packages/data-objectstack/package.json index 629ec8d480..2b5d38b23b 100644 --- a/packages/data-objectstack/package.json +++ b/packages/data-objectstack/package.json @@ -31,8 +31,8 @@ "dependencies": { "@object-ui/core": "workspace:*", "@object-ui/types": "workspace:*", - "@objectstack/client": "^18.0.0-next.0", - "@objectstack/spec": "^18.0.0-next.0" + "@objectstack/client": "^18.0.0-next.1", + "@objectstack/spec": "^18.0.0-next.1" }, "devDependencies": { "@object-ui/test-support": "workspace:*", diff --git a/packages/fields/package.json b/packages/fields/package.json index a936906264..846ccdc729 100644 --- a/packages/fields/package.json +++ b/packages/fields/package.json @@ -37,7 +37,7 @@ "@object-ui/providers": "workspace:*", "@object-ui/react": "workspace:*", "@object-ui/types": "workspace:*", - "@objectstack/spec": "^18.0.0-next.0", + "@objectstack/spec": "^18.0.0-next.1", "lucide-react": "^1.43.0", "react-markdown": "^10.1.0", "rehype-sanitize": "^6.0.0", diff --git a/packages/layout/package.json b/packages/layout/package.json index dff2c1512b..d5a061d2dd 100644 --- a/packages/layout/package.json +++ b/packages/layout/package.json @@ -31,7 +31,7 @@ "@object-ui/core": "workspace:*", "@object-ui/react": "workspace:*", "@object-ui/types": "workspace:*", - "@objectstack/spec": "^18.0.0-next.0", + "@objectstack/spec": "^18.0.0-next.1", "lucide-react": "^1.43.0" }, "peerDependencies": { diff --git a/packages/mobile/package.json b/packages/mobile/package.json index a4dcd90a7a..528ae47e20 100644 --- a/packages/mobile/package.json +++ b/packages/mobile/package.json @@ -40,7 +40,7 @@ "@object-ui/types": "workspace:*" }, "devDependencies": { - "@objectstack/spec": "^18.0.0-next.0", + "@objectstack/spec": "^18.0.0-next.1", "@types/react": "19.2.18", "react": "19.2.8", "typescript": "^6.0.3", diff --git a/packages/permissions/package.json b/packages/permissions/package.json index e71f49d306..4f918f2de6 100644 --- a/packages/permissions/package.json +++ b/packages/permissions/package.json @@ -38,7 +38,7 @@ }, "dependencies": { "@object-ui/types": "workspace:*", - "@objectstack/spec": "^18.0.0-next.0" + "@objectstack/spec": "^18.0.0-next.1" }, "devDependencies": { "@types/react": "19.2.18", diff --git a/packages/plugin-calendar/src/ObjectCalendar.tsx b/packages/plugin-calendar/src/ObjectCalendar.tsx index 26ee66489b..2d19ef492f 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.0 (objectui#12030), three legs: `{}` and `{ titleField: 't' }` both fail + * the installed 18.0.0-next.1 (objectui#12030, objectui#12370), 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 ebdd7d0ad7..c05c77928c 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.0: `ComponentPropsMap['object-calendar']` + * installed `@objectstack/spec` 18.0.0-next.1: `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-charts/package.json b/packages/plugin-charts/package.json index 5c75e25bba..c1301ea8d2 100644 --- a/packages/plugin-charts/package.json +++ b/packages/plugin-charts/package.json @@ -45,7 +45,7 @@ }, "devDependencies": { "@object-ui/test-support": "workspace:*", - "@objectstack/spec": "^18.0.0-next.0", + "@objectstack/spec": "^18.0.0-next.1", "@types/react": "19.2.18", "@types/react-dom": "19.2.4", "@vitejs/plugin-react": "^6.0.5", diff --git a/packages/plugin-chatbot/package.json b/packages/plugin-chatbot/package.json index 296fe9aa70..05d79bb822 100644 --- a/packages/plugin-chatbot/package.json +++ b/packages/plugin-chatbot/package.json @@ -38,7 +38,7 @@ "@object-ui/react": "workspace:*", "@object-ui/types": "workspace:*", "@radix-ui/react-slot": "^1.3.3", - "@objectstack/spec": "^18.0.0-next.0", + "@objectstack/spec": "^18.0.0-next.1", "@radix-ui/react-use-controllable-state": "^1.2.6", "ai": "^7.0.65", "class-variance-authority": "^0.7.1", diff --git a/packages/plugin-dashboard/package.json b/packages/plugin-dashboard/package.json index b7ebab166b..f224e19e3a 100644 --- a/packages/plugin-dashboard/package.json +++ b/packages/plugin-dashboard/package.json @@ -31,7 +31,7 @@ "@object-ui/permissions": "workspace:*", "@object-ui/react": "workspace:*", "@object-ui/types": "workspace:*", - "@objectstack/spec": "^18.0.0-next.0", + "@objectstack/spec": "^18.0.0-next.1", "lucide-react": "^1.43.0" }, "peerDependencies": { diff --git a/packages/plugin-designer/package.json b/packages/plugin-designer/package.json index f4842b0cc1..e13869b6bb 100644 --- a/packages/plugin-designer/package.json +++ b/packages/plugin-designer/package.json @@ -42,7 +42,7 @@ "@object-ui/plugin-grid": "workspace:*", "@object-ui/react": "workspace:*", "@object-ui/types": "workspace:*", - "@objectstack/spec": "^18.0.0-next.0", + "@objectstack/spec": "^18.0.0-next.1", "clsx": "^2.1.1", "lucide-react": "^1.43.0", "sonner": "^2.0.8", diff --git a/packages/plugin-designer/src/MetadataFieldsPage.tsx b/packages/plugin-designer/src/MetadataFieldsPage.tsx index 6b980677b6..be93fd6fae 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.0 (objectui#12030): + * so in the refusal itself. Measured on the installed 18.0.0-next.1 (objectui#12030, objectui#12370): * * FieldSchema.safeParse({ type: 'lookup', label: 'L', referenceTo: 'account' }) * => success = false diff --git a/packages/plugin-detail/package.json b/packages/plugin-detail/package.json index 8a4b0044fc..2b16407748 100644 --- a/packages/plugin-detail/package.json +++ b/packages/plugin-detail/package.json @@ -32,7 +32,7 @@ }, "dependencies": { "@object-ui/i18n": "workspace:*", - "@objectstack/spec": "^18.0.0-next.0", + "@objectstack/spec": "^18.0.0-next.1", "lucide-react": "^1.43.0" }, "peerDependencies": { diff --git a/packages/plugin-detail/src/index.tsx b/packages/plugin-detail/src/index.tsx index 7134b5229b..7993e3a0fb 100644 --- a/packages/plugin-detail/src/index.tsx +++ b/packages/plugin-detail/src/index.tsx @@ -953,7 +953,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.0 — read + // recommended write. (The row DOES exist as of the installed 18.0.0-next.1 — 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", … })' }, @@ -961,7 +961,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.0 (`dist/ui/index.d.ts`, the + // INSTALLED `@objectstack/spec` 18.0.0-next.1 (`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/package.json b/packages/plugin-form/package.json index 92d4f8f66a..0cf13e60be 100644 --- a/packages/plugin-form/package.json +++ b/packages/plugin-form/package.json @@ -28,7 +28,7 @@ "@object-ui/permissions": "workspace:*", "@object-ui/react": "workspace:*", "@object-ui/types": "workspace:*", - "@objectstack/spec": "^18.0.0-next.0", + "@objectstack/spec": "^18.0.0-next.1", "lucide-react": "^1.43.0" }, "peerDependencies": { diff --git a/packages/plugin-form/src/__tests__/formSectionGroupReference-7051.test.tsx b/packages/plugin-form/src/__tests__/formSectionGroupReference-7051.test.tsx index a27b2cfe8d..7ffa47f9ad 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.0): both are refused at PARSE + * against the installed `@objectstack/spec` (18.0.0-next.1): 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 80e1d04c87..334984a849 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.0 entry carries a + * here before it is red anywhere else. The installed 18.0.0-next.1 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/package.json b/packages/plugin-gantt/package.json index 2c41dafbac..9bec771a7a 100644 --- a/packages/plugin-gantt/package.json +++ b/packages/plugin-gantt/package.json @@ -39,7 +39,7 @@ "@object-ui/plugin-detail": "workspace:*", "@object-ui/react": "workspace:*", "@object-ui/types": "workspace:*", - "@objectstack/spec": "^18.0.0-next.0", + "@objectstack/spec": "^18.0.0-next.1", "lucide-react": "^1.43.0", "sonner": "^2.0.8" }, diff --git a/packages/plugin-gantt/src/readme-navigation-example.test.ts b/packages/plugin-gantt/src/readme-navigation-example.test.ts index 8bde2480d3..d710defe6e 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.0 lands it as a tombstone, + * member. The installed `@objectstack/spec` 18.0.0-next.1 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-grid/package.json b/packages/plugin-grid/package.json index 1a2cfcc8a1..8e57251b42 100644 --- a/packages/plugin-grid/package.json +++ b/packages/plugin-grid/package.json @@ -31,7 +31,7 @@ "@object-ui/plugin-detail": "workspace:*", "@object-ui/react": "workspace:*", "@object-ui/types": "workspace:*", - "@objectstack/spec": "^18.0.0-next.0", + "@objectstack/spec": "^18.0.0-next.1", "@tanstack/react-virtual": "^3.14.9", "exceljs": "^4.4.0", "lucide-react": "^1.43.0" @@ -44,7 +44,7 @@ "@object-ui/data-objectstack": "workspace:*", "@object-ui/sdui-parser": "workspace:*", "@object-ui/test-support": "workspace:*", - "@objectstack/spec": "^18.0.0-next.0", + "@objectstack/spec": "^18.0.0-next.1", "@tailwindcss/postcss": "^4.3.3", "@vitejs/plugin-react": "^6.0.5", "msw": "^2.15.0", diff --git a/packages/plugin-grid/src/__tests__/gridDataInputContract.test.ts b/packages/plugin-grid/src/__tests__/gridDataInputContract.test.ts index 263210a50c..da55ab8a42 100644 --- a/packages/plugin-grid/src/__tests__/gridDataInputContract.test.ts +++ b/packages/plugin-grid/src/__tests__/gridDataInputContract.test.ts @@ -137,12 +137,14 @@ describe('object-grid `data` — declaration matches the contract (objectui#5090 expect(contractAcceptedArms()).toEqual(['object']); }); - it('each of the four providers parses, and none of them is an array', () => { - // What makes "the object arm" a real four-armed union rather than one - // accidental shape, and the direct measurement of the card's premise. + it('each of the three providers parses, none of them is an array, and `api` is refused', () => { + // What makes "the object arm" a real union rather than one accidental + // shape, and the direct measurement of the card's premise. Since + // @objectstack/spec 18.0.0-next.1 the view-level `api` provider is retired + // (objectstack#23160; objectui#12325 removed its readers, objectui#12370 + // installs the release): three providers remain. const providers = [ { provider: 'object', object: 'users' }, - { provider: 'api', read: { url: 'https://example.test/rows' } }, { provider: 'value', items: [{ id: 1 }] }, { provider: 'schema', schemaId: 'report' }, ]; @@ -150,6 +152,7 @@ describe('object-grid `data` — declaration matches the contract (objectui#5090 expect(ViewDataSchema.safeParse(value).success, `${value.provider} provider`).toBe(true); expect(Array.isArray(value)).toBe(false); } + expect(ViewDataSchema.safeParse({ provider: 'api', read: { url: 'https://example.test/rows' } }).success).toBe(false); }); it.each(GRID_TAGS)('$label declares the arms the contract accepts', ({ type, namespace }) => { diff --git a/packages/plugin-kanban/src/index.tsx b/packages/plugin-kanban/src/index.tsx index 2ef796ce9f..358d0520f8 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.0 pin, fourteen of them live, the + * top-level keys on the installed 18.0.0-next.1 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-list/package.json b/packages/plugin-list/package.json index 4bd7f8cfe3..52c078024e 100644 --- a/packages/plugin-list/package.json +++ b/packages/plugin-list/package.json @@ -42,7 +42,7 @@ "@object-ui/permissions": "workspace:^", "@object-ui/react": "workspace:^", "@object-ui/types": "workspace:^", - "@objectstack/spec": "^18.0.0-next.0", + "@objectstack/spec": "^18.0.0-next.1", "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" }, @@ -56,7 +56,7 @@ "@object-ui/react": "workspace:*", "@object-ui/test-support": "workspace:*", "@object-ui/types": "workspace:*", - "@objectstack/spec": "^18.0.0-next.0", + "@objectstack/spec": "^18.0.0-next.1", "@types/react": "19.2.18", "@types/react-dom": "19.2.4", "@vitejs/plugin-react": "^6.0.5", diff --git a/packages/plugin-report/package.json b/packages/plugin-report/package.json index be1105adb5..d23ce0d7cb 100644 --- a/packages/plugin-report/package.json +++ b/packages/plugin-report/package.json @@ -40,7 +40,7 @@ }, "devDependencies": { "@object-ui/test-support": "workspace:*", - "@objectstack/spec": "^18.0.0-next.0", + "@objectstack/spec": "^18.0.0-next.1", "@types/node": "^26.2.0", "@types/react": "19.2.18", "@types/react-dom": "19.2.4", diff --git a/packages/plugin-timeline/package.json b/packages/plugin-timeline/package.json index f2a71765a5..b6ecf5e122 100644 --- a/packages/plugin-timeline/package.json +++ b/packages/plugin-timeline/package.json @@ -38,7 +38,7 @@ "@object-ui/permissions": "workspace:*", "@object-ui/react": "workspace:*", "@object-ui/types": "workspace:*", - "@objectstack/spec": "^18.0.0-next.0", + "@objectstack/spec": "^18.0.0-next.1", "class-variance-authority": "^0.7.1", "zod": "^4.4.3" }, diff --git a/packages/plugin-tree/package.json b/packages/plugin-tree/package.json index 51ac3d3b8a..ded9930513 100644 --- a/packages/plugin-tree/package.json +++ b/packages/plugin-tree/package.json @@ -39,7 +39,7 @@ "@object-ui/plugin-detail": "workspace:*", "@object-ui/react": "workspace:*", "@object-ui/types": "workspace:*", - "@objectstack/spec": "^18.0.0-next.0", + "@objectstack/spec": "^18.0.0-next.1", "lucide-react": "^1.43.0" }, "peerDependencies": { diff --git a/packages/plugin-tree/src/__tests__/objectTreeInputs-11168.test.tsx b/packages/plugin-tree/src/__tests__/objectTreeInputs-11168.test.tsx index 80a709b95c..6d377164bc 100644 --- a/packages/plugin-tree/src/__tests__/objectTreeInputs-11168.test.tsx +++ b/packages/plugin-tree/src/__tests__/objectTreeInputs-11168.test.tsx @@ -312,9 +312,8 @@ describe('`object-tree.data` — the members are the `{ provider, … }` configu }); it.each([ - ['api', { provider: 'api', read: { url: '/api/units' } }], ['schema', { provider: 'schema', schemaId: 'units' }], - ])('`{ provider: "%s" }` draws nothing and queries nothing — the tree reads neither', async (_label, data) => { + ])('`{ provider: "%s" }` draws nothing and queries nothing — the tree reads it not', async (_label, data) => { expect(specRow.safeParse({ data }).success, 'the spec row accepts the configuration').toBe(true); const ds = mount({ tree: TREE, data }); expect(await drawn()).toEqual([]); @@ -322,6 +321,18 @@ describe('`object-tree.data` — the members are the `{ provider, … }` configu expect(ds.find).not.toHaveBeenCalled(); }); + it('`{ provider: "api" }` is refused by the spec row, and a stored one still draws nothing and queries nothing', async () => { + // @objectstack/spec 18.0.0-next.1 retires the view-level `api` provider + // (objectstack#23160), so authoring it is refused (objectui#12370); a + // document stored before still reaches the renderer, which reads it not. + const data = { provider: 'api', read: { url: '/api/units' } }; + expect(specRow.safeParse({ data }).success, 'the spec row refuses the retired provider').toBe(false); + const ds = mount({ tree: TREE, data }); + expect(await drawn()).toEqual([]); + expect(screen.getByText('No records')).toBeInTheDocument(); + expect(ds.find).not.toHaveBeenCalled(); + }); + it('it is read FIRST: a `data` configuration wins over `staticData` and over `objectName`', async () => { const ds = mount({ tree: TREE, diff --git a/packages/plugin-view/package.json b/packages/plugin-view/package.json index 17f6860601..4de6b64066 100644 --- a/packages/plugin-view/package.json +++ b/packages/plugin-view/package.json @@ -32,7 +32,7 @@ "@object-ui/plugin-grid": "workspace:*", "@object-ui/react": "workspace:*", "@object-ui/types": "workspace:*", - "@objectstack/spec": "^18.0.0-next.0", + "@objectstack/spec": "^18.0.0-next.1", "class-variance-authority": "^0.7.1", "lucide-react": "^1.43.0" }, diff --git a/packages/react/package.json b/packages/react/package.json index 08df381bcc..c10a2743ba 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -34,7 +34,7 @@ "@object-ui/data-objectstack": "workspace:*", "@object-ui/i18n": "workspace:*", "@object-ui/types": "workspace:*", - "@objectstack/spec": "^18.0.0-next.0" + "@objectstack/spec": "^18.0.0-next.1" }, "peerDependencies": { "react": "^18.0.0 || ^19.0.0", diff --git a/packages/runner/package.json b/packages/runner/package.json index 4dac6ea2a9..a26b477506 100644 --- a/packages/runner/package.json +++ b/packages/runner/package.json @@ -34,7 +34,7 @@ "tailwindcss-animate": "^1.0.7" }, "devDependencies": { - "@objectstack/spec": "^18.0.0-next.0", + "@objectstack/spec": "^18.0.0-next.1", "@tailwindcss/postcss": "^4.3.3", "@types/react": "19.2.18", "@types/react-dom": "19.2.4", diff --git a/packages/sdui-parser/package.json b/packages/sdui-parser/package.json index 385b465d80..3153b1bada 100644 --- a/packages/sdui-parser/package.json +++ b/packages/sdui-parser/package.json @@ -34,6 +34,6 @@ "@object-ui/core": "workspace:*", "@object-ui/react": "workspace:*", "@object-ui/types": "workspace:*", - "@objectstack/spec": "^18.0.0-next.0" + "@objectstack/spec": "^18.0.0-next.1" } } diff --git a/packages/test-support/package.json b/packages/test-support/package.json index 27bb45530d..b9197e46ac 100644 --- a/packages/test-support/package.json +++ b/packages/test-support/package.json @@ -22,7 +22,7 @@ "lint": "eslint ." }, "devDependencies": { - "@objectstack/spec": "^18.0.0-next.0", + "@objectstack/spec": "^18.0.0-next.1", "@types/node": "^26.2.0", "typescript": "^6.0.3", "zod": "^4.4.3" diff --git a/packages/types/package.json b/packages/types/package.json index 1d34c93b9a..1304fc8b11 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.0", + "@objectstack/spec": "^18.0.0-next.1", "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 b8344806a0..18f5cfc09e 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.0 and on objectstack `main`, bare `undefined` + * mark at the pinned 18.0.0-next.1 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 b2c944c044..f8deb03a0b 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.0 + * as the spec's retired key (the branded `[REMOVED]` mark at the pinned 18.0.0-next.1 * 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.0 and on objectstack + // the branded `[REMOVED]` mark at the pinned 18.0.0-next.1 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__/held-public-block-arms-10872.test.ts b/packages/types/src/__tests__/held-public-block-arms-10872.test.ts index 3af4d64eab..c72d328de4 100644 --- a/packages/types/src/__tests__/held-public-block-arms-10872.test.ts +++ b/packages/types/src/__tests__/held-public-block-arms-10872.test.ts @@ -111,15 +111,21 @@ describe('objectui#10872 batch 4 — the six held blocks are armed, by reference // (objectui#12030); it is the row by reference again, so it is back in this row. it.each(ARMS)('%s: the bag IS the spec row — nothing restated, nothing stripped', (type, arm) => { const row = rowOf(type); - // All six rows carry no default and no `z.lazy`, so the import boundary is - // the identity function on them (objectui#8317)… - expect(stripImportedDefaults(row)).toBe(row); - // …and the arm holds the spec's own schema: its DEFINITION is the row's. - // Not `toBe(row)`: 17.5.0 publishes these rows as lazy proxies whose + // The two element rows carry no default and no `z.lazy`, so the import + // boundary is the identity function on them (objectui#8317). Since + // @objectstack/spec 18.0.0-next.1 the four action rows take `onSuccess` as + // `ActionSchema`'s own block, whose `openIn` carries `.default('self')`, so + // the boundary rebuilds them without that default (objectui#12370). + const bounded = stripImportedDefaults(row); + if (type.startsWith('action:')) expect(bounded).not.toBe(row); + else expect(bounded).toBe(row); + // …and the arm holds the spec's own schema through that boundary: its + // DEFINITION is the bounded row's (memoised, so one instance per row). + // Not `toBe(bounded)`: 17.5.0 publishes these rows as lazy proxies whose // methods run on the real schema, so `.optional()` wraps the object behind // the proxy, and the definition is the identity that survives. expect((bagOf(arm) as unknown as { _zod: { def: unknown } })._zod.def) - .toBe((row as unknown as { _zod: { def: unknown } })._zod.def); + .toBe((bounded as unknown as { _zod: { def: unknown } })._zod.def); expect(keysOf(bagOf(arm))).toEqual(keysOf(row)); }); @@ -222,8 +228,13 @@ describe('objectui#10872 batch 4 — the two handler keys the action renderers r const issue = at(result, 'onSuccess')[0]; expect(issue?.code, face).toBe('invalid_type'); expect(issue?.message, face).toContain('Did you mean `onSuccess` → `properties.onSuccess`?'); - // What the remedy sends the author to is accepted. - expect(judge({ type, properties: { onSuccess: { navigate: '/tasks' } } }).success, face).toBe(true); + // What the remedy sends the author to is accepted: `properties.onSuccess` on a row + // whose executor carries the hop. Since @objectstack/spec 18.0.0-next.1 a row with + // no executor refuses `onSuccess` (objectui#12338), so the row names `api`. + expect( + judge({ type, properties: { actionType: 'api', target: '/api/tasks/archive', onSuccess: { navigate: '/tasks' } } }).success, + face, + ).toBe(true); } // The spec's own page component refuses the flat spelling as well. expect(PageComponentSchema.safeParse({ type, onSuccess: { navigate: '/tasks' } }).success).toBe(false); diff --git a/packages/types/src/__tests__/imported-defaults-8317.test.ts b/packages/types/src/__tests__/imported-defaults-8317.test.ts index 0f12c67e59..e7c58a3661 100644 --- a/packages/types/src/__tests__/imported-defaults-8317.test.ts +++ b/packages/types/src/__tests__/imported-defaults-8317.test.ts @@ -142,6 +142,7 @@ import { checkDashboardWidgetChartMeasureArity, checkPageRequiresKind, checkPageSlotPair, + checkPageComponentViewData, VIEW_METADATA_MEMBERS as SpecViewMetadataMembers, } from '@objectstack/spec/ui'; import { @@ -701,6 +702,10 @@ describe('the import boundary strips every imported default (objectui#8317)', () // `PageSchema`, re-attached on `PageNodeSchema` and `PageKindNodeSchema` // under the same ruling. ['checkPageSlotPair', checkPageSlotPair], + // objectui#12370: the page view-data check `@objectstack/spec` 18.0.0-next.1 adds to + // `PageSchema` (the retired `api` provider under `regions` / `slots`), re-attached on + // `PageNodeSchema` and `PageKindNodeSchema` under the same ruling. + ['checkPageComponentViewData', checkPageComponentViewData], ]); /** 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 c3984f9445..f9c56332cb 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.0). ⛔ Not a copy of the + * shape, off `@objectstack/spec` as installed (18.0.0-next.1). ⛔ 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 4b1355708e..13b7edbf59 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.0 and on objectstack `main`, + * pinned 18.0.0-next.1 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 49c34747bb..a4a49895f3 100644 --- a/packages/types/src/__tests__/spec-object-refinements-7715.test.ts +++ b/packages/types/src/__tests__/spec-object-refinements-7715.test.ts @@ -166,6 +166,51 @@ describe('objectui#12030 — the Page `details` + `tabs` slot-pair refusal reach }); }); +describe('objectui#12370 — the Page retired-`api` view-data refusal reaches objectui', () => { + const API = { provider: 'api', read: { url: '/api/rows' } }; + const grid = (data: unknown) => ({ type: 'object-grid', properties: { objectName: 'task', data } }); + const SLOTTED = (data: unknown) => ({ kind: 'slotted', slots: { details: [grid(data)] } }); + + it('a slot child: the spec refuses at its `properties.data.provider`, and objectui refuses with the spec\'s own issue', () => { + const at = 'slots.details.0.properties.data.provider'; + const spec = SpecPageSchema.safeParse(specPage(SLOTTED(API))); + expect(spec.success).toBe(false); + const specIssue = spec.error!.issues.find((i) => i.path.join('.') === at); + expect(specIssue?.code).toBe('custom'); + + for (const r of [PageNodeSchema.safeParse(pageNode(SLOTTED(API))), safeValidateSchema(pageNode(SLOTTED(API)))]) { + 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('a region child: the spec refuses it, and objectui refuses the same child through the component union', () => { + // objectui's regions are its own `PageNodeRegionSchema`, judged by the component union + // at every depth, and the `object-grid` arm refuses the `api` provider itself; the + // object-level check does not run once a child has failed, so the refusal here is the + // union's, at the same child. + const regions = [{ name: 'main', components: [grid(API)] }]; + const spec = SpecPageSchema.safeParse(specPage({ regions })); + const specIssue = spec.error!.issues.find((i) => i.path.join('.') === 'regions.0.components.0.properties.data.provider'); + expect(specIssue?.code).toBe('custom'); + + for (const r of [PageNodeSchema.safeParse(pageNode({ regions })), safeValidateSchema(pageNode({ regions }))]) { + expect(r.success).toBe(false); + expect(r.error!.issues.map((i) => i.path.join('.'))).toContain('regions.0.components.0'); + } + }); + + it('controls: an `object` binding in a slot and in a region passes on both doors', () => { + const OBJ = { provider: 'object', object: 'task' }; + for (const extra of [SLOTTED(OBJ), { regions: [{ name: 'main', components: [grid(OBJ)] }] }]) { + expect(SpecPageSchema.safeParse(specPage(extra)).success).toBe(true); + expect(PageNodeSchema.safeParse(pageNode(extra)).success).toBe(true); + expect(safeValidateSchema(pageNode(extra)).success).toBe(true); + } + }); +}); + // ── The census: every object-level check the spec runs is accounted for ───── /** @@ -207,7 +252,10 @@ const SITES = [ // attached by objectui#11717: it reads `kind` and `requires`, both carried by reference. // `checkPageSlotPair` joined at 18 (objectstack#22568) and was attached by objectui#12030: // it reads `slots`, carried by reference. - attached: ['checkPageSourceCompleteness', 'checkPageRequiresKind', 'checkPageSlotPair'], + // `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'], // `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 diff --git a/packages/types/src/__tests__/spec-subschema-parity.test.ts b/packages/types/src/__tests__/spec-subschema-parity.test.ts index 4174563c57..9733b4ded9 100644 --- a/packages/types/src/__tests__/spec-subschema-parity.test.ts +++ b/packages/types/src/__tests__/spec-subschema-parity.test.ts @@ -108,7 +108,7 @@ describe('spec sub-schema re-exports are the spec objects (by reference)', () => * `stripImportedDefaults` is the identity function on a subtree with nothing * to strip (see its walker's identity property), so for a schema that carries * no `ZodDefault` the assertion above degenerates into `toBe(spec)` — the - * pre-objectui#8317 pin, unchanged and still load-bearing. These three are + * pre-objectui#8317 pin, unchanged and still load-bearing. These four are * that case, asserted directly so it is a MEASUREMENT rather than a claim in * a docblock: if the boundary ever started cloning unconditionally, this goes * red and the pin above would not. @@ -117,12 +117,16 @@ describe('spec sub-schema re-exports are the spec objects (by reference)', () => ['HttpMethodSchema', HttpMethodSchema, SpecHttpMethodSubsetSchema], ['ChartTypeSchema', ChartTypeSchema, SpecChartTypeSchema], ['PageTypeSchema', PageTypeSchema, SpecPageTypeSchema], + // Since @objectstack/spec 18.0.0-next.1 retired the view-level `api` + // provider (objectstack#23160), whose request block carried the defaults, + // `ViewDataSchema` has nothing to strip either (objectui#12370). + ['ViewDataSchema', ViewDataSchema, SpecViewDataSchema], ] as const)('%s carries no imported default, so it is still the raw spec object', (name, oui, spec) => { expect(oui, `${name} has nothing to strip and must stay reference-equal to the spec object`).toBe(spec); }); /** - * …and the other half of the same control: the four that DID carry an + * …and the other half of the same control: the three that DO carry an * imported default are NOT the raw spec object any more. That is the * behaviour change objectui#8317 shipped, pinned so it cannot be undone by * quietly reverting the boundary — and so a reader who lands on the @@ -131,7 +135,6 @@ describe('spec sub-schema re-exports are the spec objects (by reference)', () => */ it.each([ ['HttpRequestSchema', HttpRequestSchema, SpecHttpRequestSchema], - ['ViewDataSchema', ViewDataSchema, SpecViewDataSchema], ['SelectionConfigSchema', SelectionConfigSchema, SpecSelectionConfigSchema], ['PaginationConfigSchema', PaginationConfigSchema, SpecPaginationConfigSchema], ] as const)('%s carried an imported default, so it is the boundary derivation', (name, oui, spec) => { diff --git a/packages/types/src/field-types.ts b/packages/types/src/field-types.ts index 8308ef2e8b..9a1824475c 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.0), `FieldSchema` declares + * Measured on the installed `@objectstack/spec` (18.0.0-next.1), `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.0: + * same ruling. Measured on the installed `@objectstack/spec` 18.0.0-next.1: * `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.0: an option carrying `description` + * installed `@objectstack/spec` 18.0.0-next.1: 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 e5e4badf05..2e7ffca706 100644 --- a/packages/types/src/objectql.ts +++ b/packages/types/src/objectql.ts @@ -4207,7 +4207,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.0 — the + * MEASURED on the installed artifact at `@objectstack/spec` 18.0.0-next.1 — 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 cde183642e..360597fa0e 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.0, against a control — `columns: '2'` — that + * on the installed pin, 18.0.0-next.1, 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. @@ -345,7 +345,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.0, + * the WHOLE document with it. Measured on the installed pin, 18.0.0-next.1, * `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 @@ -377,7 +377,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.0, + * never accepted it: measured on the installed pin, 18.0.0-next.1, * `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 8fcb756ae1..1712973942 100644 --- a/packages/types/src/zod/layout.zod.ts +++ b/packages/types/src/zod/layout.zod.ts @@ -22,6 +22,7 @@ import { PageSchema as SpecPageSchema, PageTypeSchema as SpecPageTypeSchema, PageVariableSchema as SpecPageVariableSchema, + checkPageComponentViewData, checkPageRequiresKind, checkPageSlotPair, checkPageSourceCompleteness, @@ -1338,18 +1339,32 @@ export const PageNodeSchema = BaseSchema.extend(SpecPageFields.shape).extend({ // - a page that authors both `slots.details` and `slots.tabs` is refused at // `slots.details`, because the `tabs` slot replaces the strip the details // body lives in (`checkPageSlotPair`, objectstack#22568, the spec's 18; - // attached by objectui#12030). - // The spec exports all three and all three are attached here as-is: they read - // `kind`, `source`, `requires` and `slots`, and this node carries all four by - // reference — none is in {@link PAGE_SPEC_EXCLUDED} nor overridden above. The - // spec's fourth page check, `checkPagePrintComposition`, reads `type` and - // `regions`, which this node does NOT carry by reference, so it is not - // attached; the census below records why. + // attached by objectui#12030); + // - a view-data component (`object-grid` / `-map` / `-gantt` / `-tree`) under + // `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 + // 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 + // by reference, and its children are NOT judged by the component union, so + // without the check a slotted page's view-data block naming `api` passed here + // while the spec refused it. `regions` is this node's own + // {@link PageNodeRegionSchema}, whose components ARE judged by the union, and + // 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`, + // 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. // `__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(checkPageSlotPair) + .superRefine(checkPageComponentViewData); /** * The spec page KINDS a node may carry in `type` (objectui#11440): `record`, @@ -1397,9 +1412,10 @@ 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 three attachable - * object-level checks (`source`, `requires` by `kind`, and the `details` / - * `tabs` slot pair) come with it. `regions` stays the node's own + * `maxWidth`, `padding`), the `body` refusal and the spec's four 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 * {@link PageNodeRegionSchema}, so each region component is judged by this * union at every depth, as on `page`. * @@ -1409,7 +1425,8 @@ const { type: _pageNodeTypeLiteral, ...PAGE_NODE_MEMBERS } = PageNodeSchema.shap 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(checkPageSourceCompleteness).superRefine(checkPageRequiresKind).superRefine(checkPageSlotPair) + .superRefine(checkPageComponentViewData); /** * 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 76f108b5df..89ac8e8b49 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.0 (objectui#12030), each of which answers + * and again on the installed 18.0.0-next.1 (objectui#12030, objectui#12370), 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.0 (objectui#12030). + * (objectui#11717), and again on the installed 18.0.0-next.1 (objectui#12030, objectui#12370). * * ⇒ 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 845df7d78d..35c92a15ed 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -34,8 +34,8 @@ importers: specifier: workspace:* version: link:packages/test-support '@objectstack/spec': - specifier: ^18.0.0-next.0 - version: 18.0.0-next.0(ai@7.0.65(zod@4.6.5)) + specifier: ^18.0.0-next.1 + version: 18.0.0-next.1(ai@7.0.65(zod@4.6.5)) '@playwright/test': specifier: ^1.62.1 version: 1.62.1 @@ -272,14 +272,14 @@ importers: specifier: workspace:* version: link:../../packages/types '@objectstack/client': - specifier: ^18.0.0-next.0 - version: 18.0.0-next.0(ai@7.0.65(zod@4.6.5)) + specifier: ^18.0.0-next.1 + version: 18.0.0-next.1(ai@7.0.65(zod@4.6.5)) '@objectstack/lint': - specifier: ^18.0.0-next.0 - version: 18.0.0-next.0(ai@7.0.65(zod@4.6.5)) + specifier: ^18.0.0-next.1 + version: 18.0.0-next.1(ai@7.0.65(zod@4.6.5)) '@objectstack/spec': - specifier: ^18.0.0-next.0 - version: 18.0.0-next.0(ai@7.0.65(zod@4.6.5)) + specifier: ^18.0.0-next.1 + version: 18.0.0-next.1(ai@7.0.65(zod@4.6.5)) '@tailwindcss/postcss': specifier: ^4.3.3 version: 4.3.3 @@ -416,8 +416,8 @@ importers: specifier: workspace:* version: link:../../packages/types '@objectstack/spec': - specifier: ^18.0.0-next.0 - version: 18.0.0-next.0(ai@7.0.65(zod@4.6.5)) + specifier: ^18.0.0-next.1 + version: 18.0.0-next.1(ai@7.0.65(zod@4.6.5)) 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) @@ -774,14 +774,14 @@ importers: specifier: workspace:* version: link:../types '@objectstack/formula': - specifier: ^18.0.0-next.0 - version: 18.0.0-next.0(ai@7.0.65(zod@4.6.5)) + specifier: ^18.0.0-next.1 + version: 18.0.0-next.1(ai@7.0.65(zod@4.6.5)) '@objectstack/lint': - specifier: ^18.0.0-next.0 - version: 18.0.0-next.0(ai@7.0.65(zod@4.6.5)) + specifier: ^18.0.0-next.1 + version: 18.0.0-next.1(ai@7.0.65(zod@4.6.5)) '@objectstack/spec': - specifier: ^18.0.0-next.0 - version: 18.0.0-next.0(ai@7.0.65(zod@4.6.5)) + specifier: ^18.0.0-next.1 + version: 18.0.0-next.1(ai@7.0.65(zod@4.6.5)) '@sentry/react': specifier: ^10.70.0 version: 10.70.0(react@19.2.8) @@ -871,8 +871,8 @@ importers: packages/auth: dependencies: '@objectstack/spec': - specifier: ^18.0.0-next.0 - version: 18.0.0-next.0(ai@7.0.65(zod@4.6.5)) + specifier: ^18.0.0-next.1 + version: 18.0.0-next.1(ai@7.0.65(zod@4.6.5)) 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) @@ -902,8 +902,8 @@ importers: specifier: workspace:* version: link:../types '@objectstack/spec': - specifier: ^18.0.0-next.0 - version: 18.0.0-next.0(ai@7.0.65(zod@4.6.5)) + specifier: ^18.0.0-next.1 + version: 18.0.0-next.1(ai@7.0.65(zod@4.6.5)) '@tailwindcss/postcss': specifier: ^4.3.3 version: 4.3.3 @@ -970,8 +970,8 @@ importers: version: link:../types devDependencies: '@objectstack/spec': - specifier: ^18.0.0-next.0 - version: 18.0.0-next.0(ai@7.0.65(zod@4.6.5)) + specifier: ^18.0.0-next.1 + version: 18.0.0-next.1(ai@7.0.65(zod@4.6.5)) '@types/react': specifier: 19.2.18 version: 19.2.18 @@ -1006,8 +1006,8 @@ importers: specifier: workspace:* version: link:../types '@objectstack/spec': - specifier: ^18.0.0-next.0 - version: 18.0.0-next.0(ai@7.0.65(zod@4.6.5)) + specifier: ^18.0.0-next.1 + version: 18.0.0-next.1(ai@7.0.65(zod@4.6.5)) '@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) @@ -1190,11 +1190,11 @@ importers: specifier: workspace:* version: link:../types '@objectstack/formula': - specifier: ^18.0.0-next.0 - version: 18.0.0-next.0(ai@7.0.65(zod@4.6.5)) + specifier: ^18.0.0-next.1 + version: 18.0.0-next.1(ai@7.0.65(zod@4.6.5)) '@objectstack/spec': - specifier: ^18.0.0-next.0 - version: 18.0.0-next.0(ai@7.0.65(zod@4.6.5)) + specifier: ^18.0.0-next.1 + version: 18.0.0-next.1(ai@7.0.65(zod@4.6.5)) devDependencies: '@object-ui/test-support': specifier: workspace:* @@ -1249,11 +1249,11 @@ importers: specifier: workspace:* version: link:../types '@objectstack/client': - specifier: ^18.0.0-next.0 - version: 18.0.0-next.0(ai@7.0.65(zod@4.6.5)) + specifier: ^18.0.0-next.1 + version: 18.0.0-next.1(ai@7.0.65(zod@4.6.5)) '@objectstack/spec': - specifier: ^18.0.0-next.0 - version: 18.0.0-next.0(ai@7.0.65(zod@4.6.5)) + specifier: ^18.0.0-next.1 + version: 18.0.0-next.1(ai@7.0.65(zod@4.6.5)) devDependencies: '@object-ui/test-support': specifier: workspace:* @@ -1292,8 +1292,8 @@ importers: specifier: workspace:* version: link:../types '@objectstack/spec': - specifier: ^18.0.0-next.0 - version: 18.0.0-next.0(ai@7.0.65(zod@4.6.5)) + specifier: ^18.0.0-next.1 + version: 18.0.0-next.1(ai@7.0.65(zod@4.6.5)) lucide-react: specifier: ^1.43.0 version: 1.43.0(react@19.2.8) @@ -1396,8 +1396,8 @@ importers: specifier: workspace:* version: link:../types '@objectstack/spec': - specifier: ^18.0.0-next.0 - version: 18.0.0-next.0(ai@7.0.65(zod@4.6.5)) + specifier: ^18.0.0-next.1 + version: 18.0.0-next.1(ai@7.0.65(zod@4.6.5)) lucide-react: specifier: ^1.43.0 version: 1.43.0(react@19.2.8) @@ -1437,8 +1437,8 @@ importers: version: link:../types devDependencies: '@objectstack/spec': - specifier: ^18.0.0-next.0 - version: 18.0.0-next.0(ai@7.0.65(zod@4.6.5)) + specifier: ^18.0.0-next.1 + version: 18.0.0-next.1(ai@7.0.65(zod@4.6.5)) '@types/react': specifier: 19.2.18 version: 19.2.18 @@ -1458,8 +1458,8 @@ importers: specifier: workspace:* version: link:../types '@objectstack/spec': - specifier: ^18.0.0-next.0 - version: 18.0.0-next.0(ai@7.0.65(zod@4.6.5)) + specifier: ^18.0.0-next.1 + version: 18.0.0-next.1(ai@7.0.65(zod@4.6.5)) devDependencies: '@types/react': specifier: 19.2.18 @@ -1621,8 +1621,8 @@ importers: specifier: workspace:* version: link:../test-support '@objectstack/spec': - specifier: ^18.0.0-next.0 - version: 18.0.0-next.0(ai@7.0.65(zod@4.6.5)) + specifier: ^18.0.0-next.1 + version: 18.0.0-next.1(ai@7.0.65(zod@4.6.5)) '@types/react': specifier: 19.2.18 version: 19.2.18 @@ -1663,8 +1663,8 @@ importers: specifier: workspace:* version: link:../types '@objectstack/spec': - specifier: ^18.0.0-next.0 - version: 18.0.0-next.0(ai@7.0.65(zod@4.6.5)) + specifier: ^18.0.0-next.1 + version: 18.0.0-next.1(ai@7.0.65(zod@4.6.5)) '@radix-ui/react-slot': specifier: ^1.3.3 version: 1.3.3(@types/react@19.2.18)(react@19.2.8) @@ -1754,8 +1754,8 @@ importers: specifier: workspace:* version: link:../types '@objectstack/spec': - specifier: ^18.0.0-next.0 - version: 18.0.0-next.0(ai@7.0.65(zod@4.6.5)) + specifier: ^18.0.0-next.1 + version: 18.0.0-next.1(ai@7.0.65(zod@4.6.5)) lucide-react: specifier: ^1.43.0 version: 1.43.0(react@19.2.8) @@ -1824,8 +1824,8 @@ importers: specifier: workspace:* version: link:../types '@objectstack/spec': - specifier: ^18.0.0-next.0 - version: 18.0.0-next.0(ai@7.0.65(zod@4.6.5)) + specifier: ^18.0.0-next.1 + version: 18.0.0-next.1(ai@7.0.65(zod@4.6.5)) clsx: specifier: ^2.1.1 version: 2.1.1 @@ -1876,8 +1876,8 @@ importers: specifier: workspace:* version: link:../i18n '@objectstack/spec': - specifier: ^18.0.0-next.0 - version: 18.0.0-next.0(ai@7.0.65(zod@4.6.5)) + specifier: ^18.0.0-next.1 + version: 18.0.0-next.1(ai@7.0.65(zod@4.6.5)) lucide-react: specifier: ^1.43.0 version: 1.43.0(react@19.2.8) @@ -2001,8 +2001,8 @@ importers: specifier: workspace:* version: link:../types '@objectstack/spec': - specifier: ^18.0.0-next.0 - version: 18.0.0-next.0(ai@7.0.65(zod@4.6.5)) + specifier: ^18.0.0-next.1 + version: 18.0.0-next.1(ai@7.0.65(zod@4.6.5)) lucide-react: specifier: ^1.43.0 version: 1.43.0(react@19.2.8) @@ -2062,8 +2062,8 @@ importers: specifier: workspace:* version: link:../types '@objectstack/spec': - specifier: ^18.0.0-next.0 - version: 18.0.0-next.0(ai@7.0.65(zod@4.6.5)) + specifier: ^18.0.0-next.1 + version: 18.0.0-next.1(ai@7.0.65(zod@4.6.5)) lucide-react: specifier: ^1.43.0 version: 1.43.0(react@19.2.8) @@ -2132,8 +2132,8 @@ importers: specifier: workspace:* version: link:../types '@objectstack/spec': - specifier: ^18.0.0-next.0 - version: 18.0.0-next.0(ai@7.0.65(zod@4.6.5)) + specifier: ^18.0.0-next.1 + version: 18.0.0-next.1(ai@7.0.65(zod@4.6.5)) '@tanstack/react-virtual': specifier: ^3.14.9 version: 3.14.9(react-dom@19.2.8(react@19.2.8))(react@19.2.8) @@ -2306,8 +2306,8 @@ importers: specifier: workspace:* version: link:../types '@objectstack/spec': - specifier: ^18.0.0-next.0 - version: 18.0.0-next.0(ai@7.0.65(zod@4.6.5)) + specifier: ^18.0.0-next.1 + version: 18.0.0-next.1(ai@7.0.65(zod@4.6.5)) '@types/react': specifier: 19.2.18 version: 19.2.18 @@ -2483,8 +2483,8 @@ importers: specifier: workspace:* version: link:../test-support '@objectstack/spec': - specifier: ^18.0.0-next.0 - version: 18.0.0-next.0(ai@7.0.65(zod@4.6.5)) + specifier: ^18.0.0-next.1 + version: 18.0.0-next.1(ai@7.0.65(zod@4.6.5)) '@types/node': specifier: ^26.2.0 version: 26.2.0 @@ -2531,8 +2531,8 @@ importers: specifier: workspace:* version: link:../types '@objectstack/spec': - specifier: ^18.0.0-next.0 - version: 18.0.0-next.0(ai@7.0.65(zod@4.6.5)) + specifier: ^18.0.0-next.1 + version: 18.0.0-next.1(ai@7.0.65(zod@4.6.5)) class-variance-authority: specifier: ^0.7.1 version: 0.7.1 @@ -2601,8 +2601,8 @@ importers: specifier: workspace:* version: link:../types '@objectstack/spec': - specifier: ^18.0.0-next.0 - version: 18.0.0-next.0(ai@7.0.65(zod@4.6.5)) + specifier: ^18.0.0-next.1 + version: 18.0.0-next.1(ai@7.0.65(zod@4.6.5)) lucide-react: specifier: ^1.43.0 version: 1.43.0(react@19.2.8) @@ -2674,8 +2674,8 @@ importers: specifier: workspace:* version: link:../types '@objectstack/spec': - specifier: ^18.0.0-next.0 - version: 18.0.0-next.0(ai@7.0.65(zod@4.6.5)) + specifier: ^18.0.0-next.1 + version: 18.0.0-next.1(ai@7.0.65(zod@4.6.5)) class-variance-authority: specifier: ^0.7.1 version: 0.7.1 @@ -2739,8 +2739,8 @@ importers: specifier: workspace:* version: link:../types '@objectstack/spec': - specifier: ^18.0.0-next.0 - version: 18.0.0-next.0(ai@7.0.65(zod@4.6.5)) + specifier: ^18.0.0-next.1 + version: 18.0.0-next.1(ai@7.0.65(zod@4.6.5)) react: specifier: 19.2.8 version: 19.2.8 @@ -2804,8 +2804,8 @@ importers: version: 1.0.7(tailwindcss@4.3.3) devDependencies: '@objectstack/spec': - specifier: ^18.0.0-next.0 - version: 18.0.0-next.0(ai@7.0.65(zod@4.6.5)) + specifier: ^18.0.0-next.1 + version: 18.0.0-next.1(ai@7.0.65(zod@4.6.5)) '@tailwindcss/postcss': specifier: ^4.3.3 version: 4.3.3 @@ -2846,14 +2846,14 @@ importers: specifier: workspace:* version: link:../types '@objectstack/spec': - specifier: ^18.0.0-next.0 - version: 18.0.0-next.0(ai@7.0.65(zod@4.6.5)) + specifier: ^18.0.0-next.1 + version: 18.0.0-next.1(ai@7.0.65(zod@4.6.5)) packages/test-support: devDependencies: '@objectstack/spec': - specifier: ^18.0.0-next.0 - version: 18.0.0-next.0(ai@7.0.65(zod@4.6.5)) + specifier: ^18.0.0-next.1 + version: 18.0.0-next.1(ai@7.0.65(zod@4.6.5)) '@types/node': specifier: ^26.2.0 version: 26.2.0 @@ -2867,8 +2867,8 @@ importers: packages/types: dependencies: '@objectstack/spec': - specifier: ^18.0.0-next.0 - version: 18.0.0-next.0(ai@7.0.65(zod@4.6.5)) + specifier: ^18.0.0-next.1 + version: 18.0.0-next.1(ai@7.0.65(zod@4.6.5)) zod: specifier: ^4.6.1 version: 4.6.5 @@ -4229,26 +4229,26 @@ packages: resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} engines: {node: '>= 8'} - '@objectstack/client@18.0.0-next.0': - resolution: {integrity: sha512-gFflUycBVPIvc1a44psjRBQ3z1NuaDkmfBOcVRhc6nvc7paVXr4kqYG1NdlmnmCwm8qfAvGL7BuftWCYUWqtYg==} + '@objectstack/client@18.0.0-next.1': + resolution: {integrity: sha512-3KlwtJUTV7yrtWeTqs/z19iWURmoKd5smuOY/KN7a82Ffll3GDliju25Nh6JOdF4UmuJtfaoblygflS/U+tgpw==} engines: {node: '>=22.0.0'} - '@objectstack/core@18.0.0-next.0': - resolution: {integrity: sha512-6Ms8bsOdnIKxY4EwXyVl2OfQ3ydB5eH0J/u7KA1lWXquZgSDggLk05upOzf7XtuUeLb8JSLbmG25OIKuamBi3Q==} + '@objectstack/core@18.0.0-next.1': + resolution: {integrity: sha512-+d+tGi0lWeIMC3TjI6leyDYt3uVlpthifwjsgXMWl1jjMNdD8Pw3Uc2Q7QipmrVXj3CcINKEH0cri5SCYIeNPw==} engines: {node: '>=22.0.0'} - '@objectstack/formula@18.0.0-next.0': - resolution: {integrity: sha512-UyVOqJz1QLvjnr6qSCFnex6BiU1Ly3N6vLBiB6/8FmqHdnboozfNGdLgjhmS/m3wWq0ZGoY9d5RYkpDfC65UDQ==} + '@objectstack/formula@18.0.0-next.1': + resolution: {integrity: sha512-acgpTRlVuRkNHyVr+gaaKK9AhNhihyFM658qiYxMxZy0ynWHbOMTjJq6/3X18HSsWbgdAc68OILu3QJcf8Rr2g==} - '@objectstack/lint@18.0.0-next.0': - resolution: {integrity: sha512-cxEbba3qAbQ2Pvc76tcY+pqTMiO79XoruOo3uQCttR7w8abrikFFCXv2cprawXIEgYkshQeJaAExCdqp01aG6Q==} + '@objectstack/lint@18.0.0-next.1': + resolution: {integrity: sha512-/Ae71Tv3Nfk3xzBKMwZdGt89e32lI0+rnqHKWjuO5ZlcCvpZLIA3qPEvydwrsQV7ep7iYEjVG35cthgD/YbafQ==} engines: {node: '>=22.0.0'} - '@objectstack/sdui-parser@18.0.0-next.0': - resolution: {integrity: sha512-fACYC57H+MbpW8cfjtY4J+0HDgaxBjnVgNTMVrJ742JP2FtGn3zsgLt34EMYYoMS41w+spwaBq+5s/sWt3xheA==} + '@objectstack/sdui-parser@18.0.0-next.1': + resolution: {integrity: sha512-Jc6brfLZjz3dFss3G4Qu0jTCASIKipCUM13I5v+/Tw/cClqMbFntkudbaDEbo588+WOnqf3gLtuvghabK3/kNA==} - '@objectstack/spec@18.0.0-next.0': - resolution: {integrity: sha512-ASTh6+q5jo2y8VhYT5osOb4H0JUyGAVYHIUPE39OnxSAD3fYg12x1YiNz09JA0aP+8JxigeA0otHWB3j16i2Ow==} + '@objectstack/spec@18.0.0-next.1': + resolution: {integrity: sha512-pDNzwgJz1/SzVr1K7WGA3kDIR/rBVrA/K8UpVIw2P4SWJ1ONdxVy/K3+IZzl2MC3/+ye1ChePbQFw9i4gvAhFg==} engines: {node: '>=22.0.0'} peerDependencies: ai: ^7.0.0 @@ -4256,8 +4256,8 @@ packages: ai: optional: true - '@objectstack/types@18.0.0-next.0': - resolution: {integrity: sha512-rR+m5ZnBB4zSKn3RKiTKmiksTHjUa66Iz1etHVxUf57rW2qFrp8tQtH7UJlX4V5+5O0HjiRPvPnOgOK2mvV9Qw==} + '@objectstack/types@18.0.0-next.1': + resolution: {integrity: sha512-Mjulyi0JgLMT16Qf014sK6L/QufOzfQZe7yjVFHyiO9umDDCMA59s2hA4GsYdbOSNyS/YV2WBi3NAupjSX84NA==} engines: {node: '>=22.0.0'} '@open-draft/deferred-promise@2.2.0': @@ -12331,33 +12331,33 @@ snapshots: '@nodelib/fs.scandir': 2.1.5 fastq: 1.20.1 - '@objectstack/client@18.0.0-next.0(ai@7.0.65(zod@4.6.5))': + '@objectstack/client@18.0.0-next.1(ai@7.0.65(zod@4.6.5))': dependencies: - '@objectstack/core': 18.0.0-next.0(ai@7.0.65(zod@4.6.5)) - '@objectstack/spec': 18.0.0-next.0(ai@7.0.65(zod@4.6.5)) + '@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)) transitivePeerDependencies: - ai - '@objectstack/core@18.0.0-next.0(ai@7.0.65(zod@4.6.5))': + '@objectstack/core@18.0.0-next.1(ai@7.0.65(zod@4.6.5))': dependencies: - '@objectstack/spec': 18.0.0-next.0(ai@7.0.65(zod@4.6.5)) - '@objectstack/types': 18.0.0-next.0(ai@7.0.65(zod@4.6.5)) + '@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 transitivePeerDependencies: - ai - '@objectstack/formula@18.0.0-next.0(ai@7.0.65(zod@4.6.5))': + '@objectstack/formula@18.0.0-next.1(ai@7.0.65(zod@4.6.5))': dependencies: '@marcbachmann/cel-js': 8.0.0 - '@objectstack/spec': 18.0.0-next.0(ai@7.0.65(zod@4.6.5)) + '@objectstack/spec': 18.0.0-next.1(ai@7.0.65(zod@4.6.5)) transitivePeerDependencies: - ai - '@objectstack/lint@18.0.0-next.0(ai@7.0.65(zod@4.6.5))': + '@objectstack/lint@18.0.0-next.1(ai@7.0.65(zod@4.6.5))': dependencies: - '@objectstack/formula': 18.0.0-next.0(ai@7.0.65(zod@4.6.5)) - '@objectstack/sdui-parser': 18.0.0-next.0 - '@objectstack/spec': 18.0.0-next.0(ai@7.0.65(zod@4.6.5)) + '@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)) ajv: 8.20.0 ajv-formats: 3.0.1(ajv@8.20.0) sucrase: 3.35.1 @@ -12365,18 +12365,18 @@ snapshots: transitivePeerDependencies: - ai - '@objectstack/sdui-parser@18.0.0-next.0': {} + '@objectstack/sdui-parser@18.0.0-next.1': {} - '@objectstack/spec@18.0.0-next.0(ai@7.0.65(zod@4.6.5))': + '@objectstack/spec@18.0.0-next.1(ai@7.0.65(zod@4.6.5))': dependencies: pg-connection-string: 2.14.0 zod: 4.6.5 optionalDependencies: ai: 7.0.65(zod@4.6.5) - '@objectstack/types@18.0.0-next.0(ai@7.0.65(zod@4.6.5))': + '@objectstack/types@18.0.0-next.1(ai@7.0.65(zod@4.6.5))': dependencies: - '@objectstack/spec': 18.0.0-next.0(ai@7.0.65(zod@4.6.5)) + '@objectstack/spec': 18.0.0-next.1(ai@7.0.65(zod@4.6.5)) transitivePeerDependencies: - ai diff --git a/scripts/__tests__/check-lockfile-integrity.test.ts b/scripts/__tests__/check-lockfile-integrity.test.ts index be989fe88a..00c0f29555 100644 --- a/scripts/__tests__/check-lockfile-integrity.test.ts +++ b/scripts/__tests__/check-lockfile-integrity.test.ts @@ -89,8 +89,8 @@ 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.0` - * resolving 18.0.0-next.0 today (objectui#12030; `^17.x` and 17.4.0 when this sample was + * 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 * 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,9 +98,9 @@ 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\\.0`, 'g'), '$117.2.0'); + out = out.replace(new RegExp(`(@objectstack/${pkg}@)18\\.0\\.0-next\\.1`, 'g'), '$117.2.0'); } - const specKey = " '@objectstack/spec@18.0.0-next.0(ai@7.0.65(zod@4.6.5))':"; + const specKey = " '@objectstack/spec@18.0.0-next.1(ai@7.0.65(zod@4.6.5))':"; expect(out, 'the spec snapshot key moved — rebuild this sample before trusting it').toContain( specKey, ); @@ -124,8 +124,8 @@ function sampleA(): string { function sampleB(): string { let out = realLock; const forked = [ - " '@objectstack/spec@18.0.0-next.0(ai@7.0.65(zod@4.6.5))':", - " '@objectstack/formula@18.0.0-next.0(ai@7.0.65(zod@4.6.5))':", + " '@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):", ]; for (const key of forked) { @@ -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.0'))).toBe(true); + expect(spec?.head.every((k) => k.includes('@18.0.0-next.1'))).toBe(true); }); }); diff --git a/scripts/check-installed-spec-pin-claims.mjs b/scripts/check-installed-spec-pin-claims.mjs index 8465d67cd4..ef05912034 100644 --- a/scripts/check-installed-spec-pin-claims.mjs +++ b/scripts/check-installed-spec-pin-claims.mjs @@ -894,6 +894,14 @@ export const LEDGER = [ class: "historical", why: "\"the row declares it since 17.6.0\" on the `keyboardNavigation` input's comment \u2014 the release `object-grid` gained the member; the line's `pinned` is the verb in \"is pinned there\". Permanently true (objectui#11717).", }, + { + file: "scripts/check-eager-closure-budget.mjs", + package: "@objectstack/spec", + version: "18.0.0-next.0", + sites: 1, + class: "historical", + why: "Anchored to a named commit: \"`5488ae7` is objectui#12030's branch commit: `main` at `cea429b` with `@objectstack/*` 18.0.0-next.0 resolved\" describes the tree the eager-closure baseline was measured on. A measurement that names its tree is a record, not a claim about today (objectui#12370).", + }, ]; // ── The run ──────────────────────────────────────────────────────────────────