Injectable React editor that is side-loaded onto the statically rendered page and edits through the CMS HTTP API (POST /api/edit). - Shadow-root UI over server HTML; patches morphed in, undo/redo from server inverses (reuses @k6n/cms-editor EditClient/morph/markdown editor) - Sign-in via go-auth device grant as the CMS client (aud matches), token refresh + 401 retry; live preview swapped in on load and on tab focus - Schema-driven property form (arrays, maps, variants, $ref, validation) - Every string property editable where it is rendered (value-bound inline fields and attribute chips), markdown WYSIWYG for marked fields - Block palette + drag & drop with ghost drop targets, insertion slots, sort snapping between siblings (Alt to nest) - x-style annotations: on-page padding/margin/gap handles, Style panel, wrap-in-layout; x-graph label/group for titles and grouping - Dev workflow: Vite proxy to the live site (token injected server-side) or an offline in-memory mock CMS; jsdom test suite Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
47 lines
1.8 KiB
TypeScript
47 lines
1.8 KiB
TypeScript
import { defineConfig, loadEnv, type UserConfig } from 'vite'
|
|
import react from '@vitejs/plugin-react'
|
|
import path from 'node:path'
|
|
import { cmsLivePlugin } from './vite/live'
|
|
import { cmsMockPlugin } from './vite/mock'
|
|
|
|
export default defineConfig(({ command, mode }): UserConfig => {
|
|
const env = { ...loadEnv(mode, process.cwd(), ''), ...process.env } as Record<string, string>
|
|
const editorSrc = path.resolve(env.CMS_EDITOR_SRC || '../ecommerce/backoffice/web/packages/cms-editor/src')
|
|
const common: UserConfig = {
|
|
plugins: [react()],
|
|
resolve: {
|
|
alias: { '@k6n/cms-editor': path.join(editorSrc, 'index.ts') },
|
|
// The shared package imports tiptap from its own location; keep a single copy.
|
|
dedupe: ['react', 'react-dom', '@tiptap/core', '@tiptap/pm'],
|
|
},
|
|
server: { port: 5173, strictPort: true /* the issuer's CORS allowlist names localhost:5173 */, fs: { allow: [process.cwd(), path.resolve(editorSrc, '..')] } },
|
|
test: {
|
|
environment: 'jsdom',
|
|
environmentOptions: { jsdom: { pretendToBeVisual: true } },
|
|
include: ['test/**/*.test.{ts,tsx}', 'src/**/*.test.{ts,tsx}', 'mock/**/*.test.ts'],
|
|
setupFiles: ['test/setup.ts'],
|
|
},
|
|
} as UserConfig
|
|
|
|
if (command === 'build') {
|
|
// The artifact served at /editor/onpage-editor.js. One self-contained file;
|
|
// only loaded when the preview cookie is present (see src/main.ts).
|
|
return {
|
|
...common,
|
|
define: { 'process.env.NODE_ENV': '"production"' },
|
|
build: {
|
|
outDir: 'dist',
|
|
lib: { entry: 'src/main.ts', formats: ['es'], fileName: () => 'onpage-editor.js' },
|
|
sourcemap: true,
|
|
cssCodeSplit: false,
|
|
},
|
|
}
|
|
}
|
|
|
|
const mock = (env.CMS_MODE || 'live') === 'mock'
|
|
return {
|
|
...common,
|
|
plugins: [...(common.plugins ?? []), mock ? cmsMockPlugin() : cmsLivePlugin(env)],
|
|
}
|
|
})
|