@sanity/workbench-cli 2.2.2 → 2.2.3
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/dev.d.ts +1 -0
- package/dist/_exports/preview.d.ts +1 -0
- package/dist/actions/dev/startDevServerRegistration.js +4 -1
- package/dist/actions/dev/startDevServerRegistration.js.map +1 -1
- package/dist/actions/dev/startWorkbenchDev.js.map +1 -1
- package/dist/actions/preview/startWorkbenchPreview.js +1 -0
- package/dist/actions/preview/startWorkbenchPreview.js.map +1 -1
- package/package.json +3 -3
package/dist/_exports/dev.d.ts
CHANGED
|
@@ -22,6 +22,7 @@ interface StartWorkbenchDevOptions {
|
|
|
22
22
|
cliConfig: CliConfig;
|
|
23
23
|
/** Extract the project manifest to inline into the registry (studio-vs-app handled by the CLI). */
|
|
24
24
|
extractManifest: (params: {
|
|
25
|
+
applicationId?: string;
|
|
25
26
|
configPath: string;
|
|
26
27
|
workDir: string;
|
|
27
28
|
}) => Promise<DevServerManifest['manifest']>;
|
|
@@ -8,6 +8,7 @@ interface StartWorkbenchPreviewOptions {
|
|
|
8
8
|
cliConfig: CliConfig;
|
|
9
9
|
/** Extract the project manifest to inline into the registry (studio-vs-app handled by the CLI). */
|
|
10
10
|
extractManifest: (params: {
|
|
11
|
+
applicationId?: string;
|
|
11
12
|
configPath: string;
|
|
12
13
|
workDir: string;
|
|
13
14
|
}) => Promise<DevServerManifest['manifest']>;
|
|
@@ -94,7 +94,10 @@ import { startDevManifestWatcher } from './startDevManifestWatcher.js';
|
|
|
94
94
|
interfaces: deriveInterfaces(nextConfig.app, {
|
|
95
95
|
isApp
|
|
96
96
|
}),
|
|
97
|
-
manifest: await extractManifest(
|
|
97
|
+
manifest: await extractManifest({
|
|
98
|
+
...params,
|
|
99
|
+
applicationId: id
|
|
100
|
+
})
|
|
98
101
|
};
|
|
99
102
|
},
|
|
100
103
|
// A studio's root resolves to `sanity.config.*` but its interfaces live in
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/actions/dev/startDevServerRegistration.ts"],"sourcesContent":["import {type CliConfig, getCliConfigUncached, type Output} from '@sanity/cli-core'\nimport {type ViteDevServer} from 'vite'\n\nimport {applicationReference} from '../../applicationReference.js'\nimport {isWorkbenchApp, isWorkbenchConfig} from '../../defineApp.js'\nimport {deriveInterfaces} from '../../deriveInterfaces.js'\nimport {resolveWorkbenchConfig} from '../../resolveWorkbenchConfig.js'\nimport {formatWorkbenchAppErrors, validateWorkbenchApp} from '../../validateWorkbenchApp.js'\nimport {deriveConfigs} from './deriveConfigs.js'\nimport {trackExposesSet} from './exposesSetId.js'\nimport {type DevServerManifest, getRegisteredServers, registerDevServer} from './registry.js'\nimport {startDevManifestWatcher} from './startDevManifestWatcher.js'\n\ninterface DevServerRegistrationOptions {\n cliConfig: CliConfig\n /**\n * Extract the project manifest to inline into the registry. The caller owns the\n * studio-vs-app split (manifest formats are CLI-domain); registration re-derives\n * the interface set alongside it.\n */\n extractManifest: (params: {\n configPath: string\n workDir: string\n }) => Promise<DevServerManifest['manifest']>\n isApp: boolean\n output: Output\n server: ViteDevServer\n workDir: string\n\n /**\n * Rebuild the app's federation remote when its interface set changes, awaited\n * *before* the registry patch — the patch reloads the workbench page, which must\n * re-fetch a remote that already exposes the new interface. Resolves with the\n * recreated server so the entry gets its actual address (non-strict ports may\n * shift it); must reject if the restart produces no server, so the set stays\n * uncommitted and the next save retries instead of advertising a dead port.\n */\n onInterfaceSetChange?: () => Promise<ViteDevServer>\n}\n\ninterface DevServerRegistrationHandle {\n close: () => Promise<void>\n}\n\n/**\n * Log any app validation errors without aborting. Unlike build and deploy, dev\n * stays up on an invalid app so the author sees the errors and fixes them live on\n * the next save. A config is not an app — it isn't validated by the app schema\n * (which would spuriously demand a slug/title), so skip it here.\n */\nfunction reportConfigErrors(app: CliConfig['app'], output: Output): void {\n if (isWorkbenchConfig(app)) return\n const errors = validateWorkbenchApp(app)\n if (errors.length === 0) return\n output.warn(formatWorkbenchAppErrors(errors))\n}\n\n/** The address the server actually bound — the live socket, which can differ from the configured port under non-strict ports. */\nfunction serverAddress(server: ViteDevServer) {\n const resolvedHost = server.config.server.host\n const addr = server.httpServer?.address()\n return {\n host: typeof resolvedHost === 'string' ? resolvedHost : 'localhost',\n port: typeof addr === 'object' && addr ? addr.port : server.config.server.port,\n }\n}\n\n/**\n * Register the dev server in the registry and watch its config for manifest +\n * interface changes. The workbench reads the entry to locate and render the\n * server; the watcher keeps it current as `sanity.cli.ts` is edited.\n */\nexport async function startDevServerRegistration(\n options: DevServerRegistrationOptions,\n): Promise<DevServerRegistrationHandle> {\n const {cliConfig, extractManifest, isApp, onInterfaceSetChange, output, server, workDir} = options\n\n const {host: appHost, port: appPort} = serverAddress(server)\n\n reportConfigErrors(cliConfig.app, output)\n\n // Forwarded alongside (not inside) the manifest so the workbench renders local\n // panels/workers and reads the configs without a deploy.\n const interfaces = deriveInterfaces(cliConfig.app, {isApp})\n const configs = await deriveConfigs(cliConfig)\n\n const workbenchApp = isWorkbenchApp(cliConfig.app) ? cliConfig.app : undefined\n const config = resolveWorkbenchConfig(cliConfig)\n // A config runs alongside the app it configures, so give it its own id\n // namespace — sharing the app's slug would make the two indistinguishable here.\n const id = config ? `config:${config.appType}` : workbenchApp?.slug\n // Identity is resolved and the reference composed here, so the workbench reads\n // both off the registry entry instead of recomposing them. Name defaults to the\n // slug, mirroring brett.\n const name = workbenchApp?.name ?? workbenchApp?.slug\n const reference =\n workbenchApp && name\n ? // No workbench app is a singleton now that the only one (the Media Library)\n // is a config, not an app — so its reference is always `<org>/<name>`.\n applicationReference({\n isSingleton: false,\n name,\n organizationId: workbenchApp.organizationId,\n })\n : undefined\n\n // Separate namespaces mean a shared id is a genuine duplicate, so the gate is\n // a plain id match — no config-vs-app role left to reconcile.\n const devServer = id ? getRegisteredServers().find((server) => server.id === id) : undefined\n\n if (id && devServer) {\n output.error(\n `\"${id}\" is already served by another dev server running on port ${devServer.port}, ` +\n \"so the workbench can't tell them apart and this one stays out of it. Stop that server first.\",\n {exit: false},\n )\n return {close: async () => {}}\n }\n\n const registration = registerDevServer({\n configs,\n host: appHost,\n id,\n interfaces,\n name,\n port: appPort,\n projectId: cliConfig?.api?.projectId,\n reference,\n type: isApp ? 'coreApp' : 'studio',\n workDir,\n })\n\n const exposesSet = trackExposesSet({configs, interfaces})\n\n const watcher = await startDevManifestWatcher({\n // Re-derive every pass (don't omit): the registry patch is a shallow merge,\n // so omitting would wipe the registered set.\n extract: async (params) => {\n const nextConfig = await getCliConfigUncached(params.workDir)\n reportConfigErrors(nextConfig.app, output)\n return {\n configs: await deriveConfigs(nextConfig),\n interfaces: deriveInterfaces(nextConfig.app, {isApp}),\n manifest: await extractManifest(params),\n }\n },\n // A studio's root resolves to `sanity.config.*` but its interfaces live in\n // `sanity.cli.*` — watch that too. Apps already root at `sanity.cli.*`.\n extraWatchFilenames: isApp ? undefined : ['sanity.cli.js', 'sanity.cli.ts'],\n output,\n update: async (patch) => {\n if (\n !exposesSet.changed({\n configs: patch.configs,\n interfaces: patch.interfaces,\n })\n ) {\n registration.update(patch)\n return\n }\n // Rebuild the remote *before* patching the registry — the patch reloads the\n // page, which must re-fetch a remote that already exposes the new interface.\n const rebuiltServer = await onInterfaceSetChange?.()\n // Commit only after a successful rebuild, so a thrown one retries next pass.\n exposesSet.commit({\n configs: patch.configs,\n interfaces: patch.interfaces,\n })\n // The recreated server can bind a different port (non-strict ports).\n registration.update(rebuiltServer ? {...patch, ...serverAddress(rebuiltServer)} : patch)\n },\n workDir,\n })\n\n return {\n close: async () => {\n registration.release()\n await watcher.close()\n },\n }\n}\n"],"names":["getCliConfigUncached","applicationReference","isWorkbenchApp","isWorkbenchConfig","deriveInterfaces","resolveWorkbenchConfig","formatWorkbenchAppErrors","validateWorkbenchApp","deriveConfigs","trackExposesSet","getRegisteredServers","registerDevServer","startDevManifestWatcher","reportConfigErrors","app","output","errors","length","warn","serverAddress","server","resolvedHost","config","host","addr","httpServer","address","port","startDevServerRegistration","options","cliConfig","extractManifest","isApp","onInterfaceSetChange","workDir","appHost","appPort","interfaces","configs","workbenchApp","undefined","id","appType","slug","name","reference","isSingleton","organizationId","devServer","find","error","exit","close","registration","projectId","api","type","exposesSet","watcher","extract","params","nextConfig","manifest","extraWatchFilenames","update","patch","changed","rebuiltServer","commit","release"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../src/actions/dev/startDevServerRegistration.ts"],"sourcesContent":["import {type CliConfig, getCliConfigUncached, type Output} from '@sanity/cli-core'\nimport {type ViteDevServer} from 'vite'\n\nimport {applicationReference} from '../../applicationReference.js'\nimport {isWorkbenchApp, isWorkbenchConfig} from '../../defineApp.js'\nimport {deriveInterfaces} from '../../deriveInterfaces.js'\nimport {resolveWorkbenchConfig} from '../../resolveWorkbenchConfig.js'\nimport {formatWorkbenchAppErrors, validateWorkbenchApp} from '../../validateWorkbenchApp.js'\nimport {deriveConfigs} from './deriveConfigs.js'\nimport {trackExposesSet} from './exposesSetId.js'\nimport {type DevServerManifest, getRegisteredServers, registerDevServer} from './registry.js'\nimport {startDevManifestWatcher} from './startDevManifestWatcher.js'\n\ninterface DevServerRegistrationOptions {\n cliConfig: CliConfig\n /**\n * Extract the project manifest to inline into the registry. The caller owns the\n * studio-vs-app split (manifest formats are CLI-domain); registration re-derives\n * the interface set alongside it.\n */\n extractManifest: (params: {\n applicationId?: string\n configPath: string\n workDir: string\n }) => Promise<DevServerManifest['manifest']>\n isApp: boolean\n output: Output\n server: ViteDevServer\n workDir: string\n\n /**\n * Rebuild the app's federation remote when its interface set changes, awaited\n * *before* the registry patch — the patch reloads the workbench page, which must\n * re-fetch a remote that already exposes the new interface. Resolves with the\n * recreated server so the entry gets its actual address (non-strict ports may\n * shift it); must reject if the restart produces no server, so the set stays\n * uncommitted and the next save retries instead of advertising a dead port.\n */\n onInterfaceSetChange?: () => Promise<ViteDevServer>\n}\n\ninterface DevServerRegistrationHandle {\n close: () => Promise<void>\n}\n\n/**\n * Log any app validation errors without aborting. Unlike build and deploy, dev\n * stays up on an invalid app so the author sees the errors and fixes them live on\n * the next save. A config is not an app — it isn't validated by the app schema\n * (which would spuriously demand a slug/title), so skip it here.\n */\nfunction reportConfigErrors(app: CliConfig['app'], output: Output): void {\n if (isWorkbenchConfig(app)) return\n const errors = validateWorkbenchApp(app)\n if (errors.length === 0) return\n output.warn(formatWorkbenchAppErrors(errors))\n}\n\n/** The address the server actually bound — the live socket, which can differ from the configured port under non-strict ports. */\nfunction serverAddress(server: ViteDevServer) {\n const resolvedHost = server.config.server.host\n const addr = server.httpServer?.address()\n return {\n host: typeof resolvedHost === 'string' ? resolvedHost : 'localhost',\n port: typeof addr === 'object' && addr ? addr.port : server.config.server.port,\n }\n}\n\n/**\n * Register the dev server in the registry and watch its config for manifest +\n * interface changes. The workbench reads the entry to locate and render the\n * server; the watcher keeps it current as `sanity.cli.ts` is edited.\n */\nexport async function startDevServerRegistration(\n options: DevServerRegistrationOptions,\n): Promise<DevServerRegistrationHandle> {\n const {cliConfig, extractManifest, isApp, onInterfaceSetChange, output, server, workDir} = options\n\n const {host: appHost, port: appPort} = serverAddress(server)\n\n reportConfigErrors(cliConfig.app, output)\n\n // Forwarded alongside (not inside) the manifest so the workbench renders local\n // panels/workers and reads the configs without a deploy.\n const interfaces = deriveInterfaces(cliConfig.app, {isApp})\n const configs = await deriveConfigs(cliConfig)\n\n const workbenchApp = isWorkbenchApp(cliConfig.app) ? cliConfig.app : undefined\n const config = resolveWorkbenchConfig(cliConfig)\n // A config runs alongside the app it configures, so give it its own id\n // namespace — sharing the app's slug would make the two indistinguishable here.\n const id = config ? `config:${config.appType}` : workbenchApp?.slug\n // Identity is resolved and the reference composed here, so the workbench reads\n // both off the registry entry instead of recomposing them. Name defaults to the\n // slug, mirroring brett.\n const name = workbenchApp?.name ?? workbenchApp?.slug\n const reference =\n workbenchApp && name\n ? // No workbench app is a singleton now that the only one (the Media Library)\n // is a config, not an app — so its reference is always `<org>/<name>`.\n applicationReference({\n isSingleton: false,\n name,\n organizationId: workbenchApp.organizationId,\n })\n : undefined\n\n // Separate namespaces mean a shared id is a genuine duplicate, so the gate is\n // a plain id match — no config-vs-app role left to reconcile.\n const devServer = id ? getRegisteredServers().find((server) => server.id === id) : undefined\n\n if (id && devServer) {\n output.error(\n `\"${id}\" is already served by another dev server running on port ${devServer.port}, ` +\n \"so the workbench can't tell them apart and this one stays out of it. Stop that server first.\",\n {exit: false},\n )\n return {close: async () => {}}\n }\n\n const registration = registerDevServer({\n configs,\n host: appHost,\n id,\n interfaces,\n name,\n port: appPort,\n projectId: cliConfig?.api?.projectId,\n reference,\n type: isApp ? 'coreApp' : 'studio',\n workDir,\n })\n\n const exposesSet = trackExposesSet({configs, interfaces})\n\n const watcher = await startDevManifestWatcher({\n // Re-derive every pass (don't omit): the registry patch is a shallow merge,\n // so omitting would wipe the registered set.\n extract: async (params) => {\n const nextConfig = await getCliConfigUncached(params.workDir)\n reportConfigErrors(nextConfig.app, output)\n return {\n configs: await deriveConfigs(nextConfig),\n interfaces: deriveInterfaces(nextConfig.app, {isApp}),\n manifest: await extractManifest({...params, applicationId: id}),\n }\n },\n // A studio's root resolves to `sanity.config.*` but its interfaces live in\n // `sanity.cli.*` — watch that too. Apps already root at `sanity.cli.*`.\n extraWatchFilenames: isApp ? undefined : ['sanity.cli.js', 'sanity.cli.ts'],\n output,\n update: async (patch) => {\n if (\n !exposesSet.changed({\n configs: patch.configs,\n interfaces: patch.interfaces,\n })\n ) {\n registration.update(patch)\n return\n }\n // Rebuild the remote *before* patching the registry — the patch reloads the\n // page, which must re-fetch a remote that already exposes the new interface.\n const rebuiltServer = await onInterfaceSetChange?.()\n // Commit only after a successful rebuild, so a thrown one retries next pass.\n exposesSet.commit({\n configs: patch.configs,\n interfaces: patch.interfaces,\n })\n // The recreated server can bind a different port (non-strict ports).\n registration.update(rebuiltServer ? {...patch, ...serverAddress(rebuiltServer)} : patch)\n },\n workDir,\n })\n\n return {\n close: async () => {\n registration.release()\n await watcher.close()\n },\n }\n}\n"],"names":["getCliConfigUncached","applicationReference","isWorkbenchApp","isWorkbenchConfig","deriveInterfaces","resolveWorkbenchConfig","formatWorkbenchAppErrors","validateWorkbenchApp","deriveConfigs","trackExposesSet","getRegisteredServers","registerDevServer","startDevManifestWatcher","reportConfigErrors","app","output","errors","length","warn","serverAddress","server","resolvedHost","config","host","addr","httpServer","address","port","startDevServerRegistration","options","cliConfig","extractManifest","isApp","onInterfaceSetChange","workDir","appHost","appPort","interfaces","configs","workbenchApp","undefined","id","appType","slug","name","reference","isSingleton","organizationId","devServer","find","error","exit","close","registration","projectId","api","type","exposesSet","watcher","extract","params","nextConfig","manifest","applicationId","extraWatchFilenames","update","patch","changed","rebuiltServer","commit","release"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/actions/dev/startWorkbenchDev.ts"],"sourcesContent":["import {styleText} from 'node:util'\n\nimport {type CliConfig, type Output} from '@sanity/cli-core'\n\nimport {createServerLifecycle, toDisplayHost} from '../../util/serverOrchestration.js'\nimport {type AppServerResult, startAppServerSupervisor} from './appServerSupervisor.js'\nimport {type DevServerManifest} from './registry.js'\nimport {startDevServerRegistration} from './startDevServerRegistration.js'\nimport {\n startWorkbenchDevServer,\n startWorkbenchRemoteCoordinator,\n} from './startWorkbenchDevServer.js'\n\nexport interface StartWorkbenchDevOptions {\n /** Directory for the workbench Vite server's dependency cache. */\n cacheDir: string\n /** CLI-domain `app.id`/`deployment.appId` deprecation check, run before registering. */\n checkForDeprecatedAppId: () => void\n cliConfig: CliConfig\n /** Extract the project manifest to inline into the registry (studio-vs-app handled by the CLI). */\n extractManifest: (params: {\n configPath: string\n workDir: string\n }) => Promise<DevServerManifest['manifest']>\n httpHost: string | undefined\n httpPort: number\n isApp: boolean\n output: Output\n reactStrictMode: boolean\n /** Start the app/studio dev server — the CLI owns the server, this orchestrates it. */\n startAppServer: (params: {\n announceUrl: boolean\n cliConfig: CliConfig\n httpPort: number\n }) => Promise<AppServerResult>\n workDir: string\n}\n\n/**\n * Orchestrate the dev servers a workbench project needs: a singleton workbench\n * Vite server plus the app/studio dev server it renders, wired to the dev-server\n * registry so view/service edits re-sync live.\n *\n * A running workbench claims the configured port, so the app server binds the\n * next one. If the workbench can't start (package or port unavailable), the app\n * server falls back to the configured port and announces its own URL, exactly as\n * a plain `sanity dev` would.\n */\nexport async function startWorkbenchDev(\n options: StartWorkbenchDevOptions,\n): Promise<{close: () => Promise<void>}> {\n const {\n cacheDir,\n checkForDeprecatedAppId,\n cliConfig,\n extractManifest,\n httpHost,\n httpPort,\n isApp,\n output,\n reactStrictMode,\n startAppServer,\n workDir,\n } = options\n\n // The remote can't render itself, so it runs as a plain app server (not the\n // shell) that still claims the lock and bridges the registry, so app\n // `sanity dev`s register into it.\n if (process.env.SANITY_INTERNAL_IS_WORKBENCH_REMOTE === 'true') {\n const remote = await startAppServer({announceUrl: true, cliConfig, httpPort})\n if (!remote.started) return {close: async () => {}}\n\n const addr = remote.server.httpServer?.address()\n const port =\n (typeof addr === 'object' && addr ? addr.port : remote.server.config.server.port) ?? httpPort\n const coordinator = startWorkbenchRemoteCoordinator({httpHost, port, server: remote.server})\n\n return {\n close: async () => {\n await coordinator.close()\n await remote.close()\n },\n }\n }\n\n // Unwound in reverse on any failure or on close(): the watcher stops before\n // the app server, and the supervisor waits out an in-flight rebuild.\n const {close, closers, installSignalHandlers} = createServerLifecycle()\n\n const workbench = await startWorkbenchDevServer({\n cacheDir,\n cliConfig,\n httpHost,\n httpPort,\n mode: 'development',\n output,\n reactStrictMode,\n workDir,\n })\n closers.push(workbench.close)\n\n // A running workbench owns the configured port; the app server takes the next.\n // Without one it claims the configured port and announces its own URL.\n const appPort = workbench.workbenchAvailable ? workbench.workbenchPort + 1 : httpPort\n const announceUrl = !workbench.workbenchAvailable\n\n const supervised = await startAppServerSupervisor({\n cliConfig,\n start: (config) => startAppServer({announceUrl, cliConfig: config, httpPort: appPort}),\n workDir,\n }).catch(async (err) => {\n await close()\n throw err\n })\n\n if (!supervised.started) {\n // The app server already reported why (e.g. missing organization id). Hand\n // back a close that releases the workbench lock; nothing else came up.\n return {close}\n }\n const {supervisor} = supervised\n closers.push(supervisor.close)\n\n try {\n // The deprecated-id check and manifest extractor are CLI-domain, injected here.\n checkForDeprecatedAppId()\n const registration = await startDevServerRegistration({\n cliConfig,\n extractManifest,\n isApp,\n onInterfaceSetChange: () => supervisor.rebuild(),\n output,\n server: supervisor.server,\n workDir,\n })\n closers.push(registration.close)\n } catch (err) {\n // Registration runs after both servers are up; a failure here would leak the\n // workbench lock and dev servers without this teardown.\n await close()\n throw err\n }\n\n if (workbench.workbenchAvailable) {\n const workbenchUrl = `http://${toDisplayHost(workbench.httpHost)}:${workbench.workbenchPort}`\n const addr = supervisor.server.httpServer?.address()\n const port = typeof addr === 'object' && addr ? addr.port : supervisor.server.config.server.port\n output.log(\n `Workbench dev server started at ${styleText(['blue', 'underline'], workbenchUrl)} (app on port ${port})`,\n )\n }\n\n installSignalHandlers()\n\n return {close}\n}\n"],"names":["styleText","createServerLifecycle","toDisplayHost","startAppServerSupervisor","startDevServerRegistration","startWorkbenchDevServer","startWorkbenchRemoteCoordinator","startWorkbenchDev","options","cacheDir","checkForDeprecatedAppId","cliConfig","extractManifest","httpHost","httpPort","isApp","output","reactStrictMode","startAppServer","workDir","process","env","SANITY_INTERNAL_IS_WORKBENCH_REMOTE","remote","announceUrl","started","close","addr","server","httpServer","address","port","config","coordinator","closers","installSignalHandlers","workbench","mode","push","appPort","workbenchAvailable","workbenchPort","supervised","start","catch","err","supervisor","registration","onInterfaceSetChange","rebuild","workbenchUrl","log"],"mappings":"AAAA,SAAQA,SAAS,QAAO,YAAW;AAInC,SAAQC,qBAAqB,EAAEC,aAAa,QAAO,oCAAmC;AACtF,SAA8BC,wBAAwB,QAAO,2BAA0B;AAEvF,SAAQC,0BAA0B,QAAO,kCAAiC;AAC1E,SACEC,uBAAuB,EACvBC,+BAA+B,QAC1B,+BAA8B;
|
|
1
|
+
{"version":3,"sources":["../../../src/actions/dev/startWorkbenchDev.ts"],"sourcesContent":["import {styleText} from 'node:util'\n\nimport {type CliConfig, type Output} from '@sanity/cli-core'\n\nimport {createServerLifecycle, toDisplayHost} from '../../util/serverOrchestration.js'\nimport {type AppServerResult, startAppServerSupervisor} from './appServerSupervisor.js'\nimport {type DevServerManifest} from './registry.js'\nimport {startDevServerRegistration} from './startDevServerRegistration.js'\nimport {\n startWorkbenchDevServer,\n startWorkbenchRemoteCoordinator,\n} from './startWorkbenchDevServer.js'\n\nexport interface StartWorkbenchDevOptions {\n /** Directory for the workbench Vite server's dependency cache. */\n cacheDir: string\n /** CLI-domain `app.id`/`deployment.appId` deprecation check, run before registering. */\n checkForDeprecatedAppId: () => void\n cliConfig: CliConfig\n /** Extract the project manifest to inline into the registry (studio-vs-app handled by the CLI). */\n extractManifest: (params: {\n applicationId?: string\n configPath: string\n workDir: string\n }) => Promise<DevServerManifest['manifest']>\n httpHost: string | undefined\n httpPort: number\n isApp: boolean\n output: Output\n reactStrictMode: boolean\n /** Start the app/studio dev server — the CLI owns the server, this orchestrates it. */\n startAppServer: (params: {\n announceUrl: boolean\n cliConfig: CliConfig\n httpPort: number\n }) => Promise<AppServerResult>\n workDir: string\n}\n\n/**\n * Orchestrate the dev servers a workbench project needs: a singleton workbench\n * Vite server plus the app/studio dev server it renders, wired to the dev-server\n * registry so view/service edits re-sync live.\n *\n * A running workbench claims the configured port, so the app server binds the\n * next one. If the workbench can't start (package or port unavailable), the app\n * server falls back to the configured port and announces its own URL, exactly as\n * a plain `sanity dev` would.\n */\nexport async function startWorkbenchDev(\n options: StartWorkbenchDevOptions,\n): Promise<{close: () => Promise<void>}> {\n const {\n cacheDir,\n checkForDeprecatedAppId,\n cliConfig,\n extractManifest,\n httpHost,\n httpPort,\n isApp,\n output,\n reactStrictMode,\n startAppServer,\n workDir,\n } = options\n\n // The remote can't render itself, so it runs as a plain app server (not the\n // shell) that still claims the lock and bridges the registry, so app\n // `sanity dev`s register into it.\n if (process.env.SANITY_INTERNAL_IS_WORKBENCH_REMOTE === 'true') {\n const remote = await startAppServer({announceUrl: true, cliConfig, httpPort})\n if (!remote.started) return {close: async () => {}}\n\n const addr = remote.server.httpServer?.address()\n const port =\n (typeof addr === 'object' && addr ? addr.port : remote.server.config.server.port) ?? httpPort\n const coordinator = startWorkbenchRemoteCoordinator({httpHost, port, server: remote.server})\n\n return {\n close: async () => {\n await coordinator.close()\n await remote.close()\n },\n }\n }\n\n // Unwound in reverse on any failure or on close(): the watcher stops before\n // the app server, and the supervisor waits out an in-flight rebuild.\n const {close, closers, installSignalHandlers} = createServerLifecycle()\n\n const workbench = await startWorkbenchDevServer({\n cacheDir,\n cliConfig,\n httpHost,\n httpPort,\n mode: 'development',\n output,\n reactStrictMode,\n workDir,\n })\n closers.push(workbench.close)\n\n // A running workbench owns the configured port; the app server takes the next.\n // Without one it claims the configured port and announces its own URL.\n const appPort = workbench.workbenchAvailable ? workbench.workbenchPort + 1 : httpPort\n const announceUrl = !workbench.workbenchAvailable\n\n const supervised = await startAppServerSupervisor({\n cliConfig,\n start: (config) => startAppServer({announceUrl, cliConfig: config, httpPort: appPort}),\n workDir,\n }).catch(async (err) => {\n await close()\n throw err\n })\n\n if (!supervised.started) {\n // The app server already reported why (e.g. missing organization id). Hand\n // back a close that releases the workbench lock; nothing else came up.\n return {close}\n }\n const {supervisor} = supervised\n closers.push(supervisor.close)\n\n try {\n // The deprecated-id check and manifest extractor are CLI-domain, injected here.\n checkForDeprecatedAppId()\n const registration = await startDevServerRegistration({\n cliConfig,\n extractManifest,\n isApp,\n onInterfaceSetChange: () => supervisor.rebuild(),\n output,\n server: supervisor.server,\n workDir,\n })\n closers.push(registration.close)\n } catch (err) {\n // Registration runs after both servers are up; a failure here would leak the\n // workbench lock and dev servers without this teardown.\n await close()\n throw err\n }\n\n if (workbench.workbenchAvailable) {\n const workbenchUrl = `http://${toDisplayHost(workbench.httpHost)}:${workbench.workbenchPort}`\n const addr = supervisor.server.httpServer?.address()\n const port = typeof addr === 'object' && addr ? addr.port : supervisor.server.config.server.port\n output.log(\n `Workbench dev server started at ${styleText(['blue', 'underline'], workbenchUrl)} (app on port ${port})`,\n )\n }\n\n installSignalHandlers()\n\n return {close}\n}\n"],"names":["styleText","createServerLifecycle","toDisplayHost","startAppServerSupervisor","startDevServerRegistration","startWorkbenchDevServer","startWorkbenchRemoteCoordinator","startWorkbenchDev","options","cacheDir","checkForDeprecatedAppId","cliConfig","extractManifest","httpHost","httpPort","isApp","output","reactStrictMode","startAppServer","workDir","process","env","SANITY_INTERNAL_IS_WORKBENCH_REMOTE","remote","announceUrl","started","close","addr","server","httpServer","address","port","config","coordinator","closers","installSignalHandlers","workbench","mode","push","appPort","workbenchAvailable","workbenchPort","supervised","start","catch","err","supervisor","registration","onInterfaceSetChange","rebuild","workbenchUrl","log"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/actions/preview/startWorkbenchPreview.ts"],"sourcesContent":["import {readFile} from 'node:fs/promises'\nimport path from 'node:path'\nimport {styleText} from 'node:util'\n\nimport {type CliConfig, findProjectRoot, type Output} from '@sanity/cli-core'\n\nimport {buildAppId, SANITY_APP_ID_FILE} from '../../appId.js'\nimport {deriveInterfaces} from '../../deriveInterfaces.js'\nimport {resolveWorkbenchApp} from '../../resolveWorkbenchApp.js'\nimport {createServerLifecycle, toDisplayHost} from '../../util/serverOrchestration.js'\nimport {deriveConfigs} from '../dev/deriveConfigs.js'\nimport {type DevServerManifest, registerDevServer} from '../dev/registry.js'\nimport {startWorkbenchDevServer} from '../dev/startWorkbenchDevServer.js'\nimport {serveBuiltApplication} from './serveBuiltApplication.js'\n\nexport interface StartWorkbenchPreviewOptions {\n /** Directory for the workbench Vite server's dependency cache. */\n cacheDir: string\n /** CLI-domain `app.id`/`deployment.appId` deprecation check, run before registering. */\n checkForDeprecatedAppId: () => void\n cliConfig: CliConfig\n /** Extract the project manifest to inline into the registry (studio-vs-app handled by the CLI). */\n extractManifest: (params: {\n configPath: string\n workDir: string\n }) => Promise<DevServerManifest['manifest']>\n httpHost: string\n httpPort: number\n isApp: boolean\n /** The built `dist` directory to serve as the federation remote. */\n outDir: string\n output: Output\n reactStrictMode: boolean\n workDir: string\n}\n\n/**\n * `sanity start` for a workbench app: serve a production build the way dev serves\n * a live one. The same singleton workbench shell renders it and the same registry\n * advertises it — only the remote differs, static files from the build output\n * instead of a live Vite dev server. There's no config watcher or rebuild: a\n * build is fixed, so nothing re-syncs.\n *\n * A running workbench claims the configured port, so the built remote binds the\n * next one. Without one the remote takes the configured port and announces its\n * own URL.\n */\nexport async function startWorkbenchPreview(\n options: StartWorkbenchPreviewOptions,\n): Promise<{close: () => Promise<void>}> {\n const {\n cacheDir,\n checkForDeprecatedAppId,\n cliConfig,\n extractManifest,\n httpHost,\n httpPort,\n isApp,\n outDir,\n output,\n reactStrictMode,\n workDir,\n } = options\n\n const {close, closers, installSignalHandlers} = createServerLifecycle()\n\n const workbench = await startWorkbenchDevServer({\n cacheDir,\n cliConfig,\n httpHost,\n httpPort,\n mode: 'preview',\n output,\n reactStrictMode,\n workDir,\n })\n closers.push(workbench.close)\n\n const remotePort = workbench.workbenchAvailable ? workbench.workbenchPort + 1 : httpPort\n\n const remote = await serveBuiltApplication({\n cacheDir,\n httpHost,\n httpPort: remotePort,\n outDir,\n workDir,\n }).catch(async (err) => {\n await close()\n throw err\n })\n closers.push(remote.close)\n\n try {\n // Callers provide CLI-only validation and manifest extraction to keep them\n // out of workbench-cli.\n checkForDeprecatedAppId()\n const configPath = (await findProjectRoot(workDir)).path\n const workbench = resolveWorkbenchApp(cliConfig)\n\n if (!workbench) throw new Error('`sanity start` was invoked in a non-workbench application')\n const inlinedId = await readInlinedAppId(outDir)\n const configs = await deriveConfigs(cliConfig)\n const id = inlinedId ?? (await buildAppId(workbench))\n const registration = registerDevServer({\n configs,\n host: remote.host,\n id,\n interfaces: deriveInterfaces(cliConfig.app, {isApp}),\n manifest: await extractManifest({configPath, workDir}),\n manifestUpdatedAt: new Date().toISOString(),\n port: remote.port,\n projectId: cliConfig?.api?.projectId,\n type: isApp ? 'coreApp' : 'studio',\n workDir,\n })\n closers.push(async () => registration.release())\n } catch (err) {\n await close()\n throw err\n }\n\n if (workbench.workbenchAvailable) {\n const workbenchUrl = `http://${toDisplayHost(workbench.httpHost)}:${workbench.workbenchPort}`\n output.log(\n `Workbench preview server started at ${styleText(['blue', 'underline'], workbenchUrl)} (serving build on port ${remote.port})`,\n )\n } else {\n const remoteUrl = `http://${toDisplayHost(remote.host)}:${remote.port}`\n output.log(`Serving build at ${styleText(['blue', 'underline'], remoteUrl)}`)\n }\n\n installSignalHandlers()\n\n return {close}\n}\n\n/** The id the build inlined into its bundle, or undefined when absent. */\nasync function readInlinedAppId(outDir: string): Promise<string | undefined> {\n try {\n return (await readFile(path.join(outDir, SANITY_APP_ID_FILE), 'utf8')).trim() || undefined\n } catch {\n return undefined\n }\n}\n"],"names":["readFile","path","styleText","findProjectRoot","buildAppId","SANITY_APP_ID_FILE","deriveInterfaces","resolveWorkbenchApp","createServerLifecycle","toDisplayHost","deriveConfigs","registerDevServer","startWorkbenchDevServer","serveBuiltApplication","startWorkbenchPreview","options","cacheDir","checkForDeprecatedAppId","cliConfig","extractManifest","httpHost","httpPort","isApp","outDir","output","reactStrictMode","workDir","close","closers","installSignalHandlers","workbench","mode","push","remotePort","workbenchAvailable","workbenchPort","remote","catch","err","configPath","Error","inlinedId","readInlinedAppId","configs","id","registration","host","interfaces","app","manifest","manifestUpdatedAt","Date","toISOString","port","projectId","api","type","release","workbenchUrl","log","remoteUrl","join","trim","undefined"],"mappings":"AAAA,SAAQA,QAAQ,QAAO,mBAAkB;AACzC,OAAOC,UAAU,YAAW;AAC5B,SAAQC,SAAS,QAAO,YAAW;AAEnC,SAAwBC,eAAe,QAAoB,mBAAkB;AAE7E,SAAQC,UAAU,EAAEC,kBAAkB,QAAO,iBAAgB;AAC7D,SAAQC,gBAAgB,QAAO,4BAA2B;AAC1D,SAAQC,mBAAmB,QAAO,+BAA8B;AAChE,SAAQC,qBAAqB,EAAEC,aAAa,QAAO,oCAAmC;AACtF,SAAQC,aAAa,QAAO,0BAAyB;AACrD,SAAgCC,iBAAiB,QAAO,qBAAoB;AAC5E,SAAQC,uBAAuB,QAAO,oCAAmC;AACzE,SAAQC,qBAAqB,QAAO,6BAA4B;
|
|
1
|
+
{"version":3,"sources":["../../../src/actions/preview/startWorkbenchPreview.ts"],"sourcesContent":["import {readFile} from 'node:fs/promises'\nimport path from 'node:path'\nimport {styleText} from 'node:util'\n\nimport {type CliConfig, findProjectRoot, type Output} from '@sanity/cli-core'\n\nimport {buildAppId, SANITY_APP_ID_FILE} from '../../appId.js'\nimport {deriveInterfaces} from '../../deriveInterfaces.js'\nimport {resolveWorkbenchApp} from '../../resolveWorkbenchApp.js'\nimport {createServerLifecycle, toDisplayHost} from '../../util/serverOrchestration.js'\nimport {deriveConfigs} from '../dev/deriveConfigs.js'\nimport {type DevServerManifest, registerDevServer} from '../dev/registry.js'\nimport {startWorkbenchDevServer} from '../dev/startWorkbenchDevServer.js'\nimport {serveBuiltApplication} from './serveBuiltApplication.js'\n\nexport interface StartWorkbenchPreviewOptions {\n /** Directory for the workbench Vite server's dependency cache. */\n cacheDir: string\n /** CLI-domain `app.id`/`deployment.appId` deprecation check, run before registering. */\n checkForDeprecatedAppId: () => void\n cliConfig: CliConfig\n /** Extract the project manifest to inline into the registry (studio-vs-app handled by the CLI). */\n extractManifest: (params: {\n applicationId?: string\n configPath: string\n workDir: string\n }) => Promise<DevServerManifest['manifest']>\n httpHost: string\n httpPort: number\n isApp: boolean\n /** The built `dist` directory to serve as the federation remote. */\n outDir: string\n output: Output\n reactStrictMode: boolean\n workDir: string\n}\n\n/**\n * `sanity start` for a workbench app: serve a production build the way dev serves\n * a live one. The same singleton workbench shell renders it and the same registry\n * advertises it — only the remote differs, static files from the build output\n * instead of a live Vite dev server. There's no config watcher or rebuild: a\n * build is fixed, so nothing re-syncs.\n *\n * A running workbench claims the configured port, so the built remote binds the\n * next one. Without one the remote takes the configured port and announces its\n * own URL.\n */\nexport async function startWorkbenchPreview(\n options: StartWorkbenchPreviewOptions,\n): Promise<{close: () => Promise<void>}> {\n const {\n cacheDir,\n checkForDeprecatedAppId,\n cliConfig,\n extractManifest,\n httpHost,\n httpPort,\n isApp,\n outDir,\n output,\n reactStrictMode,\n workDir,\n } = options\n\n const {close, closers, installSignalHandlers} = createServerLifecycle()\n\n const workbench = await startWorkbenchDevServer({\n cacheDir,\n cliConfig,\n httpHost,\n httpPort,\n mode: 'preview',\n output,\n reactStrictMode,\n workDir,\n })\n closers.push(workbench.close)\n\n const remotePort = workbench.workbenchAvailable ? workbench.workbenchPort + 1 : httpPort\n\n const remote = await serveBuiltApplication({\n cacheDir,\n httpHost,\n httpPort: remotePort,\n outDir,\n workDir,\n }).catch(async (err) => {\n await close()\n throw err\n })\n closers.push(remote.close)\n\n try {\n // Callers provide CLI-only validation and manifest extraction to keep them\n // out of workbench-cli.\n checkForDeprecatedAppId()\n const configPath = (await findProjectRoot(workDir)).path\n const workbench = resolveWorkbenchApp(cliConfig)\n\n if (!workbench) throw new Error('`sanity start` was invoked in a non-workbench application')\n const inlinedId = await readInlinedAppId(outDir)\n const configs = await deriveConfigs(cliConfig)\n const id = inlinedId ?? (await buildAppId(workbench))\n const registration = registerDevServer({\n configs,\n host: remote.host,\n id,\n interfaces: deriveInterfaces(cliConfig.app, {isApp}),\n manifest: await extractManifest({applicationId: id, configPath, workDir}),\n manifestUpdatedAt: new Date().toISOString(),\n port: remote.port,\n projectId: cliConfig?.api?.projectId,\n type: isApp ? 'coreApp' : 'studio',\n workDir,\n })\n closers.push(async () => registration.release())\n } catch (err) {\n await close()\n throw err\n }\n\n if (workbench.workbenchAvailable) {\n const workbenchUrl = `http://${toDisplayHost(workbench.httpHost)}:${workbench.workbenchPort}`\n output.log(\n `Workbench preview server started at ${styleText(['blue', 'underline'], workbenchUrl)} (serving build on port ${remote.port})`,\n )\n } else {\n const remoteUrl = `http://${toDisplayHost(remote.host)}:${remote.port}`\n output.log(`Serving build at ${styleText(['blue', 'underline'], remoteUrl)}`)\n }\n\n installSignalHandlers()\n\n return {close}\n}\n\n/** The id the build inlined into its bundle, or undefined when absent. */\nasync function readInlinedAppId(outDir: string): Promise<string | undefined> {\n try {\n return (await readFile(path.join(outDir, SANITY_APP_ID_FILE), 'utf8')).trim() || undefined\n } catch {\n return undefined\n }\n}\n"],"names":["readFile","path","styleText","findProjectRoot","buildAppId","SANITY_APP_ID_FILE","deriveInterfaces","resolveWorkbenchApp","createServerLifecycle","toDisplayHost","deriveConfigs","registerDevServer","startWorkbenchDevServer","serveBuiltApplication","startWorkbenchPreview","options","cacheDir","checkForDeprecatedAppId","cliConfig","extractManifest","httpHost","httpPort","isApp","outDir","output","reactStrictMode","workDir","close","closers","installSignalHandlers","workbench","mode","push","remotePort","workbenchAvailable","workbenchPort","remote","catch","err","configPath","Error","inlinedId","readInlinedAppId","configs","id","registration","host","interfaces","app","manifest","applicationId","manifestUpdatedAt","Date","toISOString","port","projectId","api","type","release","workbenchUrl","log","remoteUrl","join","trim","undefined"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sanity/workbench-cli",
|
|
3
|
-
"version": "2.2.
|
|
3
|
+
"version": "2.2.3",
|
|
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",
|
|
@@ -66,7 +66,7 @@
|
|
|
66
66
|
"tar-fs": "^3.1.2",
|
|
67
67
|
"vite": "^8.2.1",
|
|
68
68
|
"zod": "^4.4.3",
|
|
69
|
-
"@sanity/cli-core": "^3.
|
|
69
|
+
"@sanity/cli-core": "^3.5.0"
|
|
70
70
|
},
|
|
71
71
|
"devDependencies": {
|
|
72
72
|
"@eslint/compat": "^2.1.0",
|
|
@@ -80,8 +80,8 @@
|
|
|
80
80
|
"publint": "^0.3.21",
|
|
81
81
|
"typescript": "^6.0.3",
|
|
82
82
|
"vitest": "^4.1.11",
|
|
83
|
-
"@repo/tsconfig": "3.70.0",
|
|
84
83
|
"@repo/package.config": "0.0.1",
|
|
84
|
+
"@repo/tsconfig": "3.70.0",
|
|
85
85
|
"@sanity/eslint-config-cli": "^1.1.3"
|
|
86
86
|
},
|
|
87
87
|
"engines": {
|