From 144572f8806ebc13dbbee3fd20b76b4b4d50e8c4 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 14 Feb 2026 11:00:48 +0000 Subject: [PATCH 1/4] Initial plan From f5a8b122f8cdf6f6a398a0f9974b25b531ff9245 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 14 Feb 2026 11:21:14 +0000 Subject: [PATCH 2/4] feat: upgrade @objectstack packages to ^3.0.4 and add preview mode support - Upgrade all @objectstack/* dependencies from ^3.0.2 to ^3.0.4 - Add PreviewModeOptions type and previewMode prop to AuthProvider - Add isPreviewMode and previewMode to AuthContextValue - Create PreviewBanner component for preview mode UI indication - Update ConditionalAuthWrapper to detect preview mode from discovery - Update console App to render PreviewBanner - Add tests for preview mode in AuthProvider and PreviewBanner Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com> --- apps/console/package.json | 14 +- apps/console/src/App.tsx | 3 +- .../src/components/ConditionalAuthWrapper.tsx | 38 +- examples/crm/package.json | 16 +- examples/kitchen-sink/package.json | 4 +- examples/msw-todo/package.json | 12 +- examples/todo/package.json | 6 +- package.json | 18 +- packages/auth/src/AuthContext.ts | 6 +- packages/auth/src/AuthProvider.tsx | 52 ++- packages/auth/src/PreviewBanner.tsx | 52 +++ .../__tests__/AuthProvider.preview.test.tsx | 114 ++++++ .../auth/src/__tests__/PreviewBanner.test.tsx | 57 +++ packages/auth/src/index.ts | 2 + packages/auth/src/types.ts | 20 + packages/auth/src/useAuth.ts | 2 + packages/core/package.json | 2 +- packages/data-objectstack/package.json | 2 +- packages/plugin-gantt/package.json | 2 +- packages/plugin-map/package.json | 2 +- packages/plugin-timeline/package.json | 2 +- packages/react/package.json | 2 +- packages/react/src/hooks/useDiscovery.ts | 13 + packages/types/package.json | 2 +- pnpm-lock.yaml | 352 +++++++++--------- 25 files changed, 563 insertions(+), 232 deletions(-) create mode 100644 packages/auth/src/PreviewBanner.tsx create mode 100644 packages/auth/src/__tests__/AuthProvider.preview.test.tsx create mode 100644 packages/auth/src/__tests__/PreviewBanner.test.tsx diff --git a/apps/console/package.json b/apps/console/package.json index c940b9199..30930a5c9 100644 --- a/apps/console/package.json +++ b/apps/console/package.json @@ -58,13 +58,13 @@ "@object-ui/plugin-view": "workspace:*", "@object-ui/react": "workspace:*", "@object-ui/types": "workspace:*", - "@objectstack/cli": "^3.0.2", - "@objectstack/client": "^3.0.2", - "@objectstack/driver-memory": "^3.0.2", - "@objectstack/objectql": "^3.0.2", - "@objectstack/plugin-msw": "^3.0.2", - "@objectstack/runtime": "^3.0.2", - "@objectstack/spec": "^3.0.2", + "@objectstack/cli": "^3.0.4", + "@objectstack/client": "^3.0.4", + "@objectstack/driver-memory": "^3.0.4", + "@objectstack/objectql": "^3.0.4", + "@objectstack/plugin-msw": "^3.0.4", + "@objectstack/runtime": "^3.0.4", + "@objectstack/spec": "^3.0.4", "@tailwindcss/postcss": "^4.1.18", "@testing-library/jest-dom": "^6.9.1", "@testing-library/react": "^16.3.2", diff --git a/apps/console/src/App.tsx b/apps/console/src/App.tsx index 26eb4dada..203a6d27f 100644 --- a/apps/console/src/App.tsx +++ b/apps/console/src/App.tsx @@ -7,7 +7,7 @@ import { SchemaRendererProvider } from '@object-ui/react'; import { ObjectStackAdapter } from './dataSource'; import type { ConnectionState } from './dataSource'; import appConfig from '../objectstack.shared'; -import { AuthGuard, useAuth } from '@object-ui/auth'; +import { AuthGuard, useAuth, PreviewBanner } from '@object-ui/auth'; // Components (eagerly loaded — always needed) import { ConsoleLayout } from './components/ConsoleLayout'; @@ -387,6 +387,7 @@ export function App() { + }> diff --git a/apps/console/src/components/ConditionalAuthWrapper.tsx b/apps/console/src/components/ConditionalAuthWrapper.tsx index 789644583..aec29d72f 100644 --- a/apps/console/src/components/ConditionalAuthWrapper.tsx +++ b/apps/console/src/components/ConditionalAuthWrapper.tsx @@ -3,11 +3,13 @@ * * This component fetches discovery information from the server and conditionally * enables/disables authentication based on the server's auth service status. + * Also detects preview mode from the server and configures the auth provider accordingly. */ import { useState, useEffect, ReactNode } from 'react'; import { ObjectStackAdapter } from '../dataSource'; import { AuthProvider } from '@object-ui/auth'; +import type { PreviewModeOptions } from '@object-ui/auth'; import { LoadingScreen } from './LoadingScreen'; import type { DiscoveryInfo } from '@object-ui/react'; @@ -23,11 +25,12 @@ interface ConditionalAuthWrapperProps { * 1. Creates a temporary data source connection * 2. Fetches discovery information from the server * 3. Checks if auth.enabled is true in the discovery response - * 4. Conditionally wraps children with AuthProvider if auth is enabled - * 5. Bypasses auth if discovery indicates auth is disabled (development/demo mode) + * 4. Detects preview mode from discovery (mode === 'preview') + * 5. Conditionally wraps children with AuthProvider with the appropriate config */ export function ConditionalAuthWrapper({ children, authUrl }: ConditionalAuthWrapperProps) { const [authEnabled, setAuthEnabled] = useState(null); + const [previewMode, setPreviewMode] = useState(undefined); const [isLoading, setIsLoading] = useState(true); useEffect(() => { @@ -47,10 +50,24 @@ export function ConditionalAuthWrapper({ children, authUrl }: ConditionalAuthWra const discovery = await adapter.getDiscovery() as DiscoveryInfo | null; if (!cancelled) { - // Check if auth is enabled in discovery - // Default to true if discovery doesn't provide this information - const isAuthEnabled = discovery?.services?.auth?.enabled ?? true; - setAuthEnabled(isAuthEnabled); + // Detect preview mode from discovery + if (discovery?.mode === 'preview') { + setPreviewMode({ + autoLogin: discovery.previewMode?.autoLogin ?? true, + simulatedRole: discovery.previewMode?.simulatedRole ?? 'admin', + simulatedUserName: discovery.previewMode?.simulatedUserName ?? 'Preview User', + readOnly: discovery.previewMode?.readOnly ?? false, + expiresInSeconds: discovery.previewMode?.expiresInSeconds ?? 0, + bannerMessage: discovery.previewMode?.bannerMessage, + }); + // In preview mode, auth is effectively bypassed + setAuthEnabled(false); + } else { + // Check if auth is enabled in discovery + // Default to true if discovery doesn't provide this information + const isAuthEnabled = discovery?.services?.auth?.enabled ?? true; + setAuthEnabled(isAuthEnabled); + } } } catch (error) { if (!cancelled) { @@ -76,6 +93,15 @@ export function ConditionalAuthWrapper({ children, authUrl }: ConditionalAuthWra return ; } + // If in preview mode, wrap with a preview-configured AuthProvider + if (previewMode) { + return ( + + {children} + + ); + } + // If auth is enabled, wrap with AuthProvider if (authEnabled) { return ( diff --git a/examples/crm/package.json b/examples/crm/package.json index 3fae7d940..fc3f27233 100644 --- a/examples/crm/package.json +++ b/examples/crm/package.json @@ -20,19 +20,19 @@ "dependencies": { "@hono/node-server": "^1.19.9", "@object-ui/console": "workspace:*", - "@objectstack/core": "^3.0.2", - "@objectstack/driver-memory": "^3.0.2", - "@objectstack/objectql": "^3.0.2", - "@objectstack/plugin-auth": "^3.0.2", - "@objectstack/plugin-hono-server": "^3.0.2", - "@objectstack/runtime": "^3.0.2", - "@objectstack/spec": "^3.0.2", + "@objectstack/core": "^3.0.4", + "@objectstack/driver-memory": "^3.0.4", + "@objectstack/objectql": "^3.0.4", + "@objectstack/plugin-auth": "^3.0.4", + "@objectstack/plugin-hono-server": "^3.0.4", + "@objectstack/runtime": "^3.0.4", + "@objectstack/spec": "^3.0.4", "hono": "^4.11.9", "pino": "^8.21.0", "pino-pretty": "^13.1.3" }, "devDependencies": { - "@objectstack/cli": "^3.0.2", + "@objectstack/cli": "^3.0.4", "tsx": "^4.21.0", "typescript": "^5.9.3" } diff --git a/examples/kitchen-sink/package.json b/examples/kitchen-sink/package.json index 8d66a919c..80900bda0 100644 --- a/examples/kitchen-sink/package.json +++ b/examples/kitchen-sink/package.json @@ -14,10 +14,10 @@ "build": "objectstack compile objectstack.config.ts" }, "dependencies": { - "@objectstack/spec": "^3.0.2" + "@objectstack/spec": "^3.0.4" }, "devDependencies": { - "@objectstack/cli": "^3.0.2", + "@objectstack/cli": "^3.0.4", "typescript": "^5.9.3" } } diff --git a/examples/msw-todo/package.json b/examples/msw-todo/package.json index 2ed591fe2..c84b84c08 100644 --- a/examples/msw-todo/package.json +++ b/examples/msw-todo/package.json @@ -11,12 +11,12 @@ }, "dependencies": { "@object-ui/example-todo": "workspace:*", - "@objectstack/client": "^3.0.2", - "@objectstack/driver-memory": "^3.0.2", - "@objectstack/objectql": "^3.0.2", - "@objectstack/plugin-msw": "^3.0.2", - "@objectstack/runtime": "^3.0.2", - "@objectstack/spec": "^3.0.2", + "@objectstack/client": "^3.0.4", + "@objectstack/driver-memory": "^3.0.4", + "@objectstack/objectql": "^3.0.4", + "@objectstack/plugin-msw": "^3.0.4", + "@objectstack/runtime": "^3.0.4", + "@objectstack/spec": "^3.0.4", "react": "19.2.4", "react-dom": "19.2.4" }, diff --git a/examples/todo/package.json b/examples/todo/package.json index bedf272f8..c0a93d39e 100644 --- a/examples/todo/package.json +++ b/examples/todo/package.json @@ -12,11 +12,11 @@ "build": "objectstack compile objectstack.config.ts" }, "dependencies": { - "@objectstack/client": "^3.0.2", - "@objectstack/spec": "^3.0.2" + "@objectstack/client": "^3.0.4", + "@objectstack/spec": "^3.0.4" }, "devDependencies": { - "@objectstack/cli": "^3.0.2", + "@objectstack/cli": "^3.0.4", "typescript": "^5.9.3" } } diff --git a/package.json b/package.json index 2ad57d15e..746a3b588 100644 --- a/package.json +++ b/package.json @@ -66,13 +66,13 @@ "devDependencies": { "@changesets/cli": "^2.29.8", "@eslint/js": "^9.39.2", - "@objectstack/cli": "^3.0.2", - "@objectstack/core": "^3.0.2", - "@objectstack/driver-memory": "^3.0.2", - "@objectstack/objectql": "^3.0.2", - "@objectstack/plugin-msw": "^3.0.2", - "@objectstack/runtime": "^3.0.2", - "@objectstack/spec": "^3.0.2", + "@objectstack/cli": "^3.0.4", + "@objectstack/core": "^3.0.4", + "@objectstack/driver-memory": "^3.0.4", + "@objectstack/objectql": "^3.0.4", + "@objectstack/plugin-msw": "^3.0.4", + "@objectstack/runtime": "^3.0.4", + "@objectstack/spec": "^3.0.4", "@playwright/test": "^1.58.2", "@storybook/addon-essentials": "^8.6.14", "@storybook/addon-interactions": "^8.6.14", @@ -132,8 +132,8 @@ }, "dependencies": { "@hono/node-server": "^1.19.9", - "@objectstack/plugin-hono-server": "^3.0.2", - "@objectstack/studio": "^3.0.2", + "@objectstack/plugin-hono-server": "^3.0.4", + "@objectstack/studio": "^3.0.4", "coverage-v8": "0.0.1-security", "hono": "^4.11.9", "pino": "^8.21.0", diff --git a/packages/auth/src/AuthContext.ts b/packages/auth/src/AuthContext.ts index b9aa849d9..fdf85f905 100644 --- a/packages/auth/src/AuthContext.ts +++ b/packages/auth/src/AuthContext.ts @@ -7,7 +7,7 @@ */ import { createContext } from 'react'; -import type { AuthUser, AuthSession } from './types'; +import type { AuthUser, AuthSession, PreviewModeOptions } from './types'; export interface AuthContextValue { /** Current authenticated user */ @@ -20,6 +20,10 @@ export interface AuthContextValue { isLoading: boolean; /** Authentication error */ error: Error | null; + /** Whether the app is running in preview mode */ + isPreviewMode: boolean; + /** Preview mode configuration (only set when isPreviewMode is true) */ + previewMode: PreviewModeOptions | null; /** Sign in with email and password */ signIn: (email: string, password: string) => Promise; /** Sign up with name, email, and password */ diff --git a/packages/auth/src/AuthProvider.tsx b/packages/auth/src/AuthProvider.tsx index 25aec6d5d..15bf05df6 100644 --- a/packages/auth/src/AuthProvider.tsx +++ b/packages/auth/src/AuthProvider.tsx @@ -7,7 +7,7 @@ */ import React, { useState, useEffect, useCallback, useMemo } from 'react'; -import type { AuthUser, AuthClient, AuthProviderConfig } from './types'; +import type { AuthUser, AuthClient, AuthProviderConfig, PreviewModeOptions } from './types'; import { AuthCtx, type AuthContextValue } from './AuthContext'; import { createAuthClient } from './createAuthClient'; @@ -20,6 +20,12 @@ export interface AuthProviderProps extends AuthProviderConfig { * @default true */ enabled?: boolean; + /** + * Preview mode configuration. + * When provided, the auth provider auto-logs in a simulated user and bypasses + * login/registration screens. Useful for marketplace demos and app showcases. + */ + previewMode?: PreviewModeOptions; } /** @@ -41,12 +47,19 @@ export interface AuthProviderProps extends AuthProviderConfig { * * * ``` + * @example With preview mode (marketplace demo) + * ```tsx + * + * + * + * ``` */ export function AuthProvider({ authUrl, client: externalClient, onAuthStateChange, enabled = true, + previewMode, children, }: AuthProviderProps) { const client = useMemo( @@ -59,13 +72,38 @@ export function AuthProvider({ const [isLoading, setIsLoading] = useState(true); const [error, setError] = useState(null); - // If auth is disabled, automatically set as authenticated with a guest user - const isAuthenticated = enabled + // Determine if we're in preview mode + const isPreviewMode = previewMode != null; + + // If auth is disabled or in preview mode, automatically set as authenticated + const isAuthenticated = (enabled && !isPreviewMode) ? user !== null && session !== null : true; - // Load session on mount (only if auth is enabled) + // Load session on mount (only if auth is enabled and not in preview mode) useEffect(() => { + if (isPreviewMode) { + // Preview mode: simulate a user based on previewMode config + const role = previewMode.simulatedRole ?? 'admin'; + const name = previewMode.simulatedUserName ?? 'Preview User'; + const expiresInSeconds = previewMode.expiresInSeconds ?? 0; + setUser({ + id: 'preview-user', + email: 'preview@preview.local', + name, + role, + roles: [role], + }); + setSession({ + token: 'preview-token', + expiresAt: expiresInSeconds > 0 + ? new Date(Date.now() + expiresInSeconds * 1000) + : new Date(Date.now() + 365 * 24 * 60 * 60 * 1000), + }); + setIsLoading(false); + return; + } + if (!enabled) { // When auth is disabled, set a guest user and mark as loaded setUser({ @@ -103,7 +141,7 @@ export function AuthProvider({ loadSession(); return () => { cancelled = true; }; - }, [client, enabled]); + }, [client, enabled, isPreviewMode, previewMode]); // Notify on auth state changes useEffect(() => { @@ -218,6 +256,8 @@ export function AuthProvider({ isAuthenticated, isLoading, error, + isPreviewMode, + previewMode: isPreviewMode ? previewMode : null, signIn, signUp, signOut, @@ -225,7 +265,7 @@ export function AuthProvider({ forgotPassword, resetPassword, }), - [user, session, isAuthenticated, isLoading, error, signIn, signUp, signOut, updateUser, forgotPassword, resetPassword], + [user, session, isAuthenticated, isLoading, error, isPreviewMode, previewMode, signIn, signUp, signOut, updateUser, forgotPassword, resetPassword], ); return {children}; diff --git a/packages/auth/src/PreviewBanner.tsx b/packages/auth/src/PreviewBanner.tsx new file mode 100644 index 000000000..7e3b721ef --- /dev/null +++ b/packages/auth/src/PreviewBanner.tsx @@ -0,0 +1,52 @@ +/** + * ObjectUI + * Copyright (c) 2024-present ObjectStack Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import React from 'react'; +import { useAuth } from './useAuth'; + +export interface PreviewBannerProps { + /** Custom class name for the banner */ + className?: string; +} + +/** + * Banner component that displays a message when the app is in preview mode. + * Only renders when preview mode is active. Uses the bannerMessage from + * preview mode config, or a default message if none is provided. + * + * @example + * ```tsx + * + * ``` + */ +export function PreviewBanner({ className }: PreviewBannerProps) { + const { isPreviewMode, previewMode } = useAuth(); + + if (!isPreviewMode) { + return null; + } + + const message = previewMode?.bannerMessage ?? 'You are in preview mode.'; + + return ( +
+ {message} +
+ ); +} diff --git a/packages/auth/src/__tests__/AuthProvider.preview.test.tsx b/packages/auth/src/__tests__/AuthProvider.preview.test.tsx new file mode 100644 index 000000000..2b4d746b1 --- /dev/null +++ b/packages/auth/src/__tests__/AuthProvider.preview.test.tsx @@ -0,0 +1,114 @@ +/** + * ObjectUI + * Copyright (c) 2024-present ObjectStack Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import { describe, it, expect } from 'vitest'; +import { render, screen, waitFor } from '@testing-library/react'; +import { AuthProvider } from '../AuthProvider'; +import { useAuth } from '../useAuth'; + +// Test component to access auth context +function AuthTestComponent() { + const auth = useAuth(); + return ( +
+
{String(auth.isAuthenticated)}
+
{String(auth.isLoading)}
+
{String(auth.isPreviewMode)}
+
{auth.user?.id || 'null'}
+
{auth.user?.name || 'null'}
+
{auth.user?.role || 'null'}
+
{auth.previewMode?.bannerMessage || 'null'}
+
+ ); +} + +describe('AuthProvider with preview mode', () => { + it('should auto-authenticate with simulated admin user when previewMode is provided', async () => { + render( + + + + ); + + await waitFor(() => { + expect(screen.getByTestId('is-loading').textContent).toBe('false'); + }); + + expect(screen.getByTestId('is-authenticated').textContent).toBe('true'); + expect(screen.getByTestId('is-preview-mode').textContent).toBe('true'); + expect(screen.getByTestId('user-id').textContent).toBe('preview-user'); + expect(screen.getByTestId('user-name').textContent).toBe('Preview User'); + expect(screen.getByTestId('user-role').textContent).toBe('admin'); + }); + + it('should use custom simulated user name and role', async () => { + render( + + + + ); + + await waitFor(() => { + expect(screen.getByTestId('is-loading').textContent).toBe('false'); + }); + + expect(screen.getByTestId('is-authenticated').textContent).toBe('true'); + expect(screen.getByTestId('is-preview-mode').textContent).toBe('true'); + expect(screen.getByTestId('user-name').textContent).toBe('Demo Viewer'); + expect(screen.getByTestId('user-role').textContent).toBe('viewer'); + expect(screen.getByTestId('banner-message').textContent).toBe('This is a demo.'); + }); + + it('should not be in preview mode when previewMode is not provided', async () => { + const mockClient = { + getSession: async () => null, + signIn: async () => ({ user: { id: '1', name: 'Test', email: 'test@example.com' }, session: { token: 'token' } }), + signUp: async () => ({ user: { id: '1', name: 'Test', email: 'test@example.com' }, session: { token: 'token' } }), + signOut: async () => {}, + updateUser: async () => ({ id: '1', name: 'Test', email: 'test@example.com' }), + forgotPassword: async () => {}, + resetPassword: async () => {}, + }; + + render( + + + + ); + + await waitFor(() => { + expect(screen.getByTestId('is-loading').textContent).toBe('false'); + }); + + expect(screen.getByTestId('is-preview-mode').textContent).toBe('false'); + expect(screen.getByTestId('banner-message').textContent).toBe('null'); + }); + + it('should apply default values for preview mode config', async () => { + render( + + + + ); + + await waitFor(() => { + expect(screen.getByTestId('is-loading').textContent).toBe('false'); + }); + + expect(screen.getByTestId('is-preview-mode').textContent).toBe('true'); + expect(screen.getByTestId('user-name').textContent).toBe('Preview User'); + expect(screen.getByTestId('user-role').textContent).toBe('admin'); + }); +}); diff --git a/packages/auth/src/__tests__/PreviewBanner.test.tsx b/packages/auth/src/__tests__/PreviewBanner.test.tsx new file mode 100644 index 000000000..8d03c65cb --- /dev/null +++ b/packages/auth/src/__tests__/PreviewBanner.test.tsx @@ -0,0 +1,57 @@ +/** + * ObjectUI + * Copyright (c) 2024-present ObjectStack Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import { describe, it, expect } from 'vitest'; +import { render, screen, waitFor } from '@testing-library/react'; +import { AuthProvider } from '../AuthProvider'; +import { PreviewBanner } from '../PreviewBanner'; + +describe('PreviewBanner', () => { + it('should render banner message when in preview mode', async () => { + render( + + + + ); + + await waitFor(() => { + expect(screen.getByRole('status')).toBeInTheDocument(); + }); + + expect(screen.getByRole('status').textContent).toBe('You are in a demo.'); + }); + + it('should render default message when bannerMessage is not provided', async () => { + render( + + + + ); + + await waitFor(() => { + expect(screen.getByRole('status')).toBeInTheDocument(); + }); + + expect(screen.getByRole('status').textContent).toBe('You are in preview mode.'); + }); + + it('should not render when not in preview mode', async () => { + render( + + + + ); + + await waitFor(() => { + expect(screen.queryByRole('status')).not.toBeInTheDocument(); + }); + }); +}); diff --git a/packages/auth/src/index.ts b/packages/auth/src/index.ts index 685372895..114ced788 100644 --- a/packages/auth/src/index.ts +++ b/packages/auth/src/index.ts @@ -28,6 +28,7 @@ export { LoginForm, type LoginFormProps } from './LoginForm'; export { RegisterForm, type RegisterFormProps } from './RegisterForm'; export { ForgotPasswordForm, type ForgotPasswordFormProps } from './ForgotPasswordForm'; export { UserMenu, type UserMenuProps } from './UserMenu'; +export { PreviewBanner, type PreviewBannerProps } from './PreviewBanner'; export { createAuthClient } from './createAuthClient'; export { createAuthenticatedFetch, type AuthenticatedAdapterOptions } from './createAuthenticatedFetch'; export { getUserInitials } from './types'; @@ -40,6 +41,7 @@ export type { AuthClient, AuthClientConfig, AuthProviderConfig, + PreviewModeOptions, SignInCredentials, SignUpData, } from './types'; diff --git a/packages/auth/src/types.ts b/packages/auth/src/types.ts index 86b44ab8b..69c23d54b 100644 --- a/packages/auth/src/types.ts +++ b/packages/auth/src/types.ts @@ -110,6 +110,26 @@ export interface AuthClient { updateUser: (data: Partial) => Promise; } +/** + * Preview mode configuration options. + * When preview mode is active, the auth provider auto-logs in a simulated user + * and bypasses login/registration screens. + */ +export interface PreviewModeOptions { + /** Auto-login as simulated user, skipping login/registration pages */ + autoLogin?: boolean; + /** Permission role for the simulated preview user */ + simulatedRole?: 'admin' | 'user' | 'viewer'; + /** Display name for the simulated preview user */ + simulatedUserName?: string; + /** Restrict the preview session to read-only operations */ + readOnly?: boolean; + /** Preview session duration in seconds (0 = no expiration) */ + expiresInSeconds?: number; + /** Banner message displayed in the UI during preview mode */ + bannerMessage?: string; +} + /** Auth provider configuration */ export interface AuthProviderConfig { /** Authentication server URL */ diff --git a/packages/auth/src/useAuth.ts b/packages/auth/src/useAuth.ts index 8b13419e0..0ace70533 100644 --- a/packages/auth/src/useAuth.ts +++ b/packages/auth/src/useAuth.ts @@ -33,6 +33,8 @@ export function useAuth(): AuthContextValue { isAuthenticated: false, isLoading: false, error: null, + isPreviewMode: false, + previewMode: null, signIn: async () => { throw new Error('useAuth must be used within an AuthProvider'); }, signUp: async () => { throw new Error('useAuth must be used within an AuthProvider'); }, signOut: async () => { throw new Error('useAuth must be used within an AuthProvider'); }, diff --git a/packages/core/package.json b/packages/core/package.json index c7857f572..e94b79dde 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -31,7 +31,7 @@ }, "dependencies": { "@object-ui/types": "workspace:*", - "@objectstack/spec": "^3.0.2", + "@objectstack/spec": "^3.0.4", "lodash": "^4.17.23", "zod": "^4.3.6" }, diff --git a/packages/data-objectstack/package.json b/packages/data-objectstack/package.json index 4d0646468..f63d60441 100644 --- a/packages/data-objectstack/package.json +++ b/packages/data-objectstack/package.json @@ -30,7 +30,7 @@ "dependencies": { "@object-ui/core": "workspace:*", "@object-ui/types": "workspace:*", - "@objectstack/client": "^3.0.2" + "@objectstack/client": "^3.0.4" }, "devDependencies": { "tsup": "^8.5.1", diff --git a/packages/plugin-gantt/package.json b/packages/plugin-gantt/package.json index 9622050ac..8f713a6fb 100644 --- a/packages/plugin-gantt/package.json +++ b/packages/plugin-gantt/package.json @@ -36,7 +36,7 @@ "@object-ui/fields": "workspace:*", "@object-ui/react": "workspace:*", "@object-ui/types": "workspace:*", - "@objectstack/spec": "^3.0.2", + "@objectstack/spec": "^3.0.4", "lucide-react": "^0.563.0" }, "peerDependencies": { diff --git a/packages/plugin-map/package.json b/packages/plugin-map/package.json index 56e42349d..c809b4bd4 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": "^3.0.2", + "@objectstack/spec": "^3.0.4", "lucide-react": "^0.563.0", "maplibre-gl": "^5.18.0", "react-map-gl": "^8.1.0", diff --git a/packages/plugin-timeline/package.json b/packages/plugin-timeline/package.json index 7b27c5d11..9beb10fb5 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": "^3.0.2", + "@objectstack/spec": "^3.0.4", "zod": "^4.3.6" }, "peerDependencies": { diff --git a/packages/react/package.json b/packages/react/package.json index 4eff8b495..279e76e3b 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -32,7 +32,7 @@ "@object-ui/core": "workspace:*", "@object-ui/i18n": "workspace:*", "@object-ui/types": "workspace:*", - "@objectstack/spec": "^3.0.2", + "@objectstack/spec": "^3.0.4", "react-hook-form": "^7.71.1" }, "peerDependencies": { diff --git a/packages/react/src/hooks/useDiscovery.ts b/packages/react/src/hooks/useDiscovery.ts index c34d80d93..14855e65e 100644 --- a/packages/react/src/hooks/useDiscovery.ts +++ b/packages/react/src/hooks/useDiscovery.ts @@ -18,6 +18,19 @@ export interface DiscoveryInfo { name?: string; version?: string; + /** Runtime mode (e.g., 'development', 'production', 'preview') */ + mode?: string; + + /** Preview mode configuration from the kernel (present when mode is 'preview') */ + previewMode?: { + autoLogin?: boolean; + simulatedRole?: 'admin' | 'user' | 'viewer'; + simulatedUserName?: string; + readOnly?: boolean; + expiresInSeconds?: number; + bannerMessage?: string; + }; + /** Service availability status */ services?: { /** Authentication service status */ diff --git a/packages/types/package.json b/packages/types/package.json index 960668317..baaa29000 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -82,7 +82,7 @@ "directory": "packages/types" }, "dependencies": { - "@objectstack/spec": "^3.0.2", + "@objectstack/spec": "^3.0.4", "zod": "^4.3.6" }, "devDependencies": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 40b3fb04a..9e852aed9 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -18,11 +18,11 @@ importers: specifier: ^1.19.9 version: 1.19.9(hono@4.11.9) '@objectstack/plugin-hono-server': - specifier: ^3.0.2 - version: 3.0.2(pino@8.21.0) + specifier: ^3.0.4 + version: 3.0.4(pino@8.21.0) '@objectstack/studio': - specifier: ^3.0.2 - version: 3.0.2(@types/node@25.2.3)(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(pino@8.21.0)(typescript@5.9.3) + specifier: ^3.0.4 + version: 3.0.4(@types/node@25.2.3)(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(pino@8.21.0)(typescript@5.9.3) coverage-v8: specifier: 0.0.1-security version: 0.0.1-security @@ -43,26 +43,26 @@ importers: specifier: ^9.39.2 version: 9.39.2 '@objectstack/cli': - specifier: ^3.0.2 - version: 3.0.2(@objectstack/core@3.0.2(pino@8.21.0))(esbuild@0.27.3)(pino@8.21.0) + specifier: ^3.0.4 + version: 3.0.4(@objectstack/core@3.0.4(pino@8.21.0))(esbuild@0.27.3)(pino@8.21.0) '@objectstack/core': - specifier: ^3.0.2 - version: 3.0.2(pino@8.21.0) + specifier: ^3.0.4 + version: 3.0.4(pino@8.21.0) '@objectstack/driver-memory': - specifier: ^3.0.2 - version: 3.0.2(pino@8.21.0) + specifier: ^3.0.4 + version: 3.0.4(pino@8.21.0) '@objectstack/objectql': - specifier: ^3.0.2 - version: 3.0.2(pino@8.21.0) + specifier: ^3.0.4 + version: 3.0.4(pino@8.21.0) '@objectstack/plugin-msw': - specifier: ^3.0.2 - version: 3.0.2(@objectstack/runtime@3.0.2(pino@8.21.0))(@types/node@25.2.3)(pino@8.21.0)(typescript@5.9.3) + specifier: ^3.0.4 + version: 3.0.4(@objectstack/runtime@3.0.4(pino@8.21.0))(@types/node@25.2.3)(pino@8.21.0)(typescript@5.9.3) '@objectstack/runtime': - specifier: ^3.0.2 - version: 3.0.2(pino@8.21.0) + specifier: ^3.0.4 + version: 3.0.4(pino@8.21.0) '@objectstack/spec': - specifier: ^3.0.2 - version: 3.0.2 + specifier: ^3.0.4 + version: 3.0.4 '@playwright/test': specifier: ^1.58.2 version: 1.58.2 @@ -301,26 +301,26 @@ importers: specifier: workspace:* version: link:../../packages/types '@objectstack/cli': - specifier: ^3.0.2 - version: 3.0.2(@objectstack/core@3.0.2(pino@8.21.0))(esbuild@0.27.3)(pino@8.21.0) + specifier: ^3.0.4 + version: 3.0.4(@objectstack/core@3.0.4(pino@8.21.0))(esbuild@0.27.3)(pino@8.21.0) '@objectstack/client': - specifier: ^3.0.2 - version: 3.0.2(pino@8.21.0) + specifier: ^3.0.4 + version: 3.0.4(pino@8.21.0) '@objectstack/driver-memory': - specifier: ^3.0.2 - version: 3.0.2(pino@8.21.0) + specifier: ^3.0.4 + version: 3.0.4(pino@8.21.0) '@objectstack/objectql': - specifier: ^3.0.2 - version: 3.0.2(pino@8.21.0) + specifier: ^3.0.4 + version: 3.0.4(pino@8.21.0) '@objectstack/plugin-msw': - specifier: ^3.0.2 - version: 3.0.2(@objectstack/runtime@3.0.2(pino@8.21.0))(@types/node@25.2.3)(pino@8.21.0)(typescript@5.9.3) + specifier: ^3.0.4 + version: 3.0.4(@objectstack/runtime@3.0.4(pino@8.21.0))(@types/node@25.2.3)(pino@8.21.0)(typescript@5.9.3) '@objectstack/runtime': - specifier: ^3.0.2 - version: 3.0.2(pino@8.21.0) + specifier: ^3.0.4 + version: 3.0.4(pino@8.21.0) '@objectstack/spec': - specifier: ^3.0.2 - version: 3.0.2 + specifier: ^3.0.4 + version: 3.0.4 '@tailwindcss/postcss': specifier: ^4.1.18 version: 4.1.18 @@ -518,26 +518,26 @@ importers: specifier: workspace:* version: link:../../apps/console '@objectstack/core': - specifier: ^3.0.2 - version: 3.0.2(pino@8.21.0) + specifier: ^3.0.4 + version: 3.0.4(pino@8.21.0) '@objectstack/driver-memory': - specifier: ^3.0.2 - version: 3.0.2(pino@8.21.0) + specifier: ^3.0.4 + version: 3.0.4(pino@8.21.0) '@objectstack/objectql': - specifier: ^3.0.2 - version: 3.0.2(pino@8.21.0) + specifier: ^3.0.4 + version: 3.0.4(pino@8.21.0) '@objectstack/plugin-auth': - specifier: ^3.0.2 - version: 3.0.2(next@16.1.6(@babel/core@7.29.0)(@playwright/test@1.58.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(pino@8.21.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(vitest@4.0.18) + specifier: ^3.0.4 + version: 3.0.4(next@16.1.6(@babel/core@7.29.0)(@playwright/test@1.58.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(pino@8.21.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(vitest@4.0.18) '@objectstack/plugin-hono-server': - specifier: ^3.0.2 - version: 3.0.2(pino@8.21.0) + specifier: ^3.0.4 + version: 3.0.4(pino@8.21.0) '@objectstack/runtime': - specifier: ^3.0.2 - version: 3.0.2(pino@8.21.0) + specifier: ^3.0.4 + version: 3.0.4(pino@8.21.0) '@objectstack/spec': - specifier: ^3.0.2 - version: 3.0.2 + specifier: ^3.0.4 + version: 3.0.4 hono: specifier: ^4.11.9 version: 4.11.9 @@ -549,8 +549,8 @@ importers: version: 13.1.3 devDependencies: '@objectstack/cli': - specifier: ^3.0.2 - version: 3.0.2(@objectstack/core@3.0.2(pino@8.21.0))(esbuild@0.27.3)(pino@8.21.0) + specifier: ^3.0.4 + version: 3.0.4(@objectstack/core@3.0.4(pino@8.21.0))(esbuild@0.27.3)(pino@8.21.0) tsx: specifier: ^4.21.0 version: 4.21.0 @@ -579,12 +579,12 @@ importers: examples/kitchen-sink: dependencies: '@objectstack/spec': - specifier: ^3.0.2 - version: 3.0.2 + specifier: ^3.0.4 + version: 3.0.4 devDependencies: '@objectstack/cli': - specifier: ^3.0.2 - version: 3.0.2(@objectstack/core@3.0.2(pino@8.21.0))(esbuild@0.27.3)(pino@8.21.0) + specifier: ^3.0.4 + version: 3.0.4(@objectstack/core@3.0.4(pino@8.21.0))(esbuild@0.27.3)(pino@8.21.0) typescript: specifier: ^5.9.3 version: 5.9.3 @@ -595,23 +595,23 @@ importers: specifier: workspace:* version: link:../todo '@objectstack/client': - specifier: ^3.0.2 - version: 3.0.2(pino@8.21.0) + specifier: ^3.0.4 + version: 3.0.4(pino@8.21.0) '@objectstack/driver-memory': - specifier: ^3.0.2 - version: 3.0.2(pino@8.21.0) + specifier: ^3.0.4 + version: 3.0.4(pino@8.21.0) '@objectstack/objectql': - specifier: ^3.0.2 - version: 3.0.2(pino@8.21.0) + specifier: ^3.0.4 + version: 3.0.4(pino@8.21.0) '@objectstack/plugin-msw': - specifier: ^3.0.2 - version: 3.0.2(@objectstack/runtime@3.0.2(pino@8.21.0))(@types/node@25.2.3)(pino@8.21.0)(typescript@5.9.3) + specifier: ^3.0.4 + version: 3.0.4(@objectstack/runtime@3.0.4(pino@8.21.0))(@types/node@25.2.3)(pino@8.21.0)(typescript@5.9.3) '@objectstack/runtime': - specifier: ^3.0.2 - version: 3.0.2(pino@8.21.0) + specifier: ^3.0.4 + version: 3.0.4(pino@8.21.0) '@objectstack/spec': - specifier: ^3.0.2 - version: 3.0.2 + specifier: ^3.0.4 + version: 3.0.4 react: specifier: 19.2.4 version: 19.2.4 @@ -653,15 +653,15 @@ importers: examples/todo: dependencies: '@objectstack/client': - specifier: ^3.0.2 - version: 3.0.2(pino@8.21.0) + specifier: ^3.0.4 + version: 3.0.4(pino@8.21.0) '@objectstack/spec': - specifier: ^3.0.2 - version: 3.0.2 + specifier: ^3.0.4 + version: 3.0.4 devDependencies: '@objectstack/cli': - specifier: ^3.0.2 - version: 3.0.2(@objectstack/core@3.0.2(pino@8.21.0))(esbuild@0.27.3)(pino@8.21.0) + specifier: ^3.0.4 + version: 3.0.4(@objectstack/core@3.0.4(pino@8.21.0))(esbuild@0.27.3)(pino@8.21.0) typescript: specifier: ^5.9.3 version: 5.9.3 @@ -967,8 +967,8 @@ importers: specifier: workspace:* version: link:../types '@objectstack/spec': - specifier: ^3.0.2 - version: 3.0.2 + specifier: ^3.0.4 + version: 3.0.4 lodash: specifier: ^4.17.23 version: 4.17.23 @@ -1026,8 +1026,8 @@ importers: specifier: workspace:* version: link:../types '@objectstack/client': - specifier: ^3.0.2 - version: 3.0.2(pino@8.21.0) + specifier: ^3.0.4 + version: 3.0.4(pino@8.21.0) devDependencies: tsup: specifier: ^8.5.1 @@ -1696,8 +1696,8 @@ importers: specifier: workspace:* version: link:../types '@objectstack/spec': - specifier: ^3.0.2 - version: 3.0.2 + specifier: ^3.0.4 + version: 3.0.4 lucide-react: specifier: ^0.563.0 version: 0.563.0(react@19.2.4) @@ -1901,8 +1901,8 @@ importers: specifier: workspace:* version: link:../types '@objectstack/spec': - specifier: ^3.0.2 - version: 3.0.2 + specifier: ^3.0.4 + version: 3.0.4 lucide-react: specifier: ^0.563.0 version: 0.563.0(react@19.2.4) @@ -2063,8 +2063,8 @@ importers: specifier: workspace:* version: link:../types '@objectstack/spec': - specifier: ^3.0.2 - version: 3.0.2 + specifier: ^3.0.4 + version: 3.0.4 react: specifier: 19.2.4 version: 19.2.4 @@ -2207,8 +2207,8 @@ importers: specifier: workspace:* version: link:../types '@objectstack/spec': - specifier: ^3.0.2 - version: 3.0.2 + specifier: ^3.0.4 + version: 3.0.4 react: specifier: 19.2.4 version: 19.2.4 @@ -2321,8 +2321,8 @@ importers: packages/types: dependencies: '@objectstack/spec': - specifier: ^3.0.2 - version: 3.0.2 + specifier: ^3.0.4 + version: 3.0.4 zod: specifier: ^4.3.6 version: 4.3.6 @@ -3929,63 +3929,63 @@ packages: resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} engines: {node: '>= 8'} - '@objectstack/cli@3.0.2': - resolution: {integrity: sha512-LAdGrxX+3wUKusj2LNt5+QFJCpdGPnn9g1EvwHKQbsXdSnTdoxHMKVXpQHn10tcBaDeIgYBbFDDOtPrmbHQiuA==} + '@objectstack/cli@3.0.4': + resolution: {integrity: sha512-6pDfBfOl9PMp0lkF1nNNOKLH0fdgAXCWqRtAzv5Z7WA9X/en7k4ffGmrYVZsXaOe0sYumBeWlRzLKnA8aTqjtQ==} hasBin: true peerDependencies: - '@objectstack/core': 3.0.2 + '@objectstack/core': 3.0.4 - '@objectstack/client-react@3.0.2': - resolution: {integrity: sha512-GL575/+TDdw294anDf4DhxXAyugWVkV7XQlOje8plgg/7mFO9UbAfHfEI/BuMfaOz/YZvXgxACTEz3hQv7I7Vg==} + '@objectstack/client-react@3.0.4': + resolution: {integrity: sha512-PxmylYXdv1/fstowp3OK5o6a25pKGanbS1gkGZgK/Nn1kZmCOPcBHqoOXi3sbgwliCeBZ6HCP3ufTdXSiWV/ow==} peerDependencies: react: 19.2.4 - '@objectstack/client@3.0.2': - resolution: {integrity: sha512-a/zVeVYjid38nIDV5mzvQH5sKJSen+4bIhjTW/LHaIHytEBcugwVJ1kgC96YEAodVWTolXBY898QrYifIAIYgA==} + '@objectstack/client@3.0.4': + resolution: {integrity: sha512-Pz0jCSKEcssW/QP080b/m+u2cuoiztorFkREDOYxMOZ/+8Mw/Ng5lU0c4S6EyC2HJcqqwAtxQ4V43PtxvQ+bTA==} - '@objectstack/core@3.0.2': - resolution: {integrity: sha512-NGOUXg8Kq2TSJXDzsK48RuXUFHbNEclVlYkfz7x3WzSBAEcv+TUWTctRX8y75y5N8ZY8XWSnlOz5sbMX8+Frxg==} + '@objectstack/core@3.0.4': + resolution: {integrity: sha512-x4LvbsP9d3ohJctYi20FtzZf7kkSoaisgZfPMlNsnXfLmm1BUsjeXY79XNaf+vfwDM3kG0WyrmkiTD/HwfxfwA==} peerDependencies: pino: ^8.0.0 peerDependenciesMeta: pino: optional: true - '@objectstack/driver-memory@3.0.2': - resolution: {integrity: sha512-Kkt5b5vnf3vTGYwoiNTL/FzVNLNkR6ucPJU8kHIZ7OVOIW74fTdd88n58/2RG4bN2I/xidBtpIRjlm/eaS6b/A==} + '@objectstack/driver-memory@3.0.4': + resolution: {integrity: sha512-Ip01vkdfknT0cJQmhR7CLYSaR/C6pWTgPc/KP0UNx7+WZ/cTcKEMhBHsWCN7SDCY/Pfo7T4m6N5uv1nqqGWQVQ==} - '@objectstack/metadata@3.0.2': - resolution: {integrity: sha512-i88ho79CaVmCJY8D8pMMM1PNlnt2k1LBW6y/sE30q3/1PsyP16fY/KnpbRgbGf+JkUqsA4/1QK38IYtEKzvTGw==} + '@objectstack/metadata@3.0.4': + resolution: {integrity: sha512-1Gwa3tqwho6Vt3cPObfZA6FFDh8xgd/qi/70BMuNHLpUZOJAJoJKEchYugX2zHmaBcgPs6MI0rA8PZrvWYafGA==} - '@objectstack/objectql@3.0.2': - resolution: {integrity: sha512-bwnNDGaSvBrs6gj+qyWeP6tq1Be5eWSWQWbS6rv3VuwGI9gThwX8Q7icQ2MSy7msELrXUQqf/bmhkcX2ORLhrg==} + '@objectstack/objectql@3.0.4': + resolution: {integrity: sha512-FnvaDCXV6FTgCOLBQfC+LN+GtOVSgC+xB5rYe6jQlCkwz11BR0G+OwYQH1+ANyNCIe8XfQovI++7EeeHEVm2xw==} - '@objectstack/plugin-auth@3.0.2': - resolution: {integrity: sha512-cxu14egMYW4KBDjbJ99pBZ5qt4NyrrNj2CPE5l2j9phYoAgkaEHmRO445IWUGzPwuCQLRphHEmNhV3UjVTbPLA==} + '@objectstack/plugin-auth@3.0.4': + resolution: {integrity: sha512-LEjq20g475wEyiTSslZOhXaCipe7++7lZVohfHqF0mygd2gA14HO6MSv9opz0dp7gS4m5nzqWlpsP4FfGKu09A==} - '@objectstack/plugin-hono-server@3.0.2': - resolution: {integrity: sha512-HZ6m550nfpOC0nVgBQilqnUi+0sl4UD8W/HN5q6ZjAZVsor0It5DG04FS4j0FKvl5yEj7xt4J637YOnQ6hWdPQ==} + '@objectstack/plugin-hono-server@3.0.4': + resolution: {integrity: sha512-Ie4Rf+b7PEhGRWyHXc0ZmDAsa/Wn9V6k/tGPUZEB5JgpzOOAx0RRGEdGzAIU7+z8IWmXQIIm+EbOSBjWqGHesg==} - '@objectstack/plugin-msw@3.0.2': - resolution: {integrity: sha512-hZ6aHPQUbFo/8wrzd3Ytx5A/Equn/0Vd+IuuxcuOPm8Ul30I+G27DOO2FiCbdPNanHhRxfHFFRixm1lbs0c3OA==} + '@objectstack/plugin-msw@3.0.4': + resolution: {integrity: sha512-Sov1svbMp1hWL5AuauwIM38GDFE8uaI1TzaT9GN5woxykEpTfMgNlbhhnkabnY+tfn4VGqzquzOp9K3vbv5XFQ==} peerDependencies: - '@objectstack/runtime': 3.0.2 + '@objectstack/runtime': 3.0.4 - '@objectstack/rest@3.0.2': - resolution: {integrity: sha512-3Sd7vibsgHD0MLCrqzmz76VgrB1Ka2MLLcr8uvhzLySdhOBzmgrdFt2hnjdQ3482TlW3ua7TRC4zNKp/LGnGhw==} + '@objectstack/rest@3.0.4': + resolution: {integrity: sha512-e1KLLG6p/DrY646T+1heMuRlAgjwZcyhjnyKqM7xirvUZEPa+X2PFlKhG6Z+QhlYRvm57K+zI0vpCzju3oP3tA==} - '@objectstack/runtime@3.0.2': - resolution: {integrity: sha512-eDKUYNwxYGFsRsbM3qjazYY5AjdFi3dzcnu8vu1VBZSnLoApofVm/Q7ieO2Aik5tTae6JZlO7h3//lopCyzbgg==} + '@objectstack/runtime@3.0.4': + resolution: {integrity: sha512-vmSnC3FESFK9l5mj3Lf0IGu5LZ8lIr6J3l5FVlKJQslMrCpOC4/Bhipql0kjxxzozeBuHZ+cnmXLpm2Q0Cpwsg==} - '@objectstack/spec@3.0.2': - resolution: {integrity: sha512-EA5mToq46WKj/1Ki4zwvmuRogqL2NLW4OJz9ZT5CNJFF7QJTVhxE8V0xXsezugJQ1xrRQBinci0VRc2fxeC3gA==} + '@objectstack/spec@3.0.4': + resolution: {integrity: sha512-Uwg+jJ9VQJF2oX6sAMf00hIlMHOo+bz4sbORYseZj4YbENbL3CyudObmWm7yeMEFWqJh3g6YBTNW/5Du7b79lw==} engines: {node: '>=18.0.0'} - '@objectstack/studio@3.0.2': - resolution: {integrity: sha512-lT89t8/2yAOv9mW356sXsCdApOYX0Aj6b8jjtfw2IY7/YgsYNWeVybSAUxDjXcdTJtCO9gEakeF0MPeK5MJjug==} + '@objectstack/studio@3.0.4': + resolution: {integrity: sha512-eM5AIwBo8P0HM0nFp2MCSuAKME1KyTZUF7VI6lZyqkKLLEA3qSvWNYZRQKo1DbErh/MDCqengDqCZL+DOXNoEA==} - '@objectstack/types@3.0.2': - resolution: {integrity: sha512-OPF+eCT4HuKkqRkH9X0GrgVZgrjt5MzS9heVlhp0GjMF+IZwC/srkp4tuM+iomD7TBIi0XQQAjnbEtxEkVf33w==} + '@objectstack/types@3.0.4': + resolution: {integrity: sha512-dCslJv2l3HSliSNP8uM5Qxp/GX6/kmG7m/DzGcwNug2i4bvz31AxkU/LFv6OVoTOycqmBRz7zX+f//diW0cFoQ==} '@open-draft/deferred-promise@2.2.0': resolution: {integrity: sha512-CecwLWx3rhxVQF6V4bAgPS5t+So2sTbPgAzafKkVizyi7tlwpcFpdFqq+wqF2OwNBmqFuu6tOyouTuxgpMfzmA==} @@ -13245,15 +13245,15 @@ snapshots: '@nodelib/fs.scandir': 2.1.5 fastq: 1.20.1 - '@objectstack/cli@3.0.2(@objectstack/core@3.0.2(pino@8.21.0))(esbuild@0.27.3)(pino@8.21.0)': + '@objectstack/cli@3.0.4(@objectstack/core@3.0.4(pino@8.21.0))(esbuild@0.27.3)(pino@8.21.0)': dependencies: - '@objectstack/core': 3.0.2(pino@8.21.0) - '@objectstack/driver-memory': 3.0.2(pino@8.21.0) - '@objectstack/objectql': 3.0.2(pino@8.21.0) - '@objectstack/plugin-hono-server': 3.0.2(pino@8.21.0) - '@objectstack/rest': 3.0.2(pino@8.21.0) - '@objectstack/runtime': 3.0.2(pino@8.21.0) - '@objectstack/spec': 3.0.2 + '@objectstack/core': 3.0.4(pino@8.21.0) + '@objectstack/driver-memory': 3.0.4(pino@8.21.0) + '@objectstack/objectql': 3.0.4(pino@8.21.0) + '@objectstack/plugin-hono-server': 3.0.4(pino@8.21.0) + '@objectstack/rest': 3.0.4(pino@8.21.0) + '@objectstack/runtime': 3.0.4(pino@8.21.0) + '@objectstack/spec': 3.0.4 bundle-require: 5.1.0(esbuild@0.27.3) chalk: 5.6.2 commander: 14.0.3 @@ -13263,43 +13263,43 @@ snapshots: - esbuild - pino - '@objectstack/client-react@3.0.2(pino@8.21.0)(react@19.2.4)': + '@objectstack/client-react@3.0.4(pino@8.21.0)(react@19.2.4)': dependencies: - '@objectstack/client': 3.0.2(pino@8.21.0) - '@objectstack/core': 3.0.2(pino@8.21.0) - '@objectstack/spec': 3.0.2 + '@objectstack/client': 3.0.4(pino@8.21.0) + '@objectstack/core': 3.0.4(pino@8.21.0) + '@objectstack/spec': 3.0.4 react: 19.2.4 transitivePeerDependencies: - pino - '@objectstack/client@3.0.2(pino@8.21.0)': + '@objectstack/client@3.0.4(pino@8.21.0)': dependencies: - '@objectstack/core': 3.0.2(pino@8.21.0) - '@objectstack/spec': 3.0.2 + '@objectstack/core': 3.0.4(pino@8.21.0) + '@objectstack/spec': 3.0.4 transitivePeerDependencies: - pino - '@objectstack/core@3.0.2(pino@8.21.0)': + '@objectstack/core@3.0.4(pino@8.21.0)': dependencies: - '@objectstack/spec': 3.0.2 + '@objectstack/spec': 3.0.4 pino-pretty: 13.1.3 zod: 4.3.6 optionalDependencies: pino: 8.21.0 - '@objectstack/driver-memory@3.0.2(pino@8.21.0)': + '@objectstack/driver-memory@3.0.4(pino@8.21.0)': dependencies: - '@objectstack/core': 3.0.2(pino@8.21.0) - '@objectstack/spec': 3.0.2 + '@objectstack/core': 3.0.4(pino@8.21.0) + '@objectstack/spec': 3.0.4 mingo: 7.2.0 transitivePeerDependencies: - pino - '@objectstack/metadata@3.0.2(pino@8.21.0)': + '@objectstack/metadata@3.0.4(pino@8.21.0)': dependencies: - '@objectstack/core': 3.0.2(pino@8.21.0) - '@objectstack/spec': 3.0.2 - '@objectstack/types': 3.0.2 + '@objectstack/core': 3.0.4(pino@8.21.0) + '@objectstack/spec': 3.0.4 + '@objectstack/types': 3.0.4 chokidar: 5.0.0 glob: 13.0.3 js-yaml: 4.1.1 @@ -13307,18 +13307,18 @@ snapshots: transitivePeerDependencies: - pino - '@objectstack/objectql@3.0.2(pino@8.21.0)': + '@objectstack/objectql@3.0.4(pino@8.21.0)': dependencies: - '@objectstack/core': 3.0.2(pino@8.21.0) - '@objectstack/spec': 3.0.2 - '@objectstack/types': 3.0.2 + '@objectstack/core': 3.0.4(pino@8.21.0) + '@objectstack/spec': 3.0.4 + '@objectstack/types': 3.0.4 transitivePeerDependencies: - pino - '@objectstack/plugin-auth@3.0.2(next@16.1.6(@babel/core@7.29.0)(@playwright/test@1.58.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(pino@8.21.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(vitest@4.0.18)': + '@objectstack/plugin-auth@3.0.4(next@16.1.6(@babel/core@7.29.0)(@playwright/test@1.58.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(pino@8.21.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(vitest@4.0.18)': dependencies: - '@objectstack/core': 3.0.2(pino@8.21.0) - '@objectstack/spec': 3.0.2 + '@objectstack/core': 3.0.4(pino@8.21.0) + '@objectstack/spec': 3.0.4 better-auth: 1.4.18(next@16.1.6(@babel/core@7.29.0)(@playwright/test@1.58.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(vitest@4.0.18) transitivePeerDependencies: - '@lynx-js/react' @@ -13342,60 +13342,60 @@ snapshots: - vitest - vue - '@objectstack/plugin-hono-server@3.0.2(pino@8.21.0)': + '@objectstack/plugin-hono-server@3.0.4(pino@8.21.0)': dependencies: '@hono/node-server': 1.19.9(hono@4.11.9) - '@objectstack/core': 3.0.2(pino@8.21.0) - '@objectstack/spec': 3.0.2 + '@objectstack/core': 3.0.4(pino@8.21.0) + '@objectstack/spec': 3.0.4 hono: 4.11.9 transitivePeerDependencies: - pino - '@objectstack/plugin-msw@3.0.2(@objectstack/runtime@3.0.2(pino@8.21.0))(@types/node@25.2.3)(pino@8.21.0)(typescript@5.9.3)': + '@objectstack/plugin-msw@3.0.4(@objectstack/runtime@3.0.4(pino@8.21.0))(@types/node@25.2.3)(pino@8.21.0)(typescript@5.9.3)': dependencies: - '@objectstack/core': 3.0.2(pino@8.21.0) - '@objectstack/objectql': 3.0.2(pino@8.21.0) - '@objectstack/runtime': 3.0.2(pino@8.21.0) - '@objectstack/spec': 3.0.2 - '@objectstack/types': 3.0.2 + '@objectstack/core': 3.0.4(pino@8.21.0) + '@objectstack/objectql': 3.0.4(pino@8.21.0) + '@objectstack/runtime': 3.0.4(pino@8.21.0) + '@objectstack/spec': 3.0.4 + '@objectstack/types': 3.0.4 msw: 2.12.10(@types/node@25.2.3)(typescript@5.9.3) transitivePeerDependencies: - '@types/node' - pino - typescript - '@objectstack/rest@3.0.2(pino@8.21.0)': + '@objectstack/rest@3.0.4(pino@8.21.0)': dependencies: - '@objectstack/core': 3.0.2(pino@8.21.0) - '@objectstack/spec': 3.0.2 + '@objectstack/core': 3.0.4(pino@8.21.0) + '@objectstack/spec': 3.0.4 zod: 4.3.6 transitivePeerDependencies: - pino - '@objectstack/runtime@3.0.2(pino@8.21.0)': + '@objectstack/runtime@3.0.4(pino@8.21.0)': dependencies: - '@objectstack/core': 3.0.2(pino@8.21.0) - '@objectstack/rest': 3.0.2(pino@8.21.0) - '@objectstack/spec': 3.0.2 - '@objectstack/types': 3.0.2 + '@objectstack/core': 3.0.4(pino@8.21.0) + '@objectstack/rest': 3.0.4(pino@8.21.0) + '@objectstack/spec': 3.0.4 + '@objectstack/types': 3.0.4 zod: 4.3.6 transitivePeerDependencies: - pino - '@objectstack/spec@3.0.2': + '@objectstack/spec@3.0.4': dependencies: zod: 4.3.6 - '@objectstack/studio@3.0.2(@types/node@25.2.3)(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(pino@8.21.0)(typescript@5.9.3)': + '@objectstack/studio@3.0.4(@types/node@25.2.3)(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(pino@8.21.0)(typescript@5.9.3)': dependencies: - '@objectstack/client': 3.0.2(pino@8.21.0) - '@objectstack/client-react': 3.0.2(pino@8.21.0)(react@19.2.4) - '@objectstack/driver-memory': 3.0.2(pino@8.21.0) - '@objectstack/metadata': 3.0.2(pino@8.21.0) - '@objectstack/objectql': 3.0.2(pino@8.21.0) - '@objectstack/plugin-msw': 3.0.2(@objectstack/runtime@3.0.2(pino@8.21.0))(@types/node@25.2.3)(pino@8.21.0)(typescript@5.9.3) - '@objectstack/runtime': 3.0.2(pino@8.21.0) - '@objectstack/spec': 3.0.2 + '@objectstack/client': 3.0.4(pino@8.21.0) + '@objectstack/client-react': 3.0.4(pino@8.21.0)(react@19.2.4) + '@objectstack/driver-memory': 3.0.4(pino@8.21.0) + '@objectstack/metadata': 3.0.4(pino@8.21.0) + '@objectstack/objectql': 3.0.4(pino@8.21.0) + '@objectstack/plugin-msw': 3.0.4(@objectstack/runtime@3.0.4(pino@8.21.0))(@types/node@25.2.3)(pino@8.21.0)(typescript@5.9.3) + '@objectstack/runtime': 3.0.4(pino@8.21.0) + '@objectstack/spec': 3.0.4 '@radix-ui/react-avatar': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@radix-ui/react-checkbox': 1.3.3(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@radix-ui/react-collapsible': 1.1.12(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) @@ -13425,9 +13425,9 @@ snapshots: - pino - typescript - '@objectstack/types@3.0.2': + '@objectstack/types@3.0.4': dependencies: - '@objectstack/spec': 3.0.2 + '@objectstack/spec': 3.0.4 '@open-draft/deferred-promise@2.2.0': {} From a4df074bd0b07f74fc06f98b510c20ba48ee62ad Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 14 Feb 2026 11:34:01 +0000 Subject: [PATCH 3/4] docs: add preview mode documentation to auth README, react README, and changelogs - packages/auth/README.md: Add Preview Mode section with usage, PreviewModeOptions table, PreviewBanner docs, and detection example - packages/auth/README.md: Update useAuth hook docs with isPreviewMode and previewMode fields - packages/auth/CHANGELOG.md: Add preview mode feature entries - packages/react/README.md: Add useDiscovery hook docs with DiscoveryInfo and preview mode fields - CHANGELOG.md: Add @objectstack v3.0.4 upgrade and preview mode feature entries Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com> --- CHANGELOG.md | 4 ++ packages/auth/CHANGELOG.md | 11 +++++ packages/auth/README.md | 94 +++++++++++++++++++++++++++++++++++++- packages/react/README.md | 41 +++++++++++++++++ 4 files changed, 149 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 199d108a1..92397b3c2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed +- **@objectstack v3.0.4 Upgrade**: Upgraded all `@objectstack/*` packages from `^3.0.2` to `^3.0.4` across 42 references - **@objectstack v3.0.0 Upgrade**: Upgraded all `@objectstack/*` packages from `^2.0.7` to `^3.0.0` across 13 package.json files - **Breaking change migrations**: - `Hub` namespace → `Cloud` in @object-ui/types re-exports @@ -22,6 +23,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added +- **Preview Mode** (`@object-ui/auth`): New `previewMode` prop on `AuthProvider` for auto-login with simulated identity — skip login/registration for marketplace demos and app showcases. Includes `PreviewBanner` component, `isPreviewMode` / `previewMode` on `useAuth()`, and `PreviewModeOptions` type. Aligns with `@objectstack/spec` kernel `PreviewModeConfig`. +- **Discovery Preview Detection** (`@object-ui/react`): Extended `DiscoveryInfo` with `mode` and `previewMode` fields for server-driven preview mode detection. +- **Console Preview Support**: `ConditionalAuthWrapper` auto-detects `mode === 'preview'` from server discovery and configures auth accordingly. - **Console Bundle Optimization**: Split monolithic 3.7 MB main chunk into 17 granular cacheable chunks via `manualChunks` — main entry reduced from 1,008 KB gzip to 48.5 KB gzip (95% reduction) - **Gzip + Brotli Compression**: Pre-compressed assets via `vite-plugin-compression2` — Brotli main entry at 40 KB - **Bundle Analysis**: Added `rollup-plugin-visualizer` generating interactive treemap at `dist/stats.html`; new `build:analyze` script diff --git a/packages/auth/CHANGELOG.md b/packages/auth/CHANGELOG.md index dada057ed..1cf07d004 100644 --- a/packages/auth/CHANGELOG.md +++ b/packages/auth/CHANGELOG.md @@ -6,6 +6,17 @@ - @object-ui/types@3.0.1 +### Added + +- **Preview Mode** (`previewMode` prop on `AuthProvider`): Auto-login with simulated identity for marketplace demos and app showcases. Configurable role, display name, session expiry, read-only mode, and banner message. +- **PreviewBanner** component: Renders a status banner when preview mode is active. +- `isPreviewMode` and `previewMode` fields exposed on `AuthContextValue` / `useAuth()` hook. +- New `PreviewModeOptions` type mirroring spec's `PreviewModeConfig`. + +### Changed + +- Upgraded `@objectstack/spec` from `^3.0.2` to `^3.0.4`. + ## 3.0.0 ### Minor Changes diff --git a/packages/auth/README.md b/packages/auth/README.md index 032e3a267..f8d65f4ab 100644 --- a/packages/auth/README.md +++ b/packages/auth/README.md @@ -10,6 +10,7 @@ Authentication system for Object UI — AuthProvider, guards, login/register for - 👤 **UserMenu** - Display authenticated user info with sign-out support - 🔑 **Auth Client Factory** - `createAuthClient` for pluggable backend integration - 🌐 **Authenticated Fetch** - `createAuthenticatedFetch` for automatic token injection +- 👀 **Preview Mode** - Auto-login with simulated identity for marketplace demos and app showcases - 🎯 **Type-Safe** - Full TypeScript support with exported types ## Installation @@ -71,9 +72,31 @@ Wraps your application with authentication context: Hook for accessing auth state and methods: ```tsx -const { user, session, signIn, signOut, signUp, isAuthenticated, isLoading } = useAuth(); +const { + user, + session, + signIn, + signOut, + signUp, + isAuthenticated, + isLoading, + isPreviewMode, + previewMode, +} = useAuth(); ``` +| Property | Type | Description | +| --- | --- | --- | +| `user` | `AuthUser \| null` | Current authenticated user | +| `session` | `AuthSession \| null` | Current session information | +| `isAuthenticated` | `boolean` | Whether the user is authenticated | +| `isLoading` | `boolean` | Whether auth state is loading | +| `isPreviewMode` | `boolean` | Whether the app is running in preview mode | +| `previewMode` | `PreviewModeOptions \| null` | Preview mode configuration (only set when `isPreviewMode` is true) | +| `signIn` | `(email, password) => Promise` | Sign in with credentials | +| `signOut` | `() => Promise` | Sign out the current user | +| `signUp` | `(name, email, password) => Promise` | Register a new user | + ### AuthGuard Protects children from unauthenticated access: @@ -110,6 +133,75 @@ Creates a fetch wrapper that injects auth tokens into DataSource requests: const authedFetch = createAuthenticatedFetch({ getToken: () => session.token }); ``` +## Preview Mode + +Preview mode allows visitors (e.g. marketplace customers) to explore the platform without registering or logging in. The `AuthProvider` auto-authenticates with a simulated user identity and bypasses login/registration screens. + +This feature aligns with the `PreviewModeConfig` from `@objectstack/spec/kernel` ([spec PR #676](https://github.com/objectstack-ai/spec/pull/676)). + +### Usage + +```tsx +import { AuthProvider, PreviewBanner } from '@object-ui/auth'; + +function App() { + return ( + + + + + ); +} +``` + +### PreviewModeOptions + +| Property | Type | Default | Description | +| --- | --- | --- | --- | +| `autoLogin` | `boolean` | `true` | Auto-login as simulated user, skipping login/registration pages | +| `simulatedRole` | `'admin' \| 'user' \| 'viewer'` | `'admin'` | Permission role for the simulated preview user | +| `simulatedUserName` | `string` | `'Preview User'` | Display name for the simulated preview user | +| `readOnly` | `boolean` | `false` | Restrict the preview session to read-only operations | +| `expiresInSeconds` | `number` | `0` | Preview session duration in seconds (0 = no expiration) | +| `bannerMessage` | `string` | — | Banner message displayed in the UI during preview mode | + +### PreviewBanner + +A component that renders a status banner when preview mode is active. Shows `bannerMessage` from the preview config, or a default message. + +```tsx +import { PreviewBanner } from '@object-ui/auth'; + +// Only renders when isPreviewMode is true + +``` + +### Detecting Preview Mode + +Use the `useAuth` hook to check if the app is in preview mode: + +```tsx +function MyComponent() { + const { isPreviewMode, previewMode } = useAuth(); + + if (isPreviewMode && previewMode?.readOnly) { + // Disable write operations + } + + return
...
; +} +``` + +> **⚠️ Security:** Preview mode should **never** be used in production environments. + ## License MIT diff --git a/packages/react/README.md b/packages/react/README.md index 5f768ea0d..34616d3d4 100644 --- a/packages/react/README.md +++ b/packages/react/README.md @@ -112,6 +112,47 @@ function MyComponent() { } ``` +### useDiscovery + +Access server discovery information including preview mode detection: + +```tsx +import { useDiscovery } from '@object-ui/react' + +function MyComponent() { + const { discovery, isLoading, isAuthEnabled } = useDiscovery() + + // Check if the server is in preview mode + if (discovery?.mode === 'preview') { + console.log('Preview mode active:', discovery.previewMode) + } + + return
Server: {discovery?.name}
+} +``` + +#### DiscoveryInfo + +| Property | Type | Description | +| --- | --- | --- | +| `name` | `string` | Server name | +| `version` | `string` | Server version | +| `mode` | `string` | Runtime mode (e.g. `'development'`, `'production'`, `'preview'`) | +| `previewMode` | `object` | Preview mode configuration (present when mode is `'preview'`) | +| `services` | `object` | Service availability status (auth, data, metadata) | +| `capabilities` | `string[]` | API capabilities | + +The `previewMode` object contains: + +| Property | Type | Default | Description | +| --- | --- | --- | --- | +| `autoLogin` | `boolean` | `true` | Skip login/registration pages | +| `simulatedRole` | `'admin' \| 'user' \| 'viewer'` | `'admin'` | Simulated user role | +| `simulatedUserName` | `string` | `'Preview User'` | Display name | +| `readOnly` | `boolean` | `false` | Read-only mode | +| `expiresInSeconds` | `number` | `0` | Session duration (0 = no expiry) | +| `bannerMessage` | `string` | — | UI banner message | + ## API Reference See [full documentation](https://objectui.org/api/react) for detailed API reference. From 7169d99e4ee8b059157e7375124c9e9cb96c8cd6 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 14 Feb 2026 11:49:03 +0000 Subject: [PATCH 4/4] fix: break cyclic dependency between console and crm example MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace @object-ui/console workspace dependency in examples/crm with relative path imports to apps/console/plugin.ts. This resolves the turbo build failure caused by the cyclic dependency: @object-ui/console → @object-ui/example-crm → @object-ui/console Updated files: - examples/crm/package.json: Remove @object-ui/console dependency - examples/crm/objectstack.config.ts: Use relative import - examples/crm/server.ts: Use relative import - examples/crm/console-plugin.ts: Use relative import All 215 test files pass (3998 tests), all 37 packages build, lint passes. Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com> --- examples/crm/console-plugin.ts | 2 +- examples/crm/objectstack.config.ts | 2 +- examples/crm/package.json | 1 - examples/crm/server.ts | 2 +- pnpm-lock.yaml | 3 --- 5 files changed, 3 insertions(+), 7 deletions(-) diff --git a/examples/crm/console-plugin.ts b/examples/crm/console-plugin.ts index 196b09939..049894bb6 100644 --- a/examples/crm/console-plugin.ts +++ b/examples/crm/console-plugin.ts @@ -9,4 +9,4 @@ * import { ConsolePlugin } from './console-plugin'; * kernel.use(ConsolePlugin); */ -export { ConsolePlugin } from '@object-ui/console'; +export { ConsolePlugin } from '../../apps/console/plugin'; diff --git a/examples/crm/objectstack.config.ts b/examples/crm/objectstack.config.ts index 23644b4d6..a118d1eb2 100644 --- a/examples/crm/objectstack.config.ts +++ b/examples/crm/objectstack.config.ts @@ -8,7 +8,7 @@ import { OrderObject } from './src/objects/order.object'; import { UserObject } from './src/objects/user.object'; import { ProjectObject } from './src/objects/project.object'; import { EventObject } from './src/objects/event.object'; -import { ConsolePlugin } from '@object-ui/console'; +import { ConsolePlugin } from '../../apps/console/plugin'; export default defineStack({ objects: [ diff --git a/examples/crm/package.json b/examples/crm/package.json index fc3f27233..bf2d001af 100644 --- a/examples/crm/package.json +++ b/examples/crm/package.json @@ -19,7 +19,6 @@ }, "dependencies": { "@hono/node-server": "^1.19.9", - "@object-ui/console": "workspace:*", "@objectstack/core": "^3.0.4", "@objectstack/driver-memory": "^3.0.4", "@objectstack/objectql": "^3.0.4", diff --git a/examples/crm/server.ts b/examples/crm/server.ts index dbd09b534..0daf20f8d 100644 --- a/examples/crm/server.ts +++ b/examples/crm/server.ts @@ -7,7 +7,7 @@ import { InMemoryDriver } from '@objectstack/driver-memory'; import { AuthPlugin } from '@objectstack/plugin-auth'; import config from './objectstack.config'; import { pino } from 'pino'; -import { ConsolePlugin } from '@object-ui/console'; +import { ConsolePlugin } from '../../apps/console/plugin'; async function startServer() { const logger = pino({ diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9e852aed9..eef37057e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -514,9 +514,6 @@ importers: '@hono/node-server': specifier: ^1.19.9 version: 1.19.9(hono@4.11.9) - '@object-ui/console': - specifier: workspace:* - version: link:../../apps/console '@objectstack/core': specifier: ^3.0.4 version: 3.0.4(pino@8.21.0)