@sanity/cli 7.4.0 → 7.4.1
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/README.md +25 -1
- package/dist/actions/build/buildApp.js +19 -14
- package/dist/actions/build/buildApp.js.map +1 -1
- package/dist/actions/build/buildStaticFiles.js +1 -1
- package/dist/actions/build/buildStaticFiles.js.map +1 -1
- package/dist/actions/build/buildStudio.js +22 -18
- package/dist/actions/build/buildStudio.js.map +1 -1
- package/dist/actions/dev/devAction.js +46 -197
- package/dist/actions/dev/devAction.js.map +1 -1
- package/dist/actions/dev/servers/getDevServerConfig.js +1 -1
- package/dist/actions/dev/servers/getDevServerConfig.js.map +1 -1
- package/dist/actions/dev/servers/startAppDevServer.js +18 -9
- package/dist/actions/dev/servers/startAppDevServer.js.map +1 -1
- package/dist/actions/dev/servers/startStudioDevServer.js +2 -2
- package/dist/actions/dev/servers/startStudioDevServer.js.map +1 -1
- package/dist/actions/dev/types.js.map +1 -1
- package/dist/actions/{dev/registration/extractDevServerManifest.js → manifest/extractStudioManifest.js} +3 -3
- package/dist/actions/manifest/extractStudioManifest.js.map +1 -0
- package/dist/actions/mcp/editorConfigs.js +8 -4
- package/dist/actions/mcp/editorConfigs.js.map +1 -1
- package/dist/commands/datasets/copy.js +17 -19
- package/dist/commands/datasets/copy.js.map +1 -1
- package/dist/commands/datasets/import.js +11 -15
- package/dist/commands/datasets/import.js.map +1 -1
- package/dist/commands/doctor.js +9 -9
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/telemetry/disable.js +3 -3
- package/dist/commands/telemetry/disable.js.map +1 -1
- package/dist/commands/telemetry/enable.js +3 -3
- package/dist/commands/telemetry/enable.js.map +1 -1
- package/dist/commands/telemetry/status.js +2 -2
- package/dist/commands/telemetry/status.js.map +1 -1
- package/dist/exports/_internal.d.ts +4 -47
- package/dist/exports/_internal.js +1 -1
- package/dist/exports/_internal.js.map +1 -1
- package/dist/server/devServer.js +1 -1
- package/dist/server/devServer.js.map +1 -1
- package/dist/util/compareDependencyVersions.js.map +1 -1
- package/oclif.manifest.json +1 -1
- package/package.json +6 -5
- package/dist/actions/build/getEnvironmentVariables.js +0 -54
- package/dist/actions/build/getEnvironmentVariables.js.map +0 -1
- package/dist/actions/dev/registration/deriveInterfaces.js +0 -46
- package/dist/actions/dev/registration/deriveInterfaces.js.map +0 -1
- package/dist/actions/dev/registration/extractDevServerManifest.js.map +0 -1
- package/dist/actions/dev/registration/interfaceSetId.js +0 -41
- package/dist/actions/dev/registration/interfaceSetId.js.map +0 -1
- package/dist/actions/dev/registration/startDevManifestWatcher.js +0 -104
- package/dist/actions/dev/registration/startDevManifestWatcher.js.map +0 -1
- package/dist/actions/dev/registration/startDevServerRegistration.js +0 -121
- package/dist/actions/dev/registration/startDevServerRegistration.js.map +0 -1
- package/dist/actions/dev/workbench/startWorkbenchDevServer.js +0 -276
- package/dist/actions/dev/workbench/startWorkbenchDevServer.js.map +0 -1
- package/dist/actions/dev/workbench/writeWorkbenchRuntime.js +0 -66
- package/dist/actions/dev/workbench/writeWorkbenchRuntime.js.map +0 -1
|
@@ -1,34 +1,20 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { SANITY_CACHE_DIR } from '@sanity/cli-build/_internal/build';
|
|
2
|
+
import { isWorkbenchApp } from '@sanity/cli-core';
|
|
3
|
+
import { checkForDeprecatedAppId, getAppId } from '../../util/appId.js';
|
|
3
4
|
import { getSharedServerConfig } from '../../util/getSharedServerConfig.js';
|
|
4
|
-
import {
|
|
5
|
+
import { resolveReactStrictMode } from '../../util/resolveReactStrictMode.js';
|
|
6
|
+
import { extractCoreAppManifest } from '../manifest/extractCoreAppManifest.js';
|
|
7
|
+
import { extractStudioManifest } from '../manifest/extractStudioManifest.js';
|
|
5
8
|
import { startAppDevServer } from './servers/startAppDevServer.js';
|
|
6
9
|
import { startStudioDevServer } from './servers/startStudioDevServer.js';
|
|
7
|
-
import { startWorkbenchDevServer } from './workbench/startWorkbenchDevServer.js';
|
|
8
10
|
const noop = async ()=>{};
|
|
9
11
|
/**
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
|
|
14
|
-
// Bind-only addresses ('0.0.0.0', '::') aren't routable URLs in every
|
|
15
|
-
// browser (notably on Windows), so the displayed URL falls back to
|
|
16
|
-
// localhost. The bind address itself is untouched — listening and the
|
|
17
|
-
// lock file keep whatever the user configured.
|
|
18
|
-
function toDisplayHost(host) {
|
|
19
|
-
if (!host || host === '0.0.0.0' || host === '::' || host === '[::]') {
|
|
20
|
-
return 'localhost';
|
|
21
|
-
}
|
|
22
|
-
return host;
|
|
23
|
-
}
|
|
24
|
-
/**
|
|
25
|
-
* Orchestrates the dev servers required by the process. It will attempt to run a workbench
|
|
26
|
-
* dev-server and, if successful, will run the app/studio dev server on the next available port.
|
|
27
|
-
* If the workbench dev-server fails to start for an expected reason, e.g. because there is already
|
|
28
|
-
* a workbench instance running or the workbench package is unavailable, it will run the app/studio
|
|
29
|
-
* dev server on the configured port.
|
|
12
|
+
* Entry point for `sanity dev`. A plain studio/app starts a single dev server, as
|
|
13
|
+
* before workbench existed. A workbench app (via `unstable_defineApp`) delegates to
|
|
14
|
+
* `@sanity/workbench-cli`, injecting the CLI-domain pieces (app server, manifest
|
|
15
|
+
* extraction, app id) and loading the package lazily so plain projects never do.
|
|
30
16
|
*/ export async function devAction(options) {
|
|
31
|
-
const { cliConfig, flags, output, workDir } = options;
|
|
17
|
+
const { cliConfig, flags, isApp, output, workDir } = options;
|
|
32
18
|
const { httpHost, httpPort } = getSharedServerConfig({
|
|
33
19
|
cliConfig,
|
|
34
20
|
flags: {
|
|
@@ -37,185 +23,48 @@ function toDisplayHost(host) {
|
|
|
37
23
|
},
|
|
38
24
|
workDir
|
|
39
25
|
});
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
httpHost,
|
|
48
|
-
workbenchAvailable: false,
|
|
49
|
-
workbenchPort: httpPort
|
|
50
|
-
} : await startWorkbenchDevServer({
|
|
51
|
-
...options,
|
|
52
|
-
httpHost,
|
|
53
|
-
httpPort
|
|
54
|
-
});
|
|
55
|
-
// A running workbench claims the configured port, so the app server binds the
|
|
56
|
-
// next one — passed explicitly rather than by rewriting the shared flags.
|
|
57
|
-
// Without a workbench the app server resolves its port from flags/env/config
|
|
58
|
-
// downstream, exactly as it did before workbench existed.
|
|
59
|
-
const appOptions = workbenchAvailable ? {
|
|
60
|
-
...options,
|
|
61
|
-
httpPort: workbenchPort + 1,
|
|
62
|
-
workbenchAvailable
|
|
63
|
-
} : {
|
|
64
|
-
...options,
|
|
65
|
-
workbenchAvailable
|
|
66
|
-
};
|
|
67
|
-
let closeAppDevServer = noop;
|
|
68
|
-
// Takes the config as a param so a rebuild can feed a freshly-loaded one.
|
|
69
|
-
const startApp = async (config)=>{
|
|
70
|
-
const result = options.isApp ? await startAppDevServer({
|
|
71
|
-
...appOptions,
|
|
72
|
-
cliConfig: config
|
|
73
|
-
}) : await startStudioDevServer({
|
|
74
|
-
...appOptions,
|
|
75
|
-
cliConfig: config
|
|
26
|
+
// The app/studio server, parameterized per call; `announceUrl` is false when
|
|
27
|
+
// the workbench announces the URL on its behalf.
|
|
28
|
+
const startAppServer = (params)=>(isApp ? startAppDevServer : startStudioDevServer)({
|
|
29
|
+
...options,
|
|
30
|
+
announceUrl: params.announceUrl,
|
|
31
|
+
cliConfig: params.cliConfig,
|
|
32
|
+
httpPort: params.httpPort
|
|
76
33
|
});
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
return {
|
|
90
|
-
close: closeWorkbenchServer
|
|
91
|
-
};
|
|
92
|
-
}
|
|
93
|
-
const { server } = initial;
|
|
94
|
-
// Adding/removing a view or service in `sanity.cli.ts` during dev requires
|
|
95
|
-
// rebuilding the federation remote: its module-federation `exposes` map +
|
|
96
|
-
// codegen artifacts are computed once at server start, so a newly-declared
|
|
97
|
-
// interface has no expose until the server is recreated. `server.restart()`
|
|
98
|
-
// can't do it — it re-uses the inline config — so we tear the app server
|
|
99
|
-
// down and bring it back up with a freshly-loaded config. The workbench page
|
|
100
|
-
// then reloads (driven by the registry watch in the workbench server) to
|
|
101
|
-
// re-fetch the rebuilt remote. A view/service *source* edit doesn't change
|
|
102
|
-
// the interface set, so it stays on the HMR path untouched. Studios declare
|
|
103
|
-
// views/services the same way (only `entry` is rejected, FR-026), so they
|
|
104
|
-
// get the same rebuild. The returned-server / thrown-failed-restart contract
|
|
105
|
-
// is documented on `onInterfaceSetChange` in startDevServerRegistration.
|
|
106
|
-
// Declared ahead of `runRebuild`, which the watcher's initial background
|
|
107
|
-
// extraction can invoke before the statements below it have run.
|
|
108
|
-
let closed = false;
|
|
109
|
-
const runRebuild = async ()=>{
|
|
110
|
-
// The watcher only learns about shutdown when its own close runs, late in
|
|
111
|
-
// the teardown sequence — refuse here so a config save during shutdown
|
|
112
|
-
// can't boot a replacement server nobody owns. Checked before the first
|
|
113
|
-
// await so a rebuild can't start after close() has read `rebuildInFlight`.
|
|
114
|
-
if (closed) {
|
|
115
|
-
throw new Error('Dev server is shutting down');
|
|
116
|
-
}
|
|
117
|
-
const freshConfig = await getCliConfigUncached(workDir);
|
|
118
|
-
await closeAppDevServer();
|
|
119
|
-
const result = await startApp(freshConfig);
|
|
120
|
-
if (!result.started) {
|
|
121
|
-
// The server already reported why (e.g. organizationId was removed).
|
|
122
|
-
throw new Error('Dev server did not restart after the view/service change');
|
|
123
|
-
}
|
|
124
|
-
return result.server;
|
|
125
|
-
};
|
|
126
|
-
// `closeAppDevServer` is repointed at the replacement server only after
|
|
127
|
-
// `startApp` resolves — a close() racing a rebuild would tear down the old
|
|
128
|
-
// (already-closed) server and leave the replacement running with no owner,
|
|
129
|
-
// so close() waits on the rebuild in flight. Rejections are owned by the
|
|
130
|
-
// watcher (warn + retry on next save); the tracked copy swallows them so
|
|
131
|
-
// close() can't reject.
|
|
132
|
-
let rebuildInFlight = Promise.resolve();
|
|
133
|
-
const onInterfaceSetChange = ()=>{
|
|
134
|
-
const rebuild = runRebuild();
|
|
135
|
-
rebuildInFlight = rebuild.catch(()=>{});
|
|
136
|
-
return rebuild;
|
|
137
|
-
};
|
|
138
|
-
// Workbench is opted into solely by calling `unstable_defineApp` — its
|
|
139
|
-
// branded identity is the only signal. The workbench remote is the exception:
|
|
140
|
-
// it's the shell itself, not a dock app, so it never registers into the
|
|
141
|
-
// shared workbench registry.
|
|
142
|
-
let registration;
|
|
143
|
-
try {
|
|
144
|
-
registration = isWorkbenchApp(cliConfig?.app) && !isWorkbenchRemote ? await startDevServerRegistration({
|
|
34
|
+
if (isWorkbenchApp(cliConfig?.app)) {
|
|
35
|
+
// Lazy so a non-workbench `sanity dev` never loads the package. `doImport`
|
|
36
|
+
// is path-based and doesn't apply to a bare specifier.
|
|
37
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
38
|
+
const { startWorkbenchDev } = await import('@sanity/workbench-cli/dev');
|
|
39
|
+
return startWorkbenchDev({
|
|
40
|
+
appId: getAppId(cliConfig),
|
|
41
|
+
cacheDir: `${SANITY_CACHE_DIR}/vite`,
|
|
42
|
+
checkForDeprecatedAppId: ()=>checkForDeprecatedAppId({
|
|
43
|
+
cliConfig,
|
|
44
|
+
output
|
|
45
|
+
}),
|
|
145
46
|
cliConfig,
|
|
146
|
-
isApp:
|
|
147
|
-
|
|
47
|
+
extractManifest: isApp ? ({ workDir: wd })=>extractCoreAppManifest({
|
|
48
|
+
workDir: wd
|
|
49
|
+
}) : (params)=>extractStudioManifest(params),
|
|
50
|
+
httpHost,
|
|
51
|
+
httpPort,
|
|
52
|
+
isApp,
|
|
148
53
|
output,
|
|
149
|
-
|
|
54
|
+
// Runtime template needs a concrete boolean; collapse an unset config to off.
|
|
55
|
+
reactStrictMode: resolveReactStrictMode(cliConfig) ?? false,
|
|
56
|
+
startAppServer,
|
|
150
57
|
workDir
|
|
151
|
-
}) : undefined;
|
|
152
|
-
} catch (err) {
|
|
153
|
-
// Registration runs only after both servers are already up. If it throws
|
|
154
|
-
// (e.g. `deriveInterfaces` rejects), tear them down before rethrowing —
|
|
155
|
-
// otherwise the workbench lock and dev servers leak until the next run.
|
|
156
|
-
await Promise.allSettled([
|
|
157
|
-
closeWorkbenchServer(),
|
|
158
|
-
closeAppDevServer()
|
|
159
|
-
]);
|
|
160
|
-
throw err;
|
|
161
|
-
}
|
|
162
|
-
if (workbenchAvailable) {
|
|
163
|
-
const workbenchUrl = `http://${toDisplayHost(workbenchHost)}:${workbenchPort}`;
|
|
164
|
-
const addr = server.httpServer?.address();
|
|
165
|
-
const appPort = typeof addr === 'object' && addr ? addr.port : server.config.server.port;
|
|
166
|
-
output.log(`Workbench dev server started at ${styleText([
|
|
167
|
-
'blue',
|
|
168
|
-
'underline'
|
|
169
|
-
], workbenchUrl)} (app on port ${appPort})`);
|
|
170
|
-
}
|
|
171
|
-
// Single-flight: SIGINT followed by SIGTERM (each signal has its own `once`
|
|
172
|
-
// handler), or a signal racing the caller's own close(), must share one
|
|
173
|
-
// teardown instead of double-closing every server.
|
|
174
|
-
let closing;
|
|
175
|
-
const close = ()=>{
|
|
176
|
-
closing ??= (async ()=>{
|
|
177
|
-
closed = true;
|
|
178
|
-
process.off('SIGINT', onSignal);
|
|
179
|
-
process.off('SIGTERM', onSignal);
|
|
180
|
-
await rebuildInFlight;
|
|
181
|
-
await Promise.allSettled([
|
|
182
|
-
registration?.close(),
|
|
183
|
-
closeWorkbenchServer(),
|
|
184
|
-
closeAppDevServer()
|
|
185
|
-
]);
|
|
186
|
-
})();
|
|
187
|
-
return closing;
|
|
188
|
-
};
|
|
189
|
-
// Ensure the workbench lock file and registry entries are cleaned up on
|
|
190
|
-
// abrupt shutdown. The registry is self-healing (stale PIDs are pruned on
|
|
191
|
-
// next read), but eager cleanup avoids the detect-prune-retry cycle.
|
|
192
|
-
// Plain projects have no lock or registry entry, so they keep the default
|
|
193
|
-
// signal handling (and exit codes) they had before workbench existed.
|
|
194
|
-
//
|
|
195
|
-
// Trapping the signal disables Node's default exit, and a finished teardown
|
|
196
|
-
// doesn't guarantee an empty event loop (keep-alive sockets, an extraction
|
|
197
|
-
// worker mid-run) — without an explicit exit the process lingers, holding
|
|
198
|
-
// its ports, while the shell prompt returns. Re-raising after teardown
|
|
199
|
-
// restores the default termination (the `once` handler is gone by then),
|
|
200
|
-
// with conventional signal exit semantics.
|
|
201
|
-
const onSignal = (signal)=>{
|
|
202
|
-
// Backstop for a teardown that never settles (a wedged socket or watcher):
|
|
203
|
-
// force the exit once the grace period elapses. Cleared on the normal path
|
|
204
|
-
// so the re-raise fires exactly once; `unref` keeps the timer from holding
|
|
205
|
-
// the process open by itself.
|
|
206
|
-
const graceTimer = setTimeout(()=>process.kill(process.pid, signal), SHUTDOWN_GRACE_MS);
|
|
207
|
-
graceTimer.unref();
|
|
208
|
-
void close().finally(()=>{
|
|
209
|
-
clearTimeout(graceTimer);
|
|
210
|
-
process.kill(process.pid, signal);
|
|
211
58
|
});
|
|
212
|
-
};
|
|
213
|
-
if (workbenchAvailable || registration) {
|
|
214
|
-
process.once('SIGINT', onSignal);
|
|
215
|
-
process.once('SIGTERM', onSignal);
|
|
216
59
|
}
|
|
60
|
+
// Plain non-workbench studio/app: one dev server announcing its own URL.
|
|
61
|
+
const result = await startAppServer({
|
|
62
|
+
announceUrl: true,
|
|
63
|
+
cliConfig,
|
|
64
|
+
httpPort
|
|
65
|
+
});
|
|
217
66
|
return {
|
|
218
|
-
close
|
|
67
|
+
close: result.started ? result.close : noop
|
|
219
68
|
};
|
|
220
69
|
}
|
|
221
70
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/actions/dev/devAction.ts"],"sourcesContent":["import {styleText} from 'node:util'\n\nimport {getCliConfigUncached, isWorkbenchApp} from '@sanity/cli-core'\nimport {type ViteDevServer} from 'vite'\n\nimport {getSharedServerConfig} from '../../util/getSharedServerConfig.js'\nimport {startDevServerRegistration} from './registration/startDevServerRegistration.js'\nimport {startAppDevServer} from './servers/startAppDevServer.js'\nimport {startStudioDevServer} from './servers/startStudioDevServer.js'\nimport {type DevActionOptions, type StartDevServerResult} from './types.js'\nimport {startWorkbenchDevServer} from './workbench/startWorkbenchDevServer.js'\n\nconst noop = async () => {}\n\n/**\n * How long a signal-triggered teardown may run before the process force-exits\n * by re-raising the signal — generous enough for Vite servers and watchers to\n * close, short enough not to strand a backgrounded process holding the ports.\n */\nconst SHUTDOWN_GRACE_MS = 5000\n\n// Bind-only addresses ('0.0.0.0', '::') aren't routable URLs in every\n// browser (notably on Windows), so the displayed URL falls back to\n// localhost. The bind address itself is untouched — listening and the\n// lock file keep whatever the user configured.\nfunction toDisplayHost(host: string | undefined): string {\n if (!host || host === '0.0.0.0' || host === '::' || host === '[::]') {\n return 'localhost'\n }\n return host\n}\n\n/**\n * Orchestrates the dev servers required by the process. It will attempt to run a workbench\n * dev-server and, if successful, will run the app/studio dev server on the next available port.\n * If the workbench dev-server fails to start for an expected reason, e.g. because there is already\n * a workbench instance running or the workbench package is unavailable, it will run the app/studio\n * dev server on the configured port.\n */\nexport async function devAction(options: DevActionOptions): Promise<{close: () => Promise<void>}> {\n const {cliConfig, flags, output, workDir} = options\n\n const {httpHost, httpPort} = getSharedServerConfig({\n cliConfig,\n flags: {host: flags.host, port: flags.port},\n workDir,\n })\n\n /**\n * The workbench remote is the app that renders \"workbench ready\" apps, thereby it can't render itself.\n * But it still wants to be deployed as a singleton in the sanity ecosystem. Therefore, this internal flag\n * allows us to develop the workbench remote correctly – as a standalone app.\n */\n const isWorkbenchRemote =\n isWorkbenchApp(cliConfig?.app) && process.env.SANITY_INTERNAL_IS_WORKBENCH_REMOTE === 'true'\n\n const {\n close: closeWorkbenchServer,\n httpHost: workbenchHost,\n workbenchAvailable,\n workbenchPort,\n } = isWorkbenchRemote\n ? {close: noop, httpHost, workbenchAvailable: false, workbenchPort: httpPort}\n : await startWorkbenchDevServer({...options, httpHost, httpPort})\n\n // A running workbench claims the configured port, so the app server binds the\n // next one — passed explicitly rather than by rewriting the shared flags.\n // Without a workbench the app server resolves its port from flags/env/config\n // downstream, exactly as it did before workbench existed.\n const appOptions: DevActionOptions = workbenchAvailable\n ? {...options, httpPort: workbenchPort + 1, workbenchAvailable}\n : {...options, workbenchAvailable}\n\n let closeAppDevServer: () => Promise<void> = noop\n\n // Takes the config as a param so a rebuild can feed a freshly-loaded one.\n const startApp = async (config: DevActionOptions['cliConfig']): Promise<StartDevServerResult> => {\n const result = options.isApp\n ? await startAppDevServer({...appOptions, cliConfig: config})\n : await startStudioDevServer({...appOptions, cliConfig: config})\n closeAppDevServer = result.started ? result.close : noop\n return result\n }\n\n let initial: StartDevServerResult\n try {\n initial = await startApp(cliConfig)\n } catch (err) {\n await closeWorkbenchServer()\n throw err\n }\n\n if (!initial.started) {\n // The server has already reported why (e.g. missing organization ID).\n return {close: closeWorkbenchServer}\n }\n const {server} = initial\n\n // Adding/removing a view or service in `sanity.cli.ts` during dev requires\n // rebuilding the federation remote: its module-federation `exposes` map +\n // codegen artifacts are computed once at server start, so a newly-declared\n // interface has no expose until the server is recreated. `server.restart()`\n // can't do it — it re-uses the inline config — so we tear the app server\n // down and bring it back up with a freshly-loaded config. The workbench page\n // then reloads (driven by the registry watch in the workbench server) to\n // re-fetch the rebuilt remote. A view/service *source* edit doesn't change\n // the interface set, so it stays on the HMR path untouched. Studios declare\n // views/services the same way (only `entry` is rejected, FR-026), so they\n // get the same rebuild. The returned-server / thrown-failed-restart contract\n // is documented on `onInterfaceSetChange` in startDevServerRegistration.\n\n // Declared ahead of `runRebuild`, which the watcher's initial background\n // extraction can invoke before the statements below it have run.\n let closed = false\n\n const runRebuild = async (): Promise<ViteDevServer> => {\n // The watcher only learns about shutdown when its own close runs, late in\n // the teardown sequence — refuse here so a config save during shutdown\n // can't boot a replacement server nobody owns. Checked before the first\n // await so a rebuild can't start after close() has read `rebuildInFlight`.\n if (closed) {\n throw new Error('Dev server is shutting down')\n }\n const freshConfig = await getCliConfigUncached(workDir)\n await closeAppDevServer()\n const result = await startApp(freshConfig)\n if (!result.started) {\n // The server already reported why (e.g. organizationId was removed).\n throw new Error('Dev server did not restart after the view/service change')\n }\n return result.server\n }\n\n // `closeAppDevServer` is repointed at the replacement server only after\n // `startApp` resolves — a close() racing a rebuild would tear down the old\n // (already-closed) server and leave the replacement running with no owner,\n // so close() waits on the rebuild in flight. Rejections are owned by the\n // watcher (warn + retry on next save); the tracked copy swallows them so\n // close() can't reject.\n let rebuildInFlight: Promise<unknown> = Promise.resolve()\n const onInterfaceSetChange = (): Promise<ViteDevServer> => {\n const rebuild = runRebuild()\n rebuildInFlight = rebuild.catch(() => {})\n return rebuild\n }\n\n // Workbench is opted into solely by calling `unstable_defineApp` — its\n // branded identity is the only signal. The workbench remote is the exception:\n // it's the shell itself, not a dock app, so it never registers into the\n // shared workbench registry.\n let registration: Awaited<ReturnType<typeof startDevServerRegistration>> | undefined\n try {\n registration =\n isWorkbenchApp(cliConfig?.app) && !isWorkbenchRemote\n ? await startDevServerRegistration({\n cliConfig,\n isApp: options.isApp,\n onInterfaceSetChange,\n output,\n server,\n workDir,\n })\n : undefined\n } catch (err) {\n // Registration runs only after both servers are already up. If it throws\n // (e.g. `deriveInterfaces` rejects), tear them down before rethrowing —\n // otherwise the workbench lock and dev servers leak until the next run.\n await Promise.allSettled([closeWorkbenchServer(), closeAppDevServer()])\n throw err\n }\n\n if (workbenchAvailable) {\n const workbenchUrl = `http://${toDisplayHost(workbenchHost)}:${workbenchPort}`\n const addr = server.httpServer?.address()\n const appPort = typeof addr === 'object' && addr ? addr.port : server.config.server.port\n output.log(\n `Workbench dev server started at ${styleText(['blue', 'underline'], workbenchUrl)} (app on port ${appPort})`,\n )\n }\n\n // Single-flight: SIGINT followed by SIGTERM (each signal has its own `once`\n // handler), or a signal racing the caller's own close(), must share one\n // teardown instead of double-closing every server.\n let closing: Promise<void> | undefined\n const close = () => {\n closing ??= (async () => {\n closed = true\n process.off('SIGINT', onSignal)\n process.off('SIGTERM', onSignal)\n await rebuildInFlight\n await Promise.allSettled([registration?.close(), closeWorkbenchServer(), closeAppDevServer()])\n })()\n return closing\n }\n\n // Ensure the workbench lock file and registry entries are cleaned up on\n // abrupt shutdown. The registry is self-healing (stale PIDs are pruned on\n // next read), but eager cleanup avoids the detect-prune-retry cycle.\n // Plain projects have no lock or registry entry, so they keep the default\n // signal handling (and exit codes) they had before workbench existed.\n //\n // Trapping the signal disables Node's default exit, and a finished teardown\n // doesn't guarantee an empty event loop (keep-alive sockets, an extraction\n // worker mid-run) — without an explicit exit the process lingers, holding\n // its ports, while the shell prompt returns. Re-raising after teardown\n // restores the default termination (the `once` handler is gone by then),\n // with conventional signal exit semantics.\n const onSignal = (signal: NodeJS.Signals) => {\n // Backstop for a teardown that never settles (a wedged socket or watcher):\n // force the exit once the grace period elapses. Cleared on the normal path\n // so the re-raise fires exactly once; `unref` keeps the timer from holding\n // the process open by itself.\n const graceTimer = setTimeout(() => process.kill(process.pid, signal), SHUTDOWN_GRACE_MS)\n graceTimer.unref()\n void close().finally(() => {\n clearTimeout(graceTimer)\n process.kill(process.pid, signal)\n })\n }\n if (workbenchAvailable || registration) {\n process.once('SIGINT', onSignal)\n process.once('SIGTERM', onSignal)\n }\n\n return {close}\n}\n"],"names":["styleText","getCliConfigUncached","isWorkbenchApp","getSharedServerConfig","startDevServerRegistration","startAppDevServer","startStudioDevServer","startWorkbenchDevServer","noop","SHUTDOWN_GRACE_MS","toDisplayHost","host","devAction","options","cliConfig","flags","output","workDir","httpHost","httpPort","port","isWorkbenchRemote","app","process","env","SANITY_INTERNAL_IS_WORKBENCH_REMOTE","close","closeWorkbenchServer","workbenchHost","workbenchAvailable","workbenchPort","appOptions","closeAppDevServer","startApp","config","result","isApp","started","initial","err","server","closed","runRebuild","Error","freshConfig","rebuildInFlight","Promise","resolve","onInterfaceSetChange","rebuild","catch","registration","undefined","allSettled","workbenchUrl","addr","httpServer","address","appPort","log","closing","off","onSignal","signal","graceTimer","setTimeout","kill","pid","unref","finally","clearTimeout","once"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../src/actions/dev/devAction.ts"],"sourcesContent":["import {SANITY_CACHE_DIR} from '@sanity/cli-build/_internal/build'\nimport {type CliConfig, isWorkbenchApp} from '@sanity/cli-core'\n\nimport {checkForDeprecatedAppId, getAppId} from '../../util/appId.js'\nimport {getSharedServerConfig} from '../../util/getSharedServerConfig.js'\nimport {resolveReactStrictMode} from '../../util/resolveReactStrictMode.js'\nimport {extractCoreAppManifest} from '../manifest/extractCoreAppManifest.js'\nimport {extractStudioManifest} from '../manifest/extractStudioManifest.js'\nimport {startAppDevServer} from './servers/startAppDevServer.js'\nimport {startStudioDevServer} from './servers/startStudioDevServer.js'\nimport {type DevActionOptions} from './types.js'\n\nconst noop = async () => {}\n\n/**\n * Entry point for `sanity dev`. A plain studio/app starts a single dev server, as\n * before workbench existed. A workbench app (via `unstable_defineApp`) delegates to\n * `@sanity/workbench-cli`, injecting the CLI-domain pieces (app server, manifest\n * extraction, app id) and loading the package lazily so plain projects never do.\n */\nexport async function devAction(options: DevActionOptions): Promise<{close: () => Promise<void>}> {\n const {cliConfig, flags, isApp, output, workDir} = options\n\n const {httpHost, httpPort} = getSharedServerConfig({\n cliConfig,\n flags: {host: flags.host, port: flags.port},\n workDir,\n })\n\n // The app/studio server, parameterized per call; `announceUrl` is false when\n // the workbench announces the URL on its behalf.\n const startAppServer = (params: {announceUrl: boolean; cliConfig: CliConfig; httpPort: number}) =>\n (isApp ? startAppDevServer : startStudioDevServer)({\n ...options,\n announceUrl: params.announceUrl,\n cliConfig: params.cliConfig,\n httpPort: params.httpPort,\n })\n\n if (isWorkbenchApp(cliConfig?.app)) {\n // Lazy so a non-workbench `sanity dev` never loads the package. `doImport`\n // is path-based and doesn't apply to a bare specifier.\n // eslint-disable-next-line no-restricted-syntax\n const {startWorkbenchDev} = await import('@sanity/workbench-cli/dev')\n return startWorkbenchDev({\n appId: getAppId(cliConfig),\n cacheDir: `${SANITY_CACHE_DIR}/vite`,\n checkForDeprecatedAppId: () => checkForDeprecatedAppId({cliConfig, output}),\n cliConfig,\n extractManifest: isApp\n ? ({workDir: wd}) => extractCoreAppManifest({workDir: wd})\n : (params) => extractStudioManifest(params),\n httpHost,\n httpPort,\n isApp,\n output,\n // Runtime template needs a concrete boolean; collapse an unset config to off.\n reactStrictMode: resolveReactStrictMode(cliConfig) ?? false,\n startAppServer,\n workDir,\n })\n }\n\n // Plain non-workbench studio/app: one dev server announcing its own URL.\n const result = await startAppServer({announceUrl: true, cliConfig, httpPort})\n return {close: result.started ? result.close : noop}\n}\n"],"names":["SANITY_CACHE_DIR","isWorkbenchApp","checkForDeprecatedAppId","getAppId","getSharedServerConfig","resolveReactStrictMode","extractCoreAppManifest","extractStudioManifest","startAppDevServer","startStudioDevServer","noop","devAction","options","cliConfig","flags","isApp","output","workDir","httpHost","httpPort","host","port","startAppServer","params","announceUrl","app","startWorkbenchDev","appId","cacheDir","extractManifest","wd","reactStrictMode","result","close","started"],"mappings":"AAAA,SAAQA,gBAAgB,QAAO,oCAAmC;AAClE,SAAwBC,cAAc,QAAO,mBAAkB;AAE/D,SAAQC,uBAAuB,EAAEC,QAAQ,QAAO,sBAAqB;AACrE,SAAQC,qBAAqB,QAAO,sCAAqC;AACzE,SAAQC,sBAAsB,QAAO,uCAAsC;AAC3E,SAAQC,sBAAsB,QAAO,wCAAuC;AAC5E,SAAQC,qBAAqB,QAAO,uCAAsC;AAC1E,SAAQC,iBAAiB,QAAO,iCAAgC;AAChE,SAAQC,oBAAoB,QAAO,oCAAmC;AAGtE,MAAMC,OAAO,WAAa;AAE1B;;;;;CAKC,GACD,OAAO,eAAeC,UAAUC,OAAyB;IACvD,MAAM,EAACC,SAAS,EAAEC,KAAK,EAAEC,KAAK,EAAEC,MAAM,EAAEC,OAAO,EAAC,GAAGL;IAEnD,MAAM,EAACM,QAAQ,EAAEC,QAAQ,EAAC,GAAGf,sBAAsB;QACjDS;QACAC,OAAO;YAACM,MAAMN,MAAMM,IAAI;YAAEC,MAAMP,MAAMO,IAAI;QAAA;QAC1CJ;IACF;IAEA,6EAA6E;IAC7E,iDAAiD;IACjD,MAAMK,iBAAiB,CAACC,SACtB,AAACR,CAAAA,QAAQP,oBAAoBC,oBAAmB,EAAG;YACjD,GAAGG,OAAO;YACVY,aAAaD,OAAOC,WAAW;YAC/BX,WAAWU,OAAOV,SAAS;YAC3BM,UAAUI,OAAOJ,QAAQ;QAC3B;IAEF,IAAIlB,eAAeY,WAAWY,MAAM;QAClC,2EAA2E;QAC3E,uDAAuD;QACvD,gDAAgD;QAChD,MAAM,EAACC,iBAAiB,EAAC,GAAG,MAAM,MAAM,CAAC;QACzC,OAAOA,kBAAkB;YACvBC,OAAOxB,SAASU;YAChBe,UAAU,GAAG5B,iBAAiB,KAAK,CAAC;YACpCE,yBAAyB,IAAMA,wBAAwB;oBAACW;oBAAWG;gBAAM;YACzEH;YACAgB,iBAAiBd,QACb,CAAC,EAACE,SAASa,EAAE,EAAC,GAAKxB,uBAAuB;oBAACW,SAASa;gBAAE,KACtD,CAACP,SAAWhB,sBAAsBgB;YACtCL;YACAC;YACAJ;YACAC;YACA,8EAA8E;YAC9Ee,iBAAiB1B,uBAAuBQ,cAAc;YACtDS;YACAL;QACF;IACF;IAEA,yEAAyE;IACzE,MAAMe,SAAS,MAAMV,eAAe;QAACE,aAAa;QAAMX;QAAWM;IAAQ;IAC3E,OAAO;QAACc,OAAOD,OAAOE,OAAO,GAAGF,OAAOC,KAAK,GAAGvB;IAAI;AACrD"}
|
|
@@ -27,7 +27,7 @@ export function getDevServerConfig({ cliConfig, flags, httpPort, output, workDir
|
|
|
27
27
|
return {
|
|
28
28
|
...baseConfig,
|
|
29
29
|
// The app's navigable entry. A branded app that omits `entry` has no app
|
|
30
|
-
// view
|
|
30
|
+
// view: the runtime/federation skip the `./App` render path entirely.
|
|
31
31
|
entry: app?.entry,
|
|
32
32
|
// `devAction` passes an explicit port when a running workbench claimed the
|
|
33
33
|
// configured one; otherwise the shared resolution stands.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/actions/dev/servers/getDevServerConfig.ts"],"sourcesContent":["import path from 'node:path'\n\nimport {type CliConfig, getSanityEnvVar, isWorkbenchApp, type Output} from '@sanity/cli-core'\nimport {spinner} from '@sanity/cli-core/ux'\n\nimport {type DevServerOptions} from '../../../server/devServer.js'\nimport {determineIsApp} from '../../../util/determineIsApp.js'\nimport {getSharedServerConfig} from '../../../util/getSharedServerConfig.js'\nimport {resolveReactStrictMode} from '../../../util/resolveReactStrictMode.js'\nimport {type DevFlags} from '../types.js'\n\nexport function getDevServerConfig({\n cliConfig,\n flags,\n httpPort,\n output,\n workDir,\n}: {\n cliConfig?: CliConfig\n flags: DevFlags\n httpPort?: number\n output: Output\n workDir: string\n}): Omit<DevServerOptions, 'spinner'> {\n const configSpinner = spinner('Checking configuration files...')\n\n const baseConfig = getSharedServerConfig({\n cliConfig,\n flags: {\n host: flags.host,\n port: flags.port,\n },\n workDir,\n })\n\n configSpinner.succeed()\n\n const isApp = cliConfig ? determineIsApp(cliConfig) : false\n const reactStrictMode = resolveReactStrictMode(cliConfig)\n // `views` is declared via `unstable_defineApp`, so read it off the branded\n // app result rather than the legacy `app` config type.\n const app = cliConfig?.app\n\n const envBasePath = getSanityEnvVar('BASEPATH', isApp ?? false)\n if (envBasePath && cliConfig?.project?.basePath) {\n output.warn(\n `Overriding configured base path (${cliConfig.project.basePath}) with value from environment variable (${envBasePath})`,\n )\n }\n\n return {\n ...baseConfig,\n // The app's navigable entry. A branded app that omits `entry` has no app\n // view
|
|
1
|
+
{"version":3,"sources":["../../../../src/actions/dev/servers/getDevServerConfig.ts"],"sourcesContent":["import path from 'node:path'\n\nimport {type CliConfig, getSanityEnvVar, isWorkbenchApp, type Output} from '@sanity/cli-core'\nimport {spinner} from '@sanity/cli-core/ux'\n\nimport {type DevServerOptions} from '../../../server/devServer.js'\nimport {determineIsApp} from '../../../util/determineIsApp.js'\nimport {getSharedServerConfig} from '../../../util/getSharedServerConfig.js'\nimport {resolveReactStrictMode} from '../../../util/resolveReactStrictMode.js'\nimport {type DevFlags} from '../types.js'\n\nexport function getDevServerConfig({\n cliConfig,\n flags,\n httpPort,\n output,\n workDir,\n}: {\n cliConfig?: CliConfig\n flags: DevFlags\n httpPort?: number\n output: Output\n workDir: string\n}): Omit<DevServerOptions, 'spinner'> {\n const configSpinner = spinner('Checking configuration files...')\n\n const baseConfig = getSharedServerConfig({\n cliConfig,\n flags: {\n host: flags.host,\n port: flags.port,\n },\n workDir,\n })\n\n configSpinner.succeed()\n\n const isApp = cliConfig ? determineIsApp(cliConfig) : false\n const reactStrictMode = resolveReactStrictMode(cliConfig)\n // `views` is declared via `unstable_defineApp`, so read it off the branded\n // app result rather than the legacy `app` config type.\n const app = cliConfig?.app\n\n const envBasePath = getSanityEnvVar('BASEPATH', isApp ?? false)\n if (envBasePath && cliConfig?.project?.basePath) {\n output.warn(\n `Overriding configured base path (${cliConfig.project.basePath}) with value from environment variable (${envBasePath})`,\n )\n }\n\n return {\n ...baseConfig,\n // The app's navigable entry. A branded app that omits `entry` has no app\n // view: the runtime/federation skip the `./App` render path entirely.\n entry: app?.entry,\n // `devAction` passes an explicit port when a running workbench claimed the\n // configured one; otherwise the shared resolution stands.\n httpPort: httpPort ?? baseConfig.httpPort,\n isWorkbenchApp: isWorkbenchApp(app),\n reactCompiler: cliConfig && 'reactCompiler' in cliConfig ? cliConfig.reactCompiler : undefined,\n reactStrictMode,\n services: isWorkbenchApp(app) ? app.services : undefined,\n staticPath: path.join(workDir, 'static'),\n typegen: cliConfig?.typegen,\n views: isWorkbenchApp(app) ? app.views : undefined,\n }\n}\n"],"names":["path","getSanityEnvVar","isWorkbenchApp","spinner","determineIsApp","getSharedServerConfig","resolveReactStrictMode","getDevServerConfig","cliConfig","flags","httpPort","output","workDir","configSpinner","baseConfig","host","port","succeed","isApp","reactStrictMode","app","envBasePath","project","basePath","warn","entry","reactCompiler","undefined","services","staticPath","join","typegen","views"],"mappings":"AAAA,OAAOA,UAAU,YAAW;AAE5B,SAAwBC,eAAe,EAAEC,cAAc,QAAoB,mBAAkB;AAC7F,SAAQC,OAAO,QAAO,sBAAqB;AAG3C,SAAQC,cAAc,QAAO,kCAAiC;AAC9D,SAAQC,qBAAqB,QAAO,yCAAwC;AAC5E,SAAQC,sBAAsB,QAAO,0CAAyC;AAG9E,OAAO,SAASC,mBAAmB,EACjCC,SAAS,EACTC,KAAK,EACLC,QAAQ,EACRC,MAAM,EACNC,OAAO,EAOR;IACC,MAAMC,gBAAgBV,QAAQ;IAE9B,MAAMW,aAAaT,sBAAsB;QACvCG;QACAC,OAAO;YACLM,MAAMN,MAAMM,IAAI;YAChBC,MAAMP,MAAMO,IAAI;QAClB;QACAJ;IACF;IAEAC,cAAcI,OAAO;IAErB,MAAMC,QAAQV,YAAYJ,eAAeI,aAAa;IACtD,MAAMW,kBAAkBb,uBAAuBE;IAC/C,2EAA2E;IAC3E,uDAAuD;IACvD,MAAMY,MAAMZ,WAAWY;IAEvB,MAAMC,cAAcpB,gBAAgB,YAAYiB,SAAS;IACzD,IAAIG,eAAeb,WAAWc,SAASC,UAAU;QAC/CZ,OAAOa,IAAI,CACT,CAAC,iCAAiC,EAAEhB,UAAUc,OAAO,CAACC,QAAQ,CAAC,wCAAwC,EAAEF,YAAY,CAAC,CAAC;IAE3H;IAEA,OAAO;QACL,GAAGP,UAAU;QACb,yEAAyE;QACzE,sEAAsE;QACtEW,OAAOL,KAAKK;QACZ,2EAA2E;QAC3E,0DAA0D;QAC1Df,UAAUA,YAAYI,WAAWJ,QAAQ;QACzCR,gBAAgBA,eAAekB;QAC/BM,eAAelB,aAAa,mBAAmBA,YAAYA,UAAUkB,aAAa,GAAGC;QACrFR;QACAS,UAAU1B,eAAekB,OAAOA,IAAIQ,QAAQ,GAAGD;QAC/CE,YAAY7B,KAAK8B,IAAI,CAAClB,SAAS;QAC/BmB,SAASvB,WAAWuB;QACpBC,OAAO9B,eAAekB,OAAOA,IAAIY,KAAK,GAAGL;IAC3C;AACF"}
|
|
@@ -5,8 +5,16 @@ import { gracefulServerDeath } from '../../../server/gracefulServerDeath.js';
|
|
|
5
5
|
import { devDebug } from '../devDebug.js';
|
|
6
6
|
import { getDashboardAppURL } from './getDashboardAppUrl.js';
|
|
7
7
|
import { getDevServerConfig } from './getDevServerConfig.js';
|
|
8
|
+
// Bind-only addresses ('0.0.0.0', '::') aren't routable in every browser; the
|
|
9
|
+
// displayed URL falls back to localhost. The bind address itself is untouched.
|
|
10
|
+
function toDisplayHost(host) {
|
|
11
|
+
if (!host || host === '0.0.0.0' || host === '::' || host === '[::]') {
|
|
12
|
+
return 'localhost';
|
|
13
|
+
}
|
|
14
|
+
return host;
|
|
15
|
+
}
|
|
8
16
|
export async function startAppDevServer(options) {
|
|
9
|
-
const { cliConfig, flags, httpPort, output,
|
|
17
|
+
const { announceUrl = true, cliConfig, flags, httpPort, output, workDir } = options;
|
|
10
18
|
const isWorkbenchApp = determineIsWorkbenchApp(cliConfig?.app);
|
|
11
19
|
// Workbench apps don't load through the dashboard, so the flag has no
|
|
12
20
|
// meaning for them and is ignored.
|
|
@@ -43,14 +51,15 @@ export async function startAppDevServer(options) {
|
|
|
43
51
|
isApp: true
|
|
44
52
|
});
|
|
45
53
|
const { port } = server.config.server;
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
+
// Federated apps surface through the workbench, which announces the URL;
|
|
55
|
+
// only the package-unavailable fallback announces from here.
|
|
56
|
+
if (isWorkbenchApp && announceUrl) {
|
|
57
|
+
const url = `http://${toDisplayHost(config.httpHost)}:${port}`;
|
|
58
|
+
output.log(`App dev server started at ${styleText([
|
|
59
|
+
'blue',
|
|
60
|
+
'underline'
|
|
61
|
+
], url)}`);
|
|
62
|
+
} else if (!isWorkbenchApp) {
|
|
54
63
|
const httpHost = config.httpHost || 'localhost';
|
|
55
64
|
const dashboardAppUrl = await getDashboardAppURL({
|
|
56
65
|
httpHost,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/actions/dev/servers/startAppDevServer.ts"],"sourcesContent":["import {styleText} from 'node:util'\n\nimport {isWorkbenchApp as determineIsWorkbenchApp} from '@sanity/cli-core'\n\nimport {startDevServer} from '../../../server/devServer.js'\nimport {gracefulServerDeath} from '../../../server/gracefulServerDeath.js'\nimport {devDebug} from '../devDebug.js'\nimport {type DevActionOptions, type StartDevServerResult} from '../types.js'\nimport {getDashboardAppURL} from './getDashboardAppUrl.js'\nimport {getDevServerConfig} from './getDevServerConfig.js'\n\nexport async function startAppDevServer(options: DevActionOptions): Promise<StartDevServerResult> {\n const {cliConfig, flags, httpPort, output,
|
|
1
|
+
{"version":3,"sources":["../../../../src/actions/dev/servers/startAppDevServer.ts"],"sourcesContent":["import {styleText} from 'node:util'\n\nimport {isWorkbenchApp as determineIsWorkbenchApp} from '@sanity/cli-core'\n\nimport {startDevServer} from '../../../server/devServer.js'\nimport {gracefulServerDeath} from '../../../server/gracefulServerDeath.js'\nimport {devDebug} from '../devDebug.js'\nimport {type DevActionOptions, type StartDevServerResult} from '../types.js'\nimport {getDashboardAppURL} from './getDashboardAppUrl.js'\nimport {getDevServerConfig} from './getDevServerConfig.js'\n\n// Bind-only addresses ('0.0.0.0', '::') aren't routable in every browser; the\n// displayed URL falls back to localhost. The bind address itself is untouched.\nfunction toDisplayHost(host: string | undefined): string {\n if (!host || host === '0.0.0.0' || host === '::' || host === '[::]') {\n return 'localhost'\n }\n return host\n}\n\nexport async function startAppDevServer(options: DevActionOptions): Promise<StartDevServerResult> {\n const {announceUrl = true, cliConfig, flags, httpPort, output, workDir} = options\n\n const isWorkbenchApp = determineIsWorkbenchApp(cliConfig?.app)\n\n // Workbench apps don't load through the dashboard, so the flag has no\n // meaning for them and is ignored.\n if (!isWorkbenchApp && !flags['load-in-dashboard']) {\n output.warn(`Apps cannot run without the Sanity dashboard`)\n output.warn(`Starting dev server with the --load-in-dashboard flag set to true`)\n }\n\n let organizationId: string | undefined\n if (cliConfig && 'app' in cliConfig && cliConfig.app?.organizationId) {\n organizationId = cliConfig.app.organizationId\n }\n\n if (!organizationId) {\n output.error(`Apps require an organization ID (orgId) specified in your sanity.cli.ts file`, {\n exit: 1,\n })\n return {reason: 'missing-organization-id', started: false}\n }\n\n const config = getDevServerConfig({cliConfig, flags, httpPort, output, workDir})\n\n try {\n output.log('Starting dev server')\n\n const appTitle = cliConfig && 'app' in cliConfig ? cliConfig.app?.title : undefined\n const {close, server} = await startDevServer({\n ...config,\n appTitle,\n isApp: true,\n })\n\n const {port} = server.config.server\n\n // Federated apps surface through the workbench, which announces the URL;\n // only the package-unavailable fallback announces from here.\n if (isWorkbenchApp && announceUrl) {\n const url = `http://${toDisplayHost(config.httpHost)}:${port}`\n output.log(`App dev server started at ${styleText(['blue', 'underline'], url)}`)\n } else if (!isWorkbenchApp) {\n const httpHost = config.httpHost || 'localhost'\n\n const dashboardAppUrl = await getDashboardAppURL({\n httpHost,\n httpPort: port,\n organizationId,\n })\n output.log(`Dev server started on port ${port}`)\n output.log(`View your app in the Sanity dashboard here:`)\n output.log(styleText(['blue', 'underline'], dashboardAppUrl))\n }\n\n return {close, server, started: true}\n } catch (err) {\n devDebug('Error starting app dev server', err)\n throw gracefulServerDeath('dev', config.httpHost, config.httpPort, err)\n }\n}\n"],"names":["styleText","isWorkbenchApp","determineIsWorkbenchApp","startDevServer","gracefulServerDeath","devDebug","getDashboardAppURL","getDevServerConfig","toDisplayHost","host","startAppDevServer","options","announceUrl","cliConfig","flags","httpPort","output","workDir","app","warn","organizationId","error","exit","reason","started","config","log","appTitle","title","undefined","close","server","isApp","port","url","httpHost","dashboardAppUrl","err"],"mappings":"AAAA,SAAQA,SAAS,QAAO,YAAW;AAEnC,SAAQC,kBAAkBC,uBAAuB,QAAO,mBAAkB;AAE1E,SAAQC,cAAc,QAAO,+BAA8B;AAC3D,SAAQC,mBAAmB,QAAO,yCAAwC;AAC1E,SAAQC,QAAQ,QAAO,iBAAgB;AAEvC,SAAQC,kBAAkB,QAAO,0BAAyB;AAC1D,SAAQC,kBAAkB,QAAO,0BAAyB;AAE1D,8EAA8E;AAC9E,+EAA+E;AAC/E,SAASC,cAAcC,IAAwB;IAC7C,IAAI,CAACA,QAAQA,SAAS,aAAaA,SAAS,QAAQA,SAAS,QAAQ;QACnE,OAAO;IACT;IACA,OAAOA;AACT;AAEA,OAAO,eAAeC,kBAAkBC,OAAyB;IAC/D,MAAM,EAACC,cAAc,IAAI,EAAEC,SAAS,EAAEC,KAAK,EAAEC,QAAQ,EAAEC,MAAM,EAAEC,OAAO,EAAC,GAAGN;IAE1E,MAAMV,iBAAiBC,wBAAwBW,WAAWK;IAE1D,sEAAsE;IACtE,mCAAmC;IACnC,IAAI,CAACjB,kBAAkB,CAACa,KAAK,CAAC,oBAAoB,EAAE;QAClDE,OAAOG,IAAI,CAAC,CAAC,4CAA4C,CAAC;QAC1DH,OAAOG,IAAI,CAAC,CAAC,iEAAiE,CAAC;IACjF;IAEA,IAAIC;IACJ,IAAIP,aAAa,SAASA,aAAaA,UAAUK,GAAG,EAAEE,gBAAgB;QACpEA,iBAAiBP,UAAUK,GAAG,CAACE,cAAc;IAC/C;IAEA,IAAI,CAACA,gBAAgB;QACnBJ,OAAOK,KAAK,CAAC,CAAC,4EAA4E,CAAC,EAAE;YAC3FC,MAAM;QACR;QACA,OAAO;YAACC,QAAQ;YAA2BC,SAAS;QAAK;IAC3D;IAEA,MAAMC,SAASlB,mBAAmB;QAACM;QAAWC;QAAOC;QAAUC;QAAQC;IAAO;IAE9E,IAAI;QACFD,OAAOU,GAAG,CAAC;QAEX,MAAMC,WAAWd,aAAa,SAASA,YAAYA,UAAUK,GAAG,EAAEU,QAAQC;QAC1E,MAAM,EAACC,KAAK,EAAEC,MAAM,EAAC,GAAG,MAAM5B,eAAe;YAC3C,GAAGsB,MAAM;YACTE;YACAK,OAAO;QACT;QAEA,MAAM,EAACC,IAAI,EAAC,GAAGF,OAAON,MAAM,CAACM,MAAM;QAEnC,yEAAyE;QACzE,6DAA6D;QAC7D,IAAI9B,kBAAkBW,aAAa;YACjC,MAAMsB,MAAM,CAAC,OAAO,EAAE1B,cAAciB,OAAOU,QAAQ,EAAE,CAAC,EAAEF,MAAM;YAC9DjB,OAAOU,GAAG,CAAC,CAAC,0BAA0B,EAAE1B,UAAU;gBAAC;gBAAQ;aAAY,EAAEkC,MAAM;QACjF,OAAO,IAAI,CAACjC,gBAAgB;YAC1B,MAAMkC,WAAWV,OAAOU,QAAQ,IAAI;YAEpC,MAAMC,kBAAkB,MAAM9B,mBAAmB;gBAC/C6B;gBACApB,UAAUkB;gBACVb;YACF;YACAJ,OAAOU,GAAG,CAAC,CAAC,2BAA2B,EAAEO,MAAM;YAC/CjB,OAAOU,GAAG,CAAC,CAAC,2CAA2C,CAAC;YACxDV,OAAOU,GAAG,CAAC1B,UAAU;gBAAC;gBAAQ;aAAY,EAAEoC;QAC9C;QAEA,OAAO;YAACN;YAAOC;YAAQP,SAAS;QAAI;IACtC,EAAE,OAAOa,KAAK;QACZhC,SAAS,iCAAiCgC;QAC1C,MAAMjC,oBAAoB,OAAOqB,OAAOU,QAAQ,EAAEV,OAAOV,QAAQ,EAAEsB;IACrE;AACF"}
|
|
@@ -15,7 +15,7 @@ import { devDebug } from '../devDebug.js';
|
|
|
15
15
|
import { getDashboardAppURL } from './getDashboardAppUrl.js';
|
|
16
16
|
import { getDevServerConfig } from './getDevServerConfig.js';
|
|
17
17
|
export async function startStudioDevServer(options) {
|
|
18
|
-
const { cliConfig, flags, httpPort, output,
|
|
18
|
+
const { announceUrl = true, cliConfig, flags, httpPort, output, workDir } = options;
|
|
19
19
|
const projectId = cliConfig?.api?.projectId;
|
|
20
20
|
let organizationId;
|
|
21
21
|
// Workbench apps don't load through the dashboard, so the flag has no
|
|
@@ -141,7 +141,7 @@ export async function startStudioDevServer(options) {
|
|
|
141
141
|
const appType = 'Sanity Studio';
|
|
142
142
|
const viteVersion = await getLocalPackageVersion('vite', import.meta.url);
|
|
143
143
|
spin.succeed();
|
|
144
|
-
loggerInfo(`${appType} ` + `using ${styleText('cyan', `vite@${viteVersion}`)} ` + `ready in ${styleText('cyan', `${Math.ceil(startupDuration)}ms`)}` + (
|
|
144
|
+
loggerInfo(`${appType} ` + `using ${styleText('cyan', `vite@${viteVersion}`)} ` + `ready in ${styleText('cyan', `${Math.ceil(startupDuration)}ms`)}` + (announceUrl ? ` and running at ${styleText('cyan', url)}` : ''));
|
|
145
145
|
}
|
|
146
146
|
return {
|
|
147
147
|
close,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/actions/dev/servers/startStudioDevServer.ts"],"sourcesContent":["import {styleText} from 'node:util'\n\nimport {\n checkRequiredDependencies,\n checkStudioDependencyVersions,\n} from '@sanity/cli-build/_internal/build'\nimport {getLocalPackageVersion, isInteractive, isWorkbenchApp} from '@sanity/cli-core'\nimport {confirm, logSymbols, spinner} from '@sanity/cli-core/ux'\nimport {parse as semverParse} from 'semver'\n\nimport {startDevServer} from '../../../server/devServer.js'\nimport {gracefulServerDeath} from '../../../server/gracefulServerDeath.js'\nimport {getProjectById} from '../../../services/projects.js'\nimport {getAppId} from '../../../util/appId.js'\nimport {compareDependencyVersions} from '../../../util/compareDependencyVersions.js'\nimport {getPackageManagerChoice} from '../../../util/packageManager/packageManagerChoice.js'\nimport {upgradePackages} from '../../../util/packageManager/upgradePackages.js'\nimport {shouldAutoUpdate} from '../../build/shouldAutoUpdate.js'\nimport {devDebug} from '../devDebug.js'\nimport {type DevActionOptions, type StartDevServerResult} from '../types.js'\nimport {getDashboardAppURL} from './getDashboardAppUrl.js'\nimport {getDevServerConfig} from './getDevServerConfig.js'\n\nexport async function startStudioDevServer(\n options: DevActionOptions,\n): Promise<StartDevServerResult> {\n const {cliConfig, flags, httpPort, output, workbenchAvailable, workDir} = options\n const projectId = cliConfig?.api?.projectId\n let organizationId: string | undefined\n\n // Workbench apps don't load through the dashboard, so the flag has no\n // meaning for them and is ignored.\n const loadInDashboard = flags['load-in-dashboard'] && !isWorkbenchApp(cliConfig?.app)\n\n // Check studio dependency versions\n await checkStudioDependencyVersions(workDir, output)\n\n const {installedSanityVersion} = await checkRequiredDependencies(options)\n\n // Check if auto-updates are enabled\n const autoUpdatesEnabled = shouldAutoUpdate({cliConfig, flags, output})\n\n if (autoUpdatesEnabled) {\n // Get the clean version without build metadata: https://semver.org/#spec-item-10\n const cleanSanityVersion = semverParse(installedSanityVersion)?.version\n if (!cleanSanityVersion) {\n throw new Error(`Failed to parse installed Sanity version: ${installedSanityVersion}`)\n }\n\n const sanityDependencies = [\n {name: 'sanity', version: cleanSanityVersion},\n {name: '@sanity/vision', version: cleanSanityVersion},\n ]\n\n output.log(`${logSymbols.info} Running with auto-updates enabled`)\n\n // Check local versions against deployed versions\n let result: Awaited<ReturnType<typeof compareDependencyVersions>> | undefined\n\n const appId = getAppId(cliConfig)\n\n try {\n result = await compareDependencyVersions(sanityDependencies, workDir, {appId})\n } catch (err) {\n output.warn(`Failed to compare local versions against auto-updating versions: ${err}`)\n }\n\n if (result?.unresolvedPrerelease.length) {\n for (const mod of result.unresolvedPrerelease) {\n output.warn(\n `Your local version of ${mod.pkg} (${mod.version}) is a prerelease not available on the auto-updates CDN. The locally installed version will be used.`,\n )\n }\n }\n\n // mismatch between local and auto-updating dependencies\n if (result?.mismatched.length) {\n const message =\n `The following local package versions are different from the versions currently served at runtime.\\n` +\n `When using auto updates, we recommend that you run with the same versions locally as will be used when deploying.\\n\\n` +\n `${result.mismatched.map((mod) => ` - ${mod.pkg} (local version: ${mod.installed}, runtime version: ${mod.remote})`).join('\\n')}\\n\\n`\n\n if (isInteractive()) {\n const shouldUpgrade = await confirm({\n default: true,\n message: styleText('yellow', `${message}Do you want to upgrade local versions?`),\n })\n if (shouldUpgrade) {\n await upgradePackages(\n {\n packageManager: (await getPackageManagerChoice(workDir, {interactive: false})).chosen,\n packages: result.mismatched.map((res) => [res.pkg, res.remote]),\n },\n {output, workDir},\n )\n }\n } else {\n // In this case we warn the user but we don't ask them if they want to upgrade because it's not interactive.\n output.log(styleText('yellow', message))\n }\n }\n }\n\n if (cliConfig?.schemaExtraction?.enabled) {\n output.log(`${logSymbols.info} Running dev server with schema extraction enabled`)\n }\n\n const config = getDevServerConfig({cliConfig, flags, httpPort, output, workDir})\n\n if (loadInDashboard) {\n if (!projectId) {\n output.error('Project Id is required to load in dashboard', {exit: 1})\n }\n\n try {\n const project = await getProjectById(projectId!)\n organizationId = project.organizationId!\n } catch (error) {\n devDebug('Error getting organization id from project id', error)\n output.error('Failed to get organization id from project id', {exit: 1})\n }\n }\n\n try {\n const startTime = Date.now()\n const spin = spinner('Starting dev server').start()\n const {close, server} = await startDevServer(config)\n\n const {info: loggerInfo} = server.config.logger\n const {port} = server.config.server\n const httpHost = config.httpHost || 'localhost'\n\n if (loadInDashboard) {\n spin.succeed()\n\n output.log(`Dev server started on port ${port}`)\n output.log(`View your studio in the Sanity dashboard here:`)\n output.log(\n styleText(\n ['blue', 'underline'],\n await getDashboardAppURL({\n httpHost,\n httpPort: port,\n organizationId: organizationId!,\n }),\n ),\n )\n } else {\n const startupDuration = Date.now() - startTime\n const url = `http://${httpHost || 'localhost'}:${port}${config.basePath}`\n const appType = 'Sanity Studio'\n\n const viteVersion = await getLocalPackageVersion('vite', import.meta.url)\n spin.succeed()\n\n loggerInfo(\n `${appType} ` +\n `using ${styleText('cyan', `vite@${viteVersion}`)} ` +\n `ready in ${styleText('cyan', `${Math.ceil(startupDuration)}ms`)}` +\n (workbenchAvailable ? '' : ` and running at ${styleText('cyan', url)}`),\n )\n }\n\n return {close, server, started: true}\n } catch (err) {\n devDebug('Error starting studio dev server', err)\n throw gracefulServerDeath('dev', config.httpHost, config.httpPort, err)\n }\n}\n"],"names":["styleText","checkRequiredDependencies","checkStudioDependencyVersions","getLocalPackageVersion","isInteractive","isWorkbenchApp","confirm","logSymbols","spinner","parse","semverParse","startDevServer","gracefulServerDeath","getProjectById","getAppId","compareDependencyVersions","getPackageManagerChoice","upgradePackages","shouldAutoUpdate","devDebug","getDashboardAppURL","getDevServerConfig","startStudioDevServer","options","cliConfig","flags","httpPort","output","workbenchAvailable","workDir","projectId","api","organizationId","loadInDashboard","app","installedSanityVersion","autoUpdatesEnabled","cleanSanityVersion","version","Error","sanityDependencies","name","log","info","result","appId","err","warn","unresolvedPrerelease","length","mod","pkg","mismatched","message","map","installed","remote","join","shouldUpgrade","default","packageManager","interactive","chosen","packages","res","schemaExtraction","enabled","config","error","exit","project","startTime","Date","now","spin","start","close","server","loggerInfo","logger","port","httpHost","succeed","startupDuration","url","basePath","appType","viteVersion","Math","ceil","started"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../src/actions/dev/servers/startStudioDevServer.ts"],"sourcesContent":["import {styleText} from 'node:util'\n\nimport {\n checkRequiredDependencies,\n checkStudioDependencyVersions,\n} from '@sanity/cli-build/_internal/build'\nimport {getLocalPackageVersion, isInteractive, isWorkbenchApp} from '@sanity/cli-core'\nimport {confirm, logSymbols, spinner} from '@sanity/cli-core/ux'\nimport {parse as semverParse} from 'semver'\n\nimport {startDevServer} from '../../../server/devServer.js'\nimport {gracefulServerDeath} from '../../../server/gracefulServerDeath.js'\nimport {getProjectById} from '../../../services/projects.js'\nimport {getAppId} from '../../../util/appId.js'\nimport {compareDependencyVersions} from '../../../util/compareDependencyVersions.js'\nimport {getPackageManagerChoice} from '../../../util/packageManager/packageManagerChoice.js'\nimport {upgradePackages} from '../../../util/packageManager/upgradePackages.js'\nimport {shouldAutoUpdate} from '../../build/shouldAutoUpdate.js'\nimport {devDebug} from '../devDebug.js'\nimport {type DevActionOptions, type StartDevServerResult} from '../types.js'\nimport {getDashboardAppURL} from './getDashboardAppUrl.js'\nimport {getDevServerConfig} from './getDevServerConfig.js'\n\nexport async function startStudioDevServer(\n options: DevActionOptions,\n): Promise<StartDevServerResult> {\n const {announceUrl = true, cliConfig, flags, httpPort, output, workDir} = options\n const projectId = cliConfig?.api?.projectId\n let organizationId: string | undefined\n\n // Workbench apps don't load through the dashboard, so the flag has no\n // meaning for them and is ignored.\n const loadInDashboard = flags['load-in-dashboard'] && !isWorkbenchApp(cliConfig?.app)\n\n // Check studio dependency versions\n await checkStudioDependencyVersions(workDir, output)\n\n const {installedSanityVersion} = await checkRequiredDependencies(options)\n\n // Check if auto-updates are enabled\n const autoUpdatesEnabled = shouldAutoUpdate({cliConfig, flags, output})\n\n if (autoUpdatesEnabled) {\n // Get the clean version without build metadata: https://semver.org/#spec-item-10\n const cleanSanityVersion = semverParse(installedSanityVersion)?.version\n if (!cleanSanityVersion) {\n throw new Error(`Failed to parse installed Sanity version: ${installedSanityVersion}`)\n }\n\n const sanityDependencies = [\n {name: 'sanity', version: cleanSanityVersion},\n {name: '@sanity/vision', version: cleanSanityVersion},\n ]\n\n output.log(`${logSymbols.info} Running with auto-updates enabled`)\n\n // Check local versions against deployed versions\n let result: Awaited<ReturnType<typeof compareDependencyVersions>> | undefined\n\n const appId = getAppId(cliConfig)\n\n try {\n result = await compareDependencyVersions(sanityDependencies, workDir, {appId})\n } catch (err) {\n output.warn(`Failed to compare local versions against auto-updating versions: ${err}`)\n }\n\n if (result?.unresolvedPrerelease.length) {\n for (const mod of result.unresolvedPrerelease) {\n output.warn(\n `Your local version of ${mod.pkg} (${mod.version}) is a prerelease not available on the auto-updates CDN. The locally installed version will be used.`,\n )\n }\n }\n\n // mismatch between local and auto-updating dependencies\n if (result?.mismatched.length) {\n const message =\n `The following local package versions are different from the versions currently served at runtime.\\n` +\n `When using auto updates, we recommend that you run with the same versions locally as will be used when deploying.\\n\\n` +\n `${result.mismatched.map((mod) => ` - ${mod.pkg} (local version: ${mod.installed}, runtime version: ${mod.remote})`).join('\\n')}\\n\\n`\n\n if (isInteractive()) {\n const shouldUpgrade = await confirm({\n default: true,\n message: styleText('yellow', `${message}Do you want to upgrade local versions?`),\n })\n if (shouldUpgrade) {\n await upgradePackages(\n {\n packageManager: (await getPackageManagerChoice(workDir, {interactive: false})).chosen,\n packages: result.mismatched.map((res) => [res.pkg, res.remote]),\n },\n {output, workDir},\n )\n }\n } else {\n // In this case we warn the user but we don't ask them if they want to upgrade because it's not interactive.\n output.log(styleText('yellow', message))\n }\n }\n }\n\n if (cliConfig?.schemaExtraction?.enabled) {\n output.log(`${logSymbols.info} Running dev server with schema extraction enabled`)\n }\n\n const config = getDevServerConfig({cliConfig, flags, httpPort, output, workDir})\n\n if (loadInDashboard) {\n if (!projectId) {\n output.error('Project Id is required to load in dashboard', {exit: 1})\n }\n\n try {\n const project = await getProjectById(projectId!)\n organizationId = project.organizationId!\n } catch (error) {\n devDebug('Error getting organization id from project id', error)\n output.error('Failed to get organization id from project id', {exit: 1})\n }\n }\n\n try {\n const startTime = Date.now()\n const spin = spinner('Starting dev server').start()\n const {close, server} = await startDevServer(config)\n\n const {info: loggerInfo} = server.config.logger\n const {port} = server.config.server\n const httpHost = config.httpHost || 'localhost'\n\n if (loadInDashboard) {\n spin.succeed()\n\n output.log(`Dev server started on port ${port}`)\n output.log(`View your studio in the Sanity dashboard here:`)\n output.log(\n styleText(\n ['blue', 'underline'],\n await getDashboardAppURL({\n httpHost,\n httpPort: port,\n organizationId: organizationId!,\n }),\n ),\n )\n } else {\n const startupDuration = Date.now() - startTime\n const url = `http://${httpHost || 'localhost'}:${port}${config.basePath}`\n const appType = 'Sanity Studio'\n\n const viteVersion = await getLocalPackageVersion('vite', import.meta.url)\n spin.succeed()\n\n loggerInfo(\n `${appType} ` +\n `using ${styleText('cyan', `vite@${viteVersion}`)} ` +\n `ready in ${styleText('cyan', `${Math.ceil(startupDuration)}ms`)}` +\n (announceUrl ? ` and running at ${styleText('cyan', url)}` : ''),\n )\n }\n\n return {close, server, started: true}\n } catch (err) {\n devDebug('Error starting studio dev server', err)\n throw gracefulServerDeath('dev', config.httpHost, config.httpPort, err)\n }\n}\n"],"names":["styleText","checkRequiredDependencies","checkStudioDependencyVersions","getLocalPackageVersion","isInteractive","isWorkbenchApp","confirm","logSymbols","spinner","parse","semverParse","startDevServer","gracefulServerDeath","getProjectById","getAppId","compareDependencyVersions","getPackageManagerChoice","upgradePackages","shouldAutoUpdate","devDebug","getDashboardAppURL","getDevServerConfig","startStudioDevServer","options","announceUrl","cliConfig","flags","httpPort","output","workDir","projectId","api","organizationId","loadInDashboard","app","installedSanityVersion","autoUpdatesEnabled","cleanSanityVersion","version","Error","sanityDependencies","name","log","info","result","appId","err","warn","unresolvedPrerelease","length","mod","pkg","mismatched","message","map","installed","remote","join","shouldUpgrade","default","packageManager","interactive","chosen","packages","res","schemaExtraction","enabled","config","error","exit","project","startTime","Date","now","spin","start","close","server","loggerInfo","logger","port","httpHost","succeed","startupDuration","url","basePath","appType","viteVersion","Math","ceil","started"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/actions/dev/types.ts"],"sourcesContent":["import {type CliConfig, type Output} from '@sanity/cli-core'\nimport {type ViteDevServer} from 'vite'\n\nimport {type DevCommand} from '../../commands/dev.js'\n\nexport type DevFlags = DevCommand['flags']\n\nexport interface DevActionOptions {\n cliConfig: CliConfig\n flags: DevFlags\n isApp: boolean\n output: Output\n workDir: string\n\n /**\n * Port the app/studio dev server should bind. `devAction` sets it when a\n * running workbench has claimed the configured port; otherwise it stays\n * absent and the server resolves its port from flags/env/config.\n */\n httpPort?: number\n
|
|
1
|
+
{"version":3,"sources":["../../../src/actions/dev/types.ts"],"sourcesContent":["import {type CliConfig, type Output} from '@sanity/cli-core'\nimport {type ViteDevServer} from 'vite'\n\nimport {type DevCommand} from '../../commands/dev.js'\n\nexport type DevFlags = DevCommand['flags']\n\nexport interface DevActionOptions {\n cliConfig: CliConfig\n flags: DevFlags\n isApp: boolean\n output: Output\n workDir: string\n\n /** Announce the server's own URL on startup; `false` when the workbench announces it instead (default `true`). */\n announceUrl?: boolean\n\n /**\n * Port the app/studio dev server should bind. `devAction` sets it when a\n * running workbench has claimed the configured port; otherwise it stays\n * absent and the server resolves its port from flags/env/config.\n */\n httpPort?: number\n}\n\n/**\n * Result of starting an app/studio dev server. Discriminated on `started` so\n * callers handle the didn't-start case explicitly instead of null-checking\n * optional fields. A server that fails to *boot* still throws — the\n * not-started arm is reserved for expected early exits the server has\n * already reported to the user.\n */\nexport type StartDevServerResult =\n | {close: () => Promise<void>; server: ViteDevServer; started: true}\n | {reason: 'missing-organization-id'; started: false}\n"],"names":[],"mappings":"AAyBA;;;;;;CAMC,GACD,WAEuD"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { readFile } from 'node:fs/promises';
|
|
2
2
|
import { join, resolve } from 'node:path';
|
|
3
3
|
import { SANITY_CACHE_DIR } from '@sanity/cli-build/_internal/build';
|
|
4
|
-
import { extractManifest } from '
|
|
5
|
-
import { MANIFEST_FILENAME } from '
|
|
4
|
+
import { extractManifest } from './extractManifest.js';
|
|
5
|
+
import { MANIFEST_FILENAME } from './writeManifestFile.js';
|
|
6
6
|
/**
|
|
7
7
|
* Dev-time manifest output directory, relative to the studio working
|
|
8
8
|
* directory. Sibling of Vite's `cacheDir` so it stays out of `dist` and is
|
|
@@ -27,4 +27,4 @@ import { MANIFEST_FILENAME } from '../../manifest/writeManifestFile.js';
|
|
|
27
27
|
return JSON.parse(raw);
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
//# sourceMappingURL=
|
|
30
|
+
//# sourceMappingURL=extractStudioManifest.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/actions/manifest/extractStudioManifest.ts"],"sourcesContent":["import {readFile} from 'node:fs/promises'\nimport {join, resolve} from 'node:path'\n\nimport {SANITY_CACHE_DIR} from '@sanity/cli-build/_internal/build'\n\nimport {extractManifest} from './extractManifest.js'\nimport {type StudioManifest} from './types.js'\nimport {MANIFEST_FILENAME} from './writeManifestFile.js'\n\n/**\n * Dev-time manifest output directory, relative to the studio working\n * directory. Sibling of Vite's `cacheDir` so it stays out of `dist` and is\n * ignored by default in typical `.gitignore` files.\n */\nconst MANIFEST_DIR = `${SANITY_CACHE_DIR}/manifest`\n\n/**\n * Run the worker-based studio schema extraction, write the resulting manifest\n * to `MANIFEST_DIR`, then read it back so the caller can inline it into the\n * registry.\n *\n * `configPath` must be the resolved `sanity.config.(ts|js)` path — passing it\n * in (e.g. from `findProjectRoot`) avoids re-traversing the filesystem on\n * every call.\n */\nexport async function extractStudioManifest(options: {\n configPath: string\n workDir: string\n}): Promise<StudioManifest | undefined> {\n const outPath = resolve(options.workDir, MANIFEST_DIR)\n await extractManifest({outPath, path: options.configPath, workDir: options.workDir})\n const raw = await readFile(join(outPath, MANIFEST_FILENAME), 'utf8')\n return JSON.parse(raw)\n}\n"],"names":["readFile","join","resolve","SANITY_CACHE_DIR","extractManifest","MANIFEST_FILENAME","MANIFEST_DIR","extractStudioManifest","options","outPath","workDir","path","configPath","raw","JSON","parse"],"mappings":"AAAA,SAAQA,QAAQ,QAAO,mBAAkB;AACzC,SAAQC,IAAI,EAAEC,OAAO,QAAO,YAAW;AAEvC,SAAQC,gBAAgB,QAAO,oCAAmC;AAElE,SAAQC,eAAe,QAAO,uBAAsB;AAEpD,SAAQC,iBAAiB,QAAO,yBAAwB;AAExD;;;;CAIC,GACD,MAAMC,eAAe,GAAGH,iBAAiB,SAAS,CAAC;AAEnD;;;;;;;;CAQC,GACD,OAAO,eAAeI,sBAAsBC,OAG3C;IACC,MAAMC,UAAUP,QAAQM,QAAQE,OAAO,EAAEJ;IACzC,MAAMF,gBAAgB;QAACK;QAASE,MAAMH,QAAQI,UAAU;QAAEF,SAASF,QAAQE,OAAO;IAAA;IAClF,MAAMG,MAAM,MAAMb,SAASC,KAAKQ,SAASJ,oBAAoB;IAC7D,OAAOS,KAAKC,KAAK,CAACF;AACpB"}
|
|
@@ -188,13 +188,16 @@ function buildClineServerConfig(token) {
|
|
|
188
188
|
};
|
|
189
189
|
}
|
|
190
190
|
function buildCodexCliServerConfig(token) {
|
|
191
|
-
|
|
192
|
-
http_headers: {
|
|
193
|
-
Authorization: `Bearer ${token}`
|
|
194
|
-
},
|
|
191
|
+
const config = {
|
|
195
192
|
type: 'http',
|
|
196
193
|
url: MCP_SERVER_URL
|
|
197
194
|
};
|
|
195
|
+
if (token) {
|
|
196
|
+
config.http_headers = {
|
|
197
|
+
Authorization: `Bearer ${token}`
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
return config;
|
|
198
201
|
}
|
|
199
202
|
function buildGitHubCopilotCliServerConfig(token) {
|
|
200
203
|
return {
|
|
@@ -274,6 +277,7 @@ function buildZedServerConfig(token) {
|
|
|
274
277
|
configKey: 'mcp_servers',
|
|
275
278
|
detect: detectCodexCli,
|
|
276
279
|
format: 'toml',
|
|
280
|
+
oauthOnly: true,
|
|
277
281
|
readToken: readTokenFromHttpHeaders,
|
|
278
282
|
skillsCliAgent: 'codex'
|
|
279
283
|
},
|