@sanity/workbench-cli 1.6.0 → 1.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_exports/build.d.ts +11 -2
- package/dist/_exports/build.js +1 -0
- package/dist/_exports/build.js.map +1 -1
- package/dist/_exports/deploy.d.ts +56 -37
- package/dist/_exports/deploy.js +1 -1
- package/dist/_exports/deploy.js.map +1 -1
- package/dist/_exports/dev.d.ts +0 -2
- package/dist/_exports/index.d.ts +38 -0
- package/dist/_exports/index.js +1 -0
- package/dist/_exports/index.js.map +1 -1
- package/dist/_exports/init.d.ts +2 -2
- package/dist/_exports/undeploy.d.ts +4 -2
- package/dist/actions/build/vite/plugins/plugin-sanity-app-id.js +15 -1
- package/dist/actions/build/vite/plugins/plugin-sanity-app-id.js.map +1 -1
- package/dist/actions/deploy/deployWorkbenchApp.js +55 -87
- package/dist/actions/deploy/deployWorkbenchApp.js.map +1 -1
- package/dist/actions/dev/startDevServerRegistration.js +9 -2
- package/dist/actions/dev/startDevServerRegistration.js.map +1 -1
- package/dist/actions/dev/startWorkbenchDev.js +1 -2
- package/dist/actions/dev/startWorkbenchDev.js.map +1 -1
- package/dist/actions/init/cliConfig.js +2 -0
- package/dist/actions/init/cliConfig.js.map +1 -1
- package/dist/actions/preview/startWorkbenchPreview.js +18 -2
- package/dist/actions/preview/startWorkbenchPreview.js.map +1 -1
- package/dist/appId.js +52 -0
- package/dist/appId.js.map +1 -0
- package/dist/resolveWorkbenchApp.js +1 -0
- package/dist/resolveWorkbenchApp.js.map +1 -1
- package/dist/services/applications.js +31 -27
- package/dist/services/applications.js.map +1 -1
- package/package.json +1 -1
package/dist/_exports/build.d.ts
CHANGED
|
@@ -3,6 +3,13 @@ import { CliConfig } from "@sanity/cli-core";
|
|
|
3
3
|
import { PluginOption } from "vite";
|
|
4
4
|
import { z } from "zod/mini";
|
|
5
5
|
|
|
6
|
+
/**
|
|
7
|
+
* The `build`/`start` id for a workbench app — a hash of its declared shape.
|
|
8
|
+
* Shared so the bundle inlined by `sanity build` and the registry entry advertised
|
|
9
|
+
* by `sanity start` resolve to the same id.
|
|
10
|
+
*/
|
|
11
|
+
export declare function buildAppId(app: ResolvedWorkbenchApp): string;
|
|
12
|
+
|
|
6
13
|
/**
|
|
7
14
|
* User-facing input for `unstable_defineApp`. Excludes the internal
|
|
8
15
|
* `applicationType`, `isSingleton`, and `config` — validated by the
|
|
@@ -131,8 +138,12 @@ declare interface DefineAppResult extends DefineAppInput {
|
|
|
131
138
|
declare interface ResolvedWorkbenchApp {
|
|
132
139
|
/** The app's unique `name` from `unstable_defineApp`. */
|
|
133
140
|
readonly name: string;
|
|
141
|
+
/** Organization that owns the app — part of its build-id identity. */
|
|
142
|
+
readonly organizationId: string;
|
|
134
143
|
/** Background worker services the app declares. */
|
|
135
144
|
readonly services: NonNullable<DefineAppInput["services"]>;
|
|
145
|
+
/** Hostname the application is created at on first deploy. */
|
|
146
|
+
readonly slug: string;
|
|
136
147
|
/** Dock panel views the app declares. */
|
|
137
148
|
readonly views: NonNullable<DefineAppInput["views"]>;
|
|
138
149
|
/** Resolved app kind — `studio` or one of the SDK app types. */
|
|
@@ -145,8 +156,6 @@ declare interface ResolvedWorkbenchApp {
|
|
|
145
156
|
readonly icon?: string;
|
|
146
157
|
/** Explicit singleton flag (a Sanity-owned app); `undefined` when the app doesn't set it. */
|
|
147
158
|
readonly isSingleton?: boolean;
|
|
148
|
-
/** Hostname the application is created at on first deploy. */
|
|
149
|
-
readonly slug?: string;
|
|
150
159
|
/** Dashboard visibility declared by the app; `undefined` when unset. */
|
|
151
160
|
readonly visibility?: AppVisibility;
|
|
152
161
|
}
|
package/dist/_exports/build.js
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
// view (`getWorkbench`) is the deploy entry's export.
|
|
6
6
|
export { workbenchOptimizeDeps } from '../actions/build/vite/optimize-deps.js';
|
|
7
7
|
export { workbenchVitePlugins } from '../actions/build/vite/workbench-vite-plugins.js';
|
|
8
|
+
export { buildAppId } from '../appId.js';
|
|
8
9
|
export { resolveWorkbenchApp } from '../resolveWorkbenchApp.js';
|
|
9
10
|
|
|
10
11
|
//# sourceMappingURL=build.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/_exports/build.ts"],"sourcesContent":["// Node-only build entry: the module-federation Vite plugins that\n// `@sanity/cli-build`'s `getViteConfig` swaps in for a workbench app, plus the\n// resolver the build reads declared views/services from. The build needs no\n// deploy-time guards, so it takes the bare `resolveWorkbenchApp` — the guarded\n// view (`getWorkbench`) is the deploy entry's export.\n\nexport {workbenchOptimizeDeps} from '../actions/build/vite/optimize-deps.js'\nexport {workbenchVitePlugins} from '../actions/build/vite/workbench-vite-plugins.js'\nexport {resolveWorkbenchApp, type WorkbenchExposes} from '../resolveWorkbenchApp.js'\n"],"names":["workbenchOptimizeDeps","workbenchVitePlugins","resolveWorkbenchApp"],"mappings":"AAAA,iEAAiE;AACjE,+EAA+E;AAC/E,4EAA4E;AAC5E,+EAA+E;AAC/E,sDAAsD;AAEtD,SAAQA,qBAAqB,QAAO,yCAAwC;AAC5E,SAAQC,oBAAoB,QAAO,kDAAiD;AACpF,SAAQC,mBAAmB,QAA8B,4BAA2B"}
|
|
1
|
+
{"version":3,"sources":["../../src/_exports/build.ts"],"sourcesContent":["// Node-only build entry: the module-federation Vite plugins that\n// `@sanity/cli-build`'s `getViteConfig` swaps in for a workbench app, plus the\n// resolver the build reads declared views/services from. The build needs no\n// deploy-time guards, so it takes the bare `resolveWorkbenchApp` — the guarded\n// view (`getWorkbench`) is the deploy entry's export.\n\nexport {workbenchOptimizeDeps} from '../actions/build/vite/optimize-deps.js'\nexport {workbenchVitePlugins} from '../actions/build/vite/workbench-vite-plugins.js'\nexport {buildAppId} from '../appId.js'\nexport {resolveWorkbenchApp, type WorkbenchExposes} from '../resolveWorkbenchApp.js'\n"],"names":["workbenchOptimizeDeps","workbenchVitePlugins","buildAppId","resolveWorkbenchApp"],"mappings":"AAAA,iEAAiE;AACjE,+EAA+E;AAC/E,4EAA4E;AAC5E,+EAA+E;AAC/E,sDAAsD;AAEtD,SAAQA,qBAAqB,QAAO,yCAAwC;AAC5E,SAAQC,oBAAoB,QAAO,kDAAiD;AACpF,SAAQC,UAAU,QAAO,cAAa;AACtC,SAAQC,mBAAmB,QAA8B,4BAA2B"}
|
|
@@ -59,6 +59,8 @@ declare interface BrettInterfaceBase {
|
|
|
59
59
|
export declare interface BrettWorkspace {
|
|
60
60
|
dataset: string;
|
|
61
61
|
projectId: string;
|
|
62
|
+
/** Lexicon schema descriptor id; Brett requires one per workspace. */
|
|
63
|
+
schemaDescriptorId: string;
|
|
62
64
|
basePath?: string;
|
|
63
65
|
icon?: string;
|
|
64
66
|
name?: string;
|
|
@@ -93,6 +95,41 @@ declare interface BuildExposesContext {
|
|
|
93
95
|
*/
|
|
94
96
|
export declare function checkBuiltOutput(sourceDir: string): Promise<void>;
|
|
95
97
|
|
|
98
|
+
/**
|
|
99
|
+
* Create a coreApp record (no deployment), so the CLI can build with its id
|
|
100
|
+
* before shipping the first deployment. First deploy only.
|
|
101
|
+
* @internal
|
|
102
|
+
*/
|
|
103
|
+
export declare function createCoreApp(options: {
|
|
104
|
+
isSingleton?: boolean;
|
|
105
|
+
organizationId: string;
|
|
106
|
+
slug: string;
|
|
107
|
+
title: string;
|
|
108
|
+
visibility?: AppVisibility;
|
|
109
|
+
}): Promise<CreatedApplication>;
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* A freshly created application record: its id, plus a way to undo the creation.
|
|
113
|
+
* The caller builds and deploys with the id, and calls `rollback` if a later
|
|
114
|
+
* step fails so the record isn't stranded at its slug.
|
|
115
|
+
* @internal
|
|
116
|
+
*/
|
|
117
|
+
export declare interface CreatedApplication {
|
|
118
|
+
applicationId: string;
|
|
119
|
+
rollback: () => Promise<void>;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Create a studio record (no deployment).
|
|
124
|
+
* @internal
|
|
125
|
+
*/
|
|
126
|
+
export declare function createStudio(options: {
|
|
127
|
+
organizationId: string;
|
|
128
|
+
projectId: string | undefined;
|
|
129
|
+
slug: string;
|
|
130
|
+
title: string;
|
|
131
|
+
}): Promise<CreatedApplication>;
|
|
132
|
+
|
|
96
133
|
/**
|
|
97
134
|
* User-facing input for `unstable_defineApp`. Excludes the internal
|
|
98
135
|
* `applicationType`, `isSingleton`, and `config` — validated by the
|
|
@@ -253,28 +290,6 @@ export declare function deployConfig(options: {
|
|
|
253
290
|
version: string;
|
|
254
291
|
}): Promise<void>;
|
|
255
292
|
|
|
256
|
-
/**
|
|
257
|
-
* Deploy a workbench coreApp through Brett: redeploy when `appId` is set,
|
|
258
|
-
* otherwise create the application at `slug`. Returns the application id for the
|
|
259
|
-
* shell to report.
|
|
260
|
-
* @internal
|
|
261
|
-
*/
|
|
262
|
-
export declare function deployCoreApp(options: {
|
|
263
|
-
appId: string | undefined;
|
|
264
|
-
icon?: string;
|
|
265
|
-
interfaces: readonly BrettInterface[];
|
|
266
|
-
isAutoUpdating: boolean;
|
|
267
|
-
isSingleton?: boolean;
|
|
268
|
-
organizationId: string;
|
|
269
|
-
slug: string;
|
|
270
|
-
sourceDir: string;
|
|
271
|
-
title: string;
|
|
272
|
-
version: string;
|
|
273
|
-
visibility?: AppVisibility;
|
|
274
|
-
}): Promise<{
|
|
275
|
-
applicationId: string;
|
|
276
|
-
}>;
|
|
277
|
-
|
|
278
293
|
/** A view or service as the deploy report and `--json` output surface it. */
|
|
279
294
|
export declare interface DeployedExpose {
|
|
280
295
|
name: string;
|
|
@@ -284,27 +299,29 @@ export declare interface DeployedExpose {
|
|
|
284
299
|
}
|
|
285
300
|
|
|
286
301
|
/**
|
|
287
|
-
*
|
|
288
|
-
*
|
|
289
|
-
*
|
|
302
|
+
* Ship a deployment to an already-created (or `deployment.appId`) application,
|
|
303
|
+
* then sync its mutable metadata (`title`, and `icon`/`visibility` when set)
|
|
304
|
+
* from config. The deploy endpoint ignores these, so a redeploy patches them
|
|
305
|
+
* here alongside the new deployment.
|
|
306
|
+
*
|
|
307
|
+
* `onDeployed` fires the instant the deployment is live, before the metadata
|
|
308
|
+
* sync — so a caller can disarm a create-time rollback that must not delete an
|
|
309
|
+
* application once it has an active deployment.
|
|
290
310
|
* @internal
|
|
291
311
|
*/
|
|
292
|
-
export declare function
|
|
293
|
-
|
|
312
|
+
export declare function deployWorkbenchApp(options: {
|
|
313
|
+
applicationId: string;
|
|
294
314
|
icon?: string;
|
|
295
315
|
interfaces: readonly BrettInterface[];
|
|
296
316
|
isAutoUpdating: boolean;
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
projectId: string | undefined;
|
|
317
|
+
label?: string;
|
|
318
|
+
onDeployed?: () => void;
|
|
300
319
|
sourceDir: string;
|
|
301
|
-
studioHost: string | undefined;
|
|
302
320
|
title: string;
|
|
303
321
|
version: string;
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
}>;
|
|
322
|
+
visibility?: AppVisibility;
|
|
323
|
+
workspaces?: readonly BrettWorkspace[];
|
|
324
|
+
}): Promise<void>;
|
|
308
325
|
|
|
309
326
|
export declare function getApplication(
|
|
310
327
|
applicationId: string,
|
|
@@ -325,8 +342,12 @@ export declare function getWorkbenchUrl(organizationId: string): string;
|
|
|
325
342
|
declare interface ResolvedWorkbenchApp {
|
|
326
343
|
/** The app's unique `name` from `unstable_defineApp`. */
|
|
327
344
|
readonly name: string;
|
|
345
|
+
/** Organization that owns the app — part of its build-id identity. */
|
|
346
|
+
readonly organizationId: string;
|
|
328
347
|
/** Background worker services the app declares. */
|
|
329
348
|
readonly services: NonNullable<DefineAppInput["services"]>;
|
|
349
|
+
/** Hostname the application is created at on first deploy. */
|
|
350
|
+
readonly slug: string;
|
|
330
351
|
/** Dock panel views the app declares. */
|
|
331
352
|
readonly views: NonNullable<DefineAppInput["views"]>;
|
|
332
353
|
/** Resolved app kind — `studio` or one of the SDK app types. */
|
|
@@ -339,8 +360,6 @@ declare interface ResolvedWorkbenchApp {
|
|
|
339
360
|
readonly icon?: string;
|
|
340
361
|
/** Explicit singleton flag (a Sanity-owned app); `undefined` when the app doesn't set it. */
|
|
341
362
|
readonly isSingleton?: boolean;
|
|
342
|
-
/** Hostname the application is created at on first deploy. */
|
|
343
|
-
readonly slug?: string;
|
|
344
363
|
/** Dashboard visibility declared by the app; `undefined` when unset. */
|
|
345
364
|
readonly visibility?: AppVisibility;
|
|
346
365
|
}
|
package/dist/_exports/deploy.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export { buildExposes, summarizeExposes } from '../actions/deploy/buildExposes.js';
|
|
2
2
|
export { checkBuiltOutput } from '../actions/deploy/checkBuiltOutput.js';
|
|
3
3
|
export { deployConfig, resolveInstallationId, summarizeConfig } from '../actions/deploy/deployConfig.js';
|
|
4
|
-
export {
|
|
4
|
+
export { createCoreApp, createStudio, deployWorkbenchApp } from '../actions/deploy/deployWorkbenchApp.js';
|
|
5
5
|
export { getWorkbench } from '../actions/deploy/getWorkbench.js';
|
|
6
6
|
export { getApplication, getApplicationUrl, getWorkbenchUrl } from '../services/applications.js';
|
|
7
7
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/_exports/deploy.ts"],"sourcesContent":["export {\n buildExposes,\n type DeployedExpose,\n summarizeExposes,\n} from '../actions/deploy/buildExposes.js'\nexport {checkBuiltOutput} from '../actions/deploy/checkBuiltOutput.js'\nexport {\n deployConfig,\n resolveInstallationId,\n summarizeConfig,\n} from '../actions/deploy/deployConfig.js'\nexport {
|
|
1
|
+
{"version":3,"sources":["../../src/_exports/deploy.ts"],"sourcesContent":["export {\n buildExposes,\n type DeployedExpose,\n summarizeExposes,\n} from '../actions/deploy/buildExposes.js'\nexport {checkBuiltOutput} from '../actions/deploy/checkBuiltOutput.js'\nexport {\n deployConfig,\n resolveInstallationId,\n summarizeConfig,\n} from '../actions/deploy/deployConfig.js'\nexport {\n createCoreApp,\n type CreatedApplication,\n createStudio,\n deployWorkbenchApp,\n} from '../actions/deploy/deployWorkbenchApp.js'\nexport {getWorkbench} from '../actions/deploy/getWorkbench.js'\nexport {\n type Application,\n type BrettInterface,\n type BrettWorkspace,\n getApplication,\n getApplicationUrl,\n getWorkbenchUrl,\n} from '../services/applications.js'\n"],"names":["buildExposes","summarizeExposes","checkBuiltOutput","deployConfig","resolveInstallationId","summarizeConfig","createCoreApp","createStudio","deployWorkbenchApp","getWorkbench","getApplication","getApplicationUrl","getWorkbenchUrl"],"mappings":"AAAA,SACEA,YAAY,EAEZC,gBAAgB,QACX,oCAAmC;AAC1C,SAAQC,gBAAgB,QAAO,wCAAuC;AACtE,SACEC,YAAY,EACZC,qBAAqB,EACrBC,eAAe,QACV,oCAAmC;AAC1C,SACEC,aAAa,EAEbC,YAAY,EACZC,kBAAkB,QACb,0CAAyC;AAChD,SAAQC,YAAY,QAAO,oCAAmC;AAC9D,SAIEC,cAAc,EACdC,iBAAiB,EACjBC,eAAe,QACV,8BAA6B"}
|
package/dist/_exports/dev.d.ts
CHANGED
|
@@ -162,8 +162,6 @@ export declare function startWorkbenchDev(
|
|
|
162
162
|
}>;
|
|
163
163
|
|
|
164
164
|
export declare interface StartWorkbenchDevOptions {
|
|
165
|
-
/** Resolved app id for the registry entry (the CLI owns id resolution). */
|
|
166
|
-
appId: string | undefined;
|
|
167
165
|
/** Directory for the workbench Vite server's dependency cache. */
|
|
168
166
|
cacheDir: string;
|
|
169
167
|
/** CLI-domain `app.id`/`deployment.appId` deprecation check, run before registering. */
|
package/dist/_exports/index.d.ts
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
import { z } from "zod/mini";
|
|
2
2
|
|
|
3
|
+
/** The declared shape hashed into a build id — the app's identity, not its code. */
|
|
4
|
+
declare interface BuildAppIdentity {
|
|
5
|
+
name: string;
|
|
6
|
+
organizationId: string;
|
|
7
|
+
entry?: string;
|
|
8
|
+
exposes?: WorkbenchExposes;
|
|
9
|
+
}
|
|
10
|
+
|
|
3
11
|
/**
|
|
4
12
|
* User-facing input for `unstable_defineApp`. Excludes the internal
|
|
5
13
|
* `applicationType`, `isSingleton`, and `config` — validated by the
|
|
@@ -230,6 +238,25 @@ export declare type PanelViewProps = ViewComponentBaseProps<{
|
|
|
230
238
|
type: "panel";
|
|
231
239
|
}>;
|
|
232
240
|
|
|
241
|
+
/**
|
|
242
|
+
* Mints the id the workbench keys everything on (React keys, panel ownership, the
|
|
243
|
+
* message bus, and the bundle's `__SANITY_APP_ID__`). Each run mode derives it
|
|
244
|
+
* differently so a running dev app, a local build, and a deployed twin can't
|
|
245
|
+
* share one: `sanity dev` uses the bound address, `sanity build`/`start` a hash
|
|
246
|
+
* of the declared shape. `sanity deploy` resolves its own id from the
|
|
247
|
+
* applications API, so it isn't handled here.
|
|
248
|
+
*/
|
|
249
|
+
export declare function resolveAppId(
|
|
250
|
+
source:
|
|
251
|
+
| {
|
|
252
|
+
app: BuildAppIdentity;
|
|
253
|
+
}
|
|
254
|
+
| {
|
|
255
|
+
host: string;
|
|
256
|
+
port: number;
|
|
257
|
+
},
|
|
258
|
+
): string;
|
|
259
|
+
|
|
233
260
|
/** @internal */
|
|
234
261
|
declare const SERVICE_CONTRACT_VERSION = 1;
|
|
235
262
|
|
|
@@ -366,4 +393,15 @@ declare const WORKBENCH_APP: unique symbol;
|
|
|
366
393
|
export declare type WorkbenchApp = DefineAppResult &
|
|
367
394
|
z.output<typeof DefineAppInputSchema>;
|
|
368
395
|
|
|
396
|
+
/**
|
|
397
|
+
* Bundled so adding a declaration family touches this type and the artifact
|
|
398
|
+
* expanders, not every hop of build/dev plumbing in between.
|
|
399
|
+
* @internal
|
|
400
|
+
*/
|
|
401
|
+
declare interface WorkbenchExposes {
|
|
402
|
+
config?: WorkbenchApp["config"];
|
|
403
|
+
services?: DefineAppInput["services"];
|
|
404
|
+
views?: DefineAppInput["views"];
|
|
405
|
+
}
|
|
406
|
+
|
|
369
407
|
export {};
|
package/dist/_exports/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/_exports/index.ts"],"sourcesContent":["export type {InterfaceType, ServiceType} from '../contract.js'\nexport {isWorkbenchApp, unstable_defineApp, unstable_defineMediaLibrary} from '../defineApp.js'\nexport type {\n DefineAppInput,\n DefineAppResult,\n DefineMediaLibraryInput,\n DockGroup,\n MediaLibraryField,\n WorkbenchApp,\n} from '../defineApp.js'\nexport {unstable_defineService} from '../defineService.js'\nexport type {\n DefinedService,\n ServiceCallback,\n ServiceContext,\n ServiceInfo,\n} from '../defineService.js'\nexport {unstable_defineView} from '../defineView.js'\nexport type {\n DefinedView,\n PanelComponent,\n PanelViewComponents,\n PanelViewProps,\n ViewComponentsByType,\n} from '../defineView.js'\n"],"names":["isWorkbenchApp","unstable_defineApp","unstable_defineMediaLibrary","unstable_defineService","unstable_defineView"],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../../src/_exports/index.ts"],"sourcesContent":["export {resolveAppId} from '../appId.js'\nexport type {InterfaceType, ServiceType} from '../contract.js'\nexport {isWorkbenchApp, unstable_defineApp, unstable_defineMediaLibrary} from '../defineApp.js'\nexport type {\n DefineAppInput,\n DefineAppResult,\n DefineMediaLibraryInput,\n DockGroup,\n MediaLibraryField,\n WorkbenchApp,\n} from '../defineApp.js'\nexport {unstable_defineService} from '../defineService.js'\nexport type {\n DefinedService,\n ServiceCallback,\n ServiceContext,\n ServiceInfo,\n} from '../defineService.js'\nexport {unstable_defineView} from '../defineView.js'\nexport type {\n DefinedView,\n PanelComponent,\n PanelViewComponents,\n PanelViewProps,\n ViewComponentsByType,\n} from '../defineView.js'\n"],"names":["resolveAppId","isWorkbenchApp","unstable_defineApp","unstable_defineMediaLibrary","unstable_defineService","unstable_defineView"],"mappings":"AAAA,SAAQA,YAAY,QAAO,cAAa;AAExC,SAAQC,cAAc,EAAEC,kBAAkB,EAAEC,2BAA2B,QAAO,kBAAiB;AAS/F,SAAQC,sBAAsB,QAAO,sBAAqB;AAO1D,SAAQC,mBAAmB,QAAO,mBAAkB"}
|
package/dist/_exports/init.d.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
/** App scaffold — `entry` auto-declares the navigable app view. */
|
|
2
2
|
export declare const workbenchAppConfigTemplate =
|
|
3
|
-
"\nimport {defineCliConfig, unstable_defineApp} from 'sanity/cli'\n\nexport default defineCliConfig({\n app: unstable_defineApp({\n name: '%name%',\n title: '%title%',\n organizationId: '%organizationId%',\n entry: '%entry%',\n }),\n})\n";
|
|
3
|
+
"\nimport {defineCliConfig, unstable_defineApp} from 'sanity/cli'\n\nexport default defineCliConfig({\n app: unstable_defineApp({\n name: '%name%',\n title: '%title%',\n slug: '%slug%',\n organizationId: '%organizationId%',\n entry: '%entry%',\n }),\n})\n";
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Studio scaffold — brands with name/title only, no `entry` (studio app views
|
|
7
7
|
* aren't implemented yet).
|
|
8
8
|
*/
|
|
9
9
|
export declare const workbenchStudioConfigTemplate =
|
|
10
|
-
"\nimport {defineCliConfig, unstable_defineApp} from 'sanity/cli'\n\nexport default defineCliConfig({\n api: {\n projectId: '%projectId%',\n dataset: '%dataset%'\n },\n app: unstable_defineApp({\n name: '%name%',\n title: '%title%',\n organizationId: '%organizationId%',\n }),\n deployment: {\n /**\n * Enable auto-updates for studios.\n * Learn more at https://www.sanity.io/docs/studio/latest-version-of-sanity#k47faf43faf56\n */\n autoUpdates: __BOOL__autoUpdates__,\n },\n})\n";
|
|
10
|
+
"\nimport {defineCliConfig, unstable_defineApp} from 'sanity/cli'\n\nexport default defineCliConfig({\n api: {\n projectId: '%projectId%',\n dataset: '%dataset%'\n },\n app: unstable_defineApp({\n name: '%name%',\n title: '%title%',\n slug: '%slug%',\n organizationId: '%organizationId%',\n }),\n deployment: {\n /**\n * Enable auto-updates for studios.\n * Learn more at https://www.sanity.io/docs/studio/latest-version-of-sanity#k47faf43faf56\n */\n autoUpdates: __BOOL__autoUpdates__,\n },\n})\n";
|
|
11
11
|
|
|
12
12
|
export {};
|
|
@@ -175,8 +175,12 @@ declare interface DeployedExpose {
|
|
|
175
175
|
declare interface ResolvedWorkbenchApp {
|
|
176
176
|
/** The app's unique `name` from `unstable_defineApp`. */
|
|
177
177
|
readonly name: string;
|
|
178
|
+
/** Organization that owns the app — part of its build-id identity. */
|
|
179
|
+
readonly organizationId: string;
|
|
178
180
|
/** Background worker services the app declares. */
|
|
179
181
|
readonly services: NonNullable<DefineAppInput["services"]>;
|
|
182
|
+
/** Hostname the application is created at on first deploy. */
|
|
183
|
+
readonly slug: string;
|
|
180
184
|
/** Dock panel views the app declares. */
|
|
181
185
|
readonly views: NonNullable<DefineAppInput["views"]>;
|
|
182
186
|
/** Resolved app kind — `studio` or one of the SDK app types. */
|
|
@@ -189,8 +193,6 @@ declare interface ResolvedWorkbenchApp {
|
|
|
189
193
|
readonly icon?: string;
|
|
190
194
|
/** Explicit singleton flag (a Sanity-owned app); `undefined` when the app doesn't set it. */
|
|
191
195
|
readonly isSingleton?: boolean;
|
|
192
|
-
/** Hostname the application is created at on first deploy. */
|
|
193
|
-
readonly slug?: string;
|
|
194
196
|
/** Dashboard visibility declared by the app; `undefined` when unset. */
|
|
195
197
|
readonly visibility?: AppVisibility;
|
|
196
198
|
}
|
|
@@ -1,13 +1,18 @@
|
|
|
1
|
+
import { SANITY_APP_ID_FILE } from '../../../../appId.js';
|
|
1
2
|
/**
|
|
2
|
-
*
|
|
3
|
+
* Inline the app's bus identity into its bundle: `@sanity/runtime` reads
|
|
3
4
|
* `__SANITY_APP_ID__` where it connects. `define` covers everything the
|
|
4
5
|
* pipeline transforms (all of a production build, and dev-served source); the
|
|
5
6
|
* rolldown define covers dev's pre-bundled dependencies, which skip Vite's
|
|
6
7
|
* define transform.
|
|
8
|
+
*
|
|
9
|
+
* A build also writes the id to disk so `sanity start`, which serves the build
|
|
10
|
+
* without recompiling, can advertise the exact id the bundle uses.
|
|
7
11
|
*/ export function sanityAppId(appId) {
|
|
8
12
|
const define = {
|
|
9
13
|
__SANITY_APP_ID__: JSON.stringify(appId)
|
|
10
14
|
};
|
|
15
|
+
let emitted = false;
|
|
11
16
|
return {
|
|
12
17
|
config: ()=>({
|
|
13
18
|
define,
|
|
@@ -19,6 +24,15 @@
|
|
|
19
24
|
}
|
|
20
25
|
}
|
|
21
26
|
}),
|
|
27
|
+
generateBundle () {
|
|
28
|
+
if (emitted) return;
|
|
29
|
+
emitted = true;
|
|
30
|
+
this.emitFile({
|
|
31
|
+
fileName: SANITY_APP_ID_FILE,
|
|
32
|
+
source: appId,
|
|
33
|
+
type: 'asset'
|
|
34
|
+
});
|
|
35
|
+
},
|
|
22
36
|
name: 'sanity/workbench/app-id'
|
|
23
37
|
};
|
|
24
38
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../src/actions/build/vite/plugins/plugin-sanity-app-id.ts"],"sourcesContent":["import {type Plugin} from 'vite'\n\n/**\n *
|
|
1
|
+
{"version":3,"sources":["../../../../../src/actions/build/vite/plugins/plugin-sanity-app-id.ts"],"sourcesContent":["import {type Plugin} from 'vite'\n\nimport {SANITY_APP_ID_FILE} from '../../../../appId.js'\n\n/**\n * Inline the app's bus identity into its bundle: `@sanity/runtime` reads\n * `__SANITY_APP_ID__` where it connects. `define` covers everything the\n * pipeline transforms (all of a production build, and dev-served source); the\n * rolldown define covers dev's pre-bundled dependencies, which skip Vite's\n * define transform.\n *\n * A build also writes the id to disk so `sanity start`, which serves the build\n * without recompiling, can advertise the exact id the bundle uses.\n */\nexport function sanityAppId(appId: string): Plugin {\n const define = {__SANITY_APP_ID__: JSON.stringify(appId)}\n let emitted = false\n return {\n config: () => ({define, optimizeDeps: {rolldownOptions: {transform: {define}}}}),\n generateBundle() {\n if (emitted) return\n emitted = true\n this.emitFile({fileName: SANITY_APP_ID_FILE, source: appId, type: 'asset'})\n },\n name: 'sanity/workbench/app-id',\n }\n}\n"],"names":["SANITY_APP_ID_FILE","sanityAppId","appId","define","__SANITY_APP_ID__","JSON","stringify","emitted","config","optimizeDeps","rolldownOptions","transform","generateBundle","emitFile","fileName","source","type","name"],"mappings":"AAEA,SAAQA,kBAAkB,QAAO,uBAAsB;AAEvD;;;;;;;;;CASC,GACD,OAAO,SAASC,YAAYC,KAAa;IACvC,MAAMC,SAAS;QAACC,mBAAmBC,KAAKC,SAAS,CAACJ;IAAM;IACxD,IAAIK,UAAU;IACd,OAAO;QACLC,QAAQ,IAAO,CAAA;gBAACL;gBAAQM,cAAc;oBAACC,iBAAiB;wBAACC,WAAW;4BAACR;wBAAM;oBAAC;gBAAC;YAAC,CAAA;QAC9ES;YACE,IAAIL,SAAS;YACbA,UAAU;YACV,IAAI,CAACM,QAAQ,CAAC;gBAACC,UAAUd;gBAAoBe,QAAQb;gBAAOc,MAAM;YAAO;QAC3E;QACAC,MAAM;IACR;AACF"}
|
|
@@ -1,121 +1,89 @@
|
|
|
1
1
|
import { basename, dirname } from 'node:path';
|
|
2
2
|
import { createGzip } from 'node:zlib';
|
|
3
|
-
import { exitCodes } from '@sanity/cli-core';
|
|
4
3
|
import { spinner } from '@sanity/cli-core/ux';
|
|
5
4
|
import { pack } from 'tar-fs';
|
|
6
|
-
import { createApplication, createDeployment, updateApplication } from '../../services/applications.js';
|
|
5
|
+
import { createApplication, createDeployment, deleteApplication, updateApplication } from '../../services/applications.js';
|
|
7
6
|
/**
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* shell to report.
|
|
7
|
+
* Create a coreApp record (no deployment), so the CLI can build with its id
|
|
8
|
+
* before shipping the first deployment. First deploy only.
|
|
11
9
|
* @internal
|
|
12
|
-
*/ export async function
|
|
13
|
-
const
|
|
14
|
-
const tarball = pack(dirname(sourceDir), {
|
|
15
|
-
entries: [
|
|
16
|
-
basename(sourceDir)
|
|
17
|
-
]
|
|
18
|
-
}).pipe(createGzip());
|
|
19
|
-
const spin = spinner('Deploying...').start();
|
|
10
|
+
*/ export async function createCoreApp(options) {
|
|
11
|
+
const spin = spinner('Creating application...').start();
|
|
20
12
|
try {
|
|
21
|
-
if (appId) {
|
|
22
|
-
await createDeployment({
|
|
23
|
-
applicationId: appId,
|
|
24
|
-
interfaces,
|
|
25
|
-
isAutoUpdating,
|
|
26
|
-
tarball,
|
|
27
|
-
version
|
|
28
|
-
});
|
|
29
|
-
await updateApplication(appId, {
|
|
30
|
-
title,
|
|
31
|
-
...icon ? {
|
|
32
|
-
icon
|
|
33
|
-
} : {}
|
|
34
|
-
});
|
|
35
|
-
spin.succeed();
|
|
36
|
-
return {
|
|
37
|
-
applicationId: appId
|
|
38
|
-
};
|
|
39
|
-
}
|
|
40
13
|
const { id } = await createApplication({
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
isSingleton,
|
|
44
|
-
organizationId,
|
|
45
|
-
slug,
|
|
46
|
-
tarball,
|
|
47
|
-
title,
|
|
48
|
-
type: 'coreApp',
|
|
49
|
-
version,
|
|
50
|
-
visibility
|
|
14
|
+
...options,
|
|
15
|
+
type: 'coreApp'
|
|
51
16
|
});
|
|
52
17
|
spin.succeed();
|
|
53
18
|
return {
|
|
54
|
-
applicationId: id
|
|
19
|
+
applicationId: id,
|
|
20
|
+
rollback: ()=>deleteApplication(id)
|
|
55
21
|
};
|
|
56
22
|
} catch (error) {
|
|
57
|
-
spin.
|
|
23
|
+
spin.fail();
|
|
58
24
|
throw error;
|
|
59
25
|
}
|
|
60
26
|
}
|
|
61
27
|
/**
|
|
62
|
-
*
|
|
63
|
-
* otherwise create the studio at `studioHost`. Returns the application id for
|
|
64
|
-
* the shell to report; a missing `studioHost` on create is a usage error.
|
|
28
|
+
* Create a studio record (no deployment).
|
|
65
29
|
* @internal
|
|
66
|
-
*/ export async function
|
|
67
|
-
const
|
|
30
|
+
*/ export async function createStudio(options) {
|
|
31
|
+
const spin = spinner('Creating studio...').start();
|
|
32
|
+
try {
|
|
33
|
+
const { id } = await createApplication({
|
|
34
|
+
...options,
|
|
35
|
+
type: 'studio'
|
|
36
|
+
});
|
|
37
|
+
spin.succeed();
|
|
38
|
+
return {
|
|
39
|
+
applicationId: id,
|
|
40
|
+
rollback: ()=>deleteApplication(id)
|
|
41
|
+
};
|
|
42
|
+
} catch (error) {
|
|
43
|
+
spin.fail();
|
|
44
|
+
throw error;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Ship a deployment to an already-created (or `deployment.appId`) application,
|
|
49
|
+
* then sync its mutable metadata (`title`, and `icon`/`visibility` when set)
|
|
50
|
+
* from config. The deploy endpoint ignores these, so a redeploy patches them
|
|
51
|
+
* here alongside the new deployment.
|
|
52
|
+
*
|
|
53
|
+
* `onDeployed` fires the instant the deployment is live, before the metadata
|
|
54
|
+
* sync — so a caller can disarm a create-time rollback that must not delete an
|
|
55
|
+
* application once it has an active deployment.
|
|
56
|
+
* @internal
|
|
57
|
+
*/ export async function deployWorkbenchApp(options) {
|
|
58
|
+
const { applicationId, icon, interfaces, isAutoUpdating, label = 'Deploying...', onDeployed, sourceDir, title, version, visibility, workspaces } = options;
|
|
68
59
|
const tarball = pack(dirname(sourceDir), {
|
|
69
60
|
entries: [
|
|
70
61
|
basename(sourceDir)
|
|
71
62
|
]
|
|
72
63
|
}).pipe(createGzip());
|
|
73
|
-
const spin = spinner(
|
|
64
|
+
const spin = spinner(label).start();
|
|
74
65
|
try {
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
applicationId: appId,
|
|
78
|
-
interfaces,
|
|
79
|
-
isAutoUpdating,
|
|
80
|
-
tarball,
|
|
81
|
-
version,
|
|
82
|
-
workspaces
|
|
83
|
-
});
|
|
84
|
-
await updateApplication(appId, {
|
|
85
|
-
title,
|
|
86
|
-
...icon ? {
|
|
87
|
-
icon
|
|
88
|
-
} : {}
|
|
89
|
-
});
|
|
90
|
-
spin.succeed();
|
|
91
|
-
return {
|
|
92
|
-
applicationId: appId
|
|
93
|
-
};
|
|
94
|
-
}
|
|
95
|
-
if (!studioHost) {
|
|
96
|
-
spin.fail();
|
|
97
|
-
return output.error('No studio hostname configured. Set `studioHost` in sanity.cli.ts to create a studio.', {
|
|
98
|
-
exit: exitCodes.USAGE_ERROR
|
|
99
|
-
});
|
|
100
|
-
}
|
|
101
|
-
const application = await createApplication({
|
|
102
|
-
icon,
|
|
66
|
+
await createDeployment({
|
|
67
|
+
applicationId,
|
|
103
68
|
interfaces,
|
|
104
|
-
|
|
105
|
-
projectId,
|
|
106
|
-
slug: studioHost,
|
|
69
|
+
isAutoUpdating,
|
|
107
70
|
tarball,
|
|
108
|
-
title,
|
|
109
|
-
type: 'studio',
|
|
110
71
|
version,
|
|
111
72
|
workspaces
|
|
112
73
|
});
|
|
74
|
+
onDeployed?.();
|
|
75
|
+
await updateApplication(applicationId, {
|
|
76
|
+
title,
|
|
77
|
+
...icon ? {
|
|
78
|
+
icon
|
|
79
|
+
} : {},
|
|
80
|
+
...visibility ? {
|
|
81
|
+
visibility
|
|
82
|
+
} : {}
|
|
83
|
+
});
|
|
113
84
|
spin.succeed();
|
|
114
|
-
return {
|
|
115
|
-
applicationId: application.id
|
|
116
|
-
};
|
|
117
85
|
} catch (error) {
|
|
118
|
-
spin.
|
|
86
|
+
spin.clear();
|
|
119
87
|
throw error;
|
|
120
88
|
}
|
|
121
89
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/actions/deploy/deployWorkbenchApp.ts"],"sourcesContent":["import {basename, dirname} from 'node:path'\nimport {createGzip} from 'node:zlib'\n\nimport {type AppVisibility
|
|
1
|
+
{"version":3,"sources":["../../../src/actions/deploy/deployWorkbenchApp.ts"],"sourcesContent":["import {basename, dirname} from 'node:path'\nimport {createGzip} from 'node:zlib'\n\nimport {type AppVisibility} from '@sanity/cli-core'\nimport {spinner} from '@sanity/cli-core/ux'\nimport {pack} from 'tar-fs'\n\nimport {\n type BrettInterface,\n type BrettWorkspace,\n createApplication,\n createDeployment,\n deleteApplication,\n updateApplication,\n} from '../../services/applications.js'\n\n/**\n * A freshly created application record: its id, plus a way to undo the creation.\n * The caller builds and deploys with the id, and calls `rollback` if a later\n * step fails so the record isn't stranded at its slug.\n * @internal\n */\nexport interface CreatedApplication {\n applicationId: string\n rollback: () => Promise<void>\n}\n\n/**\n * Create a coreApp record (no deployment), so the CLI can build with its id\n * before shipping the first deployment. First deploy only.\n * @internal\n */\nexport async function createCoreApp(options: {\n isSingleton?: boolean\n organizationId: string\n slug: string\n title: string\n visibility?: AppVisibility\n}): Promise<CreatedApplication> {\n const spin = spinner('Creating application...').start()\n try {\n const {id} = await createApplication({...options, type: 'coreApp'})\n spin.succeed()\n return {applicationId: id, rollback: () => deleteApplication(id)}\n } catch (error) {\n spin.fail()\n throw error\n }\n}\n\n/**\n * Create a studio record (no deployment).\n * @internal\n */\nexport async function createStudio(options: {\n organizationId: string\n projectId: string | undefined\n slug: string\n title: string\n}): Promise<CreatedApplication> {\n const spin = spinner('Creating studio...').start()\n try {\n const {id} = await createApplication({...options, type: 'studio'})\n spin.succeed()\n return {applicationId: id, rollback: () => deleteApplication(id)}\n } catch (error) {\n spin.fail()\n throw error\n }\n}\n\n/**\n * Ship a deployment to an already-created (or `deployment.appId`) application,\n * then sync its mutable metadata (`title`, and `icon`/`visibility` when set)\n * from config. The deploy endpoint ignores these, so a redeploy patches them\n * here alongside the new deployment.\n *\n * `onDeployed` fires the instant the deployment is live, before the metadata\n * sync — so a caller can disarm a create-time rollback that must not delete an\n * application once it has an active deployment.\n * @internal\n */\nexport async function deployWorkbenchApp(options: {\n applicationId: string\n icon?: string\n interfaces: readonly BrettInterface[]\n isAutoUpdating: boolean\n label?: string\n onDeployed?: () => void\n sourceDir: string\n title: string\n version: string\n visibility?: AppVisibility\n workspaces?: readonly BrettWorkspace[]\n}): Promise<void> {\n const {\n applicationId,\n icon,\n interfaces,\n isAutoUpdating,\n label = 'Deploying...',\n onDeployed,\n sourceDir,\n title,\n version,\n visibility,\n workspaces,\n } = options\n const tarball = pack(dirname(sourceDir), {entries: [basename(sourceDir)]}).pipe(createGzip())\n\n const spin = spinner(label).start()\n try {\n await createDeployment({\n applicationId,\n interfaces,\n isAutoUpdating,\n tarball,\n version,\n workspaces,\n })\n onDeployed?.()\n await updateApplication(applicationId, {\n title,\n ...(icon ? {icon} : {}),\n ...(visibility ? {visibility} : {}),\n })\n spin.succeed()\n } catch (error) {\n spin.clear()\n throw error\n }\n}\n"],"names":["basename","dirname","createGzip","spinner","pack","createApplication","createDeployment","deleteApplication","updateApplication","createCoreApp","options","spin","start","id","type","succeed","applicationId","rollback","error","fail","createStudio","deployWorkbenchApp","icon","interfaces","isAutoUpdating","label","onDeployed","sourceDir","title","version","visibility","workspaces","tarball","entries","pipe","clear"],"mappings":"AAAA,SAAQA,QAAQ,EAAEC,OAAO,QAAO,YAAW;AAC3C,SAAQC,UAAU,QAAO,YAAW;AAGpC,SAAQC,OAAO,QAAO,sBAAqB;AAC3C,SAAQC,IAAI,QAAO,SAAQ;AAE3B,SAGEC,iBAAiB,EACjBC,gBAAgB,EAChBC,iBAAiB,EACjBC,iBAAiB,QACZ,iCAAgC;AAavC;;;;CAIC,GACD,OAAO,eAAeC,cAAcC,OAMnC;IACC,MAAMC,OAAOR,QAAQ,2BAA2BS,KAAK;IACrD,IAAI;QACF,MAAM,EAACC,EAAE,EAAC,GAAG,MAAMR,kBAAkB;YAAC,GAAGK,OAAO;YAAEI,MAAM;QAAS;QACjEH,KAAKI,OAAO;QACZ,OAAO;YAACC,eAAeH;YAAII,UAAU,IAAMV,kBAAkBM;QAAG;IAClE,EAAE,OAAOK,OAAO;QACdP,KAAKQ,IAAI;QACT,MAAMD;IACR;AACF;AAEA;;;CAGC,GACD,OAAO,eAAeE,aAAaV,OAKlC;IACC,MAAMC,OAAOR,QAAQ,sBAAsBS,KAAK;IAChD,IAAI;QACF,MAAM,EAACC,EAAE,EAAC,GAAG,MAAMR,kBAAkB;YAAC,GAAGK,OAAO;YAAEI,MAAM;QAAQ;QAChEH,KAAKI,OAAO;QACZ,OAAO;YAACC,eAAeH;YAAII,UAAU,IAAMV,kBAAkBM;QAAG;IAClE,EAAE,OAAOK,OAAO;QACdP,KAAKQ,IAAI;QACT,MAAMD;IACR;AACF;AAEA;;;;;;;;;;CAUC,GACD,OAAO,eAAeG,mBAAmBX,OAYxC;IACC,MAAM,EACJM,aAAa,EACbM,IAAI,EACJC,UAAU,EACVC,cAAc,EACdC,QAAQ,cAAc,EACtBC,UAAU,EACVC,SAAS,EACTC,KAAK,EACLC,OAAO,EACPC,UAAU,EACVC,UAAU,EACX,GAAGrB;IACJ,MAAMsB,UAAU5B,KAAKH,QAAQ0B,YAAY;QAACM,SAAS;YAACjC,SAAS2B;SAAW;IAAA,GAAGO,IAAI,CAAChC;IAEhF,MAAMS,OAAOR,QAAQsB,OAAOb,KAAK;IACjC,IAAI;QACF,MAAMN,iBAAiB;YACrBU;YACAO;YACAC;YACAQ;YACAH;YACAE;QACF;QACAL;QACA,MAAMlB,kBAAkBQ,eAAe;YACrCY;YACA,GAAIN,OAAO;gBAACA;YAAI,IAAI,CAAC,CAAC;YACtB,GAAIQ,aAAa;gBAACA;YAAU,IAAI,CAAC,CAAC;QACpC;QACAnB,KAAKI,OAAO;IACd,EAAE,OAAOG,OAAO;QACdP,KAAKwB,KAAK;QACV,MAAMjB;IACR;AACF"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { getCliConfigUncached } from '@sanity/cli-core';
|
|
2
|
+
import { resolveAppId } from '../../appId.js';
|
|
2
3
|
import { deriveConfigs, deriveInterfaces } from './deriveInterfaces.js';
|
|
3
4
|
import { trackExposesSet } from './exposesSetId.js';
|
|
4
5
|
import { registerDevServer } from './registry.js';
|
|
@@ -16,7 +17,7 @@ import { startDevManifestWatcher } from './startDevManifestWatcher.js';
|
|
|
16
17
|
* interface changes. The workbench reads the entry to locate and render the
|
|
17
18
|
* server; the watcher keeps it current as `sanity.cli.ts` is edited.
|
|
18
19
|
*/ export async function startDevServerRegistration(options) {
|
|
19
|
-
const {
|
|
20
|
+
const { cliConfig, extractManifest, isApp, onInterfaceSetChange, output, server, workDir } = options;
|
|
20
21
|
const { host: appHost, port: appPort } = serverAddress(server);
|
|
21
22
|
// Forwarded alongside (not inside) the manifest so the workbench renders local
|
|
22
23
|
// panels/workers and reads the configs without a deploy.
|
|
@@ -27,7 +28,13 @@ import { startDevManifestWatcher } from './startDevManifestWatcher.js';
|
|
|
27
28
|
const registration = registerDevServer({
|
|
28
29
|
configs,
|
|
29
30
|
host: appHost,
|
|
30
|
-
id
|
|
31
|
+
// Keyed by where it's served (not the deployment id), so a running app can't
|
|
32
|
+
// collide with its deployed twin — on the configured port, not the bound one,
|
|
33
|
+
// to match `__SANITY_APP_ID__`, compiled before any non-strict shift.
|
|
34
|
+
id: resolveAppId({
|
|
35
|
+
host: appHost,
|
|
36
|
+
port: server.config.server.port ?? appPort
|
|
37
|
+
}),
|
|
31
38
|
interfaces,
|
|
32
39
|
port: appPort,
|
|
33
40
|
projectId: cliConfig?.api?.projectId,
|
|
@@ -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 {deriveConfigs, deriveInterfaces} from './deriveInterfaces.js'\nimport {trackExposesSet} from './exposesSetId.js'\nimport {type DevServerManifest, registerDevServer} from './registry.js'\nimport {startDevManifestWatcher} from './startDevManifestWatcher.js'\n\ninterface DevServerRegistrationOptions {\n
|
|
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 {resolveAppId} from '../../appId.js'\nimport {deriveConfigs, deriveInterfaces} from './deriveInterfaces.js'\nimport {trackExposesSet} from './exposesSetId.js'\nimport {type DevServerManifest, 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/** 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 // 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 = deriveConfigs(cliConfig.app)\n\n const registration = registerDevServer({\n configs,\n host: appHost,\n // Keyed by where it's served (not the deployment id), so a running app can't\n // collide with its deployed twin — on the configured port, not the bound one,\n // to match `__SANITY_APP_ID__`, compiled before any non-strict shift.\n id: resolveAppId({host: appHost, port: server.config.server.port ?? appPort}),\n interfaces,\n port: appPort,\n projectId: cliConfig?.api?.projectId,\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 app = (await getCliConfigUncached(params.workDir)).app\n return {\n configs: deriveConfigs(app),\n interfaces: deriveInterfaces(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","resolveAppId","deriveConfigs","deriveInterfaces","trackExposesSet","registerDevServer","startDevManifestWatcher","serverAddress","server","resolvedHost","config","host","addr","httpServer","address","port","startDevServerRegistration","options","cliConfig","extractManifest","isApp","onInterfaceSetChange","output","workDir","appHost","appPort","interfaces","app","configs","registration","id","projectId","api","type","exposesSet","watcher","extract","params","manifest","extraWatchFilenames","undefined","update","patch","changed","rebuiltServer","commit","close","release"],"mappings":"AAAA,SAAwBA,oBAAoB,QAAoB,mBAAkB;AAGlF,SAAQC,YAAY,QAAO,iBAAgB;AAC3C,SAAQC,aAAa,EAAEC,gBAAgB,QAAO,wBAAuB;AACrE,SAAQC,eAAe,QAAO,oBAAmB;AACjD,SAAgCC,iBAAiB,QAAO,gBAAe;AACvE,SAAQC,uBAAuB,QAAO,+BAA8B;AAiCpE,+HAA+H,GAC/H,SAASC,cAAcC,MAAqB;IAC1C,MAAMC,eAAeD,OAAOE,MAAM,CAACF,MAAM,CAACG,IAAI;IAC9C,MAAMC,OAAOJ,OAAOK,UAAU,EAAEC;IAChC,OAAO;QACLH,MAAM,OAAOF,iBAAiB,WAAWA,eAAe;QACxDM,MAAM,OAAOH,SAAS,YAAYA,OAAOA,KAAKG,IAAI,GAAGP,OAAOE,MAAM,CAACF,MAAM,CAACO,IAAI;IAChF;AACF;AAEA;;;;CAIC,GACD,OAAO,eAAeC,2BACpBC,OAAqC;IAErC,MAAM,EAACC,SAAS,EAAEC,eAAe,EAAEC,KAAK,EAAEC,oBAAoB,EAAEC,MAAM,EAAEd,MAAM,EAAEe,OAAO,EAAC,GAAGN;IAE3F,MAAM,EAACN,MAAMa,OAAO,EAAET,MAAMU,OAAO,EAAC,GAAGlB,cAAcC;IAErD,+EAA+E;IAC/E,yDAAyD;IACzD,MAAMkB,aAAavB,iBAAiBe,UAAUS,GAAG,EAAE;QAACP;IAAK;IACzD,MAAMQ,UAAU1B,cAAcgB,UAAUS,GAAG;IAE3C,MAAME,eAAexB,kBAAkB;QACrCuB;QACAjB,MAAMa;QACN,6EAA6E;QAC7E,8EAA8E;QAC9E,sEAAsE;QACtEM,IAAI7B,aAAa;YAACU,MAAMa;YAAST,MAAMP,OAAOE,MAAM,CAACF,MAAM,CAACO,IAAI,IAAIU;QAAO;QAC3EC;QACAX,MAAMU;QACNM,WAAWb,WAAWc,KAAKD;QAC3BE,MAAMb,QAAQ,YAAY;QAC1BG;IACF;IAEA,MAAMW,aAAa9B,gBAAgB;QAACwB;QAASF;IAAU;IAEvD,MAAMS,UAAU,MAAM7B,wBAAwB;QAC5C,4EAA4E;QAC5E,6CAA6C;QAC7C8B,SAAS,OAAOC;YACd,MAAMV,MAAM,AAAC,CAAA,MAAM3B,qBAAqBqC,OAAOd,OAAO,CAAA,EAAGI,GAAG;YAC5D,OAAO;gBACLC,SAAS1B,cAAcyB;gBACvBD,YAAYvB,iBAAiBwB,KAAK;oBAACP;gBAAK;gBACxCkB,UAAU,MAAMnB,gBAAgBkB;YAClC;QACF;QACA,2EAA2E;QAC3E,wEAAwE;QACxEE,qBAAqBnB,QAAQoB,YAAY;YAAC;YAAiB;SAAgB;QAC3ElB;QACAmB,QAAQ,OAAOC;YACb,IACE,CAACR,WAAWS,OAAO,CAAC;gBAClBf,SAASc,MAAMd,OAAO;gBACtBF,YAAYgB,MAAMhB,UAAU;YAC9B,IACA;gBACAG,aAAaY,MAAM,CAACC;gBACpB;YACF;YACA,4EAA4E;YAC5E,6EAA6E;YAC7E,MAAME,gBAAgB,MAAMvB;YAC5B,6EAA6E;YAC7Ea,WAAWW,MAAM,CAAC;gBAChBjB,SAASc,MAAMd,OAAO;gBACtBF,YAAYgB,MAAMhB,UAAU;YAC9B;YACA,qEAAqE;YACrEG,aAAaY,MAAM,CAACG,gBAAgB;gBAAC,GAAGF,KAAK;gBAAE,GAAGnC,cAAcqC,cAAc;YAAA,IAAIF;QACpF;QACAnB;IACF;IAEA,OAAO;QACLuB,OAAO;YACLjB,aAAakB,OAAO;YACpB,MAAMZ,QAAQW,KAAK;QACrB;IACF;AACF"}
|
|
@@ -13,7 +13,7 @@ import { startWorkbenchDevServer, startWorkbenchRemoteCoordinator } from './star
|
|
|
13
13
|
* server falls back to the configured port and announces its own URL, exactly as
|
|
14
14
|
* a plain `sanity dev` would.
|
|
15
15
|
*/ export async function startWorkbenchDev(options) {
|
|
16
|
-
const {
|
|
16
|
+
const { cacheDir, checkForDeprecatedAppId, cliConfig, extractManifest, httpHost, httpPort, isApp, output, reactStrictMode, startAppServer, workDir } = options;
|
|
17
17
|
// The remote can't render itself, so it runs as a plain app server (not the
|
|
18
18
|
// shell) that still claims the lock and bridges the registry, so app
|
|
19
19
|
// `sanity dev`s register into it.
|
|
@@ -83,7 +83,6 @@ import { startWorkbenchDevServer, startWorkbenchRemoteCoordinator } from './star
|
|
|
83
83
|
// The deprecated-id check and manifest extractor are CLI-domain, injected here.
|
|
84
84
|
checkForDeprecatedAppId();
|
|
85
85
|
const registration = await startDevServerRegistration({
|
|
86
|
-
appId,
|
|
87
86
|
cliConfig,
|
|
88
87
|
extractManifest,
|
|
89
88
|
isApp,
|
|
@@ -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 /**
|
|
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":"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"}
|
|
@@ -11,6 +11,7 @@ export default defineCliConfig({
|
|
|
11
11
|
app: unstable_defineApp({
|
|
12
12
|
name: '%name%',
|
|
13
13
|
title: '%title%',
|
|
14
|
+
slug: '%slug%',
|
|
14
15
|
organizationId: '%organizationId%',
|
|
15
16
|
entry: '%entry%',
|
|
16
17
|
}),
|
|
@@ -30,6 +31,7 @@ export default defineCliConfig({
|
|
|
30
31
|
app: unstable_defineApp({
|
|
31
32
|
name: '%name%',
|
|
32
33
|
title: '%title%',
|
|
34
|
+
slug: '%slug%',
|
|
33
35
|
organizationId: '%organizationId%',
|
|
34
36
|
}),
|
|
35
37
|
deployment: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/actions/init/cliConfig.ts"],"sourcesContent":["// `sanity.cli.ts` templates for workbench (`unstable_defineApp`) projects,\n// consumed by the CLI's `init` scaffolding. The branded `unstable_defineApp`\n// result is the sole workbench (module-federation) opt-in, so its config shape\n// is workbench's to own; the CLI keeps the non-workbench templates and the\n// `%placeholder%` substitution. `%name%`/`%title%`/etc. are filled in by the\n// CLI's template processor.\n\n/** App scaffold — `entry` auto-declares the navigable app view. */\nexport const workbenchAppConfigTemplate = `\nimport {defineCliConfig, unstable_defineApp} from 'sanity/cli'\n\nexport default defineCliConfig({\n app: unstable_defineApp({\n name: '%name%',\n title: '%title%',\n organizationId: '%organizationId%',\n entry: '%entry%',\n }),\n})\n`\n\n/**\n * Studio scaffold — brands with name/title only, no `entry` (studio app views\n * aren't implemented yet).\n */\nexport const workbenchStudioConfigTemplate = `\nimport {defineCliConfig, unstable_defineApp} from 'sanity/cli'\n\nexport default defineCliConfig({\n api: {\n projectId: '%projectId%',\n dataset: '%dataset%'\n },\n app: unstable_defineApp({\n name: '%name%',\n title: '%title%',\n organizationId: '%organizationId%',\n }),\n deployment: {\n /**\n * Enable auto-updates for studios.\n * Learn more at https://www.sanity.io/docs/studio/latest-version-of-sanity#k47faf43faf56\n */\n autoUpdates: __BOOL__autoUpdates__,\n },\n})\n`\n"],"names":["workbenchAppConfigTemplate","workbenchStudioConfigTemplate"],"mappings":"AAAA,2EAA2E;AAC3E,6EAA6E;AAC7E,+EAA+E;AAC/E,2EAA2E;AAC3E,6EAA6E;AAC7E,4BAA4B;AAE5B,iEAAiE,GACjE,OAAO,MAAMA,6BAA6B,CAAC
|
|
1
|
+
{"version":3,"sources":["../../../src/actions/init/cliConfig.ts"],"sourcesContent":["// `sanity.cli.ts` templates for workbench (`unstable_defineApp`) projects,\n// consumed by the CLI's `init` scaffolding. The branded `unstable_defineApp`\n// result is the sole workbench (module-federation) opt-in, so its config shape\n// is workbench's to own; the CLI keeps the non-workbench templates and the\n// `%placeholder%` substitution. `%name%`/`%title%`/etc. are filled in by the\n// CLI's template processor.\n\n/** App scaffold — `entry` auto-declares the navigable app view. */\nexport const workbenchAppConfigTemplate = `\nimport {defineCliConfig, unstable_defineApp} from 'sanity/cli'\n\nexport default defineCliConfig({\n app: unstable_defineApp({\n name: '%name%',\n title: '%title%',\n slug: '%slug%',\n organizationId: '%organizationId%',\n entry: '%entry%',\n }),\n})\n`\n\n/**\n * Studio scaffold — brands with name/title only, no `entry` (studio app views\n * aren't implemented yet).\n */\nexport const workbenchStudioConfigTemplate = `\nimport {defineCliConfig, unstable_defineApp} from 'sanity/cli'\n\nexport default defineCliConfig({\n api: {\n projectId: '%projectId%',\n dataset: '%dataset%'\n },\n app: unstable_defineApp({\n name: '%name%',\n title: '%title%',\n slug: '%slug%',\n organizationId: '%organizationId%',\n }),\n deployment: {\n /**\n * Enable auto-updates for studios.\n * Learn more at https://www.sanity.io/docs/studio/latest-version-of-sanity#k47faf43faf56\n */\n autoUpdates: __BOOL__autoUpdates__,\n },\n})\n`\n"],"names":["workbenchAppConfigTemplate","workbenchStudioConfigTemplate"],"mappings":"AAAA,2EAA2E;AAC3E,6EAA6E;AAC7E,+EAA+E;AAC/E,2EAA2E;AAC3E,6EAA6E;AAC7E,4BAA4B;AAE5B,iEAAiE,GACjE,OAAO,MAAMA,6BAA6B,CAAC;;;;;;;;;;;;AAY3C,CAAC,CAAA;AAED;;;CAGC,GACD,OAAO,MAAMC,gCAAgC,CAAC;;;;;;;;;;;;;;;;;;;;;;AAsB9C,CAAC,CAAA"}
|
|
@@ -1,5 +1,9 @@
|
|
|
1
|
+
import { readFile } from 'node:fs/promises';
|
|
2
|
+
import path from 'node:path';
|
|
1
3
|
import { styleText } from 'node:util';
|
|
2
4
|
import { findProjectRoot } from '@sanity/cli-core';
|
|
5
|
+
import { buildAppId, SANITY_APP_ID_FILE } from '../../appId.js';
|
|
6
|
+
import { resolveWorkbenchApp } from '../../resolveWorkbenchApp.js';
|
|
3
7
|
import { createServerLifecycle, toDisplayHost } from '../../util/serverOrchestration.js';
|
|
4
8
|
import { deriveConfigs, deriveInterfaces } from '../dev/deriveInterfaces.js';
|
|
5
9
|
import { registerDevServer } from '../dev/registry.js';
|
|
@@ -46,11 +50,16 @@ import { serveBuiltApplication } from './serveBuiltApplication.js';
|
|
|
46
50
|
// out of workbench-cli.
|
|
47
51
|
checkForDeprecatedAppId();
|
|
48
52
|
const configPath = (await findProjectRoot(workDir)).path;
|
|
53
|
+
const workbench = resolveWorkbenchApp(cliConfig);
|
|
54
|
+
// Read the id the build inlined so start matches it even for a deploy build
|
|
55
|
+
// (which carries the API id, not the shape hash); fall back for older builds.
|
|
56
|
+
const inlinedId = await readInlinedAppId(outDir);
|
|
49
57
|
const registration = registerDevServer({
|
|
50
58
|
configs: deriveConfigs(cliConfig.app),
|
|
51
59
|
host: remote.host,
|
|
52
|
-
//
|
|
53
|
-
|
|
60
|
+
// `start` serves a build, so it advertises the build's inlined id (matching
|
|
61
|
+
// the bundle's `__SANITY_APP_ID__`), not the dev host-port.
|
|
62
|
+
id: workbench ? inlinedId ?? buildAppId(workbench) : `${remote.host}-${remote.port}`,
|
|
54
63
|
interfaces: deriveInterfaces(cliConfig.app, {
|
|
55
64
|
isApp
|
|
56
65
|
}),
|
|
@@ -87,5 +96,12 @@ import { serveBuiltApplication } from './serveBuiltApplication.js';
|
|
|
87
96
|
close
|
|
88
97
|
};
|
|
89
98
|
}
|
|
99
|
+
/** The id the build inlined into its bundle, or undefined when absent. */ async function readInlinedAppId(outDir) {
|
|
100
|
+
try {
|
|
101
|
+
return (await readFile(path.join(outDir, SANITY_APP_ID_FILE), 'utf8')).trim() || undefined;
|
|
102
|
+
} catch {
|
|
103
|
+
return undefined;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
90
106
|
|
|
91
107
|
//# sourceMappingURL=startWorkbenchPreview.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/actions/preview/startWorkbenchPreview.ts"],"sourcesContent":["import {styleText} from 'node:util'\n\nimport {type CliConfig, findProjectRoot, type Output} from '@sanity/cli-core'\n\nimport {createServerLifecycle, toDisplayHost} from '../../util/serverOrchestration.js'\nimport {deriveConfigs, deriveInterfaces} from '../dev/deriveInterfaces.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 registration = registerDevServer({\n configs: deriveConfigs(cliConfig.app),\n host: remote.host,\n //
|
|
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 {resolveWorkbenchApp} from '../../resolveWorkbenchApp.js'\nimport {createServerLifecycle, toDisplayHost} from '../../util/serverOrchestration.js'\nimport {deriveConfigs, deriveInterfaces} from '../dev/deriveInterfaces.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 // Read the id the build inlined so start matches it even for a deploy build\n // (which carries the API id, not the shape hash); fall back for older builds.\n const inlinedId = await readInlinedAppId(outDir)\n const registration = registerDevServer({\n configs: deriveConfigs(cliConfig.app),\n host: remote.host,\n // `start` serves a build, so it advertises the build's inlined id (matching\n // the bundle's `__SANITY_APP_ID__`), not the dev host-port.\n id: workbench ? (inlinedId ?? buildAppId(workbench)) : `${remote.host}-${remote.port}`,\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","resolveWorkbenchApp","createServerLifecycle","toDisplayHost","deriveConfigs","deriveInterfaces","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","inlinedId","readInlinedAppId","registration","configs","app","host","id","port","interfaces","manifest","manifestUpdatedAt","Date","toISOString","projectId","api","type","release","workbenchUrl","log","remoteUrl","join","trim","undefined"],"mappings":"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"}
|
package/dist/appId.js
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { hash } from 'node:crypto';
|
|
2
|
+
/**
|
|
3
|
+
* File the build writes into its output, carrying the id compiled into the
|
|
4
|
+
* bundle. `sanity start` serves a build without recompiling, so it reads this
|
|
5
|
+
* instead of recomputing — a deploy inlines the API id, not the shape hash.
|
|
6
|
+
*/ export const SANITY_APP_ID_FILE = 'sanity-app-id.txt';
|
|
7
|
+
/**
|
|
8
|
+
* Mints the id the workbench keys everything on (React keys, panel ownership, the
|
|
9
|
+
* message bus, and the bundle's `__SANITY_APP_ID__`). Each run mode derives it
|
|
10
|
+
* differently so a running dev app, a local build, and a deployed twin can't
|
|
11
|
+
* share one: `sanity dev` uses the bound address, `sanity build`/`start` a hash
|
|
12
|
+
* of the declared shape. `sanity deploy` resolves its own id from the
|
|
13
|
+
* applications API, so it isn't handled here.
|
|
14
|
+
*/ export function resolveAppId(source) {
|
|
15
|
+
if ('app' in source) {
|
|
16
|
+
const { app } = source;
|
|
17
|
+
const canonical = (interfaces)=>(interfaces ?? []).map((i)=>[
|
|
18
|
+
i.type,
|
|
19
|
+
i.name,
|
|
20
|
+
i.src
|
|
21
|
+
]).toSorted();
|
|
22
|
+
return hash('sha1', JSON.stringify({
|
|
23
|
+
config: app.exposes?.config ?? null,
|
|
24
|
+
entry: app.entry ?? null,
|
|
25
|
+
name: app.name,
|
|
26
|
+
organizationId: app.organizationId,
|
|
27
|
+
services: canonical(app.exposes?.services),
|
|
28
|
+
views: canonical(app.exposes?.views)
|
|
29
|
+
}), 'hex');
|
|
30
|
+
}
|
|
31
|
+
return `${source.host}-${source.port}`;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* The `build`/`start` id for a workbench app — a hash of its declared shape.
|
|
35
|
+
* Shared so the bundle inlined by `sanity build` and the registry entry advertised
|
|
36
|
+
* by `sanity start` resolve to the same id.
|
|
37
|
+
*/ export function buildAppId(app) {
|
|
38
|
+
return resolveAppId({
|
|
39
|
+
app: {
|
|
40
|
+
entry: app.entry,
|
|
41
|
+
exposes: {
|
|
42
|
+
config: app.config,
|
|
43
|
+
services: app.services,
|
|
44
|
+
views: app.views
|
|
45
|
+
},
|
|
46
|
+
name: app.name,
|
|
47
|
+
organizationId: app.organizationId
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
//# sourceMappingURL=appId.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/appId.ts"],"sourcesContent":["import {hash} from 'node:crypto'\n\nimport {type ResolvedWorkbenchApp, type WorkbenchExposes} from './resolveWorkbenchApp.js'\n\n/**\n * File the build writes into its output, carrying the id compiled into the\n * bundle. `sanity start` serves a build without recompiling, so it reads this\n * instead of recomputing — a deploy inlines the API id, not the shape hash.\n */\nexport const SANITY_APP_ID_FILE = 'sanity-app-id.txt'\n\n/** The declared shape hashed into a build id — the app's identity, not its code. */\nexport interface BuildAppIdentity {\n name: string\n organizationId: string\n\n entry?: string\n exposes?: WorkbenchExposes\n}\n\n/**\n * Mints the id the workbench keys everything on (React keys, panel ownership, the\n * message bus, and the bundle's `__SANITY_APP_ID__`). Each run mode derives it\n * differently so a running dev app, a local build, and a deployed twin can't\n * share one: `sanity dev` uses the bound address, `sanity build`/`start` a hash\n * of the declared shape. `sanity deploy` resolves its own id from the\n * applications API, so it isn't handled here.\n */\nexport function resolveAppId(\n source: {app: BuildAppIdentity} | {host: string; port: number},\n): string {\n if ('app' in source) {\n const {app} = source\n const canonical = (\n interfaces: ReadonlyArray<{name: string; src: string; type: string}> | undefined,\n ): Array<[string, string, string]> =>\n (interfaces ?? []).map((i): [string, string, string] => [i.type, i.name, i.src]).toSorted()\n return hash(\n 'sha1',\n JSON.stringify({\n config: app.exposes?.config ?? null,\n entry: app.entry ?? null,\n name: app.name,\n organizationId: app.organizationId,\n services: canonical(app.exposes?.services),\n views: canonical(app.exposes?.views),\n }),\n 'hex',\n )\n }\n return `${source.host}-${source.port}`\n}\n\n/**\n * The `build`/`start` id for a workbench app — a hash of its declared shape.\n * Shared so the bundle inlined by `sanity build` and the registry entry advertised\n * by `sanity start` resolve to the same id.\n */\nexport function buildAppId(app: ResolvedWorkbenchApp): string {\n return resolveAppId({\n app: {\n entry: app.entry,\n exposes: {config: app.config, services: app.services, views: app.views},\n name: app.name,\n organizationId: app.organizationId,\n },\n })\n}\n"],"names":["hash","SANITY_APP_ID_FILE","resolveAppId","source","app","canonical","interfaces","map","i","type","name","src","toSorted","JSON","stringify","config","exposes","entry","organizationId","services","views","host","port","buildAppId"],"mappings":"AAAA,SAAQA,IAAI,QAAO,cAAa;AAIhC;;;;CAIC,GACD,OAAO,MAAMC,qBAAqB,oBAAmB;AAWrD;;;;;;;CAOC,GACD,OAAO,SAASC,aACdC,MAA8D;IAE9D,IAAI,SAASA,QAAQ;QACnB,MAAM,EAACC,GAAG,EAAC,GAAGD;QACd,MAAME,YAAY,CAChBC,aAEA,AAACA,CAAAA,cAAc,EAAE,AAAD,EAAGC,GAAG,CAAC,CAACC,IAAgC;oBAACA,EAAEC,IAAI;oBAAED,EAAEE,IAAI;oBAAEF,EAAEG,GAAG;iBAAC,EAAEC,QAAQ;QAC3F,OAAOZ,KACL,QACAa,KAAKC,SAAS,CAAC;YACbC,QAAQX,IAAIY,OAAO,EAAED,UAAU;YAC/BE,OAAOb,IAAIa,KAAK,IAAI;YACpBP,MAAMN,IAAIM,IAAI;YACdQ,gBAAgBd,IAAIc,cAAc;YAClCC,UAAUd,UAAUD,IAAIY,OAAO,EAAEG;YACjCC,OAAOf,UAAUD,IAAIY,OAAO,EAAEI;QAChC,IACA;IAEJ;IACA,OAAO,GAAGjB,OAAOkB,IAAI,CAAC,CAAC,EAAElB,OAAOmB,IAAI,EAAE;AACxC;AAEA;;;;CAIC,GACD,OAAO,SAASC,WAAWnB,GAAyB;IAClD,OAAOF,aAAa;QAClBE,KAAK;YACHa,OAAOb,IAAIa,KAAK;YAChBD,SAAS;gBAACD,QAAQX,IAAIW,MAAM;gBAAEI,UAAUf,IAAIe,QAAQ;gBAAEC,OAAOhB,IAAIgB,KAAK;YAAA;YACtEV,MAAMN,IAAIM,IAAI;YACdQ,gBAAgBd,IAAIc,cAAc;QACpC;IACF;AACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/resolveWorkbenchApp.ts"],"sourcesContent":["// Package-internal shared resolver: turn a CLI config's branded\n// `unstable_defineApp` app into its declared interfaces, or `null` for a plain\n// project. The build and deploy accessors (actions/build, actions/deploy) each\n// build their command-specific view on top of this one brand-check +\n// extraction, so the discrimination lives in exactly one place.\n\nimport {type AppVisibility, type CliConfig} from '@sanity/cli-core'\n\nimport {type DefineAppInput, isWorkbenchApp, readConfig, type WorkbenchApp} from './defineApp.js'\n\n/**\n * Bundled so adding a declaration family touches this type and the artifact\n * expanders, not every hop of build/dev plumbing in between.\n * @internal\n */\nexport interface WorkbenchExposes {\n config?: WorkbenchApp['config']\n services?: DefineAppInput['services']\n views?: DefineAppInput['views']\n}\n\n/** @public */\nexport interface ResolvedWorkbenchApp {\n /** The app's unique `name` from `unstable_defineApp`. */\n readonly name: string\n /** Background worker services the app declares. */\n readonly services: NonNullable<DefineAppInput['services']>\n\n /** Dock panel views the app declares. */\n readonly views: NonNullable<DefineAppInput['views']>\n\n /** Resolved app kind — `studio` or one of the SDK app types. */\n readonly applicationType?: string\n /** Deploys on its own path, separate from the interfaces. */\n readonly config?: WorkbenchApp['config']\n /** SDK app-view entrypoint, when declared. */\n readonly entry?: string\n /** Path to the app's icon SVG, resolved and shipped to Brett on deploy. */\n readonly icon?: string\n /** Explicit singleton flag (a Sanity-owned app); `undefined` when the app doesn't set it. */\n readonly isSingleton?: boolean\n /**
|
|
1
|
+
{"version":3,"sources":["../src/resolveWorkbenchApp.ts"],"sourcesContent":["// Package-internal shared resolver: turn a CLI config's branded\n// `unstable_defineApp` app into its declared interfaces, or `null` for a plain\n// project. The build and deploy accessors (actions/build, actions/deploy) each\n// build their command-specific view on top of this one brand-check +\n// extraction, so the discrimination lives in exactly one place.\n\nimport {type AppVisibility, type CliConfig} from '@sanity/cli-core'\n\nimport {type DefineAppInput, isWorkbenchApp, readConfig, type WorkbenchApp} from './defineApp.js'\n\n/**\n * Bundled so adding a declaration family touches this type and the artifact\n * expanders, not every hop of build/dev plumbing in between.\n * @internal\n */\nexport interface WorkbenchExposes {\n config?: WorkbenchApp['config']\n services?: DefineAppInput['services']\n views?: DefineAppInput['views']\n}\n\n/** @public */\nexport interface ResolvedWorkbenchApp {\n /** The app's unique `name` from `unstable_defineApp`. */\n readonly name: string\n /** Organization that owns the app — part of its build-id identity. */\n readonly organizationId: string\n /** Background worker services the app declares. */\n readonly services: NonNullable<DefineAppInput['services']>\n\n /** Hostname the application is created at on first deploy. */\n readonly slug: string\n\n /** Dock panel views the app declares. */\n readonly views: NonNullable<DefineAppInput['views']>\n\n /** Resolved app kind — `studio` or one of the SDK app types. */\n readonly applicationType?: string\n /** Deploys on its own path, separate from the interfaces. */\n readonly config?: WorkbenchApp['config']\n /** SDK app-view entrypoint, when declared. */\n readonly entry?: string\n /** Path to the app's icon SVG, resolved and shipped to Brett on deploy. */\n readonly icon?: string\n /** Explicit singleton flag (a Sanity-owned app); `undefined` when the app doesn't set it. */\n readonly isSingleton?: boolean\n /** Dashboard visibility declared by the app; `undefined` when unset. */\n readonly visibility?: AppVisibility\n}\n\n/**\n * Resolve the workbench app for a CLI config, or `null` for a plain project.\n * @public\n */\nexport function resolveWorkbenchApp(\n cliConfig: CliConfig | null | undefined,\n): ResolvedWorkbenchApp | null {\n const app = cliConfig?.app\n if (!isWorkbenchApp(app)) return null\n\n return {\n applicationType: app.applicationType,\n config: readConfig(app),\n entry: app.entry,\n icon: app.icon,\n isSingleton: app.isSingleton,\n name: app.name,\n organizationId: app.organizationId,\n services: app.services ?? [],\n slug: app.slug,\n views: app.views ?? [],\n visibility: app.visibility,\n }\n}\n"],"names":["isWorkbenchApp","readConfig","resolveWorkbenchApp","cliConfig","app","applicationType","config","entry","icon","isSingleton","name","organizationId","services","slug","views","visibility"],"mappings":"AAAA,gEAAgE;AAChE,+EAA+E;AAC/E,+EAA+E;AAC/E,qEAAqE;AACrE,gEAAgE;AAIhE,SAA6BA,cAAc,EAAEC,UAAU,QAA0B,iBAAgB;AA0CjG;;;CAGC,GACD,OAAO,SAASC,oBACdC,SAAuC;IAEvC,MAAMC,MAAMD,WAAWC;IACvB,IAAI,CAACJ,eAAeI,MAAM,OAAO;IAEjC,OAAO;QACLC,iBAAiBD,IAAIC,eAAe;QACpCC,QAAQL,WAAWG;QACnBG,OAAOH,IAAIG,KAAK;QAChBC,MAAMJ,IAAII,IAAI;QACdC,aAAaL,IAAIK,WAAW;QAC5BC,MAAMN,IAAIM,IAAI;QACdC,gBAAgBP,IAAIO,cAAc;QAClCC,UAAUR,IAAIQ,QAAQ,IAAI,EAAE;QAC5BC,MAAMT,IAAIS,IAAI;QACdC,OAAOV,IAAIU,KAAK,IAAI,EAAE;QACtBC,YAAYX,IAAIW,UAAU;IAC5B;AACF"}
|
|
@@ -27,35 +27,39 @@ export async function getApplication(applicationId) {
|
|
|
27
27
|
throw err;
|
|
28
28
|
}
|
|
29
29
|
}
|
|
30
|
-
/**
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
30
|
+
/**
|
|
31
|
+
* Create an application record (no deployment), so the CLI can build with the
|
|
32
|
+
* returned id, then ship it via {@link createDeployment}.
|
|
33
|
+
*/ export async function createApplication(options) {
|
|
34
|
+
const { isSingleton, organizationId, projectId, slug, title, type, visibility } = options;
|
|
35
|
+
const client = await getClient();
|
|
36
|
+
return client.request({
|
|
37
|
+
body: {
|
|
38
|
+
organizationId,
|
|
39
|
+
slug,
|
|
40
|
+
title,
|
|
41
|
+
type,
|
|
42
|
+
...isSingleton === undefined ? {} : {
|
|
43
|
+
isSingleton
|
|
44
|
+
},
|
|
45
|
+
...visibility ? {
|
|
46
|
+
visibility
|
|
47
|
+
} : {},
|
|
48
|
+
// Studio config is set once, at create — it's immutable on redeploy.
|
|
49
|
+
...projectId ? {
|
|
50
|
+
config: {
|
|
51
|
+
studio: {
|
|
52
|
+
projectId
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
} : {}
|
|
56
|
+
},
|
|
57
|
+
method: 'POST',
|
|
58
|
+
uri: `/applications`
|
|
52
59
|
});
|
|
53
|
-
return request(`/applications`, formData);
|
|
54
60
|
}
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
* redeploy syncs the title (and icon) from config here alongside the new deployment.
|
|
58
|
-
*/ export async function updateApplication(applicationId, update) {
|
|
61
|
+
// Patch an application's mutable fields.
|
|
62
|
+
export async function updateApplication(applicationId, update) {
|
|
59
63
|
const client = await getClient();
|
|
60
64
|
await client.request({
|
|
61
65
|
body: update,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/services/applications.ts"],"sourcesContent":["import {PassThrough} from 'node:stream'\nimport {type Gzip} from 'node:zlib'\n\nimport {type AppVisibility, getGlobalCliClient} from '@sanity/cli-core'\nimport {isStaging} from '@sanity/cli-core/util'\nimport FormData from 'form-data'\n\nimport {type AppInterfaceMetadata} from '../contract.js'\nimport {APP_WORKBENCH_API_VERSION} from './apiVersion.js'\n\nexport type ApplicationType = 'coreApp' | 'studio'\n\nexport interface Application {\n id: string\n organizationId: string\n slug: string | null\n title: string\n type: ApplicationType\n}\n\ninterface BrettInterfaceBase {\n moduleId: string\n name: string\n title: string\n version: string\n}\n\n/**\n * An interface as Brett stores it, discriminated on `type`. `moduleId` is\n * remote-relative — the host prepends the app's id. Brett assigns the id.\n * @internal\n */\nexport type BrettInterface =\n | (BrettInterfaceBase & {metadata: AppInterfaceMetadata | null; type: 'app'})\n | (BrettInterfaceBase & {metadata: null; type: 'panel'})\n | (BrettInterfaceBase & {metadata: null; type: 'worker'})\n\n/** A studio workspace as Brett stores it. */\nexport interface BrettWorkspace {\n dataset: string\n projectId: string\n\n basePath?: string\n icon?: string\n name?: string\n subtitle?: string\n title?: string\n}\n\nexport function getWorkbenchUrl(organizationId: string): string {\n return `https://${organizationId}.${isStaging() ? 'run.sanity.work' : 'sanity.run'}`\n}\n\n/** Where a deployed application is served on its organization's workbench. */\nexport function getApplicationUrl(\n application: Pick<Application, 'id' | 'organizationId' | 'type'>,\n): string {\n const segment = application.type === 'studio' ? 'studio' : 'application'\n return `${getWorkbenchUrl(application.organizationId)}/${segment}/${application.id}`\n}\n\nasync function getClient() {\n return getGlobalCliClient({apiVersion: APP_WORKBENCH_API_VERSION, requireUser: true})\n}\n\nexport async function getApplication(applicationId: string): Promise<Application | null> {\n const client = await getClient()\n try {\n return await client.request({uri: `/applications/${applicationId}`})\n } catch (err) {\n if ((err as {statusCode?: number})?.statusCode === 404) return null\n throw err\n }\n}\n\n
|
|
1
|
+
{"version":3,"sources":["../../src/services/applications.ts"],"sourcesContent":["import {PassThrough} from 'node:stream'\nimport {type Gzip} from 'node:zlib'\n\nimport {type AppVisibility, getGlobalCliClient} from '@sanity/cli-core'\nimport {isStaging} from '@sanity/cli-core/util'\nimport FormData from 'form-data'\n\nimport {type AppInterfaceMetadata} from '../contract.js'\nimport {APP_WORKBENCH_API_VERSION} from './apiVersion.js'\n\nexport type ApplicationType = 'coreApp' | 'studio'\n\nexport interface Application {\n id: string\n organizationId: string\n slug: string | null\n title: string\n type: ApplicationType\n}\n\ninterface BrettInterfaceBase {\n moduleId: string\n name: string\n title: string\n version: string\n}\n\n/**\n * An interface as Brett stores it, discriminated on `type`. `moduleId` is\n * remote-relative — the host prepends the app's id. Brett assigns the id.\n * @internal\n */\nexport type BrettInterface =\n | (BrettInterfaceBase & {metadata: AppInterfaceMetadata | null; type: 'app'})\n | (BrettInterfaceBase & {metadata: null; type: 'panel'})\n | (BrettInterfaceBase & {metadata: null; type: 'worker'})\n\n/** A studio workspace as Brett stores it. */\nexport interface BrettWorkspace {\n dataset: string\n projectId: string\n /** Lexicon schema descriptor id; Brett requires one per workspace. */\n schemaDescriptorId: string\n\n basePath?: string\n icon?: string\n name?: string\n subtitle?: string\n title?: string\n}\n\nexport function getWorkbenchUrl(organizationId: string): string {\n return `https://${organizationId}.${isStaging() ? 'run.sanity.work' : 'sanity.run'}`\n}\n\n/** Where a deployed application is served on its organization's workbench. */\nexport function getApplicationUrl(\n application: Pick<Application, 'id' | 'organizationId' | 'type'>,\n): string {\n const segment = application.type === 'studio' ? 'studio' : 'application'\n return `${getWorkbenchUrl(application.organizationId)}/${segment}/${application.id}`\n}\n\nasync function getClient() {\n return getGlobalCliClient({apiVersion: APP_WORKBENCH_API_VERSION, requireUser: true})\n}\n\nexport async function getApplication(applicationId: string): Promise<Application | null> {\n const client = await getClient()\n try {\n return await client.request({uri: `/applications/${applicationId}`})\n } catch (err) {\n if ((err as {statusCode?: number})?.statusCode === 404) return null\n throw err\n }\n}\n\n/**\n * Create an application record (no deployment), so the CLI can build with the\n * returned id, then ship it via {@link createDeployment}.\n */\nexport async function createApplication(options: {\n isSingleton?: boolean\n organizationId: string\n projectId?: string\n slug: string\n title: string\n type: ApplicationType\n visibility?: AppVisibility\n}): Promise<Application> {\n const {isSingleton, organizationId, projectId, slug, title, type, visibility} = options\n const client = await getClient()\n return client.request({\n body: {\n organizationId,\n slug,\n title,\n type,\n ...(isSingleton === undefined ? {} : {isSingleton}),\n ...(visibility ? {visibility} : {}),\n // Studio config is set once, at create — it's immutable on redeploy.\n ...(projectId ? {config: {studio: {projectId}}} : {}),\n },\n method: 'POST',\n uri: `/applications`,\n })\n}\n\n/** Mutable application fields the deploy flow patches after create. */\nexport interface ApplicationUpdate {\n icon?: string | null\n title?: string\n visibility?: AppVisibility\n}\n\n// Patch an application's mutable fields.\nexport async function updateApplication(\n applicationId: string,\n update: ApplicationUpdate,\n): Promise<void> {\n const client = await getClient()\n await client.request({body: update, method: 'PATCH', uri: `/applications/${applicationId}`})\n}\n\n/** Deploy a new active version to an existing application. */\nexport async function createDeployment(options: {\n applicationId: string\n interfaces: readonly BrettInterface[]\n isAutoUpdating: boolean\n tarball: Gzip\n version: string\n workspaces?: readonly BrettWorkspace[]\n}): Promise<{id: string}> {\n const {applicationId, interfaces, isAutoUpdating, tarball, version, workspaces} = options\n const formData = new FormData()\n formData.append('isAutoUpdating', isAutoUpdating.toString())\n appendDeploymentParts(formData, {interfaces, tarball, version, workspaces})\n return request(`/applications/${applicationId}/deployments`, formData)\n}\n\n/** Soft-deletes the application and all its deployments; already deleted counts as done. */\nexport async function deleteApplication(applicationId: string): Promise<void> {\n const client = await getClient()\n try {\n await client.request({method: 'DELETE', uri: `/applications/${applicationId}`})\n } catch (err) {\n if ((err as {statusCode?: number})?.statusCode !== 404) throw err\n }\n}\n\nfunction appendDeploymentParts(\n formData: FormData,\n {\n interfaces,\n tarball,\n version,\n workspaces,\n }: {\n interfaces: readonly BrettInterface[]\n tarball: Gzip\n version: string\n workspaces?: readonly BrettWorkspace[]\n },\n): void {\n formData.append('version', version)\n appendJson(formData, 'interfaces', interfaces)\n // Studio-only — the server rejects a workspaces part on non-studio types.\n if (workspaces?.length) appendJson(formData, 'workspaces', workspaces)\n formData.append('tarball', tarball, {contentType: 'application/gzip', filename: 'app.tar.gz'})\n}\n\n/** Structured parts must arrive as JSON so the server parses them. */\nfunction appendJson(formData: FormData, name: string, value: unknown): void {\n formData.append(name, JSON.stringify(value), {contentType: 'application/json'})\n}\n\nasync function request<T>(uri: string, formData: FormData): Promise<T> {\n const client = await getClient()\n return client.request({\n body: formData.pipe(new PassThrough()),\n headers: formData.getHeaders(),\n method: 'POST',\n uri,\n })\n}\n"],"names":["PassThrough","getGlobalCliClient","isStaging","FormData","APP_WORKBENCH_API_VERSION","getWorkbenchUrl","organizationId","getApplicationUrl","application","segment","type","id","getClient","apiVersion","requireUser","getApplication","applicationId","client","request","uri","err","statusCode","createApplication","options","isSingleton","projectId","slug","title","visibility","body","undefined","config","studio","method","updateApplication","update","createDeployment","interfaces","isAutoUpdating","tarball","version","workspaces","formData","append","toString","appendDeploymentParts","deleteApplication","appendJson","length","contentType","filename","name","value","JSON","stringify","pipe","headers","getHeaders"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sanity/workbench-cli",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.7.0",
|
|
4
4
|
"description": "Internal implementation detail of the Sanity CLI's unstable workbench support. Not intended for direct use.",
|
|
5
5
|
"homepage": "https://github.com/sanity-io/cli",
|
|
6
6
|
"bugs": "https://github.com/sanity-io/cli/issues",
|