From e93e132b3766ebd232e576d7db01b236d9cf77e3 Mon Sep 17 00:00:00 2001 From: Jack Zhuang <277994282+os-zhuang@users.noreply.github.com> Date: Thu, 16 Jul 2026 17:05:51 +0800 Subject: [PATCH 1/3] feat(types)!: adopt @objectstack/spec 15; drop value-erased spec/ui Schema re-exports (#2561) Decision (a) from #2561: the ~84 zod-validator names (DndConfigSchema, SpecFormViewSchema, ThemeModeSchema, ...) sat inside 'export type' blocks, so importing any of them as a value from @object-ui/types silently yielded undefined at runtime. They are removed from the public surface instead of converted to value re-exports; consumers needing the runtime validators import @objectstack/spec/ui directly. Inferred types unchanged; genuine value re-exports (defineStack, ObjectStackSchema, SpecReportSchema, ...) keep working. Guardrail test pins the contract both at runtime and via source scan. Bump @objectstack/spec ^14.6.0 -> ^15.0.1 across all 14 workspace package.json files. The floor is 15.0.1: ADR-0089 D3a's .strict().transform() pipes crashed z.toJSONSchema over spec's lazySchema proxies, breaking Studio's spec-derived Page/View inspector schemas (fixed upstream in framework#3021). New view-schema.test.ts pins the previously-untested View inspector derivation. Closes #2561 Co-Authored-By: Claude Fable 5 --- .changeset/spec-15-ui-schema-reexports.md | 9 + apps/console/package.json | 2 +- apps/site/package.json | 2 +- package.json | 2 +- packages/app-shell/package.json | 2 +- .../views/metadata-admin/view-schema.test.ts | 49 +++++ packages/core/package.json | 2 +- packages/plugin-detail/package.json | 2 +- packages/plugin-form/package.json | 2 +- packages/plugin-gantt/package.json | 2 +- packages/plugin-map/package.json | 2 +- packages/plugin-timeline/package.json | 2 +- packages/plugin-tree/package.json | 2 +- packages/plugin-view/package.json | 2 +- packages/react/package.json | 2 +- packages/types/README.md | 4 +- packages/types/package.json | 2 +- .../spec-ui-schema-reexports.test.ts | 184 ++++++++++++++++++ packages/types/src/index.ts | 96 ++------- packages/types/src/theme.ts | 8 +- pnpm-lock.yaml | 71 ++++--- 21 files changed, 317 insertions(+), 132 deletions(-) create mode 100644 .changeset/spec-15-ui-schema-reexports.md create mode 100644 packages/app-shell/src/views/metadata-admin/view-schema.test.ts create mode 100644 packages/types/src/__tests__/spec-ui-schema-reexports.test.ts diff --git a/.changeset/spec-15-ui-schema-reexports.md b/.changeset/spec-15-ui-schema-reexports.md new file mode 100644 index 000000000..cb864c282 --- /dev/null +++ b/.changeset/spec-15-ui-schema-reexports.md @@ -0,0 +1,9 @@ +--- +'@object-ui/types': major +--- + +Adopt `@objectstack/spec` 15 across the workspace and drop the value-erased `…Schema` re-exports from `@object-ui/types` (#2561). + +**Removed exports.** `packages/types` re-exported the `@objectstack/spec/ui` surface inside `export type { … }` blocks, and those blocks included the zod validators (`DndConfigSchema`, `SpecFormViewSchema`, `ThemeModeSchema`, … 84 names in total). Under `export type` a zod value is erased, so importing any of them as a value from `@object-ui/types` silently yielded `undefined` at runtime. Per the #2561 decision (option a) the schema names are removed from the public surface instead of being converted to value re-exports — consumers that need the runtime validators import them from `@objectstack/spec/ui` directly. The inferred types (`DndConfig`, `SpecFormView`, …) are unchanged, and the genuine value re-exports (`defineStack`, `ObjectStackSchema`, `SpecReportSchema`, …) keep working. `BreakpointColumnMapSchema` / `BreakpointOrderMapSchema` are dropped without a type replacement (the spec exports no companion inferred type). A guardrail test (`spec-ui-schema-reexports.test.ts`) pins the contract. + +**Spec 15.** Every workspace package now depends on `@objectstack/spec` ^15.0.1. The `/ui` export-name set is identical to 14.6; the spec-level breaking change is ADR-0089 D3a — `FormFieldSchema` / `FormSectionSchema` / `PageComponentSchema` are `.strict()` and reject undeclared keys, which the workspace test suite passes under. The floor is 15.0.1 (not 15.0.0) because D3a's `.strict().transform(…)` pipes crashed `z.toJSONSchema` over spec's lazySchema proxies (`Cannot set properties of undefined (setting 'ref')`), breaking Studio's spec-derived Page/View inspector schemas; fixed upstream in framework#3021. New `view-schema.test.ts` pins the View-inspector derivation (previously untested — it degraded silently). diff --git a/apps/console/package.json b/apps/console/package.json index fb6513d33..a06e2491f 100644 --- a/apps/console/package.json +++ b/apps/console/package.json @@ -88,7 +88,7 @@ "@object-ui/react": "workspace:*", "@object-ui/types": "workspace:*", "@objectstack/client": "^14.6.0", - "@objectstack/spec": "^14.6.0", + "@objectstack/spec": "^15.0.1", "@tailwindcss/postcss": "^4.3.2", "@tailwindcss/typography": "^0.5.20", "@testing-library/jest-dom": "^6.9.1", diff --git a/apps/site/package.json b/apps/site/package.json index 17c0793d9..b4a8f98be 100644 --- a/apps/site/package.json +++ b/apps/site/package.json @@ -31,7 +31,7 @@ "@object-ui/plugin-view": "workspace:*", "@object-ui/react": "workspace:*", "@object-ui/types": "workspace:*", - "@objectstack/spec": "^14.6.0", + "@objectstack/spec": "^15.0.1", "fumadocs-core": "16.11.3", "fumadocs-mdx": "15.0.13", "fumadocs-ui": "16.11.3", diff --git a/package.json b/package.json index a0d160b3b..1f4c90003 100644 --- a/package.json +++ b/package.json @@ -61,7 +61,7 @@ "devDependencies": { "@changesets/cli": "^2.31.0", "@eslint/js": "^10.0.1", - "@objectstack/spec": "^14.6.0", + "@objectstack/spec": "^15.0.1", "@playwright/test": "^1.61.1", "@testing-library/dom": "^10.4.1", "@testing-library/jest-dom": "^6.9.1", diff --git a/packages/app-shell/package.json b/packages/app-shell/package.json index 61d743c17..77bbf9813 100644 --- a/packages/app-shell/package.json +++ b/packages/app-shell/package.json @@ -50,7 +50,7 @@ "@object-ui/types": "workspace:*", "@objectstack/formula": "^14.6.0", "@objectstack/lint": "^14.6.0", - "@objectstack/spec": "^14.6.0", + "@objectstack/spec": "^15.0.1", "@sentry/react": "^10.65.0", "jsonc-parser": "^3.3.1", "lucide-react": "^1.24.0", diff --git a/packages/app-shell/src/views/metadata-admin/view-schema.test.ts b/packages/app-shell/src/views/metadata-admin/view-schema.test.ts new file mode 100644 index 000000000..7053f410f --- /dev/null +++ b/packages/app-shell/src/views/metadata-admin/view-schema.test.ts @@ -0,0 +1,49 @@ +// Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. + +import { describe, it, expect } from 'vitest'; +import { + getListVariantSchema, + getFormVariantSchema, + getListColumnSchema, + getViewForm, +} from './view-schema'; + +/** + * Regression for objectui#2561: the View inspector's spec-derived JSONSchema + * had no test, so when spec 15 (ADR-0089 D3a) turned FormFieldSchema into a + * `.strict().transform(…)` pipe and crashed `z.toJSONSchema` over the + * lazySchema proxy (fixed upstream in framework#3021), the inspector degraded + * silently. Pin the derivation like page-schema.test.ts does for pages. + */ +describe('view-schema (spec-derived View authoring metadata)', () => { + it('derives the list-variant JSONSchema from the spec ViewSchema', () => { + const schema = getListVariantSchema(); + expect(schema).toBeTruthy(); + expect(JSON.stringify(schema)).toContain('kanban'); + }); + + it('derives the form-variant JSONSchema (recursive strict FormFieldSchema)', () => { + const schema = getFormVariantSchema(); + expect(schema).toBeTruthy(); + expect(JSON.stringify(schema)).toContain('sections'); + }); + + it('derives the ListColumn JSONSchema', () => { + expect(getListColumnSchema()).toBeTruthy(); + }); + + it('prunes inspector-owned fields from the authoring form', () => { + const form = getViewForm(); + if (form) { + const declared = new Set(); + for (const s of form.sections ?? []) { + for (const f of s.fields ?? []) { + declared.add(typeof f === 'string' ? f : (f as any)?.field); + } + } + for (const owned of ['columns', 'data', 'name']) { + expect(declared.has(owned)).toBe(false); + } + } + }); +}); diff --git a/packages/core/package.json b/packages/core/package.json index 66f71ec05..70ac0edad 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -33,7 +33,7 @@ "dependencies": { "@object-ui/types": "workspace:*", "@objectstack/formula": "^14.6.0", - "@objectstack/spec": "^14.6.0", + "@objectstack/spec": "^15.0.1", "lodash": "^4.18.1", "zod": "^4.4.3" }, diff --git a/packages/plugin-detail/package.json b/packages/plugin-detail/package.json index 0a88f1f6a..b6bc99ee7 100644 --- a/packages/plugin-detail/package.json +++ b/packages/plugin-detail/package.json @@ -32,7 +32,7 @@ }, "dependencies": { "@object-ui/i18n": "workspace:*", - "@objectstack/spec": "^14.6.0", + "@objectstack/spec": "^15.0.1", "lucide-react": "^1.24.0" }, "peerDependencies": { diff --git a/packages/plugin-form/package.json b/packages/plugin-form/package.json index e20a698db..a8b6a03d5 100644 --- a/packages/plugin-form/package.json +++ b/packages/plugin-form/package.json @@ -27,7 +27,7 @@ "@object-ui/permissions": "workspace:*", "@object-ui/react": "workspace:*", "@object-ui/types": "workspace:*", - "@objectstack/spec": "^14.6.0", + "@objectstack/spec": "^15.0.1", "lucide-react": "^1.24.0" }, "peerDependencies": { diff --git a/packages/plugin-gantt/package.json b/packages/plugin-gantt/package.json index 243511db0..e077bf624 100644 --- a/packages/plugin-gantt/package.json +++ b/packages/plugin-gantt/package.json @@ -38,7 +38,7 @@ "@object-ui/plugin-detail": "workspace:*", "@object-ui/react": "workspace:*", "@object-ui/types": "workspace:*", - "@objectstack/spec": "^14.6.0", + "@objectstack/spec": "^15.0.1", "lucide-react": "^1.24.0", "qrcode": "^1.5.4", "sonner": "^2.0.7" diff --git a/packages/plugin-map/package.json b/packages/plugin-map/package.json index cb90eb3df..c44ec78d5 100644 --- a/packages/plugin-map/package.json +++ b/packages/plugin-map/package.json @@ -35,7 +35,7 @@ "@object-ui/core": "workspace:*", "@object-ui/react": "workspace:*", "@object-ui/types": "workspace:*", - "@objectstack/spec": "^14.6.0", + "@objectstack/spec": "^15.0.1", "lucide-react": "^1.24.0", "maplibre-gl": "^5.24.0", "react-map-gl": "^8.1.1", diff --git a/packages/plugin-timeline/package.json b/packages/plugin-timeline/package.json index 7294865c4..9c6cc130a 100644 --- a/packages/plugin-timeline/package.json +++ b/packages/plugin-timeline/package.json @@ -36,7 +36,7 @@ "@object-ui/mobile": "workspace:*", "@object-ui/react": "workspace:*", "@object-ui/types": "workspace:*", - "@objectstack/spec": "^14.6.0", + "@objectstack/spec": "^15.0.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 47b813bb7..b0bf1fc5f 100644 --- a/packages/plugin-tree/package.json +++ b/packages/plugin-tree/package.json @@ -35,7 +35,7 @@ "@object-ui/core": "workspace:*", "@object-ui/react": "workspace:*", "@object-ui/types": "workspace:*", - "@objectstack/spec": "^14.6.0", + "@objectstack/spec": "^15.0.1", "lucide-react": "^1.24.0" }, "peerDependencies": { diff --git a/packages/plugin-view/package.json b/packages/plugin-view/package.json index cbe0cefb7..e7143a62a 100644 --- a/packages/plugin-view/package.json +++ b/packages/plugin-view/package.json @@ -21,7 +21,7 @@ }, "dependencies": { "@dnd-kit/core": "^6.3.1", - "@objectstack/spec": "^14.6.0", + "@objectstack/spec": "^15.0.1", "@dnd-kit/sortable": "^10.0.0", "@dnd-kit/utilities": "^3.2.2", "@object-ui/components": "workspace:*", diff --git a/packages/react/package.json b/packages/react/package.json index 884992e0d..b182593c3 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": "^14.6.0", + "@objectstack/spec": "^15.0.1", "react-hook-form": "^7.81.0" }, "peerDependencies": { diff --git a/packages/types/README.md b/packages/types/README.md index a3681107e..9a95f37ff 100644 --- a/packages/types/README.md +++ b/packages/types/README.md @@ -29,7 +29,7 @@ pnpm add @object-ui/types Object UI follows a strict **"Protocol First"** approach with a clear inheritance hierarchy: ``` -@objectstack/spec (v4.0.x) ← The "Highest Law" - Universal protocol +@objectstack/spec (v15.x) ← The "Highest Law" - Universal protocol ↓ UIComponent ← Base interface for all UI components ↓ @@ -307,7 +307,7 @@ We follow these constraints for this package: - **Node.js:** ≥ 18 - **TypeScript:** ≥ 5.0 (strict mode) -- **`@objectstack/spec`:** ^4.0.4 +- **`@objectstack/spec`:** ^15.0.0 - **`@objectstack/client`:** ^3.3.0 - **Tailwind CSS:** ≥ 3.4 (for packages with UI) diff --git a/packages/types/package.json b/packages/types/package.json index 01cb2816e..873f9d474 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -90,7 +90,7 @@ "directory": "packages/types" }, "dependencies": { - "@objectstack/spec": "^14.6.0", + "@objectstack/spec": "^15.0.1", "zod": "^4.4.3" }, "devDependencies": { diff --git a/packages/types/src/__tests__/spec-ui-schema-reexports.test.ts b/packages/types/src/__tests__/spec-ui-schema-reexports.test.ts new file mode 100644 index 000000000..0a9249a6f --- /dev/null +++ b/packages/types/src/__tests__/spec-ui-schema-reexports.test.ts @@ -0,0 +1,184 @@ +/** + * Guardrail for #2561 — decision (a): the zod validators (`…Schema`) of + * `@objectstack/spec/ui` are NOT part of @object-ui/types' public surface. + * + * Background: index.ts re-exports the spec UI surface inside + * `export type { … }` blocks. A zod schema listed in such a block is + * value-erased — a consumer importing it as a value silently got `undefined` + * at runtime. Decision (a) drops those names instead of converting them to + * value re-exports; consumers needing the runtime validators import + * `@objectstack/spec/ui` directly. + * + * Note: dual type+value names (`Dashboard`, `DensityMode`, `ThemeMode`, …) + * are intentionally re-exported type-only — only `…Schema`-suffixed zod + * values are governed by this contract. + */ +import { describe, it, expect } from 'vitest'; +import { readFileSync } from 'node:fs'; +import { fileURLToPath } from 'node:url'; +import { dirname, join } from 'node:path'; +import * as SpecUI from '@objectstack/spec/ui'; +import * as Types from '../index'; + +const SRC_DIR = join(dirname(fileURLToPath(import.meta.url)), '..'); + +/** + * The public names dropped in #2561 (previously value-erased `export type` + * re-exports of spec/ui zod schemas, listed under their exported alias). + */ +const DROPPED_SCHEMA_EXPORTS = [ + // Drag and Drop + 'DndConfigSchema', + 'DragItemSchema', + 'DropZoneSchema', + 'DragConstraintSchema', + 'DragHandleSchema', + 'DropEffectSchema', + // Focus & Keyboard Navigation + 'FocusManagementSchema', + 'FocusTrapConfigSchema', + 'KeyboardNavigationConfigSchema', + 'KeyboardShortcutSchema', + // Animation & Motion + 'ComponentAnimationSchema', + 'AnimationTriggerSchema', + 'MotionConfigSchema', + 'TransitionConfigSchema', + 'TransitionPresetSchema', + 'EasingFunctionSchema', + // Notifications + 'NotificationSchema', + 'NotificationConfigSchema', + 'NotificationActionSchema', + 'NotificationPositionSchema', + 'NotificationSeveritySchema', + 'NotificationTypeSchema', + // Gestures & Touch + 'SpecGestureConfigSchema', + 'SpecGestureTypeSchema', + 'SwipeGestureConfigSchema', + 'SwipeDirectionSchema', + 'PinchGestureConfigSchema', + 'LongPressGestureConfigSchema', + 'TouchInteractionSchema', + 'TouchTargetConfigSchema', + // Offline & Sync + 'SpecOfflineConfigSchema', + 'OfflineCacheConfigSchema', + 'OfflineStrategySchema', + 'SyncConfigSchema', + 'ConflictResolutionSchema', + 'PersistStorageSchema', + 'EvictionPolicySchema', + // View Enhancements + 'ColumnSummarySchema', + 'GalleryConfigSchema', + 'GroupingConfigSchema', + 'RowColorConfigSchema', + 'RowHeightSchema', + 'DensityModeSchema', + 'TimelineConfigSchema', + 'NavigationConfigSchema', + 'ViewSharingSchema', + // Dashboard + 'SpecDashboardSchema', + 'SpecDashboardWidgetSchema', + 'SpecDashboardHeaderSchema', + 'SpecDashboardHeaderActionSchema', + 'SpecGlobalFilterSchema', + 'GlobalFilterOptionsFromSchema', + 'WidgetColorVariantSchema', + // Sharing & Embedding + 'SharingConfigSchema', + 'EmbedConfigSchema', + // View Configuration + 'AddRecordConfigSchema', + 'AppearanceConfigSchema', + 'UserActionsConfigSchema', + 'ViewTabSchema', + // View Filter Rules + 'ViewFilterRuleSchema', + // Form View + 'SpecFormViewSchema', + 'SpecFormSectionSchema', + 'SpecFormFieldSchema', + // ListView + 'SpecListViewSchema', + 'SpecListColumnSchema', + // Page + 'SpecPageSchema', + 'SpecPageComponentSchema', + 'SpecPageRegionSchema', + 'SpecPageTypeSchema', + 'SpecPageVariableSchema', + // Performance & Page Transitions + 'PerformanceConfigSchema', + 'PageTransitionSchema', + // Accessibility + 'AriaPropsSchema', + 'WcagContrastLevelSchema', + // I18n + 'I18nLabelSchema', + 'I18nObjectSchema', + 'LocaleConfigSchema', + 'PluralRuleSchema', + 'DateFormatSchema', + 'NumberFormatSchema', + // Responsive Design + 'SpecResponsiveConfigSchema', + 'BreakpointColumnMapSchema', + 'BreakpointOrderMapSchema', + // theme.ts + 'ThemeModeSchema', +]; + +describe('spec/ui …Schema re-exports (#2561, decision (a))', () => { + it('does not runtime-export the dropped …Schema names', () => { + for (const name of DROPPED_SCHEMA_EXPORTS) { + expect( + name in Types, + `'${name}' must not be exported from @object-ui/types — #2561 dropped ` + + `the spec/ui zod-schema re-exports; import it from '@objectstack/spec/ui'`, + ).toBe(false); + } + }); + + it('keeps the genuine value re-exports intact', () => { + expect(typeof Types.defineStack).toBe('function'); + expect(Types.ObjectStackSchema).toBeDefined(); + expect(Types.SpecReportSchema).toBeDefined(); + expect(Types.SpecReportColumnSchema).toBeDefined(); + expect(Types.SpecReportTypeEnum).toBeDefined(); + expect(Types.ACTION_LOCATIONS).toBeDefined(); + expect(Types.ActionLocationSchema).toBeDefined(); + }); + + it('source: no spec/ui zod value hides inside an `export type` block', () => { + for (const file of ['index.ts', 'theme.ts']) { + const src = readFileSync(join(SRC_DIR, file), 'utf8'); + const blocks = src.matchAll( + /export type \{([^}]*)\} from '@objectstack\/spec\/ui'/g, + ); + for (const [, body] of blocks) { + const sourceNames = body + .replace(/\/\/[^\n]*/g, '') + .replace(/\/\*[\s\S]*?\*\//g, '') + .split(',') + .map((entry) => entry.trim()) + .filter(Boolean) + .map((entry) => entry.split(/\s+as\s+/)[0].trim()); + for (const name of sourceNames) { + const isValueErasedSchema = + name.endsWith('Schema') && + (SpecUI as Record)[name] !== undefined; + expect( + isValueErasedSchema, + `${file}: '${name}' is a zod value in @objectstack/spec/ui but sits ` + + `in an 'export type' block, so it would be value-erased (#2561) — ` + + `drop it or re-export it as a value deliberately`, + ).toBe(false); + } + } + } + }); +}); diff --git a/packages/types/src/index.ts b/packages/types/src/index.ts index f40db597b..cf0a01111 100644 --- a/packages/types/src/index.ts +++ b/packages/types/src/index.ts @@ -966,22 +966,26 @@ export type { ObjectUICapabilities, } from '@objectstack/spec'; +// ---------------------------------------------------------------------------- +// NOTE (#2561): the `@objectstack/spec/ui` blocks below re-export the inferred +// *types* only. The companion zod validators (`…Schema`) are deliberately NOT +// re-exported: inside `export type { … }` they were value-erased, so importing +// one as a value from `@object-ui/types` silently yielded `undefined` at +// runtime. Consumers that need the runtime validators must import them from +// `@objectstack/spec/ui` directly. Guardrail: +// `src/__tests__/spec-ui-schema-reexports.test.ts`. +// ---------------------------------------------------------------------------- + // ============================================================================ // v2.0.7 Spec UI Types — Drag and Drop // ============================================================================ export type { DndConfig, - DndConfigSchema, DragItem, - DragItemSchema, DropZone, - DropZoneSchema, DragConstraint, - DragConstraintSchema, DragHandle, - DragHandleSchema, DropEffect, - DropEffectSchema, } from '@objectstack/spec/ui'; // ============================================================================ @@ -989,13 +993,9 @@ export type { // ============================================================================ export type { FocusManagement, - FocusManagementSchema, FocusTrapConfig, - FocusTrapConfigSchema, KeyboardNavigationConfig, - KeyboardNavigationConfigSchema, KeyboardShortcut, - KeyboardShortcutSchema, } from '@objectstack/spec/ui'; // ============================================================================ @@ -1003,17 +1003,11 @@ export type { // ============================================================================ export type { ComponentAnimation, - ComponentAnimationSchema, AnimationTrigger, - AnimationTriggerSchema, MotionConfig, - MotionConfigSchema, TransitionConfig, - TransitionConfigSchema, TransitionPreset, - TransitionPresetSchema, EasingFunction, - EasingFunctionSchema, } from '@objectstack/spec/ui'; // ============================================================================ @@ -1021,17 +1015,11 @@ export type { // ============================================================================ export type { Notification, - NotificationSchema, NotificationConfig, - NotificationConfigSchema, NotificationAction, - NotificationActionSchema, NotificationPosition, - NotificationPositionSchema, NotificationSeverity, - NotificationSeveritySchema, NotificationType, - NotificationTypeSchema, } from '@objectstack/spec/ui'; // ============================================================================ @@ -1039,21 +1027,13 @@ export type { // ============================================================================ export type { GestureConfig as SpecGestureConfig, - GestureConfigSchema as SpecGestureConfigSchema, GestureType as SpecGestureType, - GestureTypeSchema as SpecGestureTypeSchema, SwipeGestureConfig, - SwipeGestureConfigSchema, SwipeDirection, - SwipeDirectionSchema, PinchGestureConfig, - PinchGestureConfigSchema, LongPressGestureConfig, - LongPressGestureConfigSchema, TouchInteraction, - TouchInteractionSchema, TouchTargetConfig, - TouchTargetConfigSchema, } from '@objectstack/spec/ui'; // ============================================================================ @@ -1061,19 +1041,12 @@ export type { // ============================================================================ export type { OfflineConfig as SpecOfflineConfig, - OfflineConfigSchema as SpecOfflineConfigSchema, OfflineCacheConfig, - OfflineCacheConfigSchema, OfflineStrategy, - OfflineStrategySchema, SyncConfig, - SyncConfigSchema, ConflictResolution, - ConflictResolutionSchema, PersistStorage, - PersistStorageSchema, EvictionPolicy, - EvictionPolicySchema, } from '@objectstack/spec/ui'; // ============================================================================ @@ -1081,23 +1054,14 @@ export type { // ============================================================================ export type { ColumnSummary, - ColumnSummarySchema, GalleryConfig, - GalleryConfigSchema, GroupingConfig, - GroupingConfigSchema, RowColorConfig, - RowColorConfigSchema, RowHeight, - RowHeightSchema, DensityMode, - DensityModeSchema, TimelineConfig, - TimelineConfigSchema, NavigationConfig, - NavigationConfigSchema, ViewSharing, - ViewSharingSchema, } from '@objectstack/spec/ui'; // ============================================================================ @@ -1105,21 +1069,14 @@ export type { // ============================================================================ export type { Dashboard as SpecDashboard, - DashboardSchema as SpecDashboardSchema, DashboardWidget as SpecDashboardWidget, - DashboardWidgetSchema as SpecDashboardWidgetSchema, DashboardHeader as SpecDashboardHeader, - DashboardHeaderSchema as SpecDashboardHeaderSchema, DashboardHeaderAction as SpecDashboardHeaderAction, - DashboardHeaderActionSchema as SpecDashboardHeaderActionSchema, GlobalFilter as SpecGlobalFilter, - GlobalFilterSchema as SpecGlobalFilterSchema, GlobalFilterOptionsFrom, - GlobalFilterOptionsFromSchema, // WidgetMeasure / WidgetMeasureSchema removed in @objectstack/spec 9.0 // (ADR-0021 single-form cutover) — dashboard widgets are dataset-bound now. WidgetColorVariant, - WidgetColorVariantSchema, } from '@objectstack/spec/ui'; // ============================================================================ @@ -1127,9 +1084,7 @@ export type { // ============================================================================ export type { SharingConfig, - SharingConfigSchema, EmbedConfig, - EmbedConfigSchema, } from '@objectstack/spec/ui'; // ============================================================================ @@ -1137,13 +1092,9 @@ export type { // ============================================================================ export type { AddRecordConfig, - AddRecordConfigSchema, AppearanceConfig, - AppearanceConfigSchema, UserActionsConfig, - UserActionsConfigSchema, ViewTab, - ViewTabSchema, } from '@objectstack/spec/ui'; // ============================================================================ @@ -1151,7 +1102,6 @@ export type { // ============================================================================ export type { ViewFilterRule, - ViewFilterRuleSchema, } from '@objectstack/spec/ui'; // ============================================================================ @@ -1159,11 +1109,8 @@ export type { // ============================================================================ export type { FormView as SpecFormView, - FormViewSchema as SpecFormViewSchema, FormSection as SpecFormSection, - FormSectionSchema as SpecFormSectionSchema, FormField as SpecFormField, - FormFieldSchema as SpecFormFieldSchema, } from '@objectstack/spec/ui'; // ============================================================================ @@ -1171,9 +1118,7 @@ export type { // ============================================================================ export type { ListView as SpecListView, - ListViewSchema as SpecListViewSchema, ListColumn as SpecListColumn, - ListColumnSchema as SpecListColumnSchema, } from '@objectstack/spec/ui'; // ============================================================================ @@ -1193,15 +1138,10 @@ export type { // ============================================================================ export type { Page as SpecPage, - PageSchema as SpecPageSchema, PageComponent as SpecPageComponent, - PageComponentSchema as SpecPageComponentSchema, PageRegion as SpecPageRegion, - PageRegionSchema as SpecPageRegionSchema, PageType as SpecPageType, - PageTypeSchema as SpecPageTypeSchema, PageVariable as SpecPageVariable, - PageVariableSchema as SpecPageVariableSchema, // BlankPageLayout{,Schema,Item,ItemSchema} dropped — `blank` page type has no // renderer; removed from @objectstack/spec PageTypeSchema (framework#2265). } from '@objectstack/spec/ui'; @@ -1211,9 +1151,7 @@ export type { // ============================================================================ export type { PerformanceConfig, - PerformanceConfigSchema, PageTransition, - PageTransitionSchema, PageComponentType, } from '@objectstack/spec/ui'; @@ -1222,9 +1160,7 @@ export type { // ============================================================================ export type { AriaProps, - AriaPropsSchema, WcagContrastLevel, - WcagContrastLevelSchema, } from '@objectstack/spec/ui'; // ============================================================================ @@ -1232,17 +1168,11 @@ export type { // ============================================================================ export type { I18nLabel, - I18nLabelSchema, I18nObject, - I18nObjectSchema, LocaleConfig, - LocaleConfigSchema, PluralRule, - PluralRuleSchema, DateFormat, - DateFormatSchema, NumberFormat, - NumberFormatSchema, } from '@objectstack/spec/ui'; // ============================================================================ @@ -1250,10 +1180,10 @@ export type { // ============================================================================ export type { ResponsiveConfig as SpecResponsiveConfig, - ResponsiveConfigSchema as SpecResponsiveConfigSchema, - BreakpointColumnMapSchema, - BreakpointOrderMapSchema, BreakpointName as SpecBreakpointName, + // BreakpointColumnMapSchema / BreakpointOrderMapSchema dropped without a + // replacement: they are zod values (value-erased here, #2561) and the spec + // exports no companion inferred type for them. } from '@objectstack/spec/ui'; // ============================================================================ diff --git a/packages/types/src/theme.ts b/packages/types/src/theme.ts index c1cafdadb..7d0bcb0f7 100644 --- a/packages/types/src/theme.ts +++ b/packages/types/src/theme.ts @@ -78,11 +78,9 @@ export type { ZIndex } from '@objectstack/spec/ui'; */ export type { ThemeMode } from '@objectstack/spec/ui'; -/** - * Theme Mode Schema - * Canonical Zod schema from @objectstack/spec/ui. - */ -export type { ThemeModeSchema } from '@objectstack/spec/ui'; +// `ThemeModeSchema` (the zod value) is intentionally not re-exported — under +// `export type` it was value-erased (#2561); import it from +// `@objectstack/spec/ui` directly when the runtime validator is needed. // Import spec types for local use in interfaces below import type { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a1a8c2624..85942c067 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -30,8 +30,8 @@ importers: specifier: ^10.0.1 version: 10.0.1(eslint@10.7.0(jiti@2.7.0)) '@objectstack/spec': - specifier: ^14.6.0 - version: 14.6.0(ai@7.0.22(zod@4.4.3)) + specifier: ^15.0.0 + version: 15.0.0(ai@7.0.22(zod@4.4.3)) '@playwright/test': specifier: ^1.61.1 version: 1.61.1 @@ -265,8 +265,8 @@ importers: specifier: ^14.6.0 version: 14.6.0(ai@7.0.22(zod@4.4.3)) '@objectstack/spec': - specifier: ^14.6.0 - version: 14.6.0(ai@7.0.22(zod@4.4.3)) + specifier: ^15.0.0 + version: 15.0.0(ai@7.0.22(zod@4.4.3)) '@tailwindcss/postcss': specifier: ^4.3.2 version: 4.3.2 @@ -397,8 +397,8 @@ importers: specifier: workspace:* version: link:../../packages/types '@objectstack/spec': - specifier: ^14.6.0 - version: 14.6.0(ai@7.0.22(zod@4.4.3)) + specifier: ^15.0.0 + version: 15.0.0(ai@7.0.22(zod@4.4.3)) fumadocs-core: specifier: 16.11.3 version: 16.11.3(@mdx-js/mdx@3.1.1)(@tanstack/react-router@1.170.8(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(@types/estree-jsx@1.0.5)(@types/hast@3.0.5)(@types/mdast@4.0.4)(@types/react@19.2.17)(lucide-react@1.24.0(react@19.2.7))(next@16.2.10(@babel/core@7.29.7)(@opentelemetry/api@1.9.1)(@playwright/test@1.61.1)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(react-dom@19.2.7(react@19.2.7))(react-router@7.18.1(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(react@19.2.7)(zod@4.4.3) @@ -692,8 +692,8 @@ importers: specifier: ^14.6.0 version: 14.6.0(ai@7.0.22(zod@4.4.3)) '@objectstack/spec': - specifier: ^14.6.0 - version: 14.6.0(ai@7.0.22(zod@4.4.3)) + specifier: ^15.0.0 + version: 15.0.0(ai@7.0.22(zod@4.4.3)) '@sentry/react': specifier: ^10.65.0 version: 10.65.0(react@19.2.7) @@ -1075,8 +1075,8 @@ importers: specifier: ^14.6.0 version: 14.6.0(ai@7.0.22(zod@4.4.3)) '@objectstack/spec': - specifier: ^14.6.0 - version: 14.6.0(ai@7.0.22(zod@4.4.3)) + specifier: ^15.0.0 + version: 15.0.0(ai@7.0.22(zod@4.4.3)) lodash: specifier: ^4.18.1 version: 4.18.1 @@ -1722,8 +1722,8 @@ importers: specifier: workspace:^ version: link:../permissions '@objectstack/spec': - specifier: ^14.6.0 - version: 14.6.0(ai@7.0.22(zod@4.4.3)) + specifier: ^15.0.0 + version: 15.0.0(ai@7.0.22(zod@4.4.3)) lucide-react: specifier: ^1.24.0 version: 1.24.0(react@19.2.7) @@ -1838,8 +1838,8 @@ importers: specifier: workspace:* version: link:../types '@objectstack/spec': - specifier: ^14.6.0 - version: 14.6.0(ai@7.0.22(zod@4.4.3)) + specifier: ^15.0.0 + version: 15.0.0(ai@7.0.22(zod@4.4.3)) lucide-react: specifier: ^1.24.0 version: 1.24.0(react@19.2.7) @@ -1893,8 +1893,8 @@ importers: specifier: workspace:* version: link:../types '@objectstack/spec': - specifier: ^14.6.0 - version: 14.6.0(ai@7.0.22(zod@4.4.3)) + specifier: ^15.0.0 + version: 15.0.0(ai@7.0.22(zod@4.4.3)) lucide-react: specifier: ^1.24.0 version: 1.24.0(react@19.2.7) @@ -2131,8 +2131,8 @@ importers: specifier: workspace:* version: link:../types '@objectstack/spec': - specifier: ^14.6.0 - version: 14.6.0(ai@7.0.22(zod@4.4.3)) + specifier: ^15.0.0 + version: 15.0.0(ai@7.0.22(zod@4.4.3)) lucide-react: specifier: ^1.24.0 version: 1.24.0(react@19.2.7) @@ -2320,8 +2320,8 @@ importers: specifier: workspace:* version: link:../types '@objectstack/spec': - specifier: ^14.6.0 - version: 14.6.0(ai@7.0.22(zod@4.4.3)) + specifier: ^15.0.0 + version: 15.0.0(ai@7.0.22(zod@4.4.3)) class-variance-authority: specifier: ^0.7.1 version: 0.7.1 @@ -2372,8 +2372,8 @@ importers: specifier: workspace:* version: link:../types '@objectstack/spec': - specifier: ^14.6.0 - version: 14.6.0(ai@7.0.22(zod@4.4.3)) + specifier: ^15.0.0 + version: 15.0.0(ai@7.0.22(zod@4.4.3)) lucide-react: specifier: ^1.24.0 version: 1.24.0(react@19.2.7) @@ -2436,8 +2436,8 @@ importers: specifier: workspace:* version: link:../types '@objectstack/spec': - specifier: ^14.6.0 - version: 14.6.0(ai@7.0.22(zod@4.4.3)) + specifier: ^15.0.0 + version: 15.0.0(ai@7.0.22(zod@4.4.3)) class-variance-authority: specifier: ^0.7.1 version: 0.7.1 @@ -2501,8 +2501,8 @@ importers: specifier: workspace:* version: link:../types '@objectstack/spec': - specifier: ^14.6.0 - version: 14.6.0(ai@7.0.22(zod@4.4.3)) + specifier: ^15.0.0 + version: 15.0.0(ai@7.0.22(zod@4.4.3)) react: specifier: 19.2.7 version: 19.2.7 @@ -2626,8 +2626,8 @@ importers: packages/types: dependencies: '@objectstack/spec': - specifier: ^14.6.0 - version: 14.6.0(ai@7.0.22(zod@4.4.3)) + specifier: ^15.0.0 + version: 15.0.0(ai@7.0.22(zod@4.4.3)) zod: specifier: ^4.4.3 version: 4.4.3 @@ -3999,6 +3999,15 @@ packages: ai: optional: true + '@objectstack/spec@15.0.0': + resolution: {integrity: sha512-ZK9iExKLnZnIKd01/YaHzE7y8WihHZiQO+O+dVgkDuvH6Us50NVC6J0yHVpxSN3cCBkO9Xlj68wJ+2GQQpW6fg==} + engines: {node: '>=18.0.0'} + peerDependencies: + ai: ^7.0.0 + peerDependenciesMeta: + ai: + optional: true + '@open-draft/deferred-promise@2.2.0': resolution: {integrity: sha512-CecwLWx3rhxVQF6V4bAgPS5t+So2sTbPgAzafKkVizyi7tlwpcFpdFqq+wqF2OwNBmqFuu6tOyouTuxgpMfzmA==} @@ -12155,6 +12164,12 @@ snapshots: optionalDependencies: ai: 7.0.22(zod@4.4.3) + '@objectstack/spec@15.0.0(ai@7.0.22(zod@4.4.3))': + dependencies: + zod: 4.4.3 + optionalDependencies: + ai: 7.0.22(zod@4.4.3) + '@open-draft/deferred-promise@2.2.0': {} '@open-draft/deferred-promise@3.0.0': {} From b256dada6c14f644f40ddfcaf89d3c5059df939e Mon Sep 17 00:00:00 2001 From: Jack Zhuang <277994282+os-zhuang@users.noreply.github.com> Date: Thu, 16 Jul 2026 17:35:47 +0800 Subject: [PATCH 2/3] chore: raise @objectstack/spec floor to ^15.1.0 (release train includes the framework#3021 fix) Co-Authored-By: Claude Fable 5 --- .changeset/spec-15-ui-schema-reexports.md | 2 +- apps/console/package.json | 2 +- apps/site/package.json | 2 +- package.json | 2 +- packages/app-shell/package.json | 2 +- packages/core/package.json | 2 +- packages/plugin-detail/package.json | 2 +- packages/plugin-form/package.json | 2 +- packages/plugin-gantt/package.json | 2 +- packages/plugin-map/package.json | 2 +- packages/plugin-timeline/package.json | 2 +- packages/plugin-tree/package.json | 2 +- packages/plugin-view/package.json | 2 +- packages/react/package.json | 2 +- packages/types/package.json | 2 +- 15 files changed, 15 insertions(+), 15 deletions(-) diff --git a/.changeset/spec-15-ui-schema-reexports.md b/.changeset/spec-15-ui-schema-reexports.md index cb864c282..8b153dfc2 100644 --- a/.changeset/spec-15-ui-schema-reexports.md +++ b/.changeset/spec-15-ui-schema-reexports.md @@ -6,4 +6,4 @@ Adopt `@objectstack/spec` 15 across the workspace and drop the value-erased `… **Removed exports.** `packages/types` re-exported the `@objectstack/spec/ui` surface inside `export type { … }` blocks, and those blocks included the zod validators (`DndConfigSchema`, `SpecFormViewSchema`, `ThemeModeSchema`, … 84 names in total). Under `export type` a zod value is erased, so importing any of them as a value from `@object-ui/types` silently yielded `undefined` at runtime. Per the #2561 decision (option a) the schema names are removed from the public surface instead of being converted to value re-exports — consumers that need the runtime validators import them from `@objectstack/spec/ui` directly. The inferred types (`DndConfig`, `SpecFormView`, …) are unchanged, and the genuine value re-exports (`defineStack`, `ObjectStackSchema`, `SpecReportSchema`, …) keep working. `BreakpointColumnMapSchema` / `BreakpointOrderMapSchema` are dropped without a type replacement (the spec exports no companion inferred type). A guardrail test (`spec-ui-schema-reexports.test.ts`) pins the contract. -**Spec 15.** Every workspace package now depends on `@objectstack/spec` ^15.0.1. The `/ui` export-name set is identical to 14.6; the spec-level breaking change is ADR-0089 D3a — `FormFieldSchema` / `FormSectionSchema` / `PageComponentSchema` are `.strict()` and reject undeclared keys, which the workspace test suite passes under. The floor is 15.0.1 (not 15.0.0) because D3a's `.strict().transform(…)` pipes crashed `z.toJSONSchema` over spec's lazySchema proxies (`Cannot set properties of undefined (setting 'ref')`), breaking Studio's spec-derived Page/View inspector schemas; fixed upstream in framework#3021. New `view-schema.test.ts` pins the View-inspector derivation (previously untested — it degraded silently). +**Spec 15.** Every workspace package now depends on `@objectstack/spec` ^15.1.0. The `/ui` export-name set is identical to 14.6; the spec-level breaking change is ADR-0089 D3a — `FormFieldSchema` / `FormSectionSchema` / `PageComponentSchema` are `.strict()` and reject undeclared keys, which the workspace test suite passes under. The floor is 15.1.0 (not 15.0.0) because D3a's `.strict().transform(…)` pipes crashed `z.toJSONSchema` over spec's lazySchema proxies (`Cannot set properties of undefined (setting 'ref')`), breaking Studio's spec-derived Page/View inspector schemas; fixed upstream in framework#3021. New `view-schema.test.ts` pins the View-inspector derivation (previously untested — it degraded silently). diff --git a/apps/console/package.json b/apps/console/package.json index a06e2491f..63bb95593 100644 --- a/apps/console/package.json +++ b/apps/console/package.json @@ -88,7 +88,7 @@ "@object-ui/react": "workspace:*", "@object-ui/types": "workspace:*", "@objectstack/client": "^14.6.0", - "@objectstack/spec": "^15.0.1", + "@objectstack/spec": "^15.1.0", "@tailwindcss/postcss": "^4.3.2", "@tailwindcss/typography": "^0.5.20", "@testing-library/jest-dom": "^6.9.1", diff --git a/apps/site/package.json b/apps/site/package.json index b4a8f98be..64588f73d 100644 --- a/apps/site/package.json +++ b/apps/site/package.json @@ -31,7 +31,7 @@ "@object-ui/plugin-view": "workspace:*", "@object-ui/react": "workspace:*", "@object-ui/types": "workspace:*", - "@objectstack/spec": "^15.0.1", + "@objectstack/spec": "^15.1.0", "fumadocs-core": "16.11.3", "fumadocs-mdx": "15.0.13", "fumadocs-ui": "16.11.3", diff --git a/package.json b/package.json index 1f4c90003..0f3863772 100644 --- a/package.json +++ b/package.json @@ -61,7 +61,7 @@ "devDependencies": { "@changesets/cli": "^2.31.0", "@eslint/js": "^10.0.1", - "@objectstack/spec": "^15.0.1", + "@objectstack/spec": "^15.1.0", "@playwright/test": "^1.61.1", "@testing-library/dom": "^10.4.1", "@testing-library/jest-dom": "^6.9.1", diff --git a/packages/app-shell/package.json b/packages/app-shell/package.json index 77bbf9813..64079ff4e 100644 --- a/packages/app-shell/package.json +++ b/packages/app-shell/package.json @@ -50,7 +50,7 @@ "@object-ui/types": "workspace:*", "@objectstack/formula": "^14.6.0", "@objectstack/lint": "^14.6.0", - "@objectstack/spec": "^15.0.1", + "@objectstack/spec": "^15.1.0", "@sentry/react": "^10.65.0", "jsonc-parser": "^3.3.1", "lucide-react": "^1.24.0", diff --git a/packages/core/package.json b/packages/core/package.json index 70ac0edad..65c81b2ef 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -33,7 +33,7 @@ "dependencies": { "@object-ui/types": "workspace:*", "@objectstack/formula": "^14.6.0", - "@objectstack/spec": "^15.0.1", + "@objectstack/spec": "^15.1.0", "lodash": "^4.18.1", "zod": "^4.4.3" }, diff --git a/packages/plugin-detail/package.json b/packages/plugin-detail/package.json index b6bc99ee7..31181e5c2 100644 --- a/packages/plugin-detail/package.json +++ b/packages/plugin-detail/package.json @@ -32,7 +32,7 @@ }, "dependencies": { "@object-ui/i18n": "workspace:*", - "@objectstack/spec": "^15.0.1", + "@objectstack/spec": "^15.1.0", "lucide-react": "^1.24.0" }, "peerDependencies": { diff --git a/packages/plugin-form/package.json b/packages/plugin-form/package.json index a8b6a03d5..3dc555c9d 100644 --- a/packages/plugin-form/package.json +++ b/packages/plugin-form/package.json @@ -27,7 +27,7 @@ "@object-ui/permissions": "workspace:*", "@object-ui/react": "workspace:*", "@object-ui/types": "workspace:*", - "@objectstack/spec": "^15.0.1", + "@objectstack/spec": "^15.1.0", "lucide-react": "^1.24.0" }, "peerDependencies": { diff --git a/packages/plugin-gantt/package.json b/packages/plugin-gantt/package.json index e077bf624..8b3381342 100644 --- a/packages/plugin-gantt/package.json +++ b/packages/plugin-gantt/package.json @@ -38,7 +38,7 @@ "@object-ui/plugin-detail": "workspace:*", "@object-ui/react": "workspace:*", "@object-ui/types": "workspace:*", - "@objectstack/spec": "^15.0.1", + "@objectstack/spec": "^15.1.0", "lucide-react": "^1.24.0", "qrcode": "^1.5.4", "sonner": "^2.0.7" diff --git a/packages/plugin-map/package.json b/packages/plugin-map/package.json index c44ec78d5..c8dea7ec9 100644 --- a/packages/plugin-map/package.json +++ b/packages/plugin-map/package.json @@ -35,7 +35,7 @@ "@object-ui/core": "workspace:*", "@object-ui/react": "workspace:*", "@object-ui/types": "workspace:*", - "@objectstack/spec": "^15.0.1", + "@objectstack/spec": "^15.1.0", "lucide-react": "^1.24.0", "maplibre-gl": "^5.24.0", "react-map-gl": "^8.1.1", diff --git a/packages/plugin-timeline/package.json b/packages/plugin-timeline/package.json index 9c6cc130a..03923d157 100644 --- a/packages/plugin-timeline/package.json +++ b/packages/plugin-timeline/package.json @@ -36,7 +36,7 @@ "@object-ui/mobile": "workspace:*", "@object-ui/react": "workspace:*", "@object-ui/types": "workspace:*", - "@objectstack/spec": "^15.0.1", + "@objectstack/spec": "^15.1.0", "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 b0bf1fc5f..f3b2ebc1a 100644 --- a/packages/plugin-tree/package.json +++ b/packages/plugin-tree/package.json @@ -35,7 +35,7 @@ "@object-ui/core": "workspace:*", "@object-ui/react": "workspace:*", "@object-ui/types": "workspace:*", - "@objectstack/spec": "^15.0.1", + "@objectstack/spec": "^15.1.0", "lucide-react": "^1.24.0" }, "peerDependencies": { diff --git a/packages/plugin-view/package.json b/packages/plugin-view/package.json index e7143a62a..a2cee2057 100644 --- a/packages/plugin-view/package.json +++ b/packages/plugin-view/package.json @@ -21,7 +21,7 @@ }, "dependencies": { "@dnd-kit/core": "^6.3.1", - "@objectstack/spec": "^15.0.1", + "@objectstack/spec": "^15.1.0", "@dnd-kit/sortable": "^10.0.0", "@dnd-kit/utilities": "^3.2.2", "@object-ui/components": "workspace:*", diff --git a/packages/react/package.json b/packages/react/package.json index b182593c3..7ad3a40ae 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": "^15.0.1", + "@objectstack/spec": "^15.1.0", "react-hook-form": "^7.81.0" }, "peerDependencies": { diff --git a/packages/types/package.json b/packages/types/package.json index 873f9d474..8ffe0e495 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -90,7 +90,7 @@ "directory": "packages/types" }, "dependencies": { - "@objectstack/spec": "^15.0.1", + "@objectstack/spec": "^15.1.0", "zod": "^4.4.3" }, "devDependencies": { From ae222ef4dbd8912c8a9c27f8c0c6ba8415d23f9e Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 17 Jul 2026 10:00:00 +0000 Subject: [PATCH 3/3] chore(types): pin @objectstack/spec floor to ^15.1.1 (framework#3021 fix release) framework#3021's z.toJSONSchema/lazySchema-proxy fix shipped in @objectstack/spec 15.1.1, not 15.1.0. Raise the floor across the workspace to ^15.1.1 so the Studio Page/View inspector derivation is guaranteed the fix, and refresh the lockfile to 15.1.1. Align the changeset and types README narrative. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_015Cijq425rfCKbyvFthNWTD --- .changeset/spec-15-ui-schema-reexports.md | 2 +- apps/console/package.json | 2 +- apps/site/package.json | 2 +- package.json | 2 +- packages/app-shell/package.json | 2 +- packages/core/package.json | 2 +- packages/plugin-detail/package.json | 2 +- packages/plugin-form/package.json | 2 +- packages/plugin-gantt/package.json | 2 +- packages/plugin-map/package.json | 2 +- packages/plugin-timeline/package.json | 2 +- packages/plugin-tree/package.json | 2 +- packages/plugin-view/package.json | 2 +- packages/react/package.json | 2 +- packages/types/README.md | 2 +- packages/types/package.json | 2 +- pnpm-lock.yaml | 62 +++++++++++------------ 17 files changed, 47 insertions(+), 47 deletions(-) diff --git a/.changeset/spec-15-ui-schema-reexports.md b/.changeset/spec-15-ui-schema-reexports.md index 8b153dfc2..d5e7beaf8 100644 --- a/.changeset/spec-15-ui-schema-reexports.md +++ b/.changeset/spec-15-ui-schema-reexports.md @@ -6,4 +6,4 @@ Adopt `@objectstack/spec` 15 across the workspace and drop the value-erased `… **Removed exports.** `packages/types` re-exported the `@objectstack/spec/ui` surface inside `export type { … }` blocks, and those blocks included the zod validators (`DndConfigSchema`, `SpecFormViewSchema`, `ThemeModeSchema`, … 84 names in total). Under `export type` a zod value is erased, so importing any of them as a value from `@object-ui/types` silently yielded `undefined` at runtime. Per the #2561 decision (option a) the schema names are removed from the public surface instead of being converted to value re-exports — consumers that need the runtime validators import them from `@objectstack/spec/ui` directly. The inferred types (`DndConfig`, `SpecFormView`, …) are unchanged, and the genuine value re-exports (`defineStack`, `ObjectStackSchema`, `SpecReportSchema`, …) keep working. `BreakpointColumnMapSchema` / `BreakpointOrderMapSchema` are dropped without a type replacement (the spec exports no companion inferred type). A guardrail test (`spec-ui-schema-reexports.test.ts`) pins the contract. -**Spec 15.** Every workspace package now depends on `@objectstack/spec` ^15.1.0. The `/ui` export-name set is identical to 14.6; the spec-level breaking change is ADR-0089 D3a — `FormFieldSchema` / `FormSectionSchema` / `PageComponentSchema` are `.strict()` and reject undeclared keys, which the workspace test suite passes under. The floor is 15.1.0 (not 15.0.0) because D3a's `.strict().transform(…)` pipes crashed `z.toJSONSchema` over spec's lazySchema proxies (`Cannot set properties of undefined (setting 'ref')`), breaking Studio's spec-derived Page/View inspector schemas; fixed upstream in framework#3021. New `view-schema.test.ts` pins the View-inspector derivation (previously untested — it degraded silently). +**Spec 15.** Every workspace package now depends on `@objectstack/spec` ^15.1.1. The `/ui` export-name set is identical to 14.6; the spec-level breaking change is ADR-0089 D3a — `FormFieldSchema` / `FormSectionSchema` / `PageComponentSchema` are `.strict()` and reject undeclared keys, which the workspace test suite passes under. The floor is 15.1.1 (not 15.0.0) because D3a's `.strict().transform(…)` pipes crashed `z.toJSONSchema` over spec's lazySchema proxies (`Cannot set properties of undefined (setting 'ref')`), breaking Studio's spec-derived Page/View inspector schemas; fixed upstream in framework#3021, which shipped in spec 15.1.1. New `view-schema.test.ts` pins the View-inspector derivation (previously untested — it degraded silently). diff --git a/apps/console/package.json b/apps/console/package.json index 7aa55cf28..735fb4c47 100644 --- a/apps/console/package.json +++ b/apps/console/package.json @@ -88,7 +88,7 @@ "@object-ui/react": "workspace:*", "@object-ui/types": "workspace:*", "@objectstack/client": "^14.6.0", - "@objectstack/spec": "^15.1.0", + "@objectstack/spec": "^15.1.1", "@tailwindcss/postcss": "^4.3.2", "@tailwindcss/typography": "^0.5.20", "@testing-library/jest-dom": "^6.9.1", diff --git a/apps/site/package.json b/apps/site/package.json index 64588f73d..0e24b0d1d 100644 --- a/apps/site/package.json +++ b/apps/site/package.json @@ -31,7 +31,7 @@ "@object-ui/plugin-view": "workspace:*", "@object-ui/react": "workspace:*", "@object-ui/types": "workspace:*", - "@objectstack/spec": "^15.1.0", + "@objectstack/spec": "^15.1.1", "fumadocs-core": "16.11.3", "fumadocs-mdx": "15.0.13", "fumadocs-ui": "16.11.3", diff --git a/package.json b/package.json index 0f3863772..d49becac1 100644 --- a/package.json +++ b/package.json @@ -61,7 +61,7 @@ "devDependencies": { "@changesets/cli": "^2.31.0", "@eslint/js": "^10.0.1", - "@objectstack/spec": "^15.1.0", + "@objectstack/spec": "^15.1.1", "@playwright/test": "^1.61.1", "@testing-library/dom": "^10.4.1", "@testing-library/jest-dom": "^6.9.1", diff --git a/packages/app-shell/package.json b/packages/app-shell/package.json index 754038312..b06108908 100644 --- a/packages/app-shell/package.json +++ b/packages/app-shell/package.json @@ -50,7 +50,7 @@ "@object-ui/types": "workspace:*", "@objectstack/formula": "^14.6.0", "@objectstack/lint": "^14.6.0", - "@objectstack/spec": "^15.1.0", + "@objectstack/spec": "^15.1.1", "@sentry/react": "^10.65.0", "jsonc-parser": "^3.3.1", "lucide-react": "^1.24.0", diff --git a/packages/core/package.json b/packages/core/package.json index 2f4e62176..98eb75e55 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -33,7 +33,7 @@ "dependencies": { "@object-ui/types": "workspace:*", "@objectstack/formula": "^14.6.0", - "@objectstack/spec": "^15.1.0", + "@objectstack/spec": "^15.1.1", "lodash": "^4.18.1", "zod": "^4.4.3" }, diff --git a/packages/plugin-detail/package.json b/packages/plugin-detail/package.json index 420de96c0..012b0b5f8 100644 --- a/packages/plugin-detail/package.json +++ b/packages/plugin-detail/package.json @@ -32,7 +32,7 @@ }, "dependencies": { "@object-ui/i18n": "workspace:*", - "@objectstack/spec": "^15.1.0", + "@objectstack/spec": "^15.1.1", "lucide-react": "^1.24.0" }, "peerDependencies": { diff --git a/packages/plugin-form/package.json b/packages/plugin-form/package.json index 024c4dabf..95595fb07 100644 --- a/packages/plugin-form/package.json +++ b/packages/plugin-form/package.json @@ -27,7 +27,7 @@ "@object-ui/permissions": "workspace:*", "@object-ui/react": "workspace:*", "@object-ui/types": "workspace:*", - "@objectstack/spec": "^15.1.0", + "@objectstack/spec": "^15.1.1", "lucide-react": "^1.24.0" }, "peerDependencies": { diff --git a/packages/plugin-gantt/package.json b/packages/plugin-gantt/package.json index ac655cf37..2de086598 100644 --- a/packages/plugin-gantt/package.json +++ b/packages/plugin-gantt/package.json @@ -38,7 +38,7 @@ "@object-ui/plugin-detail": "workspace:*", "@object-ui/react": "workspace:*", "@object-ui/types": "workspace:*", - "@objectstack/spec": "^15.1.0", + "@objectstack/spec": "^15.1.1", "lucide-react": "^1.24.0", "qrcode": "^1.5.4", "sonner": "^2.0.7" diff --git a/packages/plugin-map/package.json b/packages/plugin-map/package.json index 9aed21aad..d31754610 100644 --- a/packages/plugin-map/package.json +++ b/packages/plugin-map/package.json @@ -35,7 +35,7 @@ "@object-ui/core": "workspace:*", "@object-ui/react": "workspace:*", "@object-ui/types": "workspace:*", - "@objectstack/spec": "^15.1.0", + "@objectstack/spec": "^15.1.1", "lucide-react": "^1.24.0", "maplibre-gl": "^5.24.0", "react-map-gl": "^8.1.1", diff --git a/packages/plugin-timeline/package.json b/packages/plugin-timeline/package.json index 36260c388..41ab7850a 100644 --- a/packages/plugin-timeline/package.json +++ b/packages/plugin-timeline/package.json @@ -36,7 +36,7 @@ "@object-ui/mobile": "workspace:*", "@object-ui/react": "workspace:*", "@object-ui/types": "workspace:*", - "@objectstack/spec": "^15.1.0", + "@objectstack/spec": "^15.1.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 c3a7a5078..748bd14ba 100644 --- a/packages/plugin-tree/package.json +++ b/packages/plugin-tree/package.json @@ -35,7 +35,7 @@ "@object-ui/core": "workspace:*", "@object-ui/react": "workspace:*", "@object-ui/types": "workspace:*", - "@objectstack/spec": "^15.1.0", + "@objectstack/spec": "^15.1.1", "lucide-react": "^1.24.0" }, "peerDependencies": { diff --git a/packages/plugin-view/package.json b/packages/plugin-view/package.json index d64e4ef8d..53dbe718b 100644 --- a/packages/plugin-view/package.json +++ b/packages/plugin-view/package.json @@ -30,7 +30,7 @@ "@object-ui/plugin-grid": "workspace:*", "@object-ui/react": "workspace:*", "@object-ui/types": "workspace:*", - "@objectstack/spec": "^15.1.0", + "@objectstack/spec": "^15.1.1", "class-variance-authority": "^0.7.1", "lucide-react": "^1.24.0" }, diff --git a/packages/react/package.json b/packages/react/package.json index f45273084..0f2214722 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": "^15.1.0", + "@objectstack/spec": "^15.1.1", "react-hook-form": "^7.81.0" }, "peerDependencies": { diff --git a/packages/types/README.md b/packages/types/README.md index 9a95f37ff..30819e451 100644 --- a/packages/types/README.md +++ b/packages/types/README.md @@ -307,7 +307,7 @@ We follow these constraints for this package: - **Node.js:** ≥ 18 - **TypeScript:** ≥ 5.0 (strict mode) -- **`@objectstack/spec`:** ^15.0.0 +- **`@objectstack/spec`:** ^15.1.1 - **`@objectstack/client`:** ^3.3.0 - **Tailwind CSS:** ≥ 3.4 (for packages with UI) diff --git a/packages/types/package.json b/packages/types/package.json index 0756807c1..183af67f5 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -90,7 +90,7 @@ "directory": "packages/types" }, "dependencies": { - "@objectstack/spec": "^15.1.0", + "@objectstack/spec": "^15.1.1", "zod": "^4.4.3" }, "devDependencies": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a4059db37..a5fee76e9 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -30,8 +30,8 @@ importers: specifier: ^10.0.1 version: 10.0.1(eslint@10.7.0(jiti@2.7.0)) '@objectstack/spec': - specifier: ^15.1.0 - version: 15.1.0(ai@7.0.22(zod@4.4.3)) + specifier: ^15.1.1 + version: 15.1.1(ai@7.0.22(zod@4.4.3)) '@playwright/test': specifier: ^1.61.1 version: 1.61.1 @@ -265,8 +265,8 @@ importers: specifier: ^14.6.0 version: 14.6.0(ai@7.0.22(zod@4.4.3)) '@objectstack/spec': - specifier: ^15.1.0 - version: 15.1.0(ai@7.0.22(zod@4.4.3)) + specifier: ^15.1.1 + version: 15.1.1(ai@7.0.22(zod@4.4.3)) '@tailwindcss/postcss': specifier: ^4.3.2 version: 4.3.2 @@ -397,8 +397,8 @@ importers: specifier: workspace:* version: link:../../packages/types '@objectstack/spec': - specifier: ^15.1.0 - version: 15.1.0(ai@7.0.22(zod@4.4.3)) + specifier: ^15.1.1 + version: 15.1.1(ai@7.0.22(zod@4.4.3)) fumadocs-core: specifier: 16.11.3 version: 16.11.3(@mdx-js/mdx@3.1.1)(@tanstack/react-router@1.170.8(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(@types/estree-jsx@1.0.5)(@types/hast@3.0.5)(@types/mdast@4.0.4)(@types/react@19.2.17)(lucide-react@1.24.0(react@19.2.7))(next@16.2.10(@babel/core@7.29.7)(@opentelemetry/api@1.9.1)(@playwright/test@1.61.1)(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(react-dom@19.2.7(react@19.2.7))(react-router@7.18.1(react-dom@19.2.7(react@19.2.7))(react@19.2.7))(react@19.2.7)(zod@4.4.3) @@ -692,8 +692,8 @@ importers: specifier: ^14.6.0 version: 14.6.0(ai@7.0.22(zod@4.4.3)) '@objectstack/spec': - specifier: ^15.1.0 - version: 15.1.0(ai@7.0.22(zod@4.4.3)) + specifier: ^15.1.1 + version: 15.1.1(ai@7.0.22(zod@4.4.3)) '@sentry/react': specifier: ^10.65.0 version: 10.65.0(react@19.2.7) @@ -1075,8 +1075,8 @@ importers: specifier: ^14.6.0 version: 14.6.0(ai@7.0.22(zod@4.4.3)) '@objectstack/spec': - specifier: ^15.1.0 - version: 15.1.0(ai@7.0.22(zod@4.4.3)) + specifier: ^15.1.1 + version: 15.1.1(ai@7.0.22(zod@4.4.3)) lodash: specifier: ^4.18.1 version: 4.18.1 @@ -1722,8 +1722,8 @@ importers: specifier: workspace:^ version: link:../permissions '@objectstack/spec': - specifier: ^15.1.0 - version: 15.1.0(ai@7.0.22(zod@4.4.3)) + specifier: ^15.1.1 + version: 15.1.1(ai@7.0.22(zod@4.4.3)) lucide-react: specifier: ^1.24.0 version: 1.24.0(react@19.2.7) @@ -1838,8 +1838,8 @@ importers: specifier: workspace:* version: link:../types '@objectstack/spec': - specifier: ^15.1.0 - version: 15.1.0(ai@7.0.22(zod@4.4.3)) + specifier: ^15.1.1 + version: 15.1.1(ai@7.0.22(zod@4.4.3)) lucide-react: specifier: ^1.24.0 version: 1.24.0(react@19.2.7) @@ -1893,8 +1893,8 @@ importers: specifier: workspace:* version: link:../types '@objectstack/spec': - specifier: ^15.1.0 - version: 15.1.0(ai@7.0.22(zod@4.4.3)) + specifier: ^15.1.1 + version: 15.1.1(ai@7.0.22(zod@4.4.3)) lucide-react: specifier: ^1.24.0 version: 1.24.0(react@19.2.7) @@ -2131,8 +2131,8 @@ importers: specifier: workspace:* version: link:../types '@objectstack/spec': - specifier: ^15.1.0 - version: 15.1.0(ai@7.0.22(zod@4.4.3)) + specifier: ^15.1.1 + version: 15.1.1(ai@7.0.22(zod@4.4.3)) lucide-react: specifier: ^1.24.0 version: 1.24.0(react@19.2.7) @@ -2320,8 +2320,8 @@ importers: specifier: workspace:* version: link:../types '@objectstack/spec': - specifier: ^15.1.0 - version: 15.1.0(ai@7.0.22(zod@4.4.3)) + specifier: ^15.1.1 + version: 15.1.1(ai@7.0.22(zod@4.4.3)) class-variance-authority: specifier: ^0.7.1 version: 0.7.1 @@ -2372,8 +2372,8 @@ importers: specifier: workspace:* version: link:../types '@objectstack/spec': - specifier: ^15.1.0 - version: 15.1.0(ai@7.0.22(zod@4.4.3)) + specifier: ^15.1.1 + version: 15.1.1(ai@7.0.22(zod@4.4.3)) lucide-react: specifier: ^1.24.0 version: 1.24.0(react@19.2.7) @@ -2436,8 +2436,8 @@ importers: specifier: workspace:* version: link:../types '@objectstack/spec': - specifier: ^15.1.0 - version: 15.1.0(ai@7.0.22(zod@4.4.3)) + specifier: ^15.1.1 + version: 15.1.1(ai@7.0.22(zod@4.4.3)) class-variance-authority: specifier: ^0.7.1 version: 0.7.1 @@ -2501,8 +2501,8 @@ importers: specifier: workspace:* version: link:../types '@objectstack/spec': - specifier: ^15.1.0 - version: 15.1.0(ai@7.0.22(zod@4.4.3)) + specifier: ^15.1.1 + version: 15.1.1(ai@7.0.22(zod@4.4.3)) react: specifier: 19.2.7 version: 19.2.7 @@ -2607,8 +2607,8 @@ importers: packages/types: dependencies: '@objectstack/spec': - specifier: ^15.1.0 - version: 15.1.0(ai@7.0.22(zod@4.4.3)) + specifier: ^15.1.1 + version: 15.1.1(ai@7.0.22(zod@4.4.3)) zod: specifier: ^4.4.3 version: 4.4.3 @@ -3980,8 +3980,8 @@ packages: ai: optional: true - '@objectstack/spec@15.1.0': - resolution: {integrity: sha512-gL5toOEKTZ2whRJqQYfSa2G3D72jQJd4in3NtHlI02zR7olKzLx7z6+FbbcmI7cienYSxHMl3oDnRV/xFp2+aA==} + '@objectstack/spec@15.1.1': + resolution: {integrity: sha512-Eto1iLtzmnh3kSzIVGPUQF9DZGE1dY3YWFm+3qRpNBFB8iSvOilLwNYVSF64D5sTobp0CZSzB1/GalzFAR1icA==} engines: {node: '>=18.0.0'} peerDependencies: ai: ^7.0.0 @@ -12145,7 +12145,7 @@ snapshots: optionalDependencies: ai: 7.0.22(zod@4.4.3) - '@objectstack/spec@15.1.0(ai@7.0.22(zod@4.4.3))': + '@objectstack/spec@15.1.1(ai@7.0.22(zod@4.4.3))': dependencies: zod: 4.4.3 optionalDependencies: