@sanity/workbench-cli 1.5.0 → 1.6.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 +36 -1
- package/dist/_exports/build.js +1 -0
- package/dist/_exports/build.js.map +1 -1
- package/dist/_exports/deploy.d.ts +5 -1
- package/dist/_exports/index.d.ts +1 -1
- package/dist/_exports/preview.d.ts +169 -0
- package/dist/_exports/preview.js +3 -0
- package/dist/_exports/preview.js.map +1 -0
- package/dist/_exports/undeploy.d.ts +3 -1
- package/dist/actions/build/vite/optimize-deps.js +84 -0
- package/dist/actions/build/vite/optimize-deps.js.map +1 -0
- package/dist/actions/deploy/checkBuiltOutput.js +16 -2
- package/dist/actions/deploy/checkBuiltOutput.js.map +1 -1
- package/dist/actions/deploy/deployWorkbenchApp.js +17 -3
- package/dist/actions/deploy/deployWorkbenchApp.js.map +1 -1
- package/dist/actions/dev/registry.js +69 -1
- package/dist/actions/dev/registry.js.map +1 -1
- package/dist/actions/dev/startWorkbenchDev.js +6 -41
- package/dist/actions/dev/startWorkbenchDev.js.map +1 -1
- package/dist/actions/dev/startWorkbenchDevServer.js +7 -3
- package/dist/actions/dev/startWorkbenchDevServer.js.map +1 -1
- package/dist/actions/preview/serveBuiltApplication.js +53 -0
- package/dist/actions/preview/serveBuiltApplication.js.map +1 -0
- package/dist/actions/preview/startWorkbenchPreview.js +91 -0
- package/dist/actions/preview/startWorkbenchPreview.js.map +1 -0
- package/dist/defineApp.js +2 -5
- package/dist/defineApp.js.map +1 -1
- package/dist/resolveWorkbenchApp.js +1 -0
- package/dist/resolveWorkbenchApp.js.map +1 -1
- package/dist/services/applications.js +14 -1
- package/dist/services/applications.js.map +1 -1
- package/dist/util/serverOrchestration.js +75 -0
- package/dist/util/serverOrchestration.js.map +1 -0
- package/package.json +7 -3
package/dist/_exports/build.d.ts
CHANGED
|
@@ -87,7 +87,7 @@ declare const DefineAppInputSchema: z.ZodMiniObject<
|
|
|
87
87
|
>
|
|
88
88
|
>
|
|
89
89
|
>;
|
|
90
|
-
slug: z.
|
|
90
|
+
slug: z.ZodMiniString<string>;
|
|
91
91
|
title: z.ZodMiniString<string>;
|
|
92
92
|
views: z.ZodMiniOptional<
|
|
93
93
|
z.ZodMiniArray<
|
|
@@ -141,6 +141,8 @@ declare interface ResolvedWorkbenchApp {
|
|
|
141
141
|
readonly config?: WorkbenchApp["config"];
|
|
142
142
|
/** SDK app-view entrypoint, when declared. */
|
|
143
143
|
readonly entry?: string;
|
|
144
|
+
/** Path to the app's icon SVG, resolved and shipped to Brett on deploy. */
|
|
145
|
+
readonly icon?: string;
|
|
144
146
|
/** Explicit singleton flag (a Sanity-owned app); `undefined` when the app doesn't set it. */
|
|
145
147
|
readonly isSingleton?: boolean;
|
|
146
148
|
/** Hostname the application is created at on first deploy. */
|
|
@@ -185,6 +187,39 @@ export declare interface WorkbenchExposes {
|
|
|
185
187
|
views?: DefineAppInput["views"];
|
|
186
188
|
}
|
|
187
189
|
|
|
190
|
+
/**
|
|
191
|
+
* Dep pre-bundling inputs for a workbench app's dev server.
|
|
192
|
+
*
|
|
193
|
+
* Vite's dep scanner crawls from the app's HTML entry, which reaches only the
|
|
194
|
+
* app's `entry` (or a studio's config) — never the federation `exposes` (dock
|
|
195
|
+
* views, worker services, media-library config fields), which the host loads
|
|
196
|
+
* dynamically at runtime. So a dep imported only by an exposed module (e.g.
|
|
197
|
+
* `sanity/workbench` in a service or view) escapes the startup scan; Vite
|
|
198
|
+
* discovers it on first request, re-optimizes, and full-page reloads — which
|
|
199
|
+
* flakes Playwright in e2e.
|
|
200
|
+
*
|
|
201
|
+
* Point `entries` at the source of every interface: the app `entry` (or, for a
|
|
202
|
+
* studio, its config), plus each view, service, and installation-config source.
|
|
203
|
+
* `entries` follows real import statements, so it covers whatever those sources
|
|
204
|
+
* transitively use — correct subpaths and all — with no hand-maintained dep
|
|
205
|
+
* list, and never crashes on an unresolvable name the way a bad `include` entry
|
|
206
|
+
* does. Each source is resolved to its on-disk file so an extensionless path
|
|
207
|
+
* (like the default `./src/App`) still matches `entries`' filesystem glob.
|
|
208
|
+
*
|
|
209
|
+
* @param cwd - Project root; `entries` are returned relative to it.
|
|
210
|
+
* @param appSources - Absolute paths to the app's `entry` and/or studio config.
|
|
211
|
+
* @param exposes - The app's declared views/services/config.
|
|
212
|
+
* @internal
|
|
213
|
+
*/
|
|
214
|
+
export declare function workbenchOptimizeDeps(options: {
|
|
215
|
+
appSources: readonly string[];
|
|
216
|
+
cwd: string;
|
|
217
|
+
exposes?: WorkbenchExposes;
|
|
218
|
+
}): {
|
|
219
|
+
entries: string[];
|
|
220
|
+
include: string[];
|
|
221
|
+
};
|
|
222
|
+
|
|
188
223
|
declare interface WorkbenchViteOptions {
|
|
189
224
|
/** Project root — read for the federation remote name, and the plugin workDir. */
|
|
190
225
|
cwd: string;
|
package/dist/_exports/build.js
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
// resolver the build reads declared views/services from. The build needs no
|
|
4
4
|
// deploy-time guards, so it takes the bare `resolveWorkbenchApp` — the guarded
|
|
5
5
|
// view (`getWorkbench`) is the deploy entry's export.
|
|
6
|
+
export { workbenchOptimizeDeps } from '../actions/build/vite/optimize-deps.js';
|
|
6
7
|
export { workbenchVitePlugins } from '../actions/build/vite/workbench-vite-plugins.js';
|
|
7
8
|
export { resolveWorkbenchApp } from '../resolveWorkbenchApp.js';
|
|
8
9
|
|
|
@@ -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 {workbenchVitePlugins} from '../actions/build/vite/workbench-vite-plugins.js'\nexport {resolveWorkbenchApp, type WorkbenchExposes} from '../resolveWorkbenchApp.js'\n"],"names":["workbenchVitePlugins","resolveWorkbenchApp"],"mappings":"AAAA,iEAAiE;AACjE,+EAA+E;AAC/E,4EAA4E;AAC5E,+EAA+E;AAC/E,sDAAsD;AAEtD,SAAQA,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 {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"}
|
|
@@ -177,7 +177,7 @@ declare const DefineAppInputSchema: z.ZodMiniObject<
|
|
|
177
177
|
>
|
|
178
178
|
>
|
|
179
179
|
>;
|
|
180
|
-
slug: z.
|
|
180
|
+
slug: z.ZodMiniString<string>;
|
|
181
181
|
title: z.ZodMiniString<string>;
|
|
182
182
|
views: z.ZodMiniOptional<
|
|
183
183
|
z.ZodMiniArray<
|
|
@@ -261,6 +261,7 @@ export declare function deployConfig(options: {
|
|
|
261
261
|
*/
|
|
262
262
|
export declare function deployCoreApp(options: {
|
|
263
263
|
appId: string | undefined;
|
|
264
|
+
icon?: string;
|
|
264
265
|
interfaces: readonly BrettInterface[];
|
|
265
266
|
isAutoUpdating: boolean;
|
|
266
267
|
isSingleton?: boolean;
|
|
@@ -290,6 +291,7 @@ export declare interface DeployedExpose {
|
|
|
290
291
|
*/
|
|
291
292
|
export declare function deployStudio(options: {
|
|
292
293
|
appId: string | undefined;
|
|
294
|
+
icon?: string;
|
|
293
295
|
interfaces: readonly BrettInterface[];
|
|
294
296
|
isAutoUpdating: boolean;
|
|
295
297
|
organizationId: string;
|
|
@@ -333,6 +335,8 @@ declare interface ResolvedWorkbenchApp {
|
|
|
333
335
|
readonly config?: WorkbenchApp["config"];
|
|
334
336
|
/** SDK app-view entrypoint, when declared. */
|
|
335
337
|
readonly entry?: string;
|
|
338
|
+
/** Path to the app's icon SVG, resolved and shipped to Brett on deploy. */
|
|
339
|
+
readonly icon?: string;
|
|
336
340
|
/** Explicit singleton flag (a Sanity-owned app); `undefined` when the app doesn't set it. */
|
|
337
341
|
readonly isSingleton?: boolean;
|
|
338
342
|
/** Hostname the application is created at on first deploy. */
|
package/dist/_exports/index.d.ts
CHANGED
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import { CliConfig } from "@sanity/cli-core";
|
|
2
|
+
import { Output } from "@sanity/cli-core";
|
|
3
|
+
import { z } from "zod/mini";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* A manifest describing a running dev server process (studio or app).
|
|
7
|
+
* Stored as `~/.sanity/dev-servers/<pid>.json`.
|
|
8
|
+
*
|
|
9
|
+
* The workbench singleton is tracked separately via the lock file — see
|
|
10
|
+
* `acquireWorkbenchLock` and `readWorkbenchLock` below.
|
|
11
|
+
*/
|
|
12
|
+
declare type DevServerManifest = z.infer<typeof devServerManifestSchema>;
|
|
13
|
+
|
|
14
|
+
declare const devServerManifestSchema: z.ZodMiniObject<
|
|
15
|
+
{
|
|
16
|
+
configs: z.ZodMiniOptional<
|
|
17
|
+
z.ZodMiniArray<
|
|
18
|
+
z.ZodMiniObject<
|
|
19
|
+
{
|
|
20
|
+
appType: z.ZodMiniOptional<z.ZodMiniString<string>>;
|
|
21
|
+
fields: z.ZodMiniArray<
|
|
22
|
+
z.ZodMiniObject<
|
|
23
|
+
{
|
|
24
|
+
name: z.ZodMiniString<string>;
|
|
25
|
+
public: z.ZodMiniOptional<z.ZodMiniBoolean<boolean>>;
|
|
26
|
+
src: z.ZodMiniString<string>;
|
|
27
|
+
title: z.ZodMiniString<string>;
|
|
28
|
+
},
|
|
29
|
+
z.core.$strip
|
|
30
|
+
>
|
|
31
|
+
>;
|
|
32
|
+
id: z.ZodMiniString<string>;
|
|
33
|
+
moduleName: z.ZodMiniOptional<z.ZodMiniString<string>>;
|
|
34
|
+
version: z.ZodMiniNumber<number>;
|
|
35
|
+
},
|
|
36
|
+
z.core.$strip
|
|
37
|
+
>
|
|
38
|
+
>
|
|
39
|
+
>;
|
|
40
|
+
host: z.ZodMiniString<string>;
|
|
41
|
+
id: z.ZodMiniOptional<z.ZodMiniString<string>>;
|
|
42
|
+
interfaces: z.ZodMiniOptional<
|
|
43
|
+
z.ZodMiniArray<
|
|
44
|
+
z.ZodMiniDiscriminatedUnion<
|
|
45
|
+
[
|
|
46
|
+
z.ZodMiniObject<
|
|
47
|
+
{
|
|
48
|
+
metadata: z.ZodMiniNullable<
|
|
49
|
+
z.ZodMiniObject<
|
|
50
|
+
{
|
|
51
|
+
group: z.ZodMiniOptional<z.ZodMiniString<string>>;
|
|
52
|
+
priority: z.ZodMiniOptional<z.ZodMiniNumber<number>>;
|
|
53
|
+
},
|
|
54
|
+
z.core.$strip
|
|
55
|
+
>
|
|
56
|
+
>;
|
|
57
|
+
type: z.ZodMiniLiteral<"app">;
|
|
58
|
+
id: z.ZodMiniString<string>;
|
|
59
|
+
moduleId: z.ZodMiniString<string>;
|
|
60
|
+
name: z.ZodMiniString<string>;
|
|
61
|
+
src: z.ZodMiniString<string>;
|
|
62
|
+
title: z.ZodMiniString<string>;
|
|
63
|
+
version: z.ZodMiniOptional<z.ZodMiniString<string>>;
|
|
64
|
+
},
|
|
65
|
+
z.core.$strip
|
|
66
|
+
>,
|
|
67
|
+
z.ZodMiniObject<
|
|
68
|
+
{
|
|
69
|
+
metadata: z.ZodMiniNull;
|
|
70
|
+
type: z.ZodMiniLiteral<"panel">;
|
|
71
|
+
id: z.ZodMiniString<string>;
|
|
72
|
+
moduleId: z.ZodMiniString<string>;
|
|
73
|
+
name: z.ZodMiniString<string>;
|
|
74
|
+
src: z.ZodMiniString<string>;
|
|
75
|
+
title: z.ZodMiniString<string>;
|
|
76
|
+
version: z.ZodMiniOptional<z.ZodMiniString<string>>;
|
|
77
|
+
},
|
|
78
|
+
z.core.$strip
|
|
79
|
+
>,
|
|
80
|
+
z.ZodMiniObject<
|
|
81
|
+
{
|
|
82
|
+
metadata: z.ZodMiniNull;
|
|
83
|
+
type: z.ZodMiniLiteral<"worker">;
|
|
84
|
+
id: z.ZodMiniString<string>;
|
|
85
|
+
moduleId: z.ZodMiniString<string>;
|
|
86
|
+
name: z.ZodMiniString<string>;
|
|
87
|
+
src: z.ZodMiniString<string>;
|
|
88
|
+
title: z.ZodMiniString<string>;
|
|
89
|
+
version: z.ZodMiniOptional<z.ZodMiniString<string>>;
|
|
90
|
+
},
|
|
91
|
+
z.core.$strip
|
|
92
|
+
>,
|
|
93
|
+
],
|
|
94
|
+
"type"
|
|
95
|
+
>
|
|
96
|
+
>
|
|
97
|
+
>;
|
|
98
|
+
manifest: z.ZodMiniOptional<
|
|
99
|
+
z.ZodMiniUnion<
|
|
100
|
+
readonly [
|
|
101
|
+
z.ZodMiniRecord<z.ZodMiniString<string>, z.ZodMiniUnknown>,
|
|
102
|
+
z.ZodMiniObject<
|
|
103
|
+
{
|
|
104
|
+
group: z.ZodMiniOptional<z.ZodMiniString<string>>;
|
|
105
|
+
icon: z.ZodMiniOptional<z.ZodMiniString<string>>;
|
|
106
|
+
priority: z.ZodMiniOptional<z.ZodMiniNumber<number>>;
|
|
107
|
+
slug: z.ZodMiniOptional<z.ZodMiniString<string>>;
|
|
108
|
+
title: z.ZodMiniOptional<z.ZodMiniString<string>>;
|
|
109
|
+
version: z.ZodMiniString<string>;
|
|
110
|
+
},
|
|
111
|
+
z.core.$strip
|
|
112
|
+
>,
|
|
113
|
+
]
|
|
114
|
+
>
|
|
115
|
+
>;
|
|
116
|
+
manifestUpdatedAt: z.ZodMiniOptional<z.ZodMiniString<string>>;
|
|
117
|
+
pid: z.ZodMiniNumber<number>;
|
|
118
|
+
port: z.ZodMiniNumber<number>;
|
|
119
|
+
projectId: z.ZodMiniOptional<z.ZodMiniString<string>>;
|
|
120
|
+
startedAt: z.ZodMiniString<string>;
|
|
121
|
+
type: z.ZodMiniEnum<{
|
|
122
|
+
coreApp: "coreApp";
|
|
123
|
+
studio: "studio";
|
|
124
|
+
}>;
|
|
125
|
+
version: z.ZodMiniLiteral<1>;
|
|
126
|
+
workDir: z.ZodMiniString<string>;
|
|
127
|
+
},
|
|
128
|
+
z.core.$strip
|
|
129
|
+
>;
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* `sanity start` for a workbench app: serve a production build the way dev serves
|
|
133
|
+
* a live one. The same singleton workbench shell renders it and the same registry
|
|
134
|
+
* advertises it — only the remote differs, static files from the build output
|
|
135
|
+
* instead of a live Vite dev server. There's no config watcher or rebuild: a
|
|
136
|
+
* build is fixed, so nothing re-syncs.
|
|
137
|
+
*
|
|
138
|
+
* A running workbench claims the configured port, so the built remote binds the
|
|
139
|
+
* next one. Without one the remote takes the configured port and announces its
|
|
140
|
+
* own URL.
|
|
141
|
+
*/
|
|
142
|
+
export declare function startWorkbenchPreview(
|
|
143
|
+
options: StartWorkbenchPreviewOptions,
|
|
144
|
+
): Promise<{
|
|
145
|
+
close: () => Promise<void>;
|
|
146
|
+
}>;
|
|
147
|
+
|
|
148
|
+
export declare interface StartWorkbenchPreviewOptions {
|
|
149
|
+
/** Directory for the workbench Vite server's dependency cache. */
|
|
150
|
+
cacheDir: string;
|
|
151
|
+
/** CLI-domain `app.id`/`deployment.appId` deprecation check, run before registering. */
|
|
152
|
+
checkForDeprecatedAppId: () => void;
|
|
153
|
+
cliConfig: CliConfig;
|
|
154
|
+
/** Extract the project manifest to inline into the registry (studio-vs-app handled by the CLI). */
|
|
155
|
+
extractManifest: (params: {
|
|
156
|
+
configPath: string;
|
|
157
|
+
workDir: string;
|
|
158
|
+
}) => Promise<DevServerManifest["manifest"]>;
|
|
159
|
+
httpHost: string;
|
|
160
|
+
httpPort: number;
|
|
161
|
+
isApp: boolean;
|
|
162
|
+
/** The built `dist` directory to serve as the federation remote. */
|
|
163
|
+
outDir: string;
|
|
164
|
+
output: Output;
|
|
165
|
+
reactStrictMode: boolean;
|
|
166
|
+
workDir: string;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/_exports/preview.ts"],"sourcesContent":["export {\n startWorkbenchPreview,\n type StartWorkbenchPreviewOptions,\n} from '../actions/preview/startWorkbenchPreview.js'\n"],"names":["startWorkbenchPreview"],"mappings":"AAAA,SACEA,qBAAqB,QAEhB,8CAA6C"}
|
|
@@ -102,7 +102,7 @@ declare const DefineAppInputSchema: z.ZodMiniObject<
|
|
|
102
102
|
>
|
|
103
103
|
>
|
|
104
104
|
>;
|
|
105
|
-
slug: z.
|
|
105
|
+
slug: z.ZodMiniString<string>;
|
|
106
106
|
title: z.ZodMiniString<string>;
|
|
107
107
|
views: z.ZodMiniOptional<
|
|
108
108
|
z.ZodMiniArray<
|
|
@@ -185,6 +185,8 @@ declare interface ResolvedWorkbenchApp {
|
|
|
185
185
|
readonly config?: WorkbenchApp["config"];
|
|
186
186
|
/** SDK app-view entrypoint, when declared. */
|
|
187
187
|
readonly entry?: string;
|
|
188
|
+
/** Path to the app's icon SVG, resolved and shipped to Brett on deploy. */
|
|
189
|
+
readonly icon?: string;
|
|
188
190
|
/** Explicit singleton flag (a Sanity-owned app); `undefined` when the app doesn't set it. */
|
|
189
191
|
readonly isSingleton?: boolean;
|
|
190
192
|
/** Hostname the application is created at on first deploy. */
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
/**
|
|
4
|
+
* React APIs only the generated render-contract modules import — the SPA
|
|
5
|
+
* bootstrap (`getEntryModule`) and every render artifact (`renderRemote`)
|
|
6
|
+
* `createRoot` from `react-dom/client` and `createElement` from `react`. No
|
|
7
|
+
* app/interface source imports `react-dom/client` itself, so scanning `entries`
|
|
8
|
+
* never surfaces it; every workbench app depends on react/react-dom, so both
|
|
9
|
+
* always resolve.
|
|
10
|
+
*/ const RENDER_CONTRACT_DEPS = [
|
|
11
|
+
'react',
|
|
12
|
+
'react-dom/client'
|
|
13
|
+
];
|
|
14
|
+
/** Extensions an import-style source path may omit, in resolution order. */ const SOURCE_EXTENSIONS = [
|
|
15
|
+
'.tsx',
|
|
16
|
+
'.ts',
|
|
17
|
+
'.jsx',
|
|
18
|
+
'.js',
|
|
19
|
+
'.mjs',
|
|
20
|
+
'.cjs'
|
|
21
|
+
];
|
|
22
|
+
/**
|
|
23
|
+
* Resolve an import-style source path to the file on disk. The app `entry`
|
|
24
|
+
* defaults to the extensionless `./src/App` (and a user may omit the extension
|
|
25
|
+
* anywhere), which the runtime imports fine through Vite's resolver — but
|
|
26
|
+
* `optimizeDeps.entries` is matched against the filesystem, so an extensionless
|
|
27
|
+
* path never matches and its deps go unscanned. Try the path as-is, then the
|
|
28
|
+
* common source extensions; fall back to the input so an already-resolved path
|
|
29
|
+
* (or a genuinely missing one) passes through unchanged.
|
|
30
|
+
*/ function resolveSourceFile(absPath) {
|
|
31
|
+
if (fs.existsSync(absPath) && fs.statSync(absPath).isFile()) return absPath;
|
|
32
|
+
for (const extension of SOURCE_EXTENSIONS){
|
|
33
|
+
if (fs.existsSync(`${absPath}${extension}`)) return `${absPath}${extension}`;
|
|
34
|
+
}
|
|
35
|
+
return absPath;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Dep pre-bundling inputs for a workbench app's dev server.
|
|
39
|
+
*
|
|
40
|
+
* Vite's dep scanner crawls from the app's HTML entry, which reaches only the
|
|
41
|
+
* app's `entry` (or a studio's config) — never the federation `exposes` (dock
|
|
42
|
+
* views, worker services, media-library config fields), which the host loads
|
|
43
|
+
* dynamically at runtime. So a dep imported only by an exposed module (e.g.
|
|
44
|
+
* `sanity/workbench` in a service or view) escapes the startup scan; Vite
|
|
45
|
+
* discovers it on first request, re-optimizes, and full-page reloads — which
|
|
46
|
+
* flakes Playwright in e2e.
|
|
47
|
+
*
|
|
48
|
+
* Point `entries` at the source of every interface: the app `entry` (or, for a
|
|
49
|
+
* studio, its config), plus each view, service, and installation-config source.
|
|
50
|
+
* `entries` follows real import statements, so it covers whatever those sources
|
|
51
|
+
* transitively use — correct subpaths and all — with no hand-maintained dep
|
|
52
|
+
* list, and never crashes on an unresolvable name the way a bad `include` entry
|
|
53
|
+
* does. Each source is resolved to its on-disk file so an extensionless path
|
|
54
|
+
* (like the default `./src/App`) still matches `entries`' filesystem glob.
|
|
55
|
+
*
|
|
56
|
+
* @param cwd - Project root; `entries` are returned relative to it.
|
|
57
|
+
* @param appSources - Absolute paths to the app's `entry` and/or studio config.
|
|
58
|
+
* @param exposes - The app's declared views/services/config.
|
|
59
|
+
* @internal
|
|
60
|
+
*/ export function workbenchOptimizeDeps(options) {
|
|
61
|
+
const { appSources, cwd, exposes } = options;
|
|
62
|
+
const interfaceSources = [
|
|
63
|
+
...(exposes?.views ?? []).map((view)=>view.src),
|
|
64
|
+
...(exposes?.services ?? []).map((service)=>service.src),
|
|
65
|
+
...(exposes?.config?.fields ?? []).map((field)=>field.src)
|
|
66
|
+
].map((src)=>path.resolve(cwd, src));
|
|
67
|
+
const entries = [
|
|
68
|
+
...appSources,
|
|
69
|
+
...interfaceSources
|
|
70
|
+
].map((absPath)=>{
|
|
71
|
+
const resolved = resolveSourceFile(absPath);
|
|
72
|
+
return path.relative(cwd, resolved).split(path.sep).join('/');
|
|
73
|
+
});
|
|
74
|
+
return {
|
|
75
|
+
entries: [
|
|
76
|
+
...new Set(entries)
|
|
77
|
+
],
|
|
78
|
+
include: [
|
|
79
|
+
...RENDER_CONTRACT_DEPS
|
|
80
|
+
]
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
//# sourceMappingURL=optimize-deps.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/actions/build/vite/optimize-deps.ts"],"sourcesContent":["import fs from 'node:fs'\nimport path from 'node:path'\n\nimport {type WorkbenchExposes} from '../../../resolveWorkbenchApp.js'\n\n/**\n * React APIs only the generated render-contract modules import — the SPA\n * bootstrap (`getEntryModule`) and every render artifact (`renderRemote`)\n * `createRoot` from `react-dom/client` and `createElement` from `react`. No\n * app/interface source imports `react-dom/client` itself, so scanning `entries`\n * never surfaces it; every workbench app depends on react/react-dom, so both\n * always resolve.\n */\nconst RENDER_CONTRACT_DEPS = ['react', 'react-dom/client']\n\n/** Extensions an import-style source path may omit, in resolution order. */\nconst SOURCE_EXTENSIONS = ['.tsx', '.ts', '.jsx', '.js', '.mjs', '.cjs']\n\n/**\n * Resolve an import-style source path to the file on disk. The app `entry`\n * defaults to the extensionless `./src/App` (and a user may omit the extension\n * anywhere), which the runtime imports fine through Vite's resolver — but\n * `optimizeDeps.entries` is matched against the filesystem, so an extensionless\n * path never matches and its deps go unscanned. Try the path as-is, then the\n * common source extensions; fall back to the input so an already-resolved path\n * (or a genuinely missing one) passes through unchanged.\n */\nfunction resolveSourceFile(absPath: string): string {\n if (fs.existsSync(absPath) && fs.statSync(absPath).isFile()) return absPath\n for (const extension of SOURCE_EXTENSIONS) {\n if (fs.existsSync(`${absPath}${extension}`)) return `${absPath}${extension}`\n }\n return absPath\n}\n\n/**\n * Dep pre-bundling inputs for a workbench app's dev server.\n *\n * Vite's dep scanner crawls from the app's HTML entry, which reaches only the\n * app's `entry` (or a studio's config) — never the federation `exposes` (dock\n * views, worker services, media-library config fields), which the host loads\n * dynamically at runtime. So a dep imported only by an exposed module (e.g.\n * `sanity/workbench` in a service or view) escapes the startup scan; Vite\n * discovers it on first request, re-optimizes, and full-page reloads — which\n * flakes Playwright in e2e.\n *\n * Point `entries` at the source of every interface: the app `entry` (or, for a\n * studio, its config), plus each view, service, and installation-config source.\n * `entries` follows real import statements, so it covers whatever those sources\n * transitively use — correct subpaths and all — with no hand-maintained dep\n * list, and never crashes on an unresolvable name the way a bad `include` entry\n * does. Each source is resolved to its on-disk file so an extensionless path\n * (like the default `./src/App`) still matches `entries`' filesystem glob.\n *\n * @param cwd - Project root; `entries` are returned relative to it.\n * @param appSources - Absolute paths to the app's `entry` and/or studio config.\n * @param exposes - The app's declared views/services/config.\n * @internal\n */\nexport function workbenchOptimizeDeps(options: {\n appSources: readonly string[]\n cwd: string\n exposes?: WorkbenchExposes\n}): {entries: string[]; include: string[]} {\n const {appSources, cwd, exposes} = options\n\n const interfaceSources = [\n ...(exposes?.views ?? []).map((view) => view.src),\n ...(exposes?.services ?? []).map((service) => service.src),\n ...(exposes?.config?.fields ?? []).map((field) => field.src),\n ].map((src) => path.resolve(cwd, src))\n\n const entries = [...appSources, ...interfaceSources].map((absPath) => {\n const resolved = resolveSourceFile(absPath)\n return path.relative(cwd, resolved).split(path.sep).join('/')\n })\n\n return {\n entries: [...new Set(entries)],\n include: [...RENDER_CONTRACT_DEPS],\n }\n}\n"],"names":["fs","path","RENDER_CONTRACT_DEPS","SOURCE_EXTENSIONS","resolveSourceFile","absPath","existsSync","statSync","isFile","extension","workbenchOptimizeDeps","options","appSources","cwd","exposes","interfaceSources","views","map","view","src","services","service","config","fields","field","resolve","entries","resolved","relative","split","sep","join","Set","include"],"mappings":"AAAA,OAAOA,QAAQ,UAAS;AACxB,OAAOC,UAAU,YAAW;AAI5B;;;;;;;CAOC,GACD,MAAMC,uBAAuB;IAAC;IAAS;CAAmB;AAE1D,0EAA0E,GAC1E,MAAMC,oBAAoB;IAAC;IAAQ;IAAO;IAAQ;IAAO;IAAQ;CAAO;AAExE;;;;;;;;CAQC,GACD,SAASC,kBAAkBC,OAAe;IACxC,IAAIL,GAAGM,UAAU,CAACD,YAAYL,GAAGO,QAAQ,CAACF,SAASG,MAAM,IAAI,OAAOH;IACpE,KAAK,MAAMI,aAAaN,kBAAmB;QACzC,IAAIH,GAAGM,UAAU,CAAC,GAAGD,UAAUI,WAAW,GAAG,OAAO,GAAGJ,UAAUI,WAAW;IAC9E;IACA,OAAOJ;AACT;AAEA;;;;;;;;;;;;;;;;;;;;;;;CAuBC,GACD,OAAO,SAASK,sBAAsBC,OAIrC;IACC,MAAM,EAACC,UAAU,EAAEC,GAAG,EAAEC,OAAO,EAAC,GAAGH;IAEnC,MAAMI,mBAAmB;WACpB,AAACD,CAAAA,SAASE,SAAS,EAAE,AAAD,EAAGC,GAAG,CAAC,CAACC,OAASA,KAAKC,GAAG;WAC7C,AAACL,CAAAA,SAASM,YAAY,EAAE,AAAD,EAAGH,GAAG,CAAC,CAACI,UAAYA,QAAQF,GAAG;WACtD,AAACL,CAAAA,SAASQ,QAAQC,UAAU,EAAE,AAAD,EAAGN,GAAG,CAAC,CAACO,QAAUA,MAAML,GAAG;KAC5D,CAACF,GAAG,CAAC,CAACE,MAAQlB,KAAKwB,OAAO,CAACZ,KAAKM;IAEjC,MAAMO,UAAU;WAAId;WAAeG;KAAiB,CAACE,GAAG,CAAC,CAACZ;QACxD,MAAMsB,WAAWvB,kBAAkBC;QACnC,OAAOJ,KAAK2B,QAAQ,CAACf,KAAKc,UAAUE,KAAK,CAAC5B,KAAK6B,GAAG,EAAEC,IAAI,CAAC;IAC3D;IAEA,OAAO;QACLL,SAAS;eAAI,IAAIM,IAAIN;SAAS;QAC9BO,SAAS;eAAI/B;SAAqB;IACpC;AACF"}
|
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
import { stat } from 'node:fs/promises';
|
|
2
2
|
import { join } from 'node:path';
|
|
3
|
+
/**
|
|
4
|
+
* A genuinely-missing-build error, named so callers can offer the "run sanity
|
|
5
|
+
* build" hint (the `preview` command keys off this name, matching how the studio
|
|
6
|
+
* path keys off a missing `index.html`). Only the missing cases get it — real
|
|
7
|
+
* I/O failures keep their own name so they surface as themselves.
|
|
8
|
+
*/ function buildNotFound(message) {
|
|
9
|
+
const error = new Error(message);
|
|
10
|
+
error.name = 'BUILD_NOT_FOUND';
|
|
11
|
+
return error;
|
|
12
|
+
}
|
|
3
13
|
/**
|
|
4
14
|
* Throws unless `sourceDir` is a directory holding a federation build.
|
|
5
15
|
* A workbench build always emits a module-federation remote, and may
|
|
@@ -13,13 +23,17 @@ import { join } from 'node:path';
|
|
|
13
23
|
throw new Error(`"${sourceDir}" is not a directory`);
|
|
14
24
|
}
|
|
15
25
|
} catch (err) {
|
|
16
|
-
|
|
26
|
+
if (err.code === 'ENOENT') throw buildNotFound(`Directory "${sourceDir}" does not exist`);
|
|
27
|
+
throw err;
|
|
17
28
|
}
|
|
18
29
|
const manifestPath = join(sourceDir, 'mf-manifest.json');
|
|
19
30
|
try {
|
|
20
31
|
await stat(manifestPath);
|
|
21
32
|
} catch (err) {
|
|
22
|
-
|
|
33
|
+
if (err.code === 'ENOENT') {
|
|
34
|
+
throw buildNotFound(`"${manifestPath}" does not exist. ` + 'The deploy directory must contain a federation build created with "sanity build".');
|
|
35
|
+
}
|
|
36
|
+
throw err;
|
|
23
37
|
}
|
|
24
38
|
}
|
|
25
39
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/actions/deploy/checkBuiltOutput.ts"],"sourcesContent":["import {stat} from 'node:fs/promises'\nimport {join} from 'node:path'\n\n/**\n * Throws unless `sourceDir` is a directory holding a federation build.\n * A workbench build always emits a module-federation remote, and may\n * additionally emit a standalone `index.html` SPA (workbench remotes). Either\n * way `mf-manifest.json` is the reliable marker that `sanity build` produced a\n * federation build, so that — not `index.html` — is what we check for.\n */\nexport async function checkBuiltOutput(sourceDir: string): Promise<void> {\n try {\n const stats = await stat(sourceDir)\n if (!stats.isDirectory()) {\n throw new Error(`\"${sourceDir}\" is not a directory`)\n }\n } catch (err) {\n
|
|
1
|
+
{"version":3,"sources":["../../../src/actions/deploy/checkBuiltOutput.ts"],"sourcesContent":["import {stat} from 'node:fs/promises'\nimport {join} from 'node:path'\n\n/**\n * A genuinely-missing-build error, named so callers can offer the \"run sanity\n * build\" hint (the `preview` command keys off this name, matching how the studio\n * path keys off a missing `index.html`). Only the missing cases get it — real\n * I/O failures keep their own name so they surface as themselves.\n */\nfunction buildNotFound(message: string): Error {\n const error = new Error(message)\n error.name = 'BUILD_NOT_FOUND'\n return error\n}\n\n/**\n * Throws unless `sourceDir` is a directory holding a federation build.\n * A workbench build always emits a module-federation remote, and may\n * additionally emit a standalone `index.html` SPA (workbench remotes). Either\n * way `mf-manifest.json` is the reliable marker that `sanity build` produced a\n * federation build, so that — not `index.html` — is what we check for.\n */\nexport async function checkBuiltOutput(sourceDir: string): Promise<void> {\n try {\n const stats = await stat(sourceDir)\n if (!stats.isDirectory()) {\n throw new Error(`\"${sourceDir}\" is not a directory`)\n }\n } catch (err) {\n if (err.code === 'ENOENT') throw buildNotFound(`Directory \"${sourceDir}\" does not exist`)\n throw err\n }\n\n const manifestPath = join(sourceDir, 'mf-manifest.json')\n try {\n await stat(manifestPath)\n } catch (err) {\n if (err.code === 'ENOENT') {\n throw buildNotFound(\n `\"${manifestPath}\" does not exist. ` +\n 'The deploy directory must contain a federation build created with \"sanity build\".',\n )\n }\n throw err\n }\n}\n"],"names":["stat","join","buildNotFound","message","error","Error","name","checkBuiltOutput","sourceDir","stats","isDirectory","err","code","manifestPath"],"mappings":"AAAA,SAAQA,IAAI,QAAO,mBAAkB;AACrC,SAAQC,IAAI,QAAO,YAAW;AAE9B;;;;;CAKC,GACD,SAASC,cAAcC,OAAe;IACpC,MAAMC,QAAQ,IAAIC,MAAMF;IACxBC,MAAME,IAAI,GAAG;IACb,OAAOF;AACT;AAEA;;;;;;CAMC,GACD,OAAO,eAAeG,iBAAiBC,SAAiB;IACtD,IAAI;QACF,MAAMC,QAAQ,MAAMT,KAAKQ;QACzB,IAAI,CAACC,MAAMC,WAAW,IAAI;YACxB,MAAM,IAAIL,MAAM,CAAC,CAAC,EAAEG,UAAU,oBAAoB,CAAC;QACrD;IACF,EAAE,OAAOG,KAAK;QACZ,IAAIA,IAAIC,IAAI,KAAK,UAAU,MAAMV,cAAc,CAAC,WAAW,EAAEM,UAAU,gBAAgB,CAAC;QACxF,MAAMG;IACR;IAEA,MAAME,eAAeZ,KAAKO,WAAW;IACrC,IAAI;QACF,MAAMR,KAAKa;IACb,EAAE,OAAOF,KAAK;QACZ,IAAIA,IAAIC,IAAI,KAAK,UAAU;YACzB,MAAMV,cACJ,CAAC,CAAC,EAAEW,aAAa,kBAAkB,CAAC,GAClC;QAEN;QACA,MAAMF;IACR;AACF"}
|
|
@@ -3,14 +3,14 @@ import { createGzip } from 'node:zlib';
|
|
|
3
3
|
import { exitCodes } from '@sanity/cli-core';
|
|
4
4
|
import { spinner } from '@sanity/cli-core/ux';
|
|
5
5
|
import { pack } from 'tar-fs';
|
|
6
|
-
import { createApplication, createDeployment } from '../../services/applications.js';
|
|
6
|
+
import { createApplication, createDeployment, updateApplication } from '../../services/applications.js';
|
|
7
7
|
/**
|
|
8
8
|
* Deploy a workbench coreApp through Brett: redeploy when `appId` is set,
|
|
9
9
|
* otherwise create the application at `slug`. Returns the application id for the
|
|
10
10
|
* shell to report.
|
|
11
11
|
* @internal
|
|
12
12
|
*/ export async function deployCoreApp(options) {
|
|
13
|
-
const { appId, interfaces, isAutoUpdating, isSingleton, organizationId, slug, sourceDir, title, version, visibility } = options;
|
|
13
|
+
const { appId, icon, interfaces, isAutoUpdating, isSingleton, organizationId, slug, sourceDir, title, version, visibility } = options;
|
|
14
14
|
const tarball = pack(dirname(sourceDir), {
|
|
15
15
|
entries: [
|
|
16
16
|
basename(sourceDir)
|
|
@@ -26,12 +26,19 @@ import { createApplication, createDeployment } from '../../services/applications
|
|
|
26
26
|
tarball,
|
|
27
27
|
version
|
|
28
28
|
});
|
|
29
|
+
await updateApplication(appId, {
|
|
30
|
+
title,
|
|
31
|
+
...icon ? {
|
|
32
|
+
icon
|
|
33
|
+
} : {}
|
|
34
|
+
});
|
|
29
35
|
spin.succeed();
|
|
30
36
|
return {
|
|
31
37
|
applicationId: appId
|
|
32
38
|
};
|
|
33
39
|
}
|
|
34
40
|
const { id } = await createApplication({
|
|
41
|
+
icon,
|
|
35
42
|
interfaces,
|
|
36
43
|
isSingleton,
|
|
37
44
|
organizationId,
|
|
@@ -57,7 +64,7 @@ import { createApplication, createDeployment } from '../../services/applications
|
|
|
57
64
|
* the shell to report; a missing `studioHost` on create is a usage error.
|
|
58
65
|
* @internal
|
|
59
66
|
*/ export async function deployStudio(options) {
|
|
60
|
-
const { appId, interfaces, isAutoUpdating, organizationId, output, projectId, sourceDir, studioHost, title, version, workspaces } = options;
|
|
67
|
+
const { appId, icon, interfaces, isAutoUpdating, organizationId, output, projectId, sourceDir, studioHost, title, version, workspaces } = options;
|
|
61
68
|
const tarball = pack(dirname(sourceDir), {
|
|
62
69
|
entries: [
|
|
63
70
|
basename(sourceDir)
|
|
@@ -74,6 +81,12 @@ import { createApplication, createDeployment } from '../../services/applications
|
|
|
74
81
|
version,
|
|
75
82
|
workspaces
|
|
76
83
|
});
|
|
84
|
+
await updateApplication(appId, {
|
|
85
|
+
title,
|
|
86
|
+
...icon ? {
|
|
87
|
+
icon
|
|
88
|
+
} : {}
|
|
89
|
+
});
|
|
77
90
|
spin.succeed();
|
|
78
91
|
return {
|
|
79
92
|
applicationId: appId
|
|
@@ -86,6 +99,7 @@ import { createApplication, createDeployment } from '../../services/applications
|
|
|
86
99
|
});
|
|
87
100
|
}
|
|
88
101
|
const application = await createApplication({
|
|
102
|
+
icon,
|
|
89
103
|
interfaces,
|
|
90
104
|
organizationId,
|
|
91
105
|
projectId,
|
|
@@ -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, exitCodes, type Output} 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} from '../../services/applications.js'\n\n/**\n * Deploy a workbench coreApp through Brett: redeploy when `appId` is set,\n * otherwise create the application at `slug`. Returns the application id for the\n * shell to report.\n * @internal\n */\nexport async function deployCoreApp(options: {\n appId: string | undefined\n interfaces: readonly BrettInterface[]\n isAutoUpdating: boolean\n isSingleton?: boolean\n organizationId: string\n slug: string\n sourceDir: string\n title: string\n version: string\n visibility?: AppVisibility\n}): Promise<{applicationId: string}> {\n const {\n appId,\n interfaces,\n isAutoUpdating,\n isSingleton,\n organizationId,\n slug,\n sourceDir,\n title,\n version,\n visibility,\n } = options\n const tarball = pack(dirname(sourceDir), {entries: [basename(sourceDir)]}).pipe(createGzip())\n\n const spin = spinner('Deploying...').start()\n try {\n if (appId) {\n await createDeployment({applicationId: appId, interfaces, isAutoUpdating, tarball, version})\n spin.succeed()\n return {applicationId: appId}\n }\n\n const {id} = await createApplication({\n interfaces,\n isSingleton,\n organizationId,\n slug,\n tarball,\n title,\n type: 'coreApp',\n version,\n visibility,\n })\n spin.succeed()\n return {applicationId: id}\n } catch (error) {\n spin.clear()\n throw error\n }\n}\n\n/**\n * Deploy a workbench studio through Brett: redeploy when `appId` is set,\n * otherwise create the studio at `studioHost`. Returns the application id for\n * the shell to report; a missing `studioHost` on create is a usage error.\n * @internal\n */\nexport async function deployStudio(options: {\n appId: string | undefined\n interfaces: readonly BrettInterface[]\n isAutoUpdating: boolean\n organizationId: string\n output: Output\n projectId: string | undefined\n sourceDir: string\n studioHost: string | undefined\n title: string\n version: string\n workspaces: readonly BrettWorkspace[]\n}): Promise<{applicationId: string}> {\n const {\n appId,\n interfaces,\n isAutoUpdating,\n organizationId,\n output,\n projectId,\n sourceDir,\n studioHost,\n title,\n version,\n workspaces,\n } = options\n const tarball = pack(dirname(sourceDir), {entries: [basename(sourceDir)]}).pipe(createGzip())\n\n const spin = spinner('Deploying to sanity.studio').start()\n try {\n if (appId) {\n await createDeployment({\n applicationId: appId,\n interfaces,\n isAutoUpdating,\n tarball,\n version,\n workspaces,\n })\n spin.succeed()\n return {applicationId: appId}\n }\n\n if (!studioHost) {\n spin.fail()\n return output.error(\n 'No studio hostname configured. Set `studioHost` in sanity.cli.ts to create a studio.',\n {exit: exitCodes.USAGE_ERROR},\n )\n }\n\n const application = await createApplication({\n interfaces,\n organizationId,\n projectId,\n slug: studioHost,\n tarball,\n title,\n type: 'studio',\n version,\n workspaces,\n })\n spin.succeed()\n return {applicationId: application.id}\n } catch (error) {\n spin.fail()\n throw error\n }\n}\n"],"names":["basename","dirname","createGzip","exitCodes","spinner","pack","createApplication","createDeployment","deployCoreApp","options","appId","interfaces","isAutoUpdating","isSingleton","organizationId","slug","sourceDir","title","version","visibility","tarball","entries","pipe","spin","start","applicationId","succeed","id","type","error","clear","deployStudio","output","projectId","studioHost","workspaces","fail","exit","USAGE_ERROR","application"],"mappings":"AAAA,SAAQA,QAAQ,EAAEC,OAAO,QAAO,YAAW;AAC3C,SAAQC,UAAU,QAAO,YAAW;AAEpC,SAA4BC,SAAS,QAAoB,mBAAkB;AAC3E,SAAQC,OAAO,QAAO,sBAAqB;AAC3C,SAAQC,IAAI,QAAO,SAAQ;AAE3B,SAGEC,iBAAiB,EACjBC,gBAAgB,
|
|
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, exitCodes, type Output} 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 updateApplication,\n} from '../../services/applications.js'\n\n/**\n * Deploy a workbench coreApp through Brett: redeploy when `appId` is set,\n * otherwise create the application at `slug`. Returns the application id for the\n * shell to report.\n * @internal\n */\nexport async function deployCoreApp(options: {\n appId: string | undefined\n icon?: string\n interfaces: readonly BrettInterface[]\n isAutoUpdating: boolean\n isSingleton?: boolean\n organizationId: string\n slug: string\n sourceDir: string\n title: string\n version: string\n visibility?: AppVisibility\n}): Promise<{applicationId: string}> {\n const {\n appId,\n icon,\n interfaces,\n isAutoUpdating,\n isSingleton,\n organizationId,\n slug,\n sourceDir,\n title,\n version,\n visibility,\n } = options\n const tarball = pack(dirname(sourceDir), {entries: [basename(sourceDir)]}).pipe(createGzip())\n\n const spin = spinner('Deploying...').start()\n try {\n if (appId) {\n await createDeployment({applicationId: appId, interfaces, isAutoUpdating, tarball, version})\n await updateApplication(appId, {title, ...(icon ? {icon} : {})})\n spin.succeed()\n return {applicationId: appId}\n }\n\n const {id} = await createApplication({\n icon,\n interfaces,\n isSingleton,\n organizationId,\n slug,\n tarball,\n title,\n type: 'coreApp',\n version,\n visibility,\n })\n spin.succeed()\n return {applicationId: id}\n } catch (error) {\n spin.clear()\n throw error\n }\n}\n\n/**\n * Deploy a workbench studio through Brett: redeploy when `appId` is set,\n * otherwise create the studio at `studioHost`. Returns the application id for\n * the shell to report; a missing `studioHost` on create is a usage error.\n * @internal\n */\nexport async function deployStudio(options: {\n appId: string | undefined\n icon?: string\n interfaces: readonly BrettInterface[]\n isAutoUpdating: boolean\n organizationId: string\n output: Output\n projectId: string | undefined\n sourceDir: string\n studioHost: string | undefined\n title: string\n version: string\n workspaces: readonly BrettWorkspace[]\n}): Promise<{applicationId: string}> {\n const {\n appId,\n icon,\n interfaces,\n isAutoUpdating,\n organizationId,\n output,\n projectId,\n sourceDir,\n studioHost,\n title,\n version,\n workspaces,\n } = options\n const tarball = pack(dirname(sourceDir), {entries: [basename(sourceDir)]}).pipe(createGzip())\n\n const spin = spinner('Deploying to sanity.studio').start()\n try {\n if (appId) {\n await createDeployment({\n applicationId: appId,\n interfaces,\n isAutoUpdating,\n tarball,\n version,\n workspaces,\n })\n await updateApplication(appId, {title, ...(icon ? {icon} : {})})\n spin.succeed()\n return {applicationId: appId}\n }\n\n if (!studioHost) {\n spin.fail()\n return output.error(\n 'No studio hostname configured. Set `studioHost` in sanity.cli.ts to create a studio.',\n {exit: exitCodes.USAGE_ERROR},\n )\n }\n\n const application = await createApplication({\n icon,\n interfaces,\n organizationId,\n projectId,\n slug: studioHost,\n tarball,\n title,\n type: 'studio',\n version,\n workspaces,\n })\n spin.succeed()\n return {applicationId: application.id}\n } catch (error) {\n spin.fail()\n throw error\n }\n}\n"],"names":["basename","dirname","createGzip","exitCodes","spinner","pack","createApplication","createDeployment","updateApplication","deployCoreApp","options","appId","icon","interfaces","isAutoUpdating","isSingleton","organizationId","slug","sourceDir","title","version","visibility","tarball","entries","pipe","spin","start","applicationId","succeed","id","type","error","clear","deployStudio","output","projectId","studioHost","workspaces","fail","exit","USAGE_ERROR","application"],"mappings":"AAAA,SAAQA,QAAQ,EAAEC,OAAO,QAAO,YAAW;AAC3C,SAAQC,UAAU,QAAO,YAAW;AAEpC,SAA4BC,SAAS,QAAoB,mBAAkB;AAC3E,SAAQC,OAAO,QAAO,sBAAqB;AAC3C,SAAQC,IAAI,QAAO,SAAQ;AAE3B,SAGEC,iBAAiB,EACjBC,gBAAgB,EAChBC,iBAAiB,QACZ,iCAAgC;AAEvC;;;;;CAKC,GACD,OAAO,eAAeC,cAAcC,OAYnC;IACC,MAAM,EACJC,KAAK,EACLC,IAAI,EACJC,UAAU,EACVC,cAAc,EACdC,WAAW,EACXC,cAAc,EACdC,IAAI,EACJC,SAAS,EACTC,KAAK,EACLC,OAAO,EACPC,UAAU,EACX,GAAGX;IACJ,MAAMY,UAAUjB,KAAKJ,QAAQiB,YAAY;QAACK,SAAS;YAACvB,SAASkB;SAAW;IAAA,GAAGM,IAAI,CAACtB;IAEhF,MAAMuB,OAAOrB,QAAQ,gBAAgBsB,KAAK;IAC1C,IAAI;QACF,IAAIf,OAAO;YACT,MAAMJ,iBAAiB;gBAACoB,eAAehB;gBAAOE;gBAAYC;gBAAgBQ;gBAASF;YAAO;YAC1F,MAAMZ,kBAAkBG,OAAO;gBAACQ;gBAAO,GAAIP,OAAO;oBAACA;gBAAI,IAAI,CAAC,CAAC;YAAC;YAC9Da,KAAKG,OAAO;YACZ,OAAO;gBAACD,eAAehB;YAAK;QAC9B;QAEA,MAAM,EAACkB,EAAE,EAAC,GAAG,MAAMvB,kBAAkB;YACnCM;YACAC;YACAE;YACAC;YACAC;YACAK;YACAH;YACAW,MAAM;YACNV;YACAC;QACF;QACAI,KAAKG,OAAO;QACZ,OAAO;YAACD,eAAeE;QAAE;IAC3B,EAAE,OAAOE,OAAO;QACdN,KAAKO,KAAK;QACV,MAAMD;IACR;AACF;AAEA;;;;;CAKC,GACD,OAAO,eAAeE,aAAavB,OAalC;IACC,MAAM,EACJC,KAAK,EACLC,IAAI,EACJC,UAAU,EACVC,cAAc,EACdE,cAAc,EACdkB,MAAM,EACNC,SAAS,EACTjB,SAAS,EACTkB,UAAU,EACVjB,KAAK,EACLC,OAAO,EACPiB,UAAU,EACX,GAAG3B;IACJ,MAAMY,UAAUjB,KAAKJ,QAAQiB,YAAY;QAACK,SAAS;YAACvB,SAASkB;SAAW;IAAA,GAAGM,IAAI,CAACtB;IAEhF,MAAMuB,OAAOrB,QAAQ,8BAA8BsB,KAAK;IACxD,IAAI;QACF,IAAIf,OAAO;YACT,MAAMJ,iBAAiB;gBACrBoB,eAAehB;gBACfE;gBACAC;gBACAQ;gBACAF;gBACAiB;YACF;YACA,MAAM7B,kBAAkBG,OAAO;gBAACQ;gBAAO,GAAIP,OAAO;oBAACA;gBAAI,IAAI,CAAC,CAAC;YAAC;YAC9Da,KAAKG,OAAO;YACZ,OAAO;gBAACD,eAAehB;YAAK;QAC9B;QAEA,IAAI,CAACyB,YAAY;YACfX,KAAKa,IAAI;YACT,OAAOJ,OAAOH,KAAK,CACjB,wFACA;gBAACQ,MAAMpC,UAAUqC,WAAW;YAAA;QAEhC;QAEA,MAAMC,cAAc,MAAMnC,kBAAkB;YAC1CM;YACAC;YACAG;YACAmB;YACAlB,MAAMmB;YACNd;YACAH;YACAW,MAAM;YACNV;YACAiB;QACF;QACAZ,KAAKG,OAAO;QACZ,OAAO;YAACD,eAAec,YAAYZ,EAAE;QAAA;IACvC,EAAE,OAAOE,OAAO;QACdN,KAAKa,IAAI;QACT,MAAMP;IACR;AACF"}
|