@sanity/workbench-cli 2.2.4 → 2.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_exports/build.d.ts +54 -2
- package/dist/_exports/build.js +1 -0
- package/dist/_exports/build.js.map +1 -1
- package/dist/_exports/{defineApp-Dmrf4GjS.d.ts → defineApp-KCHd3Vab.d.ts} +29 -29
- package/dist/_exports/deploy.d.ts +3 -3
- package/dist/_exports/dev.d.ts +1 -1
- package/dist/_exports/index.d.ts +3 -3
- package/dist/_exports/init.d.ts +2 -2
- package/dist/_exports/preview.d.ts +1 -1
- package/dist/_exports/{registry-HE_dEHFa.d.ts → registry-BCLMbrla.d.ts} +11 -11
- package/dist/_exports/{resolveWorkbenchConfig-0Crh5P9n.d.ts → resolveWorkbenchConfig-1CV651GT.d.ts} +2 -2
- package/dist/_exports/{summarizeInterfaces-CaYUOK3F.d.ts → summarizeInterfaces-DoG6OunM.d.ts} +4 -4
- package/dist/_exports/undeploy.d.ts +2 -2
- package/dist/actions/build/resource-bindings.js +56 -0
- package/dist/actions/build/resource-bindings.js.map +1 -0
- package/dist/actions/build/vite/plugin.js +10 -7
- package/dist/actions/build/vite/plugin.js.map +1 -1
- package/dist/actions/build/vite/plugins/plugin-sanity-environment.js +22 -3
- package/dist/actions/build/vite/plugins/plugin-sanity-environment.js.map +1 -1
- package/dist/actions/build/vite/plugins/plugin-sanity-federation-runtime.js +16 -4
- package/dist/actions/build/vite/plugins/plugin-sanity-federation-runtime.js.map +1 -1
- package/dist/actions/build/vite/workbench-vite-plugins.js +2 -1
- package/dist/actions/build/vite/workbench-vite-plugins.js.map +1 -1
- package/dist/actions/deploy/deployConfig.js +6 -6
- package/dist/actions/deploy/deployConfig.js.map +1 -1
- package/dist/actions/deploy/deployWorkbenchApp.js +11 -11
- package/dist/actions/deploy/deployWorkbenchApp.js.map +1 -1
- package/dist/actions/deploy/summarizeInterfaces.js.map +1 -1
- package/dist/actions/deploy/viewDeployment.js +2 -2
- package/dist/actions/deploy/viewDeployment.js.map +1 -1
- package/dist/actions/dev/appServerSupervisor.js.map +1 -1
- package/dist/actions/dev/registry.js +1 -1
- package/dist/actions/dev/registry.js.map +1 -1
- package/dist/actions/dev/startWorkbenchDevServer.js +3 -1
- package/dist/actions/dev/startWorkbenchDevServer.js.map +1 -1
- package/dist/actions/dev/toWireInterface.js +1 -1
- package/dist/actions/dev/toWireInterface.js.map +1 -1
- package/dist/actions/init/cliConfig.js +6 -6
- package/dist/actions/init/cliConfig.js.map +1 -1
- package/dist/contract.js +12 -12
- package/dist/contract.js.map +1 -1
- package/dist/defineView.js.map +1 -1
- package/dist/deriveInterfaces.js +5 -5
- package/dist/deriveInterfaces.js.map +1 -1
- package/package.json +9 -10
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/actions/dev/startWorkbenchDevServer.ts"],"sourcesContent":["import {fileURLToPath} from 'node:url'\n\nimport {type CliConfig, type Output, subdebug} from '@sanity/cli-core'\nimport {isStaging} from '@sanity/cli-core/util'\nimport viteReact from '@vitejs/plugin-react'\nimport {createServer, type InlineConfig, type Plugin, type ViteDevServer} from 'vite'\nimport {z} from 'zod/mini'\n\nimport {isWorkbenchApp, isWorkbenchConfig} from '../../defineApp.js'\nimport {createExposesTracker} from './exposesSetId.js'\nimport {\n acquireWorkbenchLock,\n type DevServerManifest,\n getRegisteredServers,\n isConfigOnlyServer,\n readWorkbenchLock,\n watchRegistry,\n} from './registry.js'\nimport {toWireInterface} from './toWireInterface.js'\nimport {writeWorkbenchRuntime} from './writeWorkbenchRuntime.js'\n\nconst devDebug = subdebug('dev')\nconst renderDashboardEntry = '@sanity/workbench-cli/_internal_render'\nconst renderDashboardPath = fileURLToPath(\n new URL('../../_exports/_internal_render.js', import.meta.url),\n)\n\nconst noop = async () => {}\n\n// Every server is a local app except a config-only one — a config\n// with no interfaces (the media library). A server with both lands in both channels.\nconst isLocalApp = (server: DevServerManifest): boolean => !isConfigOnlyServer(server)\n\nconst toApplicationsPayload = (servers: DevServerManifest[]) => ({\n applications: servers\n .filter((server) => isLocalApp(server))\n .map(({host, id, interfaces, manifest, port, projectId, type}) => ({\n host,\n id,\n // Views cross to the remote keyed on `type`, never the internal `surface`.\n interfaces: interfaces?.map((iface) => toWireInterface(iface)),\n manifest,\n port,\n projectId,\n type,\n })),\n configs: servers.flatMap(({configs, host, port}) =>\n // The registry stores the config flat; the workbench wire shape nests the\n // type-specific payload (`fields` for a media library) under `config`, keyed\n // by the `appType` discriminator.\n (configs ?? []).map(({appType, id, moduleName, version, ...config}) => ({\n appType,\n config,\n id,\n moduleName,\n remoteURL: `http://${host}:${port}`,\n version,\n })),\n ),\n})\n\n/**\n * Bridge the dev-server registry into a workbench Vite server's HMR channel so\n * the page tracks apps as they come and go. A changed interface set means a\n * rebuilt remote — full-reload to drop the stale remote-entry; otherwise\n * rebroadcast for a soft reconcile. Returns a detach fn.\n */\nfunction attachViteDevServerBridge(server: ViteDevServer): () => void {\n server.ws.on('sanity:workbench:get-local-applications', (_, client) => {\n client.send(\n 'sanity:workbench:local-applications',\n toApplicationsPayload(getRegisteredServers()),\n )\n })\n\n const setTracker = createExposesTracker()\n const registryWatcher = watchRegistry((servers) => {\n if (setTracker.hasChanged(servers)) {\n server.ws.send({type: 'full-reload'})\n return\n }\n server.ws.send('sanity:workbench:local-applications', toApplicationsPayload(servers))\n })\n\n return () => registryWatcher.close()\n}\n\n/**\n * Make the workbench remote act as the machine's workbench: claim the singleton\n * lock so app `sanity dev`s register into it instead of each starting their own,\n * and bridge the registry so the remote shows the local apps. No-op lock if one\n * is already held.\n */\nexport function startWorkbenchRemoteCoordinator(options: {\n httpHost: string | undefined\n port: number\n server: ViteDevServer\n}): {close: () => Promise<void>} {\n const {httpHost, port, server} = options\n\n const lock = acquireWorkbenchLock({host: httpHost || 'localhost', port})\n if (!lock) {\n const existing = readWorkbenchLock()\n devDebug(\n 'Workbench lock already held by pid %d on port %d; bridging the registry without claiming it',\n existing?.pid,\n existing?.port,\n )\n }\n\n const detachBridge = attachViteDevServerBridge(server)\n\n return {\n close: async () => {\n detachBridge()\n lock?.release()\n },\n }\n}\n\ninterface WorkbenchDevServerResult {\n close: () => Promise<void>\n httpHost: string | undefined\n workbenchAvailable: boolean\n workbenchPort: number\n}\n\nexport interface StartWorkbenchOptions {\n /** Dependency-cache dir for the workbench Vite server, kept apart from the user's own. */\n cacheDir: string\n cliConfig: CliConfig\n httpHost: string | undefined\n httpPort: number\n /** `dev` renders a live app and honors a local workbench-UI override; `preview`\n * (`sanity start`) previews a build and loads the deployed workbench UI. */\n mode: 'development' | 'preview'\n output: Output\n /** Wrap the workbench in React StrictMode; the CLI resolves it (unset collapses to `false`). */\n reactStrictMode: boolean\n workDir: string\n}\n\nexport async function startWorkbenchDevServer(\n options: StartWorkbenchOptions,\n): Promise<WorkbenchDevServerResult> {\n const {\n cacheDir,\n cliConfig,\n httpHost,\n httpPort: workbenchPort,\n mode,\n output,\n reactStrictMode,\n workDir,\n } = options\n\n // Workbench is opted into by a `defineApplication` app or a config-only\n // `unstable_defineMediaLibrary` config — the latter still needs the shell to\n // render it.\n if (!isWorkbenchApp(cliConfig?.app) && !isWorkbenchConfig(cliConfig?.app)) {\n devDebug('Not a workbench app or config, skipping workbench dev server')\n return {close: noop, httpHost, workbenchAvailable: false, workbenchPort}\n }\n\n // Acquire an exclusive lock — only one workbench per machine.\n // Uses O_EXCL which is atomic at the OS level, preventing races when\n // multiple `sanity dev` processes start simultaneously (e.g. via turbo).\n const workbenchLock = acquireWorkbenchLock({host: httpHost || 'localhost', port: workbenchPort})\n if (!workbenchLock) {\n const existing = readWorkbenchLock()\n devDebug(\n 'Workbench already running at pid %d on port %d, skipping',\n existing?.pid,\n existing?.port,\n )\n return {\n close: noop,\n httpHost: existing?.host ?? httpHost,\n workbenchAvailable: true,\n workbenchPort: existing?.port ?? workbenchPort,\n }\n }\n\n // The lock is already held; an exception here (runtime-file write failure,\n // invalid remote URL) would otherwise leak it until the next acquire prunes\n // the stale PID.\n let result: Awaited<ReturnType<typeof createWorkbenchViteServer>>\n try {\n result = await createWorkbenchViteServer({\n cacheDir,\n cliConfig,\n httpHost,\n mode,\n output,\n reactStrictMode,\n workbenchPort,\n workDir,\n })\n } catch (err) {\n workbenchLock.release()\n throw err\n }\n\n if (!result) {\n workbenchLock.release()\n return {close: noop, httpHost, workbenchAvailable: false, workbenchPort}\n }\n\n const {actualPort, close} = result\n workbenchLock.updatePort(actualPort)\n\n return {\n close: async () => {\n workbenchLock.release()\n await close()\n },\n httpHost,\n workbenchAvailable: true,\n workbenchPort: actualPort,\n }\n}\n\ninterface CreateWorkbenchViteServerOptions {\n cacheDir: string\n cliConfig: CliConfig\n httpHost: string | undefined\n mode: 'development' | 'preview'\n output: Output\n reactStrictMode: boolean\n workbenchPort: number\n workDir: string\n}\n\ninterface CreateWorkbenchViteServerResult {\n actualPort: number\n close: () => Promise<void>\n}\n\nasync function createWorkbenchViteServer(\n options: CreateWorkbenchViteServerOptions,\n): Promise<CreateWorkbenchViteServerResult | undefined> {\n const {cacheDir, cliConfig, httpHost, mode, output, reactStrictMode, workbenchPort, workDir} =\n options\n\n // `preview` loads `.env.development` (the env hook treats only `build`/`deploy`\n // as production), which points the workbench UI at a local dev server that\n // isn't running here. Ignore the override and load the deployed UI instead.\n const remoteUrl =\n mode === 'preview'\n ? undefined\n : parseRemoteUrl(process.env.SANITY_INTERNAL_WORKBENCH_REMOTE_URL)\n\n const organizationId = resolveOrganizationId(cliConfig)\n\n devDebug('Writing workbench runtime files')\n const root = await writeWorkbenchRuntime({\n cwd: workDir,\n organizationId,\n reactStrictMode,\n remoteUrl,\n })\n\n const viteConfig: InlineConfig = {\n // Custom cache directory so sanity's vite cache doesn't conflict with local vite projects\n cacheDir,\n configFile: false,\n define: {\n __SANITY_STAGING__: isStaging(),\n 'import.meta.env.SANITY_INTERNAL_WORKBENCH_REMOTE_URL': JSON.stringify(remoteUrl),\n },\n logLevel: 'warn',\n mode: 'development',\n optimizeDeps: {\n // Keep this entry out of pre-bundling so Vite injects its HMR context.\n exclude: [renderDashboardEntry],\n },\n // viteReact looks inert here — it transforms none of the host's own modules —\n // but it's load-bearing for the remotes. It serves the Fast Refresh runtime at\n // /@react-refresh and injects the preamble that defines window.$RefreshReg$. The\n // federated remotes loaded into this page are react-refresh transformed, so\n // without the preamble they throw \"can't detect preamble\", and without the\n // runtime their /@react-refresh import (wired by @module-federation/vite's\n // remoteHmr) fails. Dropping it as dead code broke every panel; see #1262.\n plugins: [viteReact(), ...(remoteUrl ? [remoteManifestPreloadHeaderPlugin(remoteUrl)] : [])],\n resolve: {\n // The generated Vite root cannot reliably resolve this package.\n alias: {[renderDashboardEntry]: renderDashboardPath},\n dedupe: ['react', 'react-dom'],\n },\n root,\n server: {\n host: httpHost,\n port: workbenchPort,\n strictPort: false,\n warmup: {\n clientFiles: ['./workbench.js'],\n },\n },\n }\n\n devDebug('Creating workbench vite server')\n const server = await createServer(viteConfig)\n try {\n await server.listen()\n } catch (err) {\n await server.close()\n output.warn(\n `Workbench dev server failed to start: ${err instanceof Error ? err.message : String(err)}`,\n )\n return undefined\n }\n\n // Vite may have picked a different port if the desired one was occupied\n const addr = server.httpServer?.address()\n const actualPort = typeof addr === 'object' && addr ? addr.port : workbenchPort\n\n // Fire-and-forget: warm the workbench remote's Vite transform pipeline so\n // the first browser request hits a pre-populated module graph.\n if (remoteUrl) {\n fetch(remoteUrl)\n .then((r) => r.body?.cancel())\n .catch(() => {})\n devDebug('Warming workbench remote at %s', remoteUrl)\n }\n\n const detachBridge = attachViteDevServerBridge(server)\n\n return {\n actualPort,\n close: async () => {\n detachBridge()\n await server.close()\n },\n }\n}\n\n// Workbench is opted into via `defineApplication`, which carries the\n// organization ID. Deliberately no fallback (e.g. resolving it from the\n// configured project): the lookup would need an authenticated user and an\n// API round-trip on every startup for something the opt-in already declares.\nconst resolveOrganizationId = (cliConfig: CliConfig): string => {\n if (cliConfig.app?.organizationId) {\n return cliConfig.app.organizationId\n }\n\n throw new Error(\n 'Workbench requires an organization ID. Pass \"organizationId\" to defineApplication() in sanity.cli.ts.',\n )\n}\n\n// Restricts protocol to http(s) so the URL is safe to interpolate into HTML\n// attributes and Link headers downstream.\nconst remoteUrlSchema = z.url({normalize: true, protocol: /^https?$/})\n\nfunction parseRemoteUrl(value: string | undefined): string | undefined {\n if (!value) return undefined\n\n const result = remoteUrlSchema.safeParse(value)\n\n if (!result.success) {\n throw new Error(\n `Invalid SANITY_INTERNAL_WORKBENCH_REMOTE_URL: ${value} (must be an http(s) URL)`,\n )\n }\n\n return result.data\n}\n\n/**\n * Sets a `Link: <remoteUrl>; rel=preload; as=fetch; crossorigin` response header\n * on the index document so the browser can start fetching the Module Federation\n * manifest as soon as response headers arrive — before HTML parsing reaches the\n * in-head preconnect hint. `as=fetch` matches how the federation runtime later\n * retrieves the JSON manifest, allowing the preload entry to satisfy that fetch.\n */\nfunction remoteManifestPreloadHeaderPlugin(remoteUrl: string): Plugin {\n return {\n apply: 'serve',\n configureServer(server) {\n server.middlewares.use((req, res, next) => {\n const pathname = (req.url || '/').split('?')[0]\n if (pathname === '/' || pathname === '/index.html') {\n res.setHeader('Link', `<${remoteUrl}>; rel=preload; as=fetch; crossorigin`)\n }\n next()\n })\n },\n name: 'sanity:workbench-remote-preload-header',\n }\n}\n"],"names":["fileURLToPath","subdebug","isStaging","viteReact","createServer","z","isWorkbenchApp","isWorkbenchConfig","createExposesTracker","acquireWorkbenchLock","getRegisteredServers","isConfigOnlyServer","readWorkbenchLock","watchRegistry","toWireInterface","writeWorkbenchRuntime","devDebug","renderDashboardEntry","renderDashboardPath","URL","url","noop","isLocalApp","server","toApplicationsPayload","servers","applications","filter","map","host","id","interfaces","manifest","port","projectId","type","iface","configs","flatMap","appType","moduleName","version","config","remoteURL","attachViteDevServerBridge","ws","on","_","client","send","setTracker","registryWatcher","hasChanged","close","startWorkbenchRemoteCoordinator","options","httpHost","lock","existing","pid","detachBridge","release","startWorkbenchDevServer","cacheDir","cliConfig","httpPort","workbenchPort","mode","output","reactStrictMode","workDir","app","workbenchAvailable","workbenchLock","result","createWorkbenchViteServer","err","actualPort","updatePort","remoteUrl","undefined","parseRemoteUrl","process","env","SANITY_INTERNAL_WORKBENCH_REMOTE_URL","organizationId","resolveOrganizationId","root","cwd","viteConfig","configFile","define","__SANITY_STAGING__","JSON","stringify","logLevel","optimizeDeps","exclude","plugins","remoteManifestPreloadHeaderPlugin","resolve","alias","dedupe","strictPort","warmup","clientFiles","listen","warn","Error","message","String","addr","httpServer","address","fetch","then","r","body","cancel","catch","remoteUrlSchema","normalize","protocol","value","safeParse","success","data","apply","configureServer","middlewares","use","req","res","next","pathname","split","setHeader","name"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../src/actions/dev/startWorkbenchDevServer.ts"],"sourcesContent":["import {fileURLToPath} from 'node:url'\n\nimport {type CliConfig, type Output, subdebug} from '@sanity/cli-core'\nimport {isStaging} from '@sanity/cli-core/util'\nimport viteReact from '@vitejs/plugin-react'\nimport {createServer, type InlineConfig, type Plugin, type ViteDevServer} from 'vite'\nimport {z} from 'zod/mini'\n\nimport {isWorkbenchApp, isWorkbenchConfig} from '../../defineApp.js'\nimport {createExposesTracker} from './exposesSetId.js'\nimport {\n acquireWorkbenchLock,\n type DevServerManifest,\n getRegisteredServers,\n isConfigOnlyServer,\n readWorkbenchLock,\n watchRegistry,\n} from './registry.js'\nimport {toWireInterface} from './toWireInterface.js'\nimport {writeWorkbenchRuntime} from './writeWorkbenchRuntime.js'\n\nconst devDebug = subdebug('dev')\nconst renderDashboardEntry = '@sanity/workbench-cli/_internal_render'\nconst renderDashboardPath = fileURLToPath(\n new URL('../../_exports/_internal_render.js', import.meta.url),\n)\n\nconst noop = async () => {}\n\n// Every server is a local app except a config-only one — a config\n// with no interfaces (the media library). A server with both lands in both channels.\nconst isLocalApp = (server: DevServerManifest): boolean => !isConfigOnlyServer(server)\n\nconst toApplicationsPayload = (servers: DevServerManifest[]) => ({\n applications: servers\n .filter((server) => isLocalApp(server))\n .map(({host, id, interfaces, manifest, name, port, projectId, reference, type}) => ({\n host,\n id,\n // Views cross to the remote keyed on `type`, never the internal `surface`.\n interfaces: interfaces?.map((iface) => toWireInterface(iface)),\n manifest,\n name,\n port,\n projectId,\n reference,\n type,\n })),\n configs: servers.flatMap(({configs, host, port}) =>\n // The registry stores the config flat; the workbench wire shape nests the\n // type-specific payload (`fields` for a media library) under `config`, keyed\n // by the `appType` discriminator.\n (configs ?? []).map(({appType, id, moduleName, version, ...config}) => ({\n appType,\n config,\n id,\n moduleName,\n remoteURL: `http://${host}:${port}`,\n version,\n })),\n ),\n})\n\n/**\n * Bridge the dev-server registry into a workbench Vite server's HMR channel so\n * the page tracks apps as they come and go. A changed interface set means a\n * rebuilt remote — full-reload to drop the stale remote-entry; otherwise\n * rebroadcast for a soft reconcile. Returns a detach fn.\n */\nfunction attachViteDevServerBridge(server: ViteDevServer): () => void {\n server.ws.on('sanity:workbench:get-local-applications', (_, client) => {\n client.send(\n 'sanity:workbench:local-applications',\n toApplicationsPayload(getRegisteredServers()),\n )\n })\n\n const setTracker = createExposesTracker()\n const registryWatcher = watchRegistry((servers) => {\n if (setTracker.hasChanged(servers)) {\n server.ws.send({type: 'full-reload'})\n return\n }\n server.ws.send('sanity:workbench:local-applications', toApplicationsPayload(servers))\n })\n\n return () => registryWatcher.close()\n}\n\n/**\n * Make the workbench remote act as the machine's workbench: claim the singleton\n * lock so app `sanity dev`s register into it instead of each starting their own,\n * and bridge the registry so the remote shows the local apps. No-op lock if one\n * is already held.\n */\nexport function startWorkbenchRemoteCoordinator(options: {\n httpHost: string | undefined\n port: number\n server: ViteDevServer\n}): {close: () => Promise<void>} {\n const {httpHost, port, server} = options\n\n const lock = acquireWorkbenchLock({host: httpHost || 'localhost', port})\n if (!lock) {\n const existing = readWorkbenchLock()\n devDebug(\n 'Workbench lock already held by pid %d on port %d; bridging the registry without claiming it',\n existing?.pid,\n existing?.port,\n )\n }\n\n const detachBridge = attachViteDevServerBridge(server)\n\n return {\n close: async () => {\n detachBridge()\n lock?.release()\n },\n }\n}\n\ninterface WorkbenchDevServerResult {\n close: () => Promise<void>\n httpHost: string | undefined\n workbenchAvailable: boolean\n workbenchPort: number\n}\n\nexport interface StartWorkbenchOptions {\n /** Dependency-cache dir for the workbench Vite server, kept apart from the user's own. */\n cacheDir: string\n cliConfig: CliConfig\n httpHost: string | undefined\n httpPort: number\n /** `dev` renders a live app and honors a local workbench-UI override; `preview`\n * (`sanity start`) previews a build and loads the deployed workbench UI. */\n mode: 'development' | 'preview'\n output: Output\n /** Wrap the workbench in React StrictMode; the CLI resolves it (unset collapses to `false`). */\n reactStrictMode: boolean\n workDir: string\n}\n\nexport async function startWorkbenchDevServer(\n options: StartWorkbenchOptions,\n): Promise<WorkbenchDevServerResult> {\n const {\n cacheDir,\n cliConfig,\n httpHost,\n httpPort: workbenchPort,\n mode,\n output,\n reactStrictMode,\n workDir,\n } = options\n\n // Workbench is opted into by a `defineApplication` app or a config-only\n // `unstable_defineMediaLibrary` config — the latter still needs the shell to\n // render it.\n if (!isWorkbenchApp(cliConfig?.app) && !isWorkbenchConfig(cliConfig?.app)) {\n devDebug('Not a workbench app or config, skipping workbench dev server')\n return {close: noop, httpHost, workbenchAvailable: false, workbenchPort}\n }\n\n // Acquire an exclusive lock — only one workbench per machine.\n // Uses O_EXCL which is atomic at the OS level, preventing races when\n // multiple `sanity dev` processes start simultaneously (e.g. via turbo).\n const workbenchLock = acquireWorkbenchLock({host: httpHost || 'localhost', port: workbenchPort})\n if (!workbenchLock) {\n const existing = readWorkbenchLock()\n devDebug(\n 'Workbench already running at pid %d on port %d, skipping',\n existing?.pid,\n existing?.port,\n )\n return {\n close: noop,\n httpHost: existing?.host ?? httpHost,\n workbenchAvailable: true,\n workbenchPort: existing?.port ?? workbenchPort,\n }\n }\n\n // The lock is already held; an exception here (runtime-file write failure,\n // invalid remote URL) would otherwise leak it until the next acquire prunes\n // the stale PID.\n let result: Awaited<ReturnType<typeof createWorkbenchViteServer>>\n try {\n result = await createWorkbenchViteServer({\n cacheDir,\n cliConfig,\n httpHost,\n mode,\n output,\n reactStrictMode,\n workbenchPort,\n workDir,\n })\n } catch (err) {\n workbenchLock.release()\n throw err\n }\n\n if (!result) {\n workbenchLock.release()\n return {close: noop, httpHost, workbenchAvailable: false, workbenchPort}\n }\n\n const {actualPort, close} = result\n workbenchLock.updatePort(actualPort)\n\n return {\n close: async () => {\n workbenchLock.release()\n await close()\n },\n httpHost,\n workbenchAvailable: true,\n workbenchPort: actualPort,\n }\n}\n\ninterface CreateWorkbenchViteServerOptions {\n cacheDir: string\n cliConfig: CliConfig\n httpHost: string | undefined\n mode: 'development' | 'preview'\n output: Output\n reactStrictMode: boolean\n workbenchPort: number\n workDir: string\n}\n\ninterface CreateWorkbenchViteServerResult {\n actualPort: number\n close: () => Promise<void>\n}\n\nasync function createWorkbenchViteServer(\n options: CreateWorkbenchViteServerOptions,\n): Promise<CreateWorkbenchViteServerResult | undefined> {\n const {cacheDir, cliConfig, httpHost, mode, output, reactStrictMode, workbenchPort, workDir} =\n options\n\n // `preview` loads `.env.development` (the env hook treats only `build`/`deploy`\n // as production), which points the workbench UI at a local dev server that\n // isn't running here. Ignore the override and load the deployed UI instead.\n const remoteUrl =\n mode === 'preview'\n ? undefined\n : parseRemoteUrl(process.env.SANITY_INTERNAL_WORKBENCH_REMOTE_URL)\n\n const organizationId = resolveOrganizationId(cliConfig)\n\n devDebug('Writing workbench runtime files')\n const root = await writeWorkbenchRuntime({\n cwd: workDir,\n organizationId,\n reactStrictMode,\n remoteUrl,\n })\n\n const viteConfig: InlineConfig = {\n // Custom cache directory so sanity's vite cache doesn't conflict with local vite projects\n cacheDir,\n configFile: false,\n define: {\n __SANITY_STAGING__: isStaging(),\n 'import.meta.env.SANITY_INTERNAL_WORKBENCH_REMOTE_URL': JSON.stringify(remoteUrl),\n },\n logLevel: 'warn',\n mode: 'development',\n optimizeDeps: {\n // Keep this entry out of pre-bundling so Vite injects its HMR context.\n exclude: [renderDashboardEntry],\n },\n // viteReact looks inert here — it transforms none of the host's own modules —\n // but it's load-bearing for the remotes. It serves the Fast Refresh runtime at\n // /@react-refresh and injects the preamble that defines window.$RefreshReg$. The\n // federated remotes loaded into this page are react-refresh transformed, so\n // without the preamble they throw \"can't detect preamble\", and without the\n // runtime their /@react-refresh import (wired by @module-federation/vite's\n // remoteHmr) fails. Dropping it as dead code broke every panel; see #1262.\n plugins: [viteReact(), ...(remoteUrl ? [remoteManifestPreloadHeaderPlugin(remoteUrl)] : [])],\n resolve: {\n // The generated Vite root cannot reliably resolve this package.\n alias: {[renderDashboardEntry]: renderDashboardPath},\n dedupe: ['react', 'react-dom'],\n },\n root,\n server: {\n host: httpHost,\n port: workbenchPort,\n strictPort: false,\n warmup: {\n clientFiles: ['./workbench.js'],\n },\n },\n }\n\n devDebug('Creating workbench vite server')\n const server = await createServer(viteConfig)\n try {\n await server.listen()\n } catch (err) {\n await server.close()\n output.warn(\n `Workbench dev server failed to start: ${err instanceof Error ? err.message : String(err)}`,\n )\n return undefined\n }\n\n // Vite may have picked a different port if the desired one was occupied\n const addr = server.httpServer?.address()\n const actualPort = typeof addr === 'object' && addr ? addr.port : workbenchPort\n\n // Fire-and-forget: warm the workbench remote's Vite transform pipeline so\n // the first browser request hits a pre-populated module graph.\n if (remoteUrl) {\n fetch(remoteUrl)\n .then((r) => r.body?.cancel())\n .catch(() => {})\n devDebug('Warming workbench remote at %s', remoteUrl)\n }\n\n const detachBridge = attachViteDevServerBridge(server)\n\n return {\n actualPort,\n close: async () => {\n detachBridge()\n await server.close()\n },\n }\n}\n\n// Workbench is opted into via `defineApplication`, which carries the\n// organization ID. Deliberately no fallback (e.g. resolving it from the\n// configured project): the lookup would need an authenticated user and an\n// API round-trip on every startup for something the opt-in already declares.\nconst resolveOrganizationId = (cliConfig: CliConfig): string => {\n if (cliConfig.app?.organizationId) {\n return cliConfig.app.organizationId\n }\n\n throw new Error(\n 'Workbench requires an organization ID. Pass \"organizationId\" to defineApplication() in sanity.cli.ts.',\n )\n}\n\n// Restricts protocol to http(s) so the URL is safe to interpolate into HTML\n// attributes and Link headers downstream.\nconst remoteUrlSchema = z.url({normalize: true, protocol: /^https?$/})\n\nfunction parseRemoteUrl(value: string | undefined): string | undefined {\n if (!value) return undefined\n\n const result = remoteUrlSchema.safeParse(value)\n\n if (!result.success) {\n throw new Error(\n `Invalid SANITY_INTERNAL_WORKBENCH_REMOTE_URL: ${value} (must be an http(s) URL)`,\n )\n }\n\n return result.data\n}\n\n/**\n * Sets a `Link: <remoteUrl>; rel=preload; as=fetch; crossorigin` response header\n * on the index document so the browser can start fetching the Module Federation\n * manifest as soon as response headers arrive — before HTML parsing reaches the\n * in-head preconnect hint. `as=fetch` matches how the federation runtime later\n * retrieves the JSON manifest, allowing the preload entry to satisfy that fetch.\n */\nfunction remoteManifestPreloadHeaderPlugin(remoteUrl: string): Plugin {\n return {\n apply: 'serve',\n configureServer(server) {\n server.middlewares.use((req, res, next) => {\n const pathname = (req.url || '/').split('?')[0]\n if (pathname === '/' || pathname === '/index.html') {\n res.setHeader('Link', `<${remoteUrl}>; rel=preload; as=fetch; crossorigin`)\n }\n next()\n })\n },\n name: 'sanity:workbench-remote-preload-header',\n }\n}\n"],"names":["fileURLToPath","subdebug","isStaging","viteReact","createServer","z","isWorkbenchApp","isWorkbenchConfig","createExposesTracker","acquireWorkbenchLock","getRegisteredServers","isConfigOnlyServer","readWorkbenchLock","watchRegistry","toWireInterface","writeWorkbenchRuntime","devDebug","renderDashboardEntry","renderDashboardPath","URL","url","noop","isLocalApp","server","toApplicationsPayload","servers","applications","filter","map","host","id","interfaces","manifest","name","port","projectId","reference","type","iface","configs","flatMap","appType","moduleName","version","config","remoteURL","attachViteDevServerBridge","ws","on","_","client","send","setTracker","registryWatcher","hasChanged","close","startWorkbenchRemoteCoordinator","options","httpHost","lock","existing","pid","detachBridge","release","startWorkbenchDevServer","cacheDir","cliConfig","httpPort","workbenchPort","mode","output","reactStrictMode","workDir","app","workbenchAvailable","workbenchLock","result","createWorkbenchViteServer","err","actualPort","updatePort","remoteUrl","undefined","parseRemoteUrl","process","env","SANITY_INTERNAL_WORKBENCH_REMOTE_URL","organizationId","resolveOrganizationId","root","cwd","viteConfig","configFile","define","__SANITY_STAGING__","JSON","stringify","logLevel","optimizeDeps","exclude","plugins","remoteManifestPreloadHeaderPlugin","resolve","alias","dedupe","strictPort","warmup","clientFiles","listen","warn","Error","message","String","addr","httpServer","address","fetch","then","r","body","cancel","catch","remoteUrlSchema","normalize","protocol","value","safeParse","success","data","apply","configureServer","middlewares","use","req","res","next","pathname","split","setHeader"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/actions/dev/toWireInterface.ts"],"sourcesContent":["import {type DevServerInterface} from './deriveConfigs.js'\n\n// The registry stores view interfaces discriminated on `surface` (the author\n// API's word), but the workbench remote — like the deployed application record\n// (see viewDeployment.ts) — keys every interface on `type`. This module is the\n// single, strictly-typed boundary that converts the internal `surface` shape to\n// the wire `type` shape for local dev, so the two can never drift again: the\n// return type carries no `surface`, so a raw registry interface cannot be sent\n// to the remote without passing through here.\n\n/** A registry view interface — the members discriminated on `surface`. */\ntype ViewInterface = Extract<DevServerInterface, {surface: unknown}>\n/** A registry worker interface — already keyed on `type`. */\ntype WorkerInterface = Extract<DevServerInterface, {type: unknown}>\n\n/**\n * An interface as the workbench remote consumes it: every member keyed on\n * `type`. Views have their `surface` renamed to `type`; workers pass through.\n * @internal\n */\nexport type WorkbenchWireInterface =\n | (Omit<ViewInterface, 'surface'> & {type: ViewInterface['surface']})\n | WorkerInterface\n\n/**\n * Convert a registry interface to the remote's wire shape. Views rename\n * `surface` → `type`; workers (already `type`) pass through untouched. The only\n * surface→type conversion for local dev — mirrors the deploy boundary.\n * @internal\n */\nexport function toWireInterface(iface: DevServerInterface): WorkbenchWireInterface {\n if ('surface' in iface) {\n const {surface, ...rest} = iface\n return {...rest, type: surface}\n }\n return iface\n}\n"],"names":["toWireInterface","iface","surface","rest","type"],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../../../src/actions/dev/toWireInterface.ts"],"sourcesContent":["import {type DevServerInterface} from './deriveConfigs.js'\n\n// The registry stores view interfaces discriminated on `surface` (the author\n// API's word), but the workbench remote — like the deployed application record\n// (see viewDeployment.ts) — keys every interface on `type`. This module is the\n// single, strictly-typed boundary that converts the internal `surface` shape to\n// the wire `type` shape for local dev, so the two can never drift again: the\n// return type carries no `surface`, so a raw registry interface cannot be sent\n// to the remote without passing through here.\n\n/** A registry view interface — the members discriminated on `surface`. */\ntype ViewInterface = Extract<DevServerInterface, {surface: unknown}>\n/** A registry worker interface — already keyed on `type`. */\ntype WorkerInterface = Extract<DevServerInterface, {type: unknown}>\n\n/**\n * An interface as the workbench remote consumes it: every member keyed on\n * `type`. Views have their `surface` renamed to `type`; workers pass through.\n * @internal\n */\nexport type WorkbenchWireInterface =\n | (Omit<ViewInterface, 'surface'> & {\n type: 'app' | Exclude<ViewInterface['surface'], 'window'>\n })\n | WorkerInterface\n\n/**\n * Convert a registry interface to the remote's wire shape. Views rename\n * `surface` → `type`; workers (already `type`) pass through untouched. The only\n * surface→type conversion for local dev — mirrors the deploy boundary.\n * @internal\n */\nexport function toWireInterface(iface: DevServerInterface): WorkbenchWireInterface {\n if ('surface' in iface) {\n const {surface, ...rest} = iface\n return {...rest, type: surface === 'window' ? 'app' : surface}\n }\n return iface\n}\n"],"names":["toWireInterface","iface","surface","rest","type"],"mappings":"AA0BA;;;;;CAKC,GACD,OAAO,SAASA,gBAAgBC,KAAyB;IACvD,IAAI,aAAaA,OAAO;QACtB,MAAM,EAACC,OAAO,EAAE,GAAGC,MAAK,GAAGF;QAC3B,OAAO;YAAC,GAAGE,IAAI;YAAEC,MAAMF,YAAY,WAAW,QAAQA;QAAO;IAC/D;IACA,OAAOD;AACT"}
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
// `sanity.cli.ts` templates for workbench (`
|
|
2
|
-
// consumed by the CLI's `init` scaffolding. The branded `
|
|
1
|
+
// `sanity.cli.ts` templates for workbench (`defineApplication`) projects,
|
|
2
|
+
// consumed by the CLI's `init` scaffolding. The branded `defineApplication`
|
|
3
3
|
// result is the sole workbench (module-federation) opt-in, so its config shape
|
|
4
4
|
// is workbench's to own; the CLI keeps the non-workbench templates and the
|
|
5
5
|
// `%placeholder%` substitution. `%slug%`/`%title%`/etc. are filled in by the
|
|
6
6
|
// CLI's template processor.
|
|
7
7
|
/** App scaffold — `entry` auto-declares the navigable app view. */ export const workbenchAppConfigTemplate = `
|
|
8
|
-
import {
|
|
8
|
+
import {defineApplication, defineCliConfig} from 'sanity/cli'
|
|
9
9
|
|
|
10
10
|
export default defineCliConfig({
|
|
11
|
-
app:
|
|
11
|
+
app: defineApplication({
|
|
12
12
|
title: '%title%',
|
|
13
13
|
slug: '%slug%',
|
|
14
14
|
organizationId: '%organizationId%',
|
|
@@ -20,14 +20,14 @@ export default defineCliConfig({
|
|
|
20
20
|
* Studio scaffold — brands with slug/title only, no `entry` (studio app views
|
|
21
21
|
* aren't implemented yet).
|
|
22
22
|
*/ export const workbenchStudioConfigTemplate = `
|
|
23
|
-
import {
|
|
23
|
+
import {defineApplication, defineCliConfig} from 'sanity/cli'
|
|
24
24
|
|
|
25
25
|
export default defineCliConfig({
|
|
26
26
|
api: {
|
|
27
27
|
projectId: '%projectId%',
|
|
28
28
|
dataset: '%dataset%'
|
|
29
29
|
},
|
|
30
|
-
app:
|
|
30
|
+
app: defineApplication({
|
|
31
31
|
title: '%title%',
|
|
32
32
|
slug: '%slug%',
|
|
33
33
|
organizationId: '%organizationId%',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/actions/init/cliConfig.ts"],"sourcesContent":["// `sanity.cli.ts` templates for workbench (`
|
|
1
|
+
{"version":3,"sources":["../../../src/actions/init/cliConfig.ts"],"sourcesContent":["// `sanity.cli.ts` templates for workbench (`defineApplication`) projects,\n// consumed by the CLI's `init` scaffolding. The branded `defineApplication`\n// result is the sole workbench (module-federation) opt-in, so its config shape\n// is workbench's to own; the CLI keeps the non-workbench templates and the\n// `%placeholder%` substitution. `%slug%`/`%title%`/etc. are filled in by the\n// CLI's template processor.\n\n/** App scaffold — `entry` auto-declares the navigable app view. */\nexport const workbenchAppConfigTemplate = `\nimport {defineApplication, defineCliConfig} from 'sanity/cli'\n\nexport default defineCliConfig({\n app: defineApplication({\n title: '%title%',\n slug: '%slug%',\n organizationId: '%organizationId%',\n entry: '%entry%',\n }),\n})\n`\n\n/**\n * Studio scaffold — brands with slug/title only, no `entry` (studio app views\n * aren't implemented yet).\n */\nexport const workbenchStudioConfigTemplate = `\nimport {defineApplication, defineCliConfig} from 'sanity/cli'\n\nexport default defineCliConfig({\n api: {\n projectId: '%projectId%',\n dataset: '%dataset%'\n },\n app: defineApplication({\n title: '%title%',\n slug: '%slug%',\n organizationId: '%organizationId%',\n }),\n deployment: {\n /**\n * Enable auto-updates for studios.\n * Learn more at https://www.sanity.io/docs/studio/latest-version-of-sanity#k47faf43faf56\n */\n autoUpdates: __BOOL__autoUpdates__,\n },\n})\n`\n"],"names":["workbenchAppConfigTemplate","workbenchStudioConfigTemplate"],"mappings":"AAAA,0EAA0E;AAC1E,4EAA4E;AAC5E,+EAA+E;AAC/E,2EAA2E;AAC3E,6EAA6E;AAC7E,4BAA4B;AAE5B,iEAAiE,GACjE,OAAO,MAAMA,6BAA6B,CAAC;;;;;;;;;;;AAW3C,CAAC,CAAA;AAED;;;CAGC,GACD,OAAO,MAAMC,gCAAgC,CAAC;;;;;;;;;;;;;;;;;;;;;AAqB9C,CAAC,CAAA"}
|
package/dist/contract.js
CHANGED
|
@@ -6,7 +6,6 @@ import { z } from 'zod/mini';
|
|
|
6
6
|
/** @internal */ export const SERVICE_CONTRACT_VERSION = 1;
|
|
7
7
|
/** @internal */ export const MEDIA_LIBRARY_CONFIG_CONTRACT_VERSION = 1;
|
|
8
8
|
/** Component slots per view surface; windows load outside the component artifact path. @internal */ export const VIEW_COMPONENTS = {
|
|
9
|
-
app: [],
|
|
10
9
|
asset_source: [
|
|
11
10
|
'asset_source'
|
|
12
11
|
],
|
|
@@ -16,7 +15,8 @@ import { z } from 'zod/mini';
|
|
|
16
15
|
],
|
|
17
16
|
tile: [
|
|
18
17
|
'tile'
|
|
19
|
-
]
|
|
18
|
+
],
|
|
19
|
+
window: []
|
|
20
20
|
};
|
|
21
21
|
/**
|
|
22
22
|
* A tile's footprint family — the shape it occupies on the dashboard. Modelled
|
|
@@ -30,9 +30,9 @@ import { z } from 'zod/mini';
|
|
|
30
30
|
'banner'
|
|
31
31
|
]);
|
|
32
32
|
const DockGroupSchema = z.enum([
|
|
33
|
-
'
|
|
34
|
-
'
|
|
35
|
-
'
|
|
33
|
+
'system',
|
|
34
|
+
'applications',
|
|
35
|
+
'user'
|
|
36
36
|
]);
|
|
37
37
|
/** @internal */ export const DockSchema = z.object({
|
|
38
38
|
group: z.optional(DockGroupSchema),
|
|
@@ -55,10 +55,10 @@ const DockGroupSchema = z.enum([
|
|
|
55
55
|
* renders/runs what it expects.
|
|
56
56
|
* @internal
|
|
57
57
|
*/ const INTERFACE_CONTRACT_VERSIONS = {
|
|
58
|
-
app: undefined,
|
|
59
58
|
asset_source: VIEW_CONTRACT_VERSION,
|
|
60
59
|
panel: VIEW_CONTRACT_VERSION,
|
|
61
60
|
tile: VIEW_CONTRACT_VERSION,
|
|
61
|
+
window: undefined,
|
|
62
62
|
worker: SERVICE_CONTRACT_VERSION
|
|
63
63
|
};
|
|
64
64
|
/** @internal */ export function interfaceContractVersion(kind) {
|
|
@@ -71,16 +71,16 @@ const DockGroupSchema = z.enum([
|
|
|
71
71
|
* @internal
|
|
72
72
|
*/ export function interfaceModuleId(kind, name) {
|
|
73
73
|
switch(kind){
|
|
74
|
-
case 'app':
|
|
75
|
-
{
|
|
76
|
-
return 'App';
|
|
77
|
-
}
|
|
78
74
|
case 'asset_source':
|
|
79
75
|
case 'panel':
|
|
80
76
|
case 'tile':
|
|
81
77
|
{
|
|
82
78
|
return `views/${name}`;
|
|
83
79
|
}
|
|
80
|
+
case 'window':
|
|
81
|
+
{
|
|
82
|
+
return 'App';
|
|
83
|
+
}
|
|
84
84
|
case 'worker':
|
|
85
85
|
{
|
|
86
86
|
return `services/${name}`;
|
|
@@ -119,14 +119,14 @@ const PanelViewSchema = z.object({
|
|
|
119
119
|
};
|
|
120
120
|
}
|
|
121
121
|
const WindowViewSchema = z.object({
|
|
122
|
-
surface: z.literal('
|
|
122
|
+
surface: z.literal('window'),
|
|
123
123
|
...interfaceDeclarationFields('View'),
|
|
124
124
|
dock: z.optional(DockSchema)
|
|
125
125
|
});
|
|
126
126
|
/** @public */ export function defineWindowView(view) {
|
|
127
127
|
return {
|
|
128
128
|
...view,
|
|
129
|
-
surface: '
|
|
129
|
+
surface: 'window'
|
|
130
130
|
};
|
|
131
131
|
}
|
|
132
132
|
const AssetSourceViewSchema = z.object({
|
package/dist/contract.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/contract.ts"],"sourcesContent":["import {z} from 'zod/mini'\n\n// Shared module-federation extension contract: interface (view/service) and\n// config declaration schemas, plus the versions the build stamps.\n// `zod/mini` keeps the bundle small.\n\n/** @internal */\nexport const VIEW_CONTRACT_VERSION = 1\n\n/** @internal */\nexport const SERVICE_CONTRACT_VERSION = 1\n\n/** @internal */\nexport const MEDIA_LIBRARY_CONFIG_CONTRACT_VERSION = 1\n\n/**\n * A view component. The return is opaque so the runtime helpers carry no React\n * dependency — the generated artifact renders it with the app's own React.\n * @public\n */\nexport type ViewComponent<TProps> = (props: TProps) => unknown\n\n/** @public */\nexport interface ViewComponentBaseProps<TView> {\n view: TView\n}\n\n/** Component slots per view surface; windows load outside the component artifact path. @internal */\nexport const VIEW_COMPONENTS = {\n app: [],\n asset_source: ['asset_source'],\n panel: ['title', 'panel'],\n tile: ['tile'],\n} as const satisfies Record<string, readonly string[]>\n\n/** @public */\nexport type ViewSurface = keyof typeof VIEW_COMPONENTS\n\n/**\n * A tile's footprint family — the shape it occupies on the dashboard. Modelled\n * on iOS WidgetKit families, not a linear scale: `banner` is full-width and\n * shallow, which a `small`→`large` magnitude can't express. The host maps a\n * family to a layout slot; the component reads it to render per footprint.\n * @public\n */\nexport const TileSizeSchema = z.enum(['small', 'large', 'banner'])\n\n/** @public */\nexport type TileSize = z.infer<typeof TileSizeSchema>\n\n/** @public */\nexport type ServiceType = 'worker'\n\nconst DockGroupSchema = z.enum(['dock.system', 'dock.applications', 'dock.user'])\n\n/** @public */\nexport type DockGroup = z.output<typeof DockGroupSchema>\n\n/** @internal */\nexport const DockSchema = z.object({\n group: z.optional(DockGroupSchema),\n order: z.optional(z.number()),\n})\n\n/** @internal */\nexport type Dock = z.infer<typeof DockSchema>\n\n/** @internal */\nexport const ViewPlacementMetadataSchema = z.object({dock: DockSchema})\n\n/** @internal */\nexport type ViewPlacementMetadata = z.infer<typeof ViewPlacementMetadataSchema>\n\n/**\n * A tile's interface metadata: its footprint `size` and an optional `order`\n * the dashboard sorts on, ascending. Both are authored as top-level view fields\n * (see {@link InterfaceDeclarationSchema}) but stored on the record as metadata.\n * @internal\n */\nexport const TileInterfaceMetadataSchema = z.object({\n order: z.optional(z.number()),\n size: TileSizeSchema,\n})\n\n/** @internal */\nexport type TileInterfaceMetadata = z.infer<typeof TileInterfaceMetadataSchema>\n\n/**\n * The contract version each interface type advertises, so the host can check it\n * renders/runs what it expects.\n * @internal\n */\nconst INTERFACE_CONTRACT_VERSIONS = {\n app: undefined,\n asset_source: VIEW_CONTRACT_VERSION,\n panel: VIEW_CONTRACT_VERSION,\n tile: VIEW_CONTRACT_VERSION,\n worker: SERVICE_CONTRACT_VERSION,\n} as const\n\n/** Every interface type an app exposes — an `app` view, a view, or a service. */\nexport type InterfaceKind = keyof typeof INTERFACE_CONTRACT_VERSIONS\n\n/** @internal */\nexport function interfaceContractVersion(kind: InterfaceKind): string | undefined {\n const version = INTERFACE_CONTRACT_VERSIONS[kind]\n return version === undefined ? undefined : String(version)\n}\n\n/**\n * The module-federation id a build exposes an interface at. Dev stamps the same\n * id a deploy would, so the workbench loads a local interface like a deployed one.\n * @internal\n */\nexport function interfaceModuleId(kind: string, name: string): string {\n switch (kind) {\n case 'app': {\n return 'App'\n }\n case 'asset_source':\n case 'panel':\n case 'tile': {\n return `views/${name}`\n }\n case 'worker': {\n return `services/${name}`\n }\n default: {\n throw new Error(`Cannot derive a moduleId for unknown interface kind: ${kind}`)\n }\n }\n}\n\n// Shared `name` + `src`; `kind` only tailors the validation message.\nfunction extensionDeclarationFields(kind: 'Field' | 'View' | 'Web worker') {\n const pattern = /^[a-zA-Z0-9_-]+$/\n return {\n name: z.string().check(z.regex(pattern, `${kind} \\`name\\` must match ${pattern}`)),\n src: z.string(),\n }\n}\n\n// Every interface shares `name` + `src` + a display `title`,\n// which Brett requires on the record each becomes.\nfunction interfaceDeclarationFields(kind: 'View' | 'Web worker') {\n return {\n ...extensionDeclarationFields(kind),\n title: z.string(`${kind} \\`title\\` is required`),\n }\n}\n\nconst PanelViewSchema = z.object({\n surface: z.literal('panel'),\n ...interfaceDeclarationFields('View'),\n dock: z.optional(DockSchema),\n})\n\n/** @public */\nexport type PanelView = z.output<typeof PanelViewSchema>\n\n/** @public */\nexport type DefinePanelViewInput = Omit<PanelView, 'surface'>\n\n/** @public */\nexport function definePanelView(view: DefinePanelViewInput): PanelView {\n return {...view, surface: 'panel'}\n}\n\nconst WindowViewSchema = z.object({\n surface: z.literal('app'),\n ...interfaceDeclarationFields('View'),\n dock: z.optional(DockSchema),\n})\n\n/** @public */\nexport type WindowView = z.output<typeof WindowViewSchema>\n\n/** @public */\nexport type DefineWindowViewInput = Omit<WindowView, 'surface'>\n\n/** @public */\nexport function defineWindowView(view: DefineWindowViewInput): WindowView {\n return {...view, surface: 'app'}\n}\n\nconst AssetSourceViewSchema = z.object({\n surface: z.literal('asset_source'),\n ...interfaceDeclarationFields('View'),\n})\n\n/** @public */\nexport type AssetSourceView = z.output<typeof AssetSourceViewSchema>\n\n/** @public */\nexport type DefineAssetSourceViewInput = Omit<AssetSourceView, 'surface'>\n\n/** @public */\nexport function defineAssetSourceView(view: DefineAssetSourceViewInput): AssetSourceView {\n return {...view, surface: 'asset_source'}\n}\n\nconst TileViewSchema = z.object({\n surface: z.literal('tile'),\n ...interfaceDeclarationFields('View'),\n /** Sort position within its layout track, ascending. Optional. */\n order: z.optional(z.number()),\n /** Footprint family the dashboard lays the tile out by. */\n size: TileSizeSchema,\n})\n\n/** @public */\nexport type TileView = z.output<typeof TileViewSchema>\n\n/** @public */\nexport type DefineTileViewInput = Omit<TileView, 'surface'>\n\n/** @public */\nexport function defineTileView(view: DefineTileViewInput): TileView {\n return {...view, surface: 'tile'}\n}\n\n/** @internal */\nexport const InterfaceDeclarationSchema = z.discriminatedUnion('surface', [\n WindowViewSchema,\n PanelViewSchema,\n AssetSourceViewSchema,\n TileViewSchema,\n])\n\n/** @public */\nexport type ViewDeclaration = z.output<typeof InterfaceDeclarationSchema>\n\nconst WebWorkerSchema = z.object({\n type: z.literal('worker'),\n ...interfaceDeclarationFields('Web worker'),\n})\n\n/** @public */\nexport type WebWorker = z.output<typeof WebWorkerSchema>\n\n/** @public */\nexport type DefineWebWorkerInput = Omit<WebWorker, 'type'>\n\n/** @public */\nexport function defineWebWorker(webWorker: DefineWebWorkerInput): WebWorker {\n return {...webWorker, type: 'worker'}\n}\n\n/** @internal */\nexport const ServiceDeclarationSchema = z.discriminatedUnion('type', [WebWorkerSchema])\n\nconst MediaLibraryFieldSchema = z.object({\n ...extensionDeclarationFields('Field'),\n public: z.optional(z.boolean()),\n title: z.string(),\n})\n\n/**\n * Stamped where the config crosses a boundary so the authoring model doesn't carry a constant discriminator.\n * @internal\n */\nexport const INSTALLATION_CONFIG_TYPE = 'installation_config'\n\n// `appType` is stamped by `unstable_defineMediaLibrary`, never authored.\nconst MediaLibraryConfigSchema = z.object({\n appType: z.literal('media-library'),\n fields: z\n .array(MediaLibraryFieldSchema)\n .check(\n z.refine(\n (fields) => new Set(fields.map((field) => field.name)).size === fields.length,\n 'Field `name` must be unique within a media library',\n ),\n ),\n})\n\n/**\n * A workbench config's built value, keyed by `appType`; deploys as a versioned\n * snapshot, not an interface.\n * @internal\n */\nexport const ConfigSchema = z.discriminatedUnion('appType', [MediaLibraryConfigSchema])\n\n/**\n * The `{appType, fields}` config value the build expands into a federation\n * remote and the deploy summarizes.\n * @internal\n */\nexport type WorkbenchConfigValue = z.output<typeof ConfigSchema>\n"],"names":["z","VIEW_CONTRACT_VERSION","SERVICE_CONTRACT_VERSION","MEDIA_LIBRARY_CONFIG_CONTRACT_VERSION","VIEW_COMPONENTS","app","asset_source","panel","tile","TileSizeSchema","enum","DockGroupSchema","DockSchema","object","group","optional","order","number","ViewPlacementMetadataSchema","dock","TileInterfaceMetadataSchema","size","INTERFACE_CONTRACT_VERSIONS","undefined","worker","interfaceContractVersion","kind","version","String","interfaceModuleId","name","Error","extensionDeclarationFields","pattern","string","check","regex","src","interfaceDeclarationFields","title","PanelViewSchema","surface","literal","definePanelView","view","WindowViewSchema","defineWindowView","AssetSourceViewSchema","defineAssetSourceView","TileViewSchema","defineTileView","InterfaceDeclarationSchema","discriminatedUnion","WebWorkerSchema","type","defineWebWorker","webWorker","ServiceDeclarationSchema","MediaLibraryFieldSchema","public","boolean","INSTALLATION_CONFIG_TYPE","MediaLibraryConfigSchema","appType","fields","array","refine","Set","map","field","length","ConfigSchema"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../src/contract.ts"],"sourcesContent":["import {z} from 'zod/mini'\n\n// Shared module-federation extension contract: interface (view/service) and\n// config declaration schemas, plus the versions the build stamps.\n// `zod/mini` keeps the bundle small.\n\n/** @internal */\nexport const VIEW_CONTRACT_VERSION = 1\n\n/** @internal */\nexport const SERVICE_CONTRACT_VERSION = 1\n\n/** @internal */\nexport const MEDIA_LIBRARY_CONFIG_CONTRACT_VERSION = 1\n\n/**\n * A view component. The return is opaque so the runtime helpers carry no React\n * dependency — the generated artifact renders it with the app's own React.\n * @public\n */\nexport type ViewComponent<TProps> = (props: TProps) => unknown\n\n/** @public */\nexport interface ViewComponentBaseProps<TView> {\n view: TView\n}\n\n/** Component slots per view surface; windows load outside the component artifact path. @internal */\nexport const VIEW_COMPONENTS = {\n asset_source: ['asset_source'],\n panel: ['title', 'panel'],\n tile: ['tile'],\n window: [],\n} as const satisfies Record<string, readonly string[]>\n\n/** @public */\nexport type ViewSurface = keyof typeof VIEW_COMPONENTS\n\n/**\n * A tile's footprint family — the shape it occupies on the dashboard. Modelled\n * on iOS WidgetKit families, not a linear scale: `banner` is full-width and\n * shallow, which a `small`→`large` magnitude can't express. The host maps a\n * family to a layout slot; the component reads it to render per footprint.\n * @public\n */\nexport const TileSizeSchema = z.enum(['small', 'large', 'banner'])\n\n/** @public */\nexport type TileSize = z.infer<typeof TileSizeSchema>\n\n/** @public */\nexport type ServiceType = 'worker'\n\nconst DockGroupSchema = z.enum(['system', 'applications', 'user'])\n\n/** @public */\nexport type DockGroup = z.output<typeof DockGroupSchema>\n\n/** @internal */\nexport const DockSchema = z.object({\n group: z.optional(DockGroupSchema),\n order: z.optional(z.number()),\n})\n\n/** @internal */\nexport type Dock = z.infer<typeof DockSchema>\n\n/** @internal */\nexport const ViewPlacementMetadataSchema = z.object({dock: DockSchema})\n\n/** @internal */\nexport type ViewPlacementMetadata = z.infer<typeof ViewPlacementMetadataSchema>\n\n/**\n * A tile's interface metadata: its footprint `size` and an optional `order`\n * the dashboard sorts on, ascending. Both are authored as top-level view fields\n * (see {@link InterfaceDeclarationSchema}) but stored on the record as metadata.\n * @internal\n */\nexport const TileInterfaceMetadataSchema = z.object({\n order: z.optional(z.number()),\n size: TileSizeSchema,\n})\n\n/** @internal */\nexport type TileInterfaceMetadata = z.infer<typeof TileInterfaceMetadataSchema>\n\n/**\n * The contract version each interface type advertises, so the host can check it\n * renders/runs what it expects.\n * @internal\n */\nconst INTERFACE_CONTRACT_VERSIONS = {\n asset_source: VIEW_CONTRACT_VERSION,\n panel: VIEW_CONTRACT_VERSION,\n tile: VIEW_CONTRACT_VERSION,\n window: undefined,\n worker: SERVICE_CONTRACT_VERSION,\n} as const\n\n/** Every interface type an app exposes — a window, a view, or a service. */\nexport type InterfaceKind = keyof typeof INTERFACE_CONTRACT_VERSIONS\n\n/** @internal */\nexport function interfaceContractVersion(kind: InterfaceKind): string | undefined {\n const version = INTERFACE_CONTRACT_VERSIONS[kind]\n return version === undefined ? undefined : String(version)\n}\n\n/**\n * The module-federation id a build exposes an interface at. Dev stamps the same\n * id a deploy would, so the workbench loads a local interface like a deployed one.\n * @internal\n */\nexport function interfaceModuleId(kind: string, name: string): string {\n switch (kind) {\n case 'asset_source':\n case 'panel':\n case 'tile': {\n return `views/${name}`\n }\n case 'window': {\n return 'App'\n }\n case 'worker': {\n return `services/${name}`\n }\n default: {\n throw new Error(`Cannot derive a moduleId for unknown interface kind: ${kind}`)\n }\n }\n}\n\n// Shared `name` + `src`; `kind` only tailors the validation message.\nfunction extensionDeclarationFields(kind: 'Field' | 'View' | 'Web worker') {\n const pattern = /^[a-zA-Z0-9_-]+$/\n return {\n name: z.string().check(z.regex(pattern, `${kind} \\`name\\` must match ${pattern}`)),\n src: z.string(),\n }\n}\n\n// Every interface shares `name` + `src` + a display `title`,\n// which Brett requires on the record each becomes.\nfunction interfaceDeclarationFields(kind: 'View' | 'Web worker') {\n return {\n ...extensionDeclarationFields(kind),\n title: z.string(`${kind} \\`title\\` is required`),\n }\n}\n\nconst PanelViewSchema = z.object({\n surface: z.literal('panel'),\n ...interfaceDeclarationFields('View'),\n dock: z.optional(DockSchema),\n})\n\n/** @public */\nexport type PanelView = z.output<typeof PanelViewSchema>\n\n/** @public */\nexport type DefinePanelViewInput = Omit<PanelView, 'surface'>\n\n/** @public */\nexport function definePanelView(view: DefinePanelViewInput): PanelView {\n return {...view, surface: 'panel'}\n}\n\nconst WindowViewSchema = z.object({\n surface: z.literal('window'),\n ...interfaceDeclarationFields('View'),\n dock: z.optional(DockSchema),\n})\n\n/** @public */\nexport type WindowView = z.output<typeof WindowViewSchema>\n\n/** @public */\nexport type DefineWindowViewInput = Omit<WindowView, 'surface'>\n\n/** @public */\nexport function defineWindowView(view: DefineWindowViewInput): WindowView {\n return {...view, surface: 'window'}\n}\n\nconst AssetSourceViewSchema = z.object({\n surface: z.literal('asset_source'),\n ...interfaceDeclarationFields('View'),\n})\n\n/** @public */\nexport type AssetSourceView = z.output<typeof AssetSourceViewSchema>\n\n/** @public */\nexport type DefineAssetSourceViewInput = Omit<AssetSourceView, 'surface'>\n\n/** @public */\nexport function defineAssetSourceView(view: DefineAssetSourceViewInput): AssetSourceView {\n return {...view, surface: 'asset_source'}\n}\n\nconst TileViewSchema = z.object({\n surface: z.literal('tile'),\n ...interfaceDeclarationFields('View'),\n /** Sort position within its layout track, ascending. Optional. */\n order: z.optional(z.number()),\n /** Footprint family the dashboard lays the tile out by. */\n size: TileSizeSchema,\n})\n\n/** @public */\nexport type TileView = z.output<typeof TileViewSchema>\n\n/** @public */\nexport type DefineTileViewInput = Omit<TileView, 'surface'>\n\n/** @public */\nexport function defineTileView(view: DefineTileViewInput): TileView {\n return {...view, surface: 'tile'}\n}\n\n/** @internal */\nexport const InterfaceDeclarationSchema = z.discriminatedUnion('surface', [\n WindowViewSchema,\n PanelViewSchema,\n AssetSourceViewSchema,\n TileViewSchema,\n])\n\n/** @public */\nexport type ViewDeclaration = z.output<typeof InterfaceDeclarationSchema>\n\nconst WebWorkerSchema = z.object({\n type: z.literal('worker'),\n ...interfaceDeclarationFields('Web worker'),\n})\n\n/** @public */\nexport type WebWorker = z.output<typeof WebWorkerSchema>\n\n/** @public */\nexport type DefineWebWorkerInput = Omit<WebWorker, 'type'>\n\n/** @public */\nexport function defineWebWorker(webWorker: DefineWebWorkerInput): WebWorker {\n return {...webWorker, type: 'worker'}\n}\n\n/** @internal */\nexport const ServiceDeclarationSchema = z.discriminatedUnion('type', [WebWorkerSchema])\n\nconst MediaLibraryFieldSchema = z.object({\n ...extensionDeclarationFields('Field'),\n public: z.optional(z.boolean()),\n title: z.string(),\n})\n\n/**\n * Stamped where the config crosses a boundary so the authoring model doesn't carry a constant discriminator.\n * @internal\n */\nexport const INSTALLATION_CONFIG_TYPE = 'installation_config'\n\n// `appType` is stamped by `unstable_defineMediaLibrary`, never authored.\nconst MediaLibraryConfigSchema = z.object({\n appType: z.literal('media-library'),\n fields: z\n .array(MediaLibraryFieldSchema)\n .check(\n z.refine(\n (fields) => new Set(fields.map((field) => field.name)).size === fields.length,\n 'Field `name` must be unique within a media library',\n ),\n ),\n})\n\n/**\n * A workbench config's built value, keyed by `appType`; deploys as a versioned\n * snapshot, not an interface.\n * @internal\n */\nexport const ConfigSchema = z.discriminatedUnion('appType', [MediaLibraryConfigSchema])\n\n/**\n * The `{appType, fields}` config value the build expands into a federation\n * remote and the deploy summarizes.\n * @internal\n */\nexport type WorkbenchConfigValue = z.output<typeof ConfigSchema>\n"],"names":["z","VIEW_CONTRACT_VERSION","SERVICE_CONTRACT_VERSION","MEDIA_LIBRARY_CONFIG_CONTRACT_VERSION","VIEW_COMPONENTS","asset_source","panel","tile","window","TileSizeSchema","enum","DockGroupSchema","DockSchema","object","group","optional","order","number","ViewPlacementMetadataSchema","dock","TileInterfaceMetadataSchema","size","INTERFACE_CONTRACT_VERSIONS","undefined","worker","interfaceContractVersion","kind","version","String","interfaceModuleId","name","Error","extensionDeclarationFields","pattern","string","check","regex","src","interfaceDeclarationFields","title","PanelViewSchema","surface","literal","definePanelView","view","WindowViewSchema","defineWindowView","AssetSourceViewSchema","defineAssetSourceView","TileViewSchema","defineTileView","InterfaceDeclarationSchema","discriminatedUnion","WebWorkerSchema","type","defineWebWorker","webWorker","ServiceDeclarationSchema","MediaLibraryFieldSchema","public","boolean","INSTALLATION_CONFIG_TYPE","MediaLibraryConfigSchema","appType","fields","array","refine","Set","map","field","length","ConfigSchema"],"mappings":"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"}
|
package/dist/defineView.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/defineView.ts"],"sourcesContent":["import {type AssetSourceComponentProps} from '@sanity/types'\n\nimport {\n type TileSize,\n VIEW_CONTRACT_VERSION,\n type ViewComponent,\n type ViewComponentBaseProps,\n type ViewSurface,\n} from './contract.js'\n\n/** @public */\nexport type WindowViewProps = ViewComponentBaseProps<{\n name: string\n src: string\n surface: '
|
|
1
|
+
{"version":3,"sources":["../src/defineView.ts"],"sourcesContent":["import {type AssetSourceComponentProps} from '@sanity/types'\n\nimport {\n type TileSize,\n VIEW_CONTRACT_VERSION,\n type ViewComponent,\n type ViewComponentBaseProps,\n type ViewSurface,\n} from './contract.js'\n\n/** @public */\nexport type WindowViewProps = ViewComponentBaseProps<{\n name: string\n src: string\n surface: 'window'\n title: string\n}>\n\n/**\n * Props a panel component receives: its interface record, minus the\n * service-assigned `id`/`deployment_id` a local dev server can't provide. Mirrors\n * the `panel` record the workbench host renders from (the wire format owned by\n * `@sanity/workbench`); drift is guarded by the stamped contract version.\n * @public\n */\nexport type PanelViewProps = ViewComponentBaseProps<{\n name: string\n src: string\n surface: 'panel'\n title: string\n}>\n\n/**\n * The component slots a `panel` view exposes — each its own module-federation\n * island, typed with the panel props.\n * @public\n */\nexport interface PanelViewComponents {\n panel: ViewComponent<PanelViewProps>\n title: ViewComponent<PanelViewProps>\n}\n\n/**\n * A panel's view-component slot — the module-federation expose for one island.\n * @public\n */\nexport type PanelComponent = keyof PanelViewComponents\n\n/**\n * The component slots an `asset_source` view exposes — a single picker island,\n * typed with the studio asset-source props it renders behind. The props are\n * `@sanity/types`' `AssetSourceComponentProps` directly, so an authored picker\n * receives exactly what a studio `AssetSource.component` does.\n * @public\n */\nexport interface AssetSourceViewComponents {\n asset_source: ViewComponent<AssetSourceComponentProps>\n}\n\n/**\n * An asset source's view-component slot — the module-federation expose for its\n * one island.\n * @public\n */\nexport type AssetSourceComponent = keyof AssetSourceViewComponents\n\n/**\n * Props a tile component receives: its own interface record plus its footprint\n * `size`, so it can render per family. Mirrors the\n * `tile` record the dashboard host renders from; drift is guarded by the stamped\n * contract version. Placement `order` is host-only metadata, not surfaced here.\n * @public\n */\nexport type TileViewProps = ViewComponentBaseProps<{\n name: string\n size: TileSize\n src: string\n surface: 'tile'\n title: string\n}>\n\n/**\n * The component slot a `tile` view exposes — a single island, typed with the\n * tile props.\n * @public\n */\nexport interface TileViewComponents {\n tile: ViewComponent<TileViewProps>\n}\n\n/**\n * A tile's view-component slot — the module-federation expose for its one island.\n * @public\n */\nexport type TileComponent = keyof TileViewComponents\n\n/**\n * The components each view surface exposes.\n * @public\n */\nexport interface ViewComponentsBySurface {\n asset_source: AssetSourceViewComponents\n panel: PanelViewComponents\n tile: TileViewComponents\n window: ViewComponent<WindowViewProps>\n}\n\n/**\n * The result of `unstable_defineView`: the author's component(s), the view surface,\n * and the internal contract version the build artifact targets.\n * @public\n */\nexport interface DefinedView<TSurface extends ViewSurface = ViewSurface> {\n readonly components: ViewComponentsBySurface[TSurface]\n readonly surface: TSurface\n /** @internal */\n readonly version: typeof VIEW_CONTRACT_VERSION\n}\n\n/**\n * Define a Sanity Workbench view. The first argument narrows the component shape\n * and the props each component receives — `\"panel\"` yields a `{title, panel}`\n * record whose components are typed with the panel props.\n *\n * Returns the component(s) tagged with their surface and contract version, for\n * the CLI build to generate render artifacts from. Used as the default export of\n * a view's `src` file.\n * @public\n */\nexport function unstable_defineView<TSurface extends ViewSurface>(\n surface: TSurface,\n components: ViewComponentsBySurface[TSurface],\n): DefinedView<TSurface> {\n return {components, surface, version: VIEW_CONTRACT_VERSION}\n}\n"],"names":["VIEW_CONTRACT_VERSION","unstable_defineView","surface","components","version"],"mappings":"AAEA,SAEEA,qBAAqB,QAIhB,gBAAe;AA+GtB;;;;;;;;;CASC,GACD,OAAO,SAASC,oBACdC,OAAiB,EACjBC,UAA6C;IAE7C,OAAO;QAACA;QAAYD;QAASE,SAASJ;IAAqB;AAC7D"}
|
package/dist/deriveInterfaces.js
CHANGED
|
@@ -3,7 +3,7 @@ import { interfaceContractVersion, interfaceModuleId } from './contract.js';
|
|
|
3
3
|
import { isWorkbenchApp } from './defineApp.js';
|
|
4
4
|
/** What a studio exposes as `./App` — the generated entry that renders `sanity.config.ts`. */ const GENERATED_ENTRY = `./${RUNTIME_DIR}/${FEDERATION_FILE_NAME}.jsx`;
|
|
5
5
|
/**
|
|
6
|
-
* `appTitle` titles the
|
|
6
|
+
* `appTitle` titles the window where a deploy resolved one through `--title`;
|
|
7
7
|
* dev takes it from the config.
|
|
8
8
|
* @internal
|
|
9
9
|
*/ export function deriveInterfaces(app, { appTitle, isApp }) {
|
|
@@ -14,7 +14,7 @@ import { isWorkbenchApp } from './defineApp.js';
|
|
|
14
14
|
throw new Error('App views for studios are not implemented yet');
|
|
15
15
|
}
|
|
16
16
|
const entry = isApp ? app.entry : GENERATED_ENTRY;
|
|
17
|
-
// Identity, not address: interface ids and the
|
|
17
|
+
// Identity, not address: interface ids and the window name key on `name`
|
|
18
18
|
// (which defaults to `slug`, so existing apps derive byte-identical ids).
|
|
19
19
|
const appName = app.name ?? app.slug;
|
|
20
20
|
const shared = (kind, declaration)=>({
|
|
@@ -54,7 +54,7 @@ import { isWorkbenchApp } from './defineApp.js';
|
|
|
54
54
|
surface: view.surface
|
|
55
55
|
};
|
|
56
56
|
}
|
|
57
|
-
if (view.surface === '
|
|
57
|
+
if (view.surface === 'panel' || view.surface === 'window') {
|
|
58
58
|
return {
|
|
59
59
|
...shared(view.surface, view),
|
|
60
60
|
metadata: placementMetadata(view.dock),
|
|
@@ -74,13 +74,13 @@ import { isWorkbenchApp } from './defineApp.js';
|
|
|
74
74
|
})),
|
|
75
75
|
...entry === undefined ? [] : [
|
|
76
76
|
{
|
|
77
|
-
...shared('
|
|
77
|
+
...shared('window', {
|
|
78
78
|
name: appName,
|
|
79
79
|
src: entry,
|
|
80
80
|
title: appTitle ?? app.title
|
|
81
81
|
}),
|
|
82
82
|
metadata: placementMetadata(),
|
|
83
|
-
surface: '
|
|
83
|
+
surface: 'window'
|
|
84
84
|
}
|
|
85
85
|
]
|
|
86
86
|
];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/deriveInterfaces.ts"],"sourcesContent":["import {type CliConfig} from '@sanity/cli-core'\n\nimport {FEDERATION_FILE_NAME, RUNTIME_DIR} from './actions/build/vite/constants.js'\nimport {\n type Dock,\n interfaceContractVersion,\n type InterfaceKind,\n interfaceModuleId,\n type TileInterfaceMetadata,\n type ViewPlacementMetadata,\n} from './contract.js'\nimport {isWorkbenchApp} from './defineApp.js'\n\n/** What a studio exposes as `./App` — the generated entry that renders `sanity.config.ts`. */\nconst GENERATED_ENTRY = `./${RUNTIME_DIR}/${FEDERATION_FILE_NAME}.jsx`\n\ninterface DerivedInterfaceBase {\n /** CLI-minted for a local interface; a deployed one gets its id from Brett. */\n id: string\n moduleId: string\n name: string\n src: string\n title: string\n\n version?: string\n}\n\n/** @internal */\nexport type DerivedInterface =\n | (DerivedInterfaceBase & {metadata: null; surface: 'asset_source'})\n | (DerivedInterfaceBase & {metadata: null; type: 'worker'})\n | (DerivedInterfaceBase & {metadata: TileInterfaceMetadata; surface: 'tile'})\n | (DerivedInterfaceBase & {metadata: ViewPlacementMetadata | null; surface: '
|
|
1
|
+
{"version":3,"sources":["../src/deriveInterfaces.ts"],"sourcesContent":["import {type CliConfig} from '@sanity/cli-core'\n\nimport {FEDERATION_FILE_NAME, RUNTIME_DIR} from './actions/build/vite/constants.js'\nimport {\n type Dock,\n interfaceContractVersion,\n type InterfaceKind,\n interfaceModuleId,\n type TileInterfaceMetadata,\n type ViewPlacementMetadata,\n} from './contract.js'\nimport {isWorkbenchApp} from './defineApp.js'\n\n/** What a studio exposes as `./App` — the generated entry that renders `sanity.config.ts`. */\nconst GENERATED_ENTRY = `./${RUNTIME_DIR}/${FEDERATION_FILE_NAME}.jsx`\n\ninterface DerivedInterfaceBase {\n /** CLI-minted for a local interface; a deployed one gets its id from Brett. */\n id: string\n moduleId: string\n name: string\n src: string\n title: string\n\n version?: string\n}\n\n/** @internal */\nexport type DerivedInterface =\n | (DerivedInterfaceBase & {metadata: null; surface: 'asset_source'})\n | (DerivedInterfaceBase & {metadata: null; type: 'worker'})\n | (DerivedInterfaceBase & {metadata: TileInterfaceMetadata; surface: 'tile'})\n | (DerivedInterfaceBase & {metadata: ViewPlacementMetadata | null; surface: 'panel'})\n | (DerivedInterfaceBase & {metadata: ViewPlacementMetadata | null; surface: 'window'})\n\n/**\n * `appTitle` titles the window where a deploy resolved one through `--title`;\n * dev takes it from the config.\n * @internal\n */\nexport function deriveInterfaces(\n app: CliConfig['app'],\n {appTitle, isApp}: {appTitle?: string; isApp: boolean},\n): DerivedInterface[] {\n if (!isWorkbenchApp(app)) return []\n\n // The schema rejects a *declared* studio with an `entry`; `isApp` is resolved\n // from the project, so a detected one only fails here.\n if (!isApp && app.entry !== undefined) {\n throw new Error('App views for studios are not implemented yet')\n }\n const entry = isApp ? app.entry : GENERATED_ENTRY\n\n // Identity, not address: interface ids and the window name key on `name`\n // (which defaults to `slug`, so existing apps derive byte-identical ids).\n const appName = app.name ?? app.slug\n\n const shared = (\n kind: InterfaceKind,\n declaration: {name: string; src: string; title: string},\n ) => ({\n id: `${appName}-${kind}-${declaration.name}`,\n moduleId: interfaceModuleId(kind, declaration.name),\n name: declaration.name,\n src: declaration.src,\n title: declaration.title,\n version: interfaceContractVersion(kind),\n })\n\n const placementMetadata = (dock?: Dock): ViewPlacementMetadata | null => {\n const group = dock?.group ?? app.dock?.group\n const order = dock?.order ?? app.dock?.order\n if (group === undefined && order === undefined) return null\n return {\n dock: {\n ...(group === undefined ? {} : {group}),\n ...(order === undefined ? {} : {order}),\n },\n }\n }\n\n return [\n ...(app.views ?? []).map((view): DerivedInterface => {\n if (view.surface === 'tile') {\n return {\n ...shared(view.surface, view),\n metadata:\n view.order === undefined ? {size: view.size} : {order: view.order, size: view.size},\n surface: view.surface,\n }\n }\n if (view.surface === 'panel' || view.surface === 'window') {\n return {\n ...shared(view.surface, view),\n metadata: placementMetadata(view.dock),\n surface: view.surface,\n }\n }\n return {...shared(view.surface, view), metadata: null, surface: view.surface}\n }),\n ...(app.webWorkers ?? []).map((webWorker): DerivedInterface => ({\n ...shared('worker', webWorker),\n metadata: null,\n type: 'worker',\n })),\n ...(entry === undefined\n ? []\n : [\n {\n ...shared('window', {name: appName, src: entry, title: appTitle ?? app.title}),\n metadata: placementMetadata(),\n surface: 'window' as const,\n },\n ]),\n ]\n}\n"],"names":["FEDERATION_FILE_NAME","RUNTIME_DIR","interfaceContractVersion","interfaceModuleId","isWorkbenchApp","GENERATED_ENTRY","deriveInterfaces","app","appTitle","isApp","entry","undefined","Error","appName","name","slug","shared","kind","declaration","id","moduleId","src","title","version","placementMetadata","dock","group","order","views","map","view","surface","metadata","size","webWorkers","webWorker","type"],"mappings":"AAEA,SAAQA,oBAAoB,EAAEC,WAAW,QAAO,oCAAmC;AACnF,SAEEC,wBAAwB,EAExBC,iBAAiB,QAGZ,gBAAe;AACtB,SAAQC,cAAc,QAAO,iBAAgB;AAE7C,4FAA4F,GAC5F,MAAMC,kBAAkB,CAAC,EAAE,EAAEJ,YAAY,CAAC,EAAED,qBAAqB,IAAI,CAAC;AAqBtE;;;;CAIC,GACD,OAAO,SAASM,iBACdC,GAAqB,EACrB,EAACC,QAAQ,EAAEC,KAAK,EAAsC;IAEtD,IAAI,CAACL,eAAeG,MAAM,OAAO,EAAE;IAEnC,8EAA8E;IAC9E,uDAAuD;IACvD,IAAI,CAACE,SAASF,IAAIG,KAAK,KAAKC,WAAW;QACrC,MAAM,IAAIC,MAAM;IAClB;IACA,MAAMF,QAAQD,QAAQF,IAAIG,KAAK,GAAGL;IAElC,yEAAyE;IACzE,0EAA0E;IAC1E,MAAMQ,UAAUN,IAAIO,IAAI,IAAIP,IAAIQ,IAAI;IAEpC,MAAMC,SAAS,CACbC,MACAC,cACI,CAAA;YACJC,IAAI,GAAGN,QAAQ,CAAC,EAAEI,KAAK,CAAC,EAAEC,YAAYJ,IAAI,EAAE;YAC5CM,UAAUjB,kBAAkBc,MAAMC,YAAYJ,IAAI;YAClDA,MAAMI,YAAYJ,IAAI;YACtBO,KAAKH,YAAYG,GAAG;YACpBC,OAAOJ,YAAYI,KAAK;YACxBC,SAASrB,yBAAyBe;QACpC,CAAA;IAEA,MAAMO,oBAAoB,CAACC;QACzB,MAAMC,QAAQD,MAAMC,SAASnB,IAAIkB,IAAI,EAAEC;QACvC,MAAMC,QAAQF,MAAME,SAASpB,IAAIkB,IAAI,EAAEE;QACvC,IAAID,UAAUf,aAAagB,UAAUhB,WAAW,OAAO;QACvD,OAAO;YACLc,MAAM;gBACJ,GAAIC,UAAUf,YAAY,CAAC,IAAI;oBAACe;gBAAK,CAAC;gBACtC,GAAIC,UAAUhB,YAAY,CAAC,IAAI;oBAACgB;gBAAK,CAAC;YACxC;QACF;IACF;IAEA,OAAO;WACF,AAACpB,CAAAA,IAAIqB,KAAK,IAAI,EAAE,AAAD,EAAGC,GAAG,CAAC,CAACC;YACxB,IAAIA,KAAKC,OAAO,KAAK,QAAQ;gBAC3B,OAAO;oBACL,GAAGf,OAAOc,KAAKC,OAAO,EAAED,KAAK;oBAC7BE,UACEF,KAAKH,KAAK,KAAKhB,YAAY;wBAACsB,MAAMH,KAAKG,IAAI;oBAAA,IAAI;wBAACN,OAAOG,KAAKH,KAAK;wBAAEM,MAAMH,KAAKG,IAAI;oBAAA;oBACpFF,SAASD,KAAKC,OAAO;gBACvB;YACF;YACA,IAAID,KAAKC,OAAO,KAAK,WAAWD,KAAKC,OAAO,KAAK,UAAU;gBACzD,OAAO;oBACL,GAAGf,OAAOc,KAAKC,OAAO,EAAED,KAAK;oBAC7BE,UAAUR,kBAAkBM,KAAKL,IAAI;oBACrCM,SAASD,KAAKC,OAAO;gBACvB;YACF;YACA,OAAO;gBAAC,GAAGf,OAAOc,KAAKC,OAAO,EAAED,KAAK;gBAAEE,UAAU;gBAAMD,SAASD,KAAKC,OAAO;YAAA;QAC9E;WACG,AAACxB,CAAAA,IAAI2B,UAAU,IAAI,EAAE,AAAD,EAAGL,GAAG,CAAC,CAACM,YAAiC,CAAA;gBAC9D,GAAGnB,OAAO,UAAUmB,UAAU;gBAC9BH,UAAU;gBACVI,MAAM;YACR,CAAA;WACI1B,UAAUC,YACV,EAAE,GACF;YACE;gBACE,GAAGK,OAAO,UAAU;oBAACF,MAAMD;oBAASQ,KAAKX;oBAAOY,OAAOd,YAAYD,IAAIe,KAAK;gBAAA,EAAE;gBAC9EU,UAAUR;gBACVO,SAAS;YACX;SACD;KACN;AACH"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sanity/workbench-cli",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.4.0",
|
|
4
4
|
"description": "Internal implementation detail of the Sanity CLI's unstable workbench support. Not intended for direct use.",
|
|
5
5
|
"homepage": "https://github.com/sanity-io/cli",
|
|
6
6
|
"bugs": "https://github.com/sanity-io/cli/issues",
|
|
@@ -59,30 +59,29 @@
|
|
|
59
59
|
"dependencies": {
|
|
60
60
|
"@module-federation/runtime": "2.9.0",
|
|
61
61
|
"@module-federation/vite": "1.21.0",
|
|
62
|
-
"@sanity/
|
|
62
|
+
"@sanity/cli-core": "^3.6.1",
|
|
63
|
+
"@sanity/types": "^6.12.0",
|
|
63
64
|
"@vitejs/plugin-react": "^6.1.1",
|
|
64
65
|
"form-data": "^4.0.5",
|
|
65
66
|
"rxjs": "^7.8.2",
|
|
66
|
-
"tar
|
|
67
|
+
"tar": "^7.5.18",
|
|
67
68
|
"vite": "^8.2.2",
|
|
68
|
-
"zod": "^4.
|
|
69
|
-
"@sanity/cli-core": "^3.5.1"
|
|
69
|
+
"zod": "^4.5.2"
|
|
70
70
|
},
|
|
71
71
|
"devDependencies": {
|
|
72
72
|
"@eslint/compat": "^2.1.0",
|
|
73
|
+
"@repo/package.config": "0.0.1",
|
|
74
|
+
"@repo/tsconfig": "3.70.0",
|
|
75
|
+
"@sanity/eslint-config-cli": "^1.1.3",
|
|
73
76
|
"@sanity/pkg-utils": "^12.3.4",
|
|
74
77
|
"@swc/cli": "^0.8.1",
|
|
75
78
|
"@swc/core": "^1.15.43",
|
|
76
79
|
"@types/node": "^22.20.0",
|
|
77
|
-
"@types/tar-fs": "^2.0.4",
|
|
78
80
|
"@vitest/coverage-istanbul": "^4.1.11",
|
|
79
81
|
"eslint": "^10.7.0",
|
|
80
82
|
"publint": "^0.3.21",
|
|
81
83
|
"typescript": "^6.0.3",
|
|
82
|
-
"vitest": "^4.1.11"
|
|
83
|
-
"@repo/package.config": "0.0.1",
|
|
84
|
-
"@repo/tsconfig": "3.70.0",
|
|
85
|
-
"@sanity/eslint-config-cli": "^1.1.3"
|
|
84
|
+
"vitest": "^4.1.11"
|
|
86
85
|
},
|
|
87
86
|
"engines": {
|
|
88
87
|
"node": ">=22.12"
|