diff --git a/.changeset/12873-spec-next-3.md b/.changeset/12873-spec-next-3.md new file mode 100644 index 0000000000..48a1ba3af7 --- /dev/null +++ b/.changeset/12873-spec-next-3.md @@ -0,0 +1,19 @@ +--- +"@object-ui/app-shell": minor +"@object-ui/types": minor +"@object-ui/core": minor +"@object-ui/plugin-calendar": minor +"@object-ui/plugin-designer": minor +"@object-ui/plugin-detail": minor +"@object-ui/plugin-kanban": minor +"@object-ui/console": minor +"@object-ui/runner": minor +--- + +Resolve `@objectstack/*` `18.0.0-next.3` (objectui#12873). + +The console and the runner bundle `18.0.0-next.3`. Every package keeps its `@objectstack/*` range (`^18.0.0-next.1`, or `^18.0.0-next.2` for `@object-ui/types` and `@object-ui/app-shell`), which already admits it. + +**An accept set that narrows with it.** `@object-ui/types` validates a `page:header` node's `properties` through the spec's own `page:header` row, so its faces (`safeValidateSchema` and `StrictAnyComponentSchema`) now refuse `showStar`, which `18.0.0-next.3` retires: the follow star it switched on is not drawn by any renderer. It was accepted before. Delete the key. + +**A type that widens with it.** `SelectOptionBase`, and the field and form option types built on it, take the spec's select option by reference, so they now carry its optional `kind` (`'open' | 'won' | 'lost'`), the lifecycle category `18.0.0-next.3` adds. The spec takes it on a single-value `select` or `radio` field's options and requires it on every option of the field an object's `stageField` names. 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 a01bced8c6..c213115152 100644 --- a/apps/console/src/__tests__/registry-inputs-spec-parity.test.ts +++ b/apps/console/src/__tests__/registry-inputs-spec-parity.test.ts @@ -396,16 +396,17 @@ function declaredInputs(type: string): string[] | null { * * So the forward direction's question — "does the contract accept this key on * this node?" — has to be asked of the whole node contract. It is DERIVED here, - * not listed: `PageComponentSchema` is a `.pipe()`, whose input side is the - * object whose shape names those keys. A spec release that adds or removes one - * moves this set with it. + * not listed: `PageComponentSchema` is the object whose shape names those keys. + * (Through `@objectstack/spec` 18.0.0-next.2 it was a `.pipe()` that folded the + * retired `visibility` spelling into `visibleWhen`, and the keys sat on its + * input side; 18.0.0-next.3 drops that fold, objectstack `105902f`.) A spec + * release that adds or removes one moves this set with it. * * ⚠️ Used by the FORWARD direction only. Feeding it to the reverse direction * would demand that every covered block publish `dataSource` — including the * blocks that do not read it, which is the exact lie the ruling refused. */ -const nodeLevelSpecKeys = (): string[] => - authorableShapeKeys((PageComponentSchema as unknown as { _def?: { in?: unknown } })._def?.in); +const nodeLevelSpecKeys = (): string[] => authorableShapeKeys(PageComponentSchema); /** Top-level inputs this block declares that its spec props schema rejects. */ function offSpecInputs(type: string): string[] { @@ -982,6 +983,8 @@ const UNJUDGED_SPEC_BLOCKS: Record = { 'EMPTY SPEC SHAPE. New in `@objectstack/spec` 18 (objectui#12030), which declares it with no top-level key at all. Registered by `@object-ui/app-shell` (`src/views/record-approvals-renderer.tsx`), outside this file\'s import graph; the empty shape is the load-bearing half either way, exactly as for `app:launcher` above. objectui#12030, ledger objectui#8176.', 'record:attachments': 'EMPTY SPEC SHAPE. New in `@objectstack/spec` 18 (objectui#12030), which declares it with no top-level key at all. Registered by `@object-ui/app-shell` (`src/views/record-attachments-renderer.tsx`), outside this file\'s import graph; the empty shape is the load-bearing half either way, exactly as for `app:launcher` above. objectui#12030, ledger objectui#8176.', + 'record:json': + 'NOT REGISTERED, DELIBERATELY. New in `@objectstack/spec` 18.0.0-next.3 (objectstack#23745, landed as `97b8e7a51d`) for the approval request page\'s raw-payload panel, which objectui#12490 was to render. The maintainer then dropped that face (pointer 6232139151 on objectui#12490: no business need for an approver to read JSON), so no renderer is built, the served-page edit closed unmerged, and the type is filed for retirement upstream (objectstack#24162). Registering it forces this entry out; the spec retiring it makes this entry RETIRED UPSTREAM. objectui#12873, ledger objectui#8176.', // The fourth class, and the only one that is not mechanically "unjudgeable": // OWED. The 17.5.0 bump booked four blocks here — new in that spec, registered // with `registerLazy` by the console (`register-plugins.ts`) and not loaded by @@ -1347,25 +1350,6 @@ const UNPUBLISHED_EXEMPTIONS: Record = { 'object-grid.title': '@deprecated in ObjectGridSchema ("Use label instead"); GA describes it as the "Fallback for `label` (the renderer reads `label || title`)". Read as back-compat, deliberately not published — the canonical `label` IS declared. Same ruled carve-out class as the five the ruling enumerated, measured on this branch — objectui#4648 (maintainer 2026-08-16).', - // ── `page:header.showStar`: retired upstream, bump not installed yet ─────── - // objectstack#23650's ruling retires the metadata switch, and it landed as - // objectstack#23781: a `retiredKey()` tombstone on `PageHeaderProps`. The - // installed `@objectstack/spec` predates that commit and still lists the key - // as live, so the reverse direction demands it. objectui#12627 stopped the - // renderer reading it and the registration publishing it AHEAD of the bump: - // the favorites star follows the host's `onToggleFavorite` alone. - // - // ⚠️ THIS ENTRY DIES ON THE BUMP, by design, and nothing has to remember it. - // The first installed spec that carries objectstack#23781 tombstones the - // key, `specTopLevelKeys` subtracts it, and `every unpublished-key exemption - // names a key the spec really declares` and `carries no stale unpublished-key - // exemption` both name this entry. Deleting it is the whole fix. ⛔ Do not - // resolve that red by re-declaring the input or by listing this key in - // `GA_PENDING_UNPUBLISHED_KEYS`: the first publishes a key the contract - // refuses, the second would hide this entry from both checks. - 'page:header.showStar': - 'Retired upstream by objectstack#23650 (landed as objectstack#23781), which the installed spec predates. The renderer no longer reads it and the registration no longer publishes it (objectui#12627): the favorites star draws where the host wires onToggleFavorite, and metadata does not control it. Goes dangling and stale on the bump that installs the tombstone; delete it there.', - // ── objectui#8176: the two lazily-registered blocks, judged for the first ── // time. ONE key left of the eighteen that entered, and as of objectui#8201 // slice 2 it is no longer A DECLARATION SOMEONE OWES. @@ -2966,11 +2950,11 @@ const MEMBER_PINS: Record = { }, 'object-grid.data': { file: 'packages/plugin-grid/src/__tests__/gridDataInputContract.test.ts', - pins: 'The `object` arm is `ViewDataSchema` discriminated on `provider`: each of the three providers parses and the retired `api` one is refused (spec 18.0.0-next.2, objectui#12370), none of them is an array, the declaration is one shape across both registered tags so the alias cannot drift, and it is pinned at compile time too (objectui#5090).', + 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.3, 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.2, re-measured by objectui#12030, objectui#12370, objectui#12626) takes the list view\'s own `{ condition, style }` rule and refuses the native members and any other key, so the spec fixes the AUTHORED shape and the read site is the rest of the member contract, the stored-rule compatibility arms included (objectui#8071 slice 12).', + 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.3, re-measured by objectui#12030, objectui#12370, objectui#12626, objectui#12873) takes the list view\'s own `{ condition, style }` rule and refuses the native members and any other key, so the spec fixes the AUTHORED shape and the read site is the rest of the member contract, the stored-rule compatibility arms included (objectui#8071 slice 12).', }, 'object-grid.operations': { file: 'packages/plugin-grid/src/__tests__/gridOperationsMembers-8071.test.tsx', @@ -3046,7 +3030,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.2, re-measured by objectui#12030, objectui#12370, objectui#12626) takes the list view\'s own `{ condition, style }` rule, so the spec fixes the authored shape and the read site is the rest of the member contract (objectui#8313).', + 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.3, re-measured by objectui#12030, objectui#12370, objectui#12626, objectui#12873) 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', @@ -4613,10 +4597,15 @@ describe('registry `inputs` vs `@objectstack/spec` ComponentPropsMap (repo-wide) // `record:attachments`, each declared with an EMPTY shape, so all three are // ledgered (9 -> 12). `judged` and `registeredPropless` do not move. // 40 + 7 + 12 = 59. - specCarried: 59, + // + // 59 -> 60 on the `@objectstack/spec` 18.0.0-next.3 pin (objectui#12873): + // one new block, `record:json`, which this repo deliberately does not + // register (its ledger entry says why), so it is ledgered (12 -> 13). + // `judged` and `registeredPropless` do not move. 40 + 7 + 13 = 60. + specCarried: 60, judged: 40, registeredPropless: 7, - ledgeredUnjudgeable: 12, + ledgeredUnjudgeable: 13, }); // Non-vacuity, stated rather than implied by the numbers above. expect(covered.length).toBeGreaterThan(0); diff --git a/content/docs/guide/ci-cd-pipeline.md b/content/docs/guide/ci-cd-pipeline.md index 5c1ff015f6..be719508b2 100644 --- a/content/docs/guide/ci-cd-pipeline.md +++ b/content/docs/guide/ci-cd-pipeline.md @@ -569,7 +569,7 @@ install the published graph without it: `start-backend.sh` adds a root `override ships, so the npm the runner installs with — dies building the ideal tree with `Cannot read properties of null (reading 'edgesOut')` on an optional `vitest` peer in the published graph ([#12649](https://github.com/objectstack-ai/objectui/issues/12649)). Nothing -installed vitest at `18.0.0-next.2`, so there the override steered the resolver and changed no +put vitest into the `18.0.0-next.2` install, so there the override steered the resolver and changed no package the backend runs — a one-off reading on that issue, which nothing here re-derives. The script carries the reason and the condition for removing it, and its stamp carries the value, so a cached fixture prepared under another install recipe is rebuilt instead of reused diff --git a/e2e/live/ci/backend.env b/e2e/live/ci/backend.env index 6bd1f57137..5b4e1ae39f 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.2 +OBJECTSTACK_VERSION=18.0.0-next.3 # There is deliberately no OBJECTSTACK_REF key here. The objectstack-ai/objectstack # commit the showcase app metadata is sparse-checked-out from is DERIVED at diff --git a/packages/app-shell/src/views/metadata-admin/celAuthoring.ts b/packages/app-shell/src/views/metadata-admin/celAuthoring.ts index 5cc6f024c9..8aa6dd3ab1 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.2 (objectui#12030, objectui#12370, objectui#12626), it mostly PRESCRIBES one: the + * rewrite. Measured against the installed 18.0.0-next.3 (objectui#12030, objectui#12370, objectui#12626, objectui#12873), 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 b44a6ed161..c82fba5ed2 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.2, objectui#12030, objectui#12370, objectui#12626): `waitForInput` is typed + // on the installed `@objectstack/spec` (18.0.0-next.3, objectui#12030, objectui#12370, objectui#12626, objectui#12873): `waitForInput` is typed // `z.boolean().optional()` with no `.default(...)`, so an omitted key // materialises nothing and there is no spec answer for a declaration to // mirror. Declaring one here would invent a default the runtime does not diff --git a/packages/app-shell/src/views/metadata-admin/inspectors/flow-node-config.startGates-12780.test.ts b/packages/app-shell/src/views/metadata-admin/inspectors/flow-node-config.startGates-12780.test.ts index de61719f63..959c23d86b 100644 --- a/packages/app-shell/src/views/metadata-admin/inspectors/flow-node-config.startGates-12780.test.ts +++ b/packages/app-shell/src/views/metadata-admin/inspectors/flow-node-config.startGates-12780.test.ts @@ -6,7 +6,7 @@ * * The table below is what `@objectstack/service-automation`'s * `AutomationEngine` and the trigger packages read, at objectstack - * `18.0.0-next.2` (the installed `@objectstack/spec` line): + * `18.0.0-next.3` (the installed `@objectstack/spec` line): * * - `secret`: the API trigger arms from `config.secret` (`trigger-api`). * - `objectName`: lifted into the `record_change` binding, which the diff --git a/packages/app-shell/src/views/metadata-admin/inspectors/flowSingleBrace-12329.test.tsx b/packages/app-shell/src/views/metadata-admin/inspectors/flowSingleBrace-12329.test.tsx index fafa8ad9f8..d2588742c8 100644 --- a/packages/app-shell/src/views/metadata-admin/inspectors/flowSingleBrace-12329.test.tsx +++ b/packages/app-shell/src/views/metadata-admin/inspectors/flowSingleBrace-12329.test.tsx @@ -6,7 +6,7 @@ * * objectstack#19939 S7 deleted the engine's single-brace resolver: a value slot * refuses a `{…}` token, a text slot reads `{{ }}` holes, and every other flow - * string is a literal. The installed spec (`18.0.0-next.2`) publishes no + * string is a literal. The installed spec (`18.0.0-next.3`) publishes no * `xExpression: 'template'` mark. So the picker has two spellings left — the * bare reference and the `{{ }}` hole — and a literal position has no picker. * diff --git a/packages/app-shell/src/views/metadata-admin/previews/block-types.ts b/packages/app-shell/src/views/metadata-admin/previews/block-types.ts index 9160a90bb8..f5562efbeb 100644 --- a/packages/app-shell/src/views/metadata-admin/previews/block-types.ts +++ b/packages/app-shell/src/views/metadata-admin/previews/block-types.ts @@ -240,6 +240,12 @@ export const PALETTE_EXCLUSIONS: Record = { 'record:approvals': 'renders (registered by `@object-ui/app-shell`), not yet offered: `@objectstack/spec` 18 added the type, and offering it in the palette is a Studio decision the version bump does not make', 'record:attachments': 'renders (registered by `@object-ui/app-shell`), not yet offered: `@objectstack/spec` 18 added the type, and offering it in the palette is a Studio decision the version bump does not make', 'record:approval_decision': 'renders (registered by `@object-ui/app-shell`), not yet offered: `@objectstack/spec` 18 added the type, and offering it in the palette is a Studio decision its registration does not make', + // + // `@objectstack/spec` 18.0.0-next.3 added `record:json` (objectstack#23745) for + // the approval request page's raw-payload panel. The maintainer dropped that + // face before objectui built it (objectui#12490), so nothing here registers + // the type, and it is filed for retirement upstream (objectstack#24162). + 'record:json': 'not rendered by objectui: `@objectstack/spec` 18.0.0-next.3 added it for a raw-payload panel the maintainer dropped (objectui#12490), so nothing registers it, and it is filed for retirement upstream (objectstack#24162)', }; /** 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 aa7ab3f1ab..794bf63b54 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.2). + * the author has ADDED but not yet configured, on the installed spec (18.0.0-next.3). * * Spec 17.5.0 carries objectstack#20316 (a node config key its executor * contract requires, left out, and a decision branch with no `label`, are diff --git a/packages/core/src/evaluator/optionRules.ts b/packages/core/src/evaluator/optionRules.ts index daaf077f18..c5a2608865 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.2, + * contract ACCEPTS. Measured on the installed `@objectstack/spec` 18.0.0-next.3, * `SelectOptionSchema`: * * { value: 'low', label: 'Low' } -> ACCEPT (lit control) diff --git a/packages/plugin-calendar/src/ObjectCalendar.tsx b/packages/plugin-calendar/src/ObjectCalendar.tsx index 4067e539d5..d5409ec9d2 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.2 (objectui#12030, objectui#12370, objectui#12626), three legs: `{}` and `{ titleField: 't' }` both fail + * the installed 18.0.0-next.3 (objectui#12030, objectui#12370, objectui#12626, objectui#12873), 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 af5fe73b72..02b265ef85 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.2: `ComponentPropsMap['object-calendar']` + * installed `@objectstack/spec` 18.0.0-next.3: `ComponentPropsMap['object-calendar']` * is STRICT and declares exactly ten flat members — `calendar` `data` * `defaultView` `filter` `loading` `locale` `navigation` `objectName` `sort` * `staticData` (nine through 17.4.0; 17.5.0 added `navigation`) — diff --git a/packages/plugin-designer/src/MetadataFieldsPage.tsx b/packages/plugin-designer/src/MetadataFieldsPage.tsx index 499604f3fa..9ae6754291 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.2 (objectui#12030, objectui#12370, objectui#12626): + * so in the refusal itself. Measured on the installed 18.0.0-next.3 (objectui#12030, objectui#12370, objectui#12626, objectui#12873): * * FieldSchema.safeParse({ type: 'lookup', label: 'L', referenceTo: 'account' }) * => success = false diff --git a/packages/plugin-detail/src/__tests__/recordDetailsInputs.spec-parity.test.ts b/packages/plugin-detail/src/__tests__/recordDetailsInputs.spec-parity.test.ts index 921be1f4cc..7de2286bd3 100644 --- a/packages/plugin-detail/src/__tests__/recordDetailsInputs.spec-parity.test.ts +++ b/packages/plugin-detail/src/__tests__/recordDetailsInputs.spec-parity.test.ts @@ -110,10 +110,11 @@ const specAcceptedTopLevelKeys = (): string[] => authorableShapeKeys(RecordDetai * `RecordDetailsProps` is this block's PROPS contract, not the whole contract of * the node: `dataSource`, the per-element binding this block reads since * objectui#12294 and declares from the seam, is a `PageComponentSchema` key. - * DERIVED from that schema's input shape (it is a `.pipe()`), never listed. + * DERIVED from that schema's own shape, never listed (a `.pipe()` through + * `@objectstack/spec` 18.0.0-next.2, whose input side carried the keys; a plain + * object since 18.0.0-next.3, objectstack `105902f`). */ -const nodeLevelSpecKeys = (): string[] => - authorableShapeKeys((PageComponentSchema as unknown as { _def?: { in?: unknown } })._def?.in); +const nodeLevelSpecKeys = (): string[] => authorableShapeKeys(PageComponentSchema); /** Member keys of one `sections[]` entry, per the spec. */ const specSectionKeys = (): string[] => diff --git a/packages/plugin-detail/src/__tests__/recordHighlightsInputs.spec-parity.test.ts b/packages/plugin-detail/src/__tests__/recordHighlightsInputs.spec-parity.test.ts index 33ca9562f5..0451e381b0 100644 --- a/packages/plugin-detail/src/__tests__/recordHighlightsInputs.spec-parity.test.ts +++ b/packages/plugin-detail/src/__tests__/recordHighlightsInputs.spec-parity.test.ts @@ -75,10 +75,11 @@ function specTopLevelKeys(): string[] { * `registry-inputs-spec-parity.test.ts` already make (objectui#6678). * `dataSource`, the per-element binding this block reads since objectui#12294 * and declares from the seam, is a `PageComponentSchema` key, not a - * `RecordHighlightsProps` one. DERIVED from that schema's input shape. + * `RecordHighlightsProps` one. DERIVED from that schema's own shape (a `.pipe()` + * through `@objectstack/spec` 18.0.0-next.2, a plain object since 18.0.0-next.3, + * objectstack `105902f`). */ -const nodeLevelSpecKeys = (): string[] => - authorableShapeKeys((PageComponentSchema as unknown as { _def?: { in?: unknown } })._def?.in); +const nodeLevelSpecKeys = (): string[] => authorableShapeKeys(PageComponentSchema); const config = () => ComponentRegistry.getConfig('record:highlights'); const inputs = () => config()?.inputs ?? []; diff --git a/packages/plugin-detail/src/__tests__/recordRelatedListInputs.spec-parity.test.ts b/packages/plugin-detail/src/__tests__/recordRelatedListInputs.spec-parity.test.ts index 3b6b1f5640..ac7d7e5b1b 100644 --- a/packages/plugin-detail/src/__tests__/recordRelatedListInputs.spec-parity.test.ts +++ b/packages/plugin-detail/src/__tests__/recordRelatedListInputs.spec-parity.test.ts @@ -84,14 +84,15 @@ const specTopLevelKeys = (): string[] => shapeKeys(RecordRelatedListProps); * through `ElementDataSourceGate` and now declares from that seam — is one of * them, and it is accepted here for the same reason `className` would be. * - * DERIVED from `PageComponentSchema`'s own input shape (it is a `.pipe()`), never - * listed, so a spec release moves it. The repo-wide half of this gate makes the + * DERIVED from `PageComponentSchema`'s own shape, never listed, so a spec release + * moves it. (It was a `.pipe()` through `@objectstack/spec` 18.0.0-next.2, whose + * input side carried the keys; 18.0.0-next.3 makes it a plain object, objectstack + * `105902f`.) The repo-wide half of this gate makes the * same widening in * `apps/console/src/__tests__/registry-inputs-spec-parity.test.ts`, and both * assert the derivation still discriminates. */ -const nodeLevelSpecKeys = (): string[] => - shapeKeys((PageComponentSchema as unknown as { _def?: { in?: unknown } })._def?.in); +const nodeLevelSpecKeys = (): string[] => shapeKeys(PageComponentSchema); const specAddKeys = (): string[] => shapeKeys(innerObject(RecordRelatedListProps, 'add')); const specPickerKeys = (): string[] => shapeKeys(innerObject(innerObject(RecordRelatedListProps, 'add'), 'picker')); diff --git a/packages/plugin-detail/src/index.tsx b/packages/plugin-detail/src/index.tsx index ff56ef265e..ed5903e490 100644 --- a/packages/plugin-detail/src/index.tsx +++ b/packages/plugin-detail/src/index.tsx @@ -966,7 +966,7 @@ ComponentRegistry.register('alert', RecordAlertRenderer, { // through `pickLocalized`, which is exactly what these descriptions teach. // Declaring the map arm therefore adds no shape the block does not already // honour; it stops the manifest gate warning `type-mismatch` on the - // recommended write. (The row DOES exist as of the installed 18.0.0-next.2 — read + // recommended write. (The row DOES exist as of the installed 18.0.0-next.3 — read // for `visible` below, objectui#9100 — so the "no entry" reading is stale; // these two arms are unaffected either way.) { name: 'title', type: ['string', 'object'], description: 'Accepts an inline translation map ({ en, "zh-CN", … })' }, @@ -974,7 +974,7 @@ ComponentRegistry.register('alert', RecordAlertRenderer, { // objectui#9100 — the spec accepts three arms here and the renderer now // resolves all three, so a single `'string'` was the declaration-narrower- // than-the-contract family of objectui#4581, one layer up. Measured on the - // INSTALLED `@objectstack/spec` 18.0.0-next.2 (`dist/ui/index.d.ts`, the + // INSTALLED `@objectstack/spec` 18.0.0-next.3 (`dist/ui/index.d.ts`, the // `ComponentPropsMap['record:alert']` row): `visible` is // `boolean | string | { dialect: 'cel'|'cron'|'template', source?, … }`, // and `renderers/record-alert.tsx` hands whichever arrives to diff --git a/packages/plugin-form/src/__tests__/formSectionGroupReference-7051.test.tsx b/packages/plugin-form/src/__tests__/formSectionGroupReference-7051.test.tsx index 32b6a3154c..1e886f7662 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.2): both are refused at PARSE + * against the installed `@objectstack/spec` (18.0.0-next.3): 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 c882557c56..acdbf0504e 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.2 entry carries a + * here before it is red anywhere else. The installed 18.0.0-next.3 entry carries a * `retiredKey()` tombstone for `sortField` (objectstack-ai/objectstack#21589); * 17.6.0 declared it as a string, and the subtraction removes the key either * way. ⛔ No row here pins which of the two shapes the spec has; the `Spec Main diff --git a/packages/plugin-gantt/src/readme-navigation-example.test.ts b/packages/plugin-gantt/src/readme-navigation-example.test.ts index 0e91176421..5504213ae0 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.2 lands it as a tombstone, + * member. The installed `@objectstack/spec` 18.0.0-next.3 lands it as a tombstone, * as 17.5.0 through 17.7.0 did (objectui#11073 measured it, objectui#11438, * objectui#11717 and objectui#12030 again: a `never` * schema, and `{ view: 'detail' }` is diff --git a/packages/plugin-kanban/src/index.tsx b/packages/plugin-kanban/src/index.tsx index fd50b45246..36a290c9f5 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.2 pin, fourteen of them live, the + * top-level keys on the installed 18.0.0-next.3 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/types/src/__tests__/chartconfig-aria-retired-4044.test.ts b/packages/types/src/__tests__/chartconfig-aria-retired-4044.test.ts index a9efdd4345..646e373d99 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.2 and on objectstack `main`, bare `undefined` + * mark at the pinned 18.0.0-next.3 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 4071dd2b1b..b653f23675 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.2 + * as the spec's retired key (the branded `[REMOVED]` mark at the pinned 18.0.0-next.3 * 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.2 and on objectstack + // the branded `[REMOVED]` mark at the pinned 18.0.0-next.3 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__/object-view-unmirrored-keys-7779.test.ts b/packages/types/src/__tests__/object-view-unmirrored-keys-7779.test.ts index 2a89f8e57c..3564ea7758 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.2). ⛔ Not a copy of the + * shape, off `@objectstack/spec` as installed (18.0.0-next.3). ⛔ 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__/page-component-view-data-12666.test.ts b/packages/types/src/__tests__/page-component-view-data-12666.test.ts index 2b1b7ed674..39b3c44cc2 100644 --- a/packages/types/src/__tests__/page-component-view-data-12666.test.ts +++ b/packages/types/src/__tests__/page-component-view-data-12666.test.ts @@ -34,9 +34,10 @@ * the binding), so it has no region leg here; that answer is the arm's own * and did not move with this change, because the spec's object-level check * never ran once a region child had failed. - * ⛔ No spec-side leg: the installed 18.0.0-next.2 still refuses the slotted - * binding and objectstack `main` accepts it, so a spec leg would read - * differently on the two trees objectui is built against. + * ⛔ No spec-side leg. None could be written while 18.0.0-next.2 refused the + * slotted binding and objectstack `main` accepted it. The installed + * 18.0.0-next.3 accepts it too (objectstack `a35f7a6`), so a spec leg is + * writable now; it would be a new assertion, not the bump that made it so. */ import { describe, it, expect } from 'vitest'; import { PageNodeSchema, safeValidateSchema } from '../zod/index.zod'; 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 8849a2cd1a..3a1fcfebc9 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.2 and on objectstack `main`, + * pinned 18.0.0-next.3 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__/select-option-spec-extension-7014.test.ts b/packages/types/src/__tests__/select-option-spec-extension-7014.test.ts index 466b771db8..c9ea01e3b5 100644 --- a/packages/types/src/__tests__/select-option-spec-extension-7014.test.ts +++ b/packages/types/src/__tests__/select-option-spec-extension-7014.test.ts @@ -86,13 +86,16 @@ const issueAtPath = (result: { success: boolean; error?: { issues: readonly any[ : result.error!.issues.find((i) => (i.path ?? []).at(-1) === key); describe('spec SelectOptionSchema — `description` is inside the vocabulary, `icon`/`disabled` are not', () => { - it('declares exactly the six keys 17.3.0 leaves it with', () => { + it('declares exactly the seven keys 18.0.0-next.3 leaves it with', () => { // If this list changes again, the comments in field-types.ts and // select-option.ts must be re-pointed with it rather than left stale. + // 17.3.0 added `description`; 18.0.0-next.3 added `kind`, the option's + // lifecycle category (objectstack `adad73f`). expect(SPEC_OPTION_KEYS).toEqual([ 'color', 'default', 'description', + 'kind', 'label', 'value', 'visibleWhen', 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 7457b344b5..ef54378953 100644 --- a/packages/types/src/__tests__/spec-object-refinements-7715.test.ts +++ b/packages/types/src/__tests__/spec-object-refinements-7715.test.ts @@ -277,8 +277,9 @@ const SITES = [ // `checkPageSlotPair` joined at 18 (objectstack#22568) and was attached by objectui#12030: // it reads `slots`, carried by reference. // objectui#12370's view-data check left this list with objectui#12666: objectstack#23784 - // removed it from the spec. The installed 18.0.0-next.2 still carries it, so the census - // below accounts for it by what it judges, not by name (`specChecksRemovedOnMain`). + // removed it from the spec, and 18.0.0-next.3 is the first release without it (objectstack + // `a35f7a6`). The census below accounts for it by what it judges, not by name + // (`specChecksRemovedOnMain`), which on the installed 18.0.0-next.3 finds nothing. // `checkPageRegionPlacement` joined at 18.0.0-next.2 and was attached by objectui#12626: it // reads `kind` and `template` (by reference) and each region's `name`, which objectui's own // region carries with the meaning `page.tsx` places it by; measured in its describe block above. @@ -372,9 +373,10 @@ const PAGE_SITE = 'SpecPageFields → PageNodeSchema (layout.zod.ts)'; * * objectstack#23784 deleted the spec's page-parse judge of a view-data * component's retired `api` binding, and objectstack builds this repository - * against its own spec tree, so no file here may name that export. The - * installed 18.0.0-next.2 still exports it and still attaches it to - * `PageSchema`, so the census would miscount by one. This reads every + * against its own spec tree, so no file here may name that export. Through + * 18.0.0-next.2 the spec exported it and attached it to `PageSchema`, where + * the census would miscount by one; 18.0.0-next.3 dropped it (objectstack + * `a35f7a6`), and on the installed 18.0.0-next.3 this answers empty. This reads every * exported check no site names and keeps the ones that refuse a slotted * `object-grid` naming `api` at its `properties.data.provider`: on next.2 that * is exactly the removed judge, and on a spec without it the list is empty, so diff --git a/packages/types/src/field-types.ts b/packages/types/src/field-types.ts index 81b45d441d..cabdbb27c4 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.2), `FieldSchema` declares + * Measured on the installed `@objectstack/spec` (18.0.0-next.3), `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.2: + * same ruling. Measured on the installed `@objectstack/spec` 18.0.0-next.3: * `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 @@ -692,7 +692,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.2: an option carrying `description` + * installed `@objectstack/spec` 18.0.0-next.3: 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 18d0e1f38a..015a74a6e0 100644 --- a/packages/types/src/objectql.ts +++ b/packages/types/src/objectql.ts @@ -4219,7 +4219,7 @@ export interface ObjectCalendarSchema extends BaseSchema { * (the spec's own `ObjectCalendarPropsSchema`) declares * `z.array(z.unknown()).optional()`, described *"Pre-fetched records — skips * the internal fetch"*. - * MEASURED on the installed artifact at `@objectstack/spec` 18.0.0-next.2 — the + * MEASURED on the installed artifact at `@objectstack/spec` 18.0.0-next.3 — 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 203c42ec64..c1013f673c 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.2, against a control — `columns: '2'` — that + * on the installed pin, 18.0.0-next.3, against a control — `columns: '2'` — that * parses green on the same instrument). Contract-first (Commandment #0.1): * the code moves to the contract's spelling, and today's `columns: 2` * authors are the defect surfacing rather than collateral damage. @@ -358,7 +358,7 @@ export interface RecordHighlightsComponentProps { * `RecordHighlightsProps.fields[]`'s object arm declares exactly * `name`/`label`/`type`/`readonly` and carries a `never` catchall, i.e. it is * `$strict`: an unlisted key is REFUSED, not stripped, and the refusal takes - * the WHOLE document with it. Measured on the installed pin, 18.0.0-next.2, + * the WHOLE document with it. Measured on the installed pin, 18.0.0-next.3, * `RecordHighlightsProps.safeParse({ fields: [{ name: 'x', icon: 'star' }] })` * is RED with `invalid_union` at `fields.0`. So `{ name: 'amount', icon: * 'dollar-sign' }` type-checked here and was refused at the door — a green @@ -390,7 +390,7 @@ export interface RecordHighlightsComponentProps { * `z.enum(['horizontal','vertical'])` behind a `.default('horizontal')`). * * It offered a third value, `grid`, until objectui#9187, and the contract - * never accepted it: measured on the installed pin, 18.0.0-next.2, + * never accepted it: measured on the installed pin, 18.0.0-next.3, * `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/select-option.ts b/packages/types/src/select-option.ts index f4cd05cb35..8d89612512 100644 --- a/packages/types/src/select-option.ts +++ b/packages/types/src/select-option.ts @@ -42,6 +42,11 @@ import type { SelectOption as SpecSelectOption } from '@objectstack/spec/data'; * for standalone forms and names that widening in its own `Omit`. * - `color` — colour code for badges/charts. * - `default` — marks the option the platform seeds a new record with. + * - `kind` — the option's lifecycle category, `open` / `won` / `lost` + * (`@objectstack/spec` 18.0.0-next.3). The spec takes it on a single-value + * `select` / `radio` field's options and requires it on every option of + * the field an object's `stageField` names; its form-view option list + * (`FormSelectOptionSchema`) does not take it. * * WHAT DIVERGES, each named at its own member below: `visibleWhen` (dropped * from the spec type in the `Omit` and re-declared on objectui's wire shape), diff --git a/packages/types/src/zod/objectql.zod.ts b/packages/types/src/zod/objectql.zod.ts index c7c4a11b2a..fd014d2512 100644 --- a/packages/types/src/zod/objectql.zod.ts +++ b/packages/types/src/zod/objectql.zod.ts @@ -1774,7 +1774,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.2 (objectui#12030, objectui#12370, objectui#12626), each of which answers + * and again on the installed 18.0.0-next.3 (objectui#12030, objectui#12370, objectui#12626, objectui#12873), each of which answers * every bullet below as 17.5.0 did: * * - `CalendarConfigSchema`'s `strictObject` options carry `surface` and @@ -1799,7 +1799,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.2 (objectui#12030, objectui#12370, objectui#12626). + * (objectui#11717), and again on the installed 18.0.0-next.3 (objectui#12030, objectui#12370, objectui#12626, objectui#12873). * * ⇒ 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 33771caf46..1a5acec4b9 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -35,7 +35,7 @@ importers: version: link:packages/test-support '@objectstack/spec': specifier: ^18.0.0-next.1 - version: 18.0.0-next.2(ai@7.0.65(zod@4.6.7)) + version: 18.0.0-next.3(ai@7.0.65(zod@4.6.7)) '@playwright/test': specifier: ^1.62.1 version: 1.62.1 @@ -273,13 +273,13 @@ importers: version: link:../../packages/types '@objectstack/client': specifier: ^18.0.0-next.1 - version: 18.0.0-next.2(ai@7.0.65(zod@4.6.7)) + version: 18.0.0-next.3(ai@7.0.65(zod@4.6.7)) '@objectstack/lint': specifier: ^18.0.0-next.1 - version: 18.0.0-next.2(ai@7.0.65(zod@4.6.7)) + version: 18.0.0-next.3(ai@7.0.65(zod@4.6.7)) '@objectstack/spec': specifier: ^18.0.0-next.1 - version: 18.0.0-next.2(ai@7.0.65(zod@4.6.7)) + version: 18.0.0-next.3(ai@7.0.65(zod@4.6.7)) '@tailwindcss/postcss': specifier: ^4.3.3 version: 4.3.3 @@ -417,7 +417,7 @@ importers: version: link:../../packages/types '@objectstack/spec': specifier: ^18.0.0-next.1 - version: 18.0.0-next.2(ai@7.0.65(zod@4.6.7)) + version: 18.0.0-next.3(ai@7.0.65(zod@4.6.7)) fumadocs-core: specifier: 16.15.4 version: 16.15.4(@mdx-js/mdx@3.1.1)(@tanstack/react-router@1.170.8(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(@types/estree-jsx@1.0.5)(@types/hast@3.0.5)(@types/mdast@4.0.4)(@types/react@19.2.18)(lucide-react@1.43.0(react@19.2.8))(next@16.3.6(@babel/core@7.29.7)(@opentelemetry/api@1.9.1)(@playwright/test@1.62.1)(@types/node@26.2.0)(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react-dom@19.2.8(react@19.2.8))(react-router@7.18.2(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react@19.2.8)(zod@4.6.7) @@ -775,13 +775,13 @@ importers: version: link:../types '@objectstack/formula': specifier: ^18.0.0-next.1 - version: 18.0.0-next.2(ai@7.0.65(zod@4.6.7)) + version: 18.0.0-next.3(ai@7.0.65(zod@4.6.7)) '@objectstack/lint': specifier: ^18.0.0-next.1 - version: 18.0.0-next.2(ai@7.0.65(zod@4.6.7)) + version: 18.0.0-next.3(ai@7.0.65(zod@4.6.7)) '@objectstack/spec': specifier: ^18.0.0-next.2 - version: 18.0.0-next.2(ai@7.0.65(zod@4.6.7)) + version: 18.0.0-next.3(ai@7.0.65(zod@4.6.7)) '@sentry/react': specifier: ^10.70.0 version: 10.70.0(react@19.2.8) @@ -872,7 +872,7 @@ importers: dependencies: '@objectstack/spec': specifier: ^18.0.0-next.1 - version: 18.0.0-next.2(ai@7.0.65(zod@4.6.7)) + version: 18.0.0-next.3(ai@7.0.65(zod@4.6.7)) better-auth: specifier: ^1.7.2 version: 1.7.2(@opentelemetry/api@1.9.1)(better-sqlite3@12.9.0)(mongodb@7.2.0(socks@2.8.9))(next@16.3.6(@babel/core@7.29.7)(@opentelemetry/api@1.9.1)(@playwright/test@1.62.1)(@types/node@26.2.0)(react-dom@19.2.8(react@19.2.8))(react@19.2.8))(react-dom@19.2.8(react@19.2.8))(react@19.2.8)(vitest@4.1.10) @@ -903,7 +903,7 @@ importers: version: link:../types '@objectstack/spec': specifier: ^18.0.0-next.1 - version: 18.0.0-next.2(ai@7.0.65(zod@4.6.7)) + version: 18.0.0-next.3(ai@7.0.65(zod@4.6.7)) '@tailwindcss/postcss': specifier: ^4.3.3 version: 4.3.3 @@ -971,7 +971,7 @@ importers: devDependencies: '@objectstack/spec': specifier: ^18.0.0-next.1 - version: 18.0.0-next.2(ai@7.0.65(zod@4.6.7)) + version: 18.0.0-next.3(ai@7.0.65(zod@4.6.7)) '@types/react': specifier: 19.2.18 version: 19.2.18 @@ -1007,7 +1007,7 @@ importers: version: link:../types '@objectstack/spec': specifier: ^18.0.0-next.1 - version: 18.0.0-next.2(ai@7.0.65(zod@4.6.7)) + version: 18.0.0-next.3(ai@7.0.65(zod@4.6.7)) '@radix-ui/react-accordion': specifier: ^1.2.20 version: 1.2.20(@types/react-dom@19.2.4(@types/react@19.2.18))(@types/react@19.2.18)(react-dom@19.2.8(react@19.2.8))(react@19.2.8) @@ -1191,10 +1191,10 @@ importers: version: link:../types '@objectstack/formula': specifier: ^18.0.0-next.1 - version: 18.0.0-next.2(ai@7.0.65(zod@4.6.7)) + version: 18.0.0-next.3(ai@7.0.65(zod@4.6.7)) '@objectstack/spec': specifier: ^18.0.0-next.1 - version: 18.0.0-next.2(ai@7.0.65(zod@4.6.7)) + version: 18.0.0-next.3(ai@7.0.65(zod@4.6.7)) devDependencies: '@object-ui/test-support': specifier: workspace:* @@ -1250,10 +1250,10 @@ importers: version: link:../types '@objectstack/client': specifier: ^18.0.0-next.1 - version: 18.0.0-next.2(ai@7.0.65(zod@4.6.7)) + version: 18.0.0-next.3(ai@7.0.65(zod@4.6.7)) '@objectstack/spec': specifier: ^18.0.0-next.1 - version: 18.0.0-next.2(ai@7.0.65(zod@4.6.7)) + version: 18.0.0-next.3(ai@7.0.65(zod@4.6.7)) devDependencies: '@object-ui/test-support': specifier: workspace:* @@ -1293,7 +1293,7 @@ importers: version: link:../types '@objectstack/spec': specifier: ^18.0.0-next.1 - version: 18.0.0-next.2(ai@7.0.65(zod@4.6.7)) + version: 18.0.0-next.3(ai@7.0.65(zod@4.6.7)) lucide-react: specifier: ^1.43.0 version: 1.43.0(react@19.2.8) @@ -1397,7 +1397,7 @@ importers: version: link:../types '@objectstack/spec': specifier: ^18.0.0-next.1 - version: 18.0.0-next.2(ai@7.0.65(zod@4.6.7)) + version: 18.0.0-next.3(ai@7.0.65(zod@4.6.7)) lucide-react: specifier: ^1.43.0 version: 1.43.0(react@19.2.8) @@ -1438,7 +1438,7 @@ importers: devDependencies: '@objectstack/spec': specifier: ^18.0.0-next.1 - version: 18.0.0-next.2(ai@7.0.65(zod@4.6.7)) + version: 18.0.0-next.3(ai@7.0.65(zod@4.6.7)) '@types/react': specifier: 19.2.18 version: 19.2.18 @@ -1459,7 +1459,7 @@ importers: version: link:../types '@objectstack/spec': specifier: ^18.0.0-next.1 - version: 18.0.0-next.2(ai@7.0.65(zod@4.6.7)) + version: 18.0.0-next.3(ai@7.0.65(zod@4.6.7)) devDependencies: '@types/react': specifier: 19.2.18 @@ -1622,7 +1622,7 @@ importers: version: link:../test-support '@objectstack/spec': specifier: ^18.0.0-next.1 - version: 18.0.0-next.2(ai@7.0.65(zod@4.6.7)) + version: 18.0.0-next.3(ai@7.0.65(zod@4.6.7)) '@types/react': specifier: 19.2.18 version: 19.2.18 @@ -1664,7 +1664,7 @@ importers: version: link:../types '@objectstack/spec': specifier: ^18.0.0-next.1 - version: 18.0.0-next.2(ai@7.0.65(zod@4.6.7)) + version: 18.0.0-next.3(ai@7.0.65(zod@4.6.7)) '@radix-ui/react-slot': specifier: ^1.3.3 version: 1.3.3(@types/react@19.2.18)(react@19.2.8) @@ -1755,7 +1755,7 @@ importers: version: link:../types '@objectstack/spec': specifier: ^18.0.0-next.1 - version: 18.0.0-next.2(ai@7.0.65(zod@4.6.7)) + version: 18.0.0-next.3(ai@7.0.65(zod@4.6.7)) lucide-react: specifier: ^1.43.0 version: 1.43.0(react@19.2.8) @@ -1825,7 +1825,7 @@ importers: version: link:../types '@objectstack/spec': specifier: ^18.0.0-next.1 - version: 18.0.0-next.2(ai@7.0.65(zod@4.6.7)) + version: 18.0.0-next.3(ai@7.0.65(zod@4.6.7)) clsx: specifier: ^2.1.1 version: 2.1.1 @@ -1877,7 +1877,7 @@ importers: version: link:../i18n '@objectstack/spec': specifier: ^18.0.0-next.1 - version: 18.0.0-next.2(ai@7.0.65(zod@4.6.7)) + version: 18.0.0-next.3(ai@7.0.65(zod@4.6.7)) lucide-react: specifier: ^1.43.0 version: 1.43.0(react@19.2.8) @@ -2002,7 +2002,7 @@ importers: version: link:../types '@objectstack/spec': specifier: ^18.0.0-next.1 - version: 18.0.0-next.2(ai@7.0.65(zod@4.6.7)) + version: 18.0.0-next.3(ai@7.0.65(zod@4.6.7)) lucide-react: specifier: ^1.43.0 version: 1.43.0(react@19.2.8) @@ -2063,7 +2063,7 @@ importers: version: link:../types '@objectstack/spec': specifier: ^18.0.0-next.1 - version: 18.0.0-next.2(ai@7.0.65(zod@4.6.7)) + version: 18.0.0-next.3(ai@7.0.65(zod@4.6.7)) lucide-react: specifier: ^1.43.0 version: 1.43.0(react@19.2.8) @@ -2133,7 +2133,7 @@ importers: version: link:../types '@objectstack/spec': specifier: ^18.0.0-next.1 - version: 18.0.0-next.2(ai@7.0.65(zod@4.6.7)) + version: 18.0.0-next.3(ai@7.0.65(zod@4.6.7)) '@tanstack/react-virtual': specifier: ^3.14.9 version: 3.14.9(react-dom@19.2.8(react@19.2.8))(react@19.2.8) @@ -2307,7 +2307,7 @@ importers: version: link:../types '@objectstack/spec': specifier: ^18.0.0-next.1 - version: 18.0.0-next.2(ai@7.0.65(zod@4.6.7)) + version: 18.0.0-next.3(ai@7.0.65(zod@4.6.7)) '@types/react': specifier: 19.2.18 version: 19.2.18 @@ -2484,7 +2484,7 @@ importers: version: link:../test-support '@objectstack/spec': specifier: ^18.0.0-next.1 - version: 18.0.0-next.2(ai@7.0.65(zod@4.6.7)) + version: 18.0.0-next.3(ai@7.0.65(zod@4.6.7)) '@types/node': specifier: ^26.2.0 version: 26.2.0 @@ -2532,7 +2532,7 @@ importers: version: link:../types '@objectstack/spec': specifier: ^18.0.0-next.1 - version: 18.0.0-next.2(ai@7.0.65(zod@4.6.7)) + version: 18.0.0-next.3(ai@7.0.65(zod@4.6.7)) class-variance-authority: specifier: ^0.7.1 version: 0.7.1 @@ -2602,7 +2602,7 @@ importers: version: link:../types '@objectstack/spec': specifier: ^18.0.0-next.1 - version: 18.0.0-next.2(ai@7.0.65(zod@4.6.7)) + version: 18.0.0-next.3(ai@7.0.65(zod@4.6.7)) lucide-react: specifier: ^1.43.0 version: 1.43.0(react@19.2.8) @@ -2675,7 +2675,7 @@ importers: version: link:../types '@objectstack/spec': specifier: ^18.0.0-next.1 - version: 18.0.0-next.2(ai@7.0.65(zod@4.6.7)) + version: 18.0.0-next.3(ai@7.0.65(zod@4.6.7)) class-variance-authority: specifier: ^0.7.1 version: 0.7.1 @@ -2740,7 +2740,7 @@ importers: version: link:../types '@objectstack/spec': specifier: ^18.0.0-next.1 - version: 18.0.0-next.2(ai@7.0.65(zod@4.6.7)) + version: 18.0.0-next.3(ai@7.0.65(zod@4.6.7)) react: specifier: 19.2.8 version: 19.2.8 @@ -2805,7 +2805,7 @@ importers: devDependencies: '@objectstack/spec': specifier: ^18.0.0-next.1 - version: 18.0.0-next.2(ai@7.0.65(zod@4.6.7)) + version: 18.0.0-next.3(ai@7.0.65(zod@4.6.7)) '@tailwindcss/postcss': specifier: ^4.3.3 version: 4.3.3 @@ -2847,13 +2847,13 @@ importers: version: link:../types '@objectstack/spec': specifier: ^18.0.0-next.1 - version: 18.0.0-next.2(ai@7.0.65(zod@4.6.7)) + version: 18.0.0-next.3(ai@7.0.65(zod@4.6.7)) packages/test-support: devDependencies: '@objectstack/spec': specifier: ^18.0.0-next.1 - version: 18.0.0-next.2(ai@7.0.65(zod@4.6.7)) + version: 18.0.0-next.3(ai@7.0.65(zod@4.6.7)) '@types/node': specifier: ^26.2.0 version: 26.2.0 @@ -2868,7 +2868,7 @@ importers: dependencies: '@objectstack/spec': specifier: ^18.0.0-next.2 - version: 18.0.0-next.2(ai@7.0.65(zod@4.6.7)) + version: 18.0.0-next.3(ai@7.0.65(zod@4.6.7)) zod: specifier: ^4.6.1 version: 4.6.7 @@ -4232,26 +4232,26 @@ packages: resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} engines: {node: '>= 8'} - '@objectstack/client@18.0.0-next.2': - resolution: {integrity: sha512-17d28OcMqU0QkauexCzOtR6O8kRuiUm2iVo/M1gn8iIZ4+K4JMzt69szVE4Se1IQ6EBoJZ+pWOf/xgt1efF0gA==} + '@objectstack/client@18.0.0-next.3': + resolution: {integrity: sha512-eiIPhI/SCf5uVJGoc6Yt4/UPrR/yj7DRSCzLqjZMST7jp/wCE8OkHbVNXwOJ3A3hVUrf/+O0swU53QwLfLP5Hw==} engines: {node: '>=22.0.0'} - '@objectstack/core@18.0.0-next.2': - resolution: {integrity: sha512-K5ZnDtUGt7UrY6ZS9UVI1okcYaiVDTdxj7I7Hw5wznFqThlZmREFETWIHr1OGnIiRElInB9bsjteVBfC+zUh5w==} + '@objectstack/core@18.0.0-next.3': + resolution: {integrity: sha512-9C9VR/T1EC2ai46T3CSMync/1v99hmHmoHg1sCZKvfs/eske9Hnt5Eqp8B+pTOqm1w3a8PESx8GEAZe8ct7aVA==} engines: {node: '>=22.0.0'} - '@objectstack/formula@18.0.0-next.2': - resolution: {integrity: sha512-zbrGzFNfn4+cjuCkpzRukEIniKuAaRaQGpoIa055uzBk0k/7Wn01gclC02rmFSTuwTyhvTshijkQBVYd8Y1grw==} + '@objectstack/formula@18.0.0-next.3': + resolution: {integrity: sha512-IAQVp6nxpHym+nJ2Sk1mTcIu01Qez6ak9TJNfjh4jwwFKQk1TahwB+0bB8JLXGDUnsdAegH5IQzEM+5CY3T9aA==} - '@objectstack/lint@18.0.0-next.2': - resolution: {integrity: sha512-Gx7YTMnw6YVtWtH2ISNNNd696WhoegBIUYmc25w7bxJ3voswRwcovEOXFt22SW9RzRolARkNhPsJU/Pz2c4Egg==} + '@objectstack/lint@18.0.0-next.3': + resolution: {integrity: sha512-aoAncO2ohd9qc9k7Py2Cw4+oIbWDXMVqAe+wL5zJT3rWZqjb0IfilHn6tfscTDZVWzN29d9GQR28KcbPQOYvsQ==} engines: {node: '>=22.0.0'} - '@objectstack/sdui-parser@18.0.0-next.2': - resolution: {integrity: sha512-D1TvInAAcdIVmDDeHdQhe+FWbFNIsJp05sC1qoKrUKhgYQCDrg/O14w1wqAyl2aqubd7STSxx9iBPzUurlVZEA==} + '@objectstack/sdui-parser@18.0.0-next.3': + resolution: {integrity: sha512-EI9FhJPACp8Hq2QY9duargzuyyoA3eRKSxGDBg3XbgI0oEIVaC9/InhhK1yNHz5/rzsFpxzLN8Aw5oteD/11Jg==} - '@objectstack/spec@18.0.0-next.2': - resolution: {integrity: sha512-cOENas5Zq1Vlum3AhiJVhoWRfZyJkcW2nhB3TuL+Ic5psP02DrWz4vEEqD12Ngp0wrcADCCuKFiIzXHoZ4qb0A==} + '@objectstack/spec@18.0.0-next.3': + resolution: {integrity: sha512-dX3SO5l9rsKLv0N8XUFPg5SH4hV6/J+JYjcczFGuGAQuFN5sOx+C97WKw8qKLv4TrWW9hNoM8dnKsvbMEHxqjQ==} engines: {node: '>=22.0.0'} peerDependencies: ai: ^7.0.0 @@ -4259,8 +4259,8 @@ packages: ai: optional: true - '@objectstack/types@18.0.0-next.2': - resolution: {integrity: sha512-ScT2JGBHqOElmFLKC9aj4t6oSa9BBYdgqznar6YQY31vMahivILGF6ZHBCyRz4EBGa2lXyFbY9MjKeaVJ4Cy0w==} + '@objectstack/types@18.0.0-next.3': + resolution: {integrity: sha512-wbW4PFH7MJDDzionDnK9TDUrhjD+wD0xwytc4l/JHy3J5aeyzo6mDrPSlL3MLN48uracZ/MSER8E7grg4w4Qdg==} engines: {node: '>=22.0.0'} '@open-draft/deferred-promise@2.2.0': @@ -9322,8 +9322,8 @@ packages: pend@1.2.0: resolution: {integrity: sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==} - pg-connection-string@2.14.0: - resolution: {integrity: sha512-XwWDGcLRGCXAR8F/AM5bG7Q+A3Wm2s6QeEjlOKZLlH3UYcguiqCWKyWXVag5TLTIjR7oOJUY8kcADaZgWPyLeg==} + pg-connection-string@2.14.1: + resolution: {integrity: sha512-qR3kGNPBLpCNtz0evbKA0Y/MRFXwSSdT+pTJvYp/bXTcReZbvX1kzF0IyTc1QnxqF7AZbOeBhNL8R5mYQZV/MA==} picocolors@1.1.1: resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} @@ -12337,33 +12337,33 @@ snapshots: '@nodelib/fs.scandir': 2.1.5 fastq: 1.20.1 - '@objectstack/client@18.0.0-next.2(ai@7.0.65(zod@4.6.7))': + '@objectstack/client@18.0.0-next.3(ai@7.0.65(zod@4.6.7))': dependencies: - '@objectstack/core': 18.0.0-next.2(ai@7.0.65(zod@4.6.7)) - '@objectstack/spec': 18.0.0-next.2(ai@7.0.65(zod@4.6.7)) + '@objectstack/core': 18.0.0-next.3(ai@7.0.65(zod@4.6.7)) + '@objectstack/spec': 18.0.0-next.3(ai@7.0.65(zod@4.6.7)) transitivePeerDependencies: - ai - '@objectstack/core@18.0.0-next.2(ai@7.0.65(zod@4.6.7))': + '@objectstack/core@18.0.0-next.3(ai@7.0.65(zod@4.6.7))': dependencies: - '@objectstack/spec': 18.0.0-next.2(ai@7.0.65(zod@4.6.7)) - '@objectstack/types': 18.0.0-next.2(ai@7.0.65(zod@4.6.7)) + '@objectstack/spec': 18.0.0-next.3(ai@7.0.65(zod@4.6.7)) + '@objectstack/types': 18.0.0-next.3(ai@7.0.65(zod@4.6.7)) zod: 4.6.7 transitivePeerDependencies: - ai - '@objectstack/formula@18.0.0-next.2(ai@7.0.65(zod@4.6.7))': + '@objectstack/formula@18.0.0-next.3(ai@7.0.65(zod@4.6.7))': dependencies: '@marcbachmann/cel-js': 8.0.0 - '@objectstack/spec': 18.0.0-next.2(ai@7.0.65(zod@4.6.7)) + '@objectstack/spec': 18.0.0-next.3(ai@7.0.65(zod@4.6.7)) transitivePeerDependencies: - ai - '@objectstack/lint@18.0.0-next.2(ai@7.0.65(zod@4.6.7))': + '@objectstack/lint@18.0.0-next.3(ai@7.0.65(zod@4.6.7))': dependencies: - '@objectstack/formula': 18.0.0-next.2(ai@7.0.65(zod@4.6.7)) - '@objectstack/sdui-parser': 18.0.0-next.2 - '@objectstack/spec': 18.0.0-next.2(ai@7.0.65(zod@4.6.7)) + '@objectstack/formula': 18.0.0-next.3(ai@7.0.65(zod@4.6.7)) + '@objectstack/sdui-parser': 18.0.0-next.3 + '@objectstack/spec': 18.0.0-next.3(ai@7.0.65(zod@4.6.7)) ajv: 8.20.0 ajv-formats: 3.0.1(ajv@8.20.0) sucrase: 3.35.1 @@ -12371,18 +12371,18 @@ snapshots: transitivePeerDependencies: - ai - '@objectstack/sdui-parser@18.0.0-next.2': {} + '@objectstack/sdui-parser@18.0.0-next.3': {} - '@objectstack/spec@18.0.0-next.2(ai@7.0.65(zod@4.6.7))': + '@objectstack/spec@18.0.0-next.3(ai@7.0.65(zod@4.6.7))': dependencies: - pg-connection-string: 2.14.0 + pg-connection-string: 2.14.1 zod: 4.6.7 optionalDependencies: ai: 7.0.65(zod@4.6.7) - '@objectstack/types@18.0.0-next.2(ai@7.0.65(zod@4.6.7))': + '@objectstack/types@18.0.0-next.3(ai@7.0.65(zod@4.6.7))': dependencies: - '@objectstack/spec': 18.0.0-next.2(ai@7.0.65(zod@4.6.7)) + '@objectstack/spec': 18.0.0-next.3(ai@7.0.65(zod@4.6.7)) transitivePeerDependencies: - ai @@ -17839,7 +17839,7 @@ snapshots: pend@1.2.0: {} - pg-connection-string@2.14.0: {} + pg-connection-string@2.14.1: {} picocolors@1.1.1: {} diff --git a/scripts/__tests__/check-lockfile-integrity.test.ts b/scripts/__tests__/check-lockfile-integrity.test.ts index 70393bd209..94810bcb5c 100644 --- a/scripts/__tests__/check-lockfile-integrity.test.ts +++ b/scripts/__tests__/check-lockfile-integrity.test.ts @@ -90,7 +90,7 @@ describe('green on main — the negative control', () => { * ⛔ It cannot be produced by running the resolver, and that impossibility is * the card's central claim: every workspace range on `@objectstack/*` is a * floating range that a fresh resolve satisfies with the newest release — `^18.0.0-next.1` - * resolving 18.0.0-next.2 today (objectui#12030, objectui#12370, objectui#12626; `^17.x` and 17.4.0 when this sample was + * resolving 18.0.0-next.3 today (objectui#12030, objectui#12370, objectui#12626, objectui#12873; `^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\\.2`, 'g'), '$117.2.0'); + out = out.replace(new RegExp(`(@objectstack/${pkg}@)18\\.0\\.0-next\\.3`, 'g'), '$117.2.0'); } - const specKey = " '@objectstack/spec@18.0.0-next.2(ai@7.0.65(zod@4.6.7))':"; + const specKey = " '@objectstack/spec@18.0.0-next.3(ai@7.0.65(zod@4.6.7))':"; 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.2(ai@7.0.65(zod@4.6.7))':", - " '@objectstack/formula@18.0.0-next.2(ai@7.0.65(zod@4.6.7))':", + " '@objectstack/spec@18.0.0-next.3(ai@7.0.65(zod@4.6.7))':", + " '@objectstack/formula@18.0.0-next.3(ai@7.0.65(zod@4.6.7))':", " ai@7.0.65(zod@4.6.7):", ]; 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.2'))).toBe(true); + expect(spec?.head.every((k) => k.includes('@18.0.0-next.3'))).toBe(true); }); });