@sanity/workbench-cli 1.1.2 → 1.2.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.
Files changed (48) hide show
  1. package/dist/_exports/build.d.ts +76 -8
  2. package/dist/_exports/build.js.map +1 -1
  3. package/dist/_exports/deploy.d.ts +151 -12
  4. package/dist/_exports/deploy.js +2 -3
  5. package/dist/_exports/deploy.js.map +1 -1
  6. package/dist/_exports/dev.d.ts +22 -0
  7. package/dist/_exports/index.d.ts +82 -31
  8. package/dist/_exports/index.js +1 -11
  9. package/dist/_exports/index.js.map +1 -1
  10. package/dist/actions/build/artifact.js +8 -7
  11. package/dist/actions/build/artifact.js.map +1 -1
  12. package/dist/actions/build/configs/artifact.js +45 -0
  13. package/dist/actions/build/configs/artifact.js.map +1 -0
  14. package/dist/actions/build/vite/plugin.js +6 -14
  15. package/dist/actions/build/vite/plugin.js.map +1 -1
  16. package/dist/actions/build/vite/plugins/plugin-sanity-app-id.js +24 -0
  17. package/dist/actions/build/vite/plugins/plugin-sanity-app-id.js.map +1 -0
  18. package/dist/actions/build/vite/workbench-vite-plugins.js +8 -4
  19. package/dist/actions/build/vite/workbench-vite-plugins.js.map +1 -1
  20. package/dist/actions/deploy/checkBuiltOutput.js +25 -0
  21. package/dist/actions/deploy/checkBuiltOutput.js.map +1 -0
  22. package/dist/actions/deploy/deployInstallationConfig.js +91 -0
  23. package/dist/actions/deploy/deployInstallationConfig.js.map +1 -0
  24. package/dist/actions/deploy/getWorkbench.js +14 -25
  25. package/dist/actions/deploy/getWorkbench.js.map +1 -1
  26. package/dist/actions/deploy/viewDeployment.js +32 -0
  27. package/dist/actions/deploy/viewDeployment.js.map +1 -0
  28. package/dist/actions/dev/deriveInterfaces.js +47 -4
  29. package/dist/actions/dev/deriveInterfaces.js.map +1 -1
  30. package/dist/actions/dev/exposesSetId.js +69 -0
  31. package/dist/actions/dev/exposesSetId.js.map +1 -0
  32. package/dist/actions/dev/registry.js +17 -0
  33. package/dist/actions/dev/registry.js.map +1 -1
  34. package/dist/actions/dev/startDevManifestWatcher.js +2 -1
  35. package/dist/actions/dev/startDevManifestWatcher.js.map +1 -1
  36. package/dist/actions/dev/startDevServerRegistration.js +26 -11
  37. package/dist/actions/dev/startDevServerRegistration.js.map +1 -1
  38. package/dist/actions/dev/startWorkbenchDevServer.js +20 -5
  39. package/dist/actions/dev/startWorkbenchDevServer.js.map +1 -1
  40. package/dist/contract.js +33 -38
  41. package/dist/contract.js.map +1 -1
  42. package/dist/defineApp.js +55 -1
  43. package/dist/defineApp.js.map +1 -1
  44. package/dist/resolveWorkbenchApp.js +4 -1
  45. package/dist/resolveWorkbenchApp.js.map +1 -1
  46. package/package.json +7 -4
  47. package/dist/actions/dev/interfaceSetId.js +0 -51
  48. package/dist/actions/dev/interfaceSetId.js.map +0 -1
@@ -4,13 +4,14 @@ import { z } from "zod/mini";
4
4
 
5
5
  /**
6
6
  * User-facing input for `unstable_defineApp`. Excludes the internal
7
- * `applicationType` that field is validated by the schema but is not part of
8
- * the public surface (Sanity-owned apps set it via `@ts-expect-error`).
7
+ * `applicationType`, `isSingleton`, and `installationConfig` validated by the
8
+ * schema but not part of the public surface (Sanity-owned apps set them via
9
+ * `@ts-expect-error`).
9
10
  * @public
10
11
  */
11
12
  declare type DefineAppInput = Omit<
12
13
  z.output<typeof DefineAppInputSchema>,
13
- "applicationType"
14
+ "applicationType" | "installationConfig" | "isSingleton"
14
15
  >;
15
16
 
16
17
  /**
@@ -23,11 +24,11 @@ declare const DefineAppInputSchema: z.ZodMiniObject<
23
24
  {
24
25
  applicationType: z.ZodMiniOptional<
25
26
  z.ZodMiniEnum<{
27
+ "media-library": "media-library";
26
28
  coreApp: "coreApp";
27
29
  studio: "studio";
28
30
  canvas: "canvas";
29
31
  dashboard: "dashboard";
30
- "media-library": "media-library";
31
32
  }>
32
33
  >;
33
34
  entry: z.ZodMiniOptional<z.ZodMiniString<string>>;
@@ -39,6 +40,31 @@ declare const DefineAppInputSchema: z.ZodMiniObject<
39
40
  }>
40
41
  >;
41
42
  icon: z.ZodMiniOptional<z.ZodMiniString<string>>;
43
+ installationConfig: z.ZodMiniOptional<
44
+ z.ZodMiniDiscriminatedUnion<
45
+ [
46
+ z.ZodMiniObject<
47
+ {
48
+ appType: z.ZodMiniLiteral<"media-library">;
49
+ fields: z.ZodMiniArray<
50
+ z.ZodMiniObject<
51
+ {
52
+ public: z.ZodMiniOptional<z.ZodMiniBoolean<boolean>>;
53
+ title: z.ZodMiniString<string>;
54
+ name: z.ZodMiniString<string>;
55
+ src: z.ZodMiniString<string>;
56
+ },
57
+ z.core.$strip
58
+ >
59
+ >;
60
+ },
61
+ z.core.$strip
62
+ >,
63
+ ],
64
+ "appType"
65
+ >
66
+ >;
67
+ isSingleton: z.ZodMiniOptional<z.ZodMiniBoolean<boolean>>;
42
68
  name: z.ZodMiniString<string>;
43
69
  organizationId: z.ZodMiniString<string>;
44
70
  priority: z.ZodMiniOptional<z.ZodMiniNumber<number>>;
@@ -81,8 +107,21 @@ declare const DefineAppInputSchema: z.ZodMiniObject<
81
107
  z.core.$strip
82
108
  >;
83
109
 
110
+ /**
111
+ * The branded result of `unstable_defineApp`. Carries the same fields as the
112
+ * input plus the internal brand — users only ever see `DefineAppInput`.
113
+ * @public
114
+ */
115
+ declare interface DefineAppResult extends DefineAppInput {
116
+ readonly [WORKBENCH_APP]: true;
117
+ }
118
+
84
119
  /** @public */
85
120
  declare interface ResolvedWorkbenchApp {
121
+ /** A Sanity-owned singleton (e.g. the Media Library) — deploys its config, not an application. */
122
+ readonly isSingleton: boolean;
123
+ /** The app's unique `name` from `unstable_defineApp`. */
124
+ readonly name: string;
86
125
  /** Background worker services the app declares. */
87
126
  readonly services: NonNullable<DefineAppInput["services"]>;
88
127
  /** Dock panel views the app declares. */
@@ -91,6 +130,8 @@ declare interface ResolvedWorkbenchApp {
91
130
  readonly applicationType?: string;
92
131
  /** SDK app-view entrypoint, when declared. */
93
132
  readonly entry?: string;
133
+ /** Deploys on its own path, separate from the interfaces. */
134
+ readonly installationConfig?: WorkbenchApp["installationConfig"];
94
135
  }
95
136
 
96
137
  /**
@@ -101,6 +142,34 @@ export declare function resolveWorkbenchApp(
101
142
  cliConfig: CliConfig | null | undefined,
102
143
  ): ResolvedWorkbenchApp | null;
103
144
 
145
+ /**
146
+ * Nominal brand the CLI discriminates on to enable the workbench build/deploy
147
+ * codepath. Registered via `Symbol.for` so the marker survives module-realm
148
+ * boundaries — `@sanity/cli-core` re-derives the same global symbol with
149
+ * `Symbol.for` rather than importing it, so it stays internal to this module.
150
+ */
151
+ declare const WORKBENCH_APP: unique symbol;
152
+
153
+ /**
154
+ * A branded app as the CLI reads it — the full schema shape, including the
155
+ * internal fields `DefineAppInput` omits. Schema-derived so the narrowing
156
+ * can't drift from what the schema validates.
157
+ * @public
158
+ */
159
+ declare type WorkbenchApp = DefineAppResult &
160
+ z.output<typeof DefineAppInputSchema>;
161
+
162
+ /**
163
+ * Bundled so adding a declaration family touches this type and the artifact
164
+ * expanders, not every hop of build/dev plumbing in between.
165
+ * @internal
166
+ */
167
+ export declare interface WorkbenchExposes {
168
+ installationConfig?: WorkbenchApp["installationConfig"];
169
+ services?: DefineAppInput["services"];
170
+ views?: DefineAppInput["views"];
171
+ }
172
+
104
173
  declare interface WorkbenchViteOptions {
105
174
  /** Project root — read for the federation remote name, and the plugin workDir. */
106
175
  cwd: string;
@@ -113,12 +182,11 @@ declare interface WorkbenchViteOptions {
113
182
  relativeConfigLocation: string | null;
114
183
  relativeEntry: string | null;
115
184
  };
185
+ /** The app's bus identity, stamped into its modules for `@sanity/runtime`. */
186
+ appId?: string;
187
+ exposes?: WorkbenchExposes;
116
188
  /** App (vs studio) build — selects the discriminated federation option shape. */
117
189
  isApp?: boolean;
118
- /** Declared background services. */
119
- services?: DefineAppInput["services"];
120
- /** Declared dock views. */
121
- views?: DefineAppInput["views"];
122
190
  }
123
191
 
124
192
  /** Build the Vite plugins for a workbench app's module-federation remote. */
@@ -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} 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,QAAO,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 {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,15 +1,25 @@
1
1
  import { CliConfig } from "@sanity/cli-core";
2
+ import { Output } from "@sanity/cli-core";
2
3
  import { z } from "zod/mini";
3
4
 
5
+ /**
6
+ * Throws unless `sourceDir` is a directory holding a federation build.
7
+ * Workbench builds emit a module-federation remote instead of a static SPA,
8
+ * so the usual `index.html` contract doesn't apply — `mf-manifest.json` is the
9
+ * marker that `sanity build` produced a federation build.
10
+ */
11
+ export declare function checkBuiltOutput(sourceDir: string): Promise<void>;
12
+
4
13
  /**
5
14
  * User-facing input for `unstable_defineApp`. Excludes the internal
6
- * `applicationType` that field is validated by the schema but is not part of
7
- * the public surface (Sanity-owned apps set it via `@ts-expect-error`).
15
+ * `applicationType`, `isSingleton`, and `installationConfig` validated by the
16
+ * schema but not part of the public surface (Sanity-owned apps set them via
17
+ * `@ts-expect-error`).
8
18
  * @public
9
19
  */
10
20
  declare type DefineAppInput = Omit<
11
21
  z.output<typeof DefineAppInputSchema>,
12
- "applicationType"
22
+ "applicationType" | "installationConfig" | "isSingleton"
13
23
  >;
14
24
 
15
25
  /**
@@ -22,11 +32,11 @@ declare const DefineAppInputSchema: z.ZodMiniObject<
22
32
  {
23
33
  applicationType: z.ZodMiniOptional<
24
34
  z.ZodMiniEnum<{
35
+ "media-library": "media-library";
25
36
  coreApp: "coreApp";
26
37
  studio: "studio";
27
38
  canvas: "canvas";
28
39
  dashboard: "dashboard";
29
- "media-library": "media-library";
30
40
  }>
31
41
  >;
32
42
  entry: z.ZodMiniOptional<z.ZodMiniString<string>>;
@@ -38,6 +48,31 @@ declare const DefineAppInputSchema: z.ZodMiniObject<
38
48
  }>
39
49
  >;
40
50
  icon: z.ZodMiniOptional<z.ZodMiniString<string>>;
51
+ installationConfig: z.ZodMiniOptional<
52
+ z.ZodMiniDiscriminatedUnion<
53
+ [
54
+ z.ZodMiniObject<
55
+ {
56
+ appType: z.ZodMiniLiteral<"media-library">;
57
+ fields: z.ZodMiniArray<
58
+ z.ZodMiniObject<
59
+ {
60
+ public: z.ZodMiniOptional<z.ZodMiniBoolean<boolean>>;
61
+ title: z.ZodMiniString<string>;
62
+ name: z.ZodMiniString<string>;
63
+ src: z.ZodMiniString<string>;
64
+ },
65
+ z.core.$strip
66
+ >
67
+ >;
68
+ },
69
+ z.core.$strip
70
+ >,
71
+ ],
72
+ "appType"
73
+ >
74
+ >;
75
+ isSingleton: z.ZodMiniOptional<z.ZodMiniBoolean<boolean>>;
41
76
  name: z.ZodMiniString<string>;
42
77
  organizationId: z.ZodMiniString<string>;
43
78
  priority: z.ZodMiniOptional<z.ZodMiniNumber<number>>;
@@ -80,28 +115,60 @@ declare const DefineAppInputSchema: z.ZodMiniObject<
80
115
  z.core.$strip
81
116
  >;
82
117
 
118
+ /**
119
+ * The branded result of `unstable_defineApp`. Carries the same fields as the
120
+ * input plus the internal brand — users only ever see `DefineAppInput`.
121
+ * @public
122
+ */
123
+ declare interface DefineAppResult extends DefineAppInput {
124
+ readonly [WORKBENCH_APP]: true;
125
+ }
126
+
83
127
  declare interface DeployableWorkbenchApp extends ResolvedWorkbenchApp {
84
128
  /**
85
- * Throws when the app declares nothing the build can expose no entry, view
86
- * or service. A federated app with none would ship a remote with nothing to
87
- * load, so deploy gates on this before any prompts or API calls.
129
+ * Throws when the app exposes nothing (no entry, view, service, or config)
130
+ * the remote would have nothing to load. Gated before any prompt or API call.
88
131
  */
89
132
  assertDeployable(): void;
90
133
  /**
91
- * Throws unless `sourceDir` is a directory holding a federation build.
92
- * Workbench builds emit a module-federation remote instead of a static SPA,
93
- * so the usual `index.html` contract doesn't apply — `mf-manifest.json` is the
94
- * marker that `sanity build` produced a federation build.
134
+ * Validates the app's declared views into the application-service payload.
135
+ * Throws when a view declaration is malformed.
136
+ */
137
+ buildViewDeploymentPayload(applicationId: string): ViewDeploymentPayload;
138
+ /**
139
+ * A singleton (the Media Library) that carries an installation config — deploy
140
+ * persists the config to the org's installation. Independent of the interfaces,
141
+ * which register regardless; non-singletons never carry a config.
95
142
  */
96
- checkBuiltOutput(sourceDir: string): Promise<void>;
143
+ deploySingletonInstallationConfig: boolean;
144
+ /** Declares something to host as an application — an entry, view, or service. */
145
+ hasInterfaces: boolean;
97
146
  }
98
147
 
148
+ /**
149
+ * Upload the built module-federation remote to the installation as its config
150
+ * snapshot. `installationId` is resolved by the caller so `--dry-run` never
151
+ * reaches this mutating step.
152
+ * @internal
153
+ */
154
+ export declare function deployInstallationConfig(options: {
155
+ appType: string;
156
+ installationId: string;
157
+ output: Output;
158
+ sourceDir: string;
159
+ version: string;
160
+ }): Promise<void>;
161
+
99
162
  export declare function getWorkbench(
100
163
  cliConfig: CliConfig | null | undefined,
101
164
  ): DeployableWorkbenchApp | null;
102
165
 
103
166
  /** @public */
104
167
  declare interface ResolvedWorkbenchApp {
168
+ /** A Sanity-owned singleton (e.g. the Media Library) — deploys its config, not an application. */
169
+ readonly isSingleton: boolean;
170
+ /** The app's unique `name` from `unstable_defineApp`. */
171
+ readonly name: string;
105
172
  /** Background worker services the app declares. */
106
173
  readonly services: NonNullable<DefineAppInput["services"]>;
107
174
  /** Dock panel views the app declares. */
@@ -110,6 +177,78 @@ declare interface ResolvedWorkbenchApp {
110
177
  readonly applicationType?: string;
111
178
  /** SDK app-view entrypoint, when declared. */
112
179
  readonly entry?: string;
180
+ /** Deploys on its own path, separate from the interfaces. */
181
+ readonly installationConfig?: WorkbenchApp["installationConfig"];
113
182
  }
114
183
 
184
+ /**
185
+ * The org's active installation for an app type, or `undefined` when none is
186
+ * installed. Read-only, so `--dry-run` can report deployability.
187
+ * @internal
188
+ */
189
+ export declare function resolveInstallationId(options: {
190
+ appType: string;
191
+ organizationId: string;
192
+ }): Promise<string | undefined>;
193
+
194
+ /**
195
+ * A report heading and item list for a config; a media library's `fields` are
196
+ * one of potentially many shapes.
197
+ * @internal
198
+ */
199
+ export declare function summarizeInstallationConfig(config: {
200
+ appType: string;
201
+ fields: {
202
+ name: string;
203
+ title: string;
204
+ }[];
205
+ }): string;
206
+
207
+ declare type ViewDeploymentPayload = z.infer<
208
+ typeof viewDeploymentPayloadSchema
209
+ >;
210
+
211
+ /**
212
+ * Payload registering an app's views with the application service on deploy.
213
+ *
214
+ * Phase 1 stub: the service that stores views does not exist yet, so the
215
+ * payload is validated and logged only — never sent. Builds the contract the
216
+ * application-service endpoint will accept.
217
+ */
218
+ declare const viewDeploymentPayloadSchema: z.ZodMiniObject<
219
+ {
220
+ applicationId: z.ZodMiniString<string>;
221
+ views: z.ZodMiniArray<
222
+ z.ZodMiniObject<
223
+ {
224
+ name: z.ZodMiniString<string>;
225
+ src: z.ZodMiniString<string>;
226
+ type: z.ZodMiniEnum<{
227
+ panel: "panel";
228
+ }>;
229
+ },
230
+ z.core.$loose
231
+ >
232
+ >;
233
+ },
234
+ z.core.$strip
235
+ >;
236
+
237
+ /**
238
+ * Nominal brand the CLI discriminates on to enable the workbench build/deploy
239
+ * codepath. Registered via `Symbol.for` so the marker survives module-realm
240
+ * boundaries — `@sanity/cli-core` re-derives the same global symbol with
241
+ * `Symbol.for` rather than importing it, so it stays internal to this module.
242
+ */
243
+ declare const WORKBENCH_APP: unique symbol;
244
+
245
+ /**
246
+ * A branded app as the CLI reads it — the full schema shape, including the
247
+ * internal fields `DefineAppInput` omits. Schema-derived so the narrowing
248
+ * can't drift from what the schema validates.
249
+ * @public
250
+ */
251
+ declare type WorkbenchApp = DefineAppResult &
252
+ z.output<typeof DefineAppInputSchema>;
253
+
115
254
  export {};
@@ -1,6 +1,5 @@
1
- // Node-only deploy entry: the workbench-app accessor with the deploy-time guards
2
- // (`assertDeployable`, `checkBuiltOutput`) the deploy command runs before
3
- // shipping. Built on the same shared resolver as the build accessor.
1
+ export { checkBuiltOutput } from '../actions/deploy/checkBuiltOutput.js';
2
+ export { deployInstallationConfig, resolveInstallationId, summarizeInstallationConfig } from '../actions/deploy/deployInstallationConfig.js';
4
3
  export { getWorkbench } from '../actions/deploy/getWorkbench.js';
5
4
 
6
5
  //# sourceMappingURL=deploy.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/_exports/deploy.ts"],"sourcesContent":["// Node-only deploy entry: the workbench-app accessor with the deploy-time guards\n// (`assertDeployable`, `checkBuiltOutput`) the deploy command runs before\n// shipping. Built on the same shared resolver as the build accessor.\nexport {getWorkbench} from '../actions/deploy/getWorkbench.js'\n"],"names":["getWorkbench"],"mappings":"AAAA,iFAAiF;AACjF,0EAA0E;AAC1E,qEAAqE;AACrE,SAAQA,YAAY,QAAO,oCAAmC"}
1
+ {"version":3,"sources":["../../src/_exports/deploy.ts"],"sourcesContent":["export {checkBuiltOutput} from '../actions/deploy/checkBuiltOutput.js'\nexport {\n deployInstallationConfig,\n resolveInstallationId,\n summarizeInstallationConfig,\n} from '../actions/deploy/deployInstallationConfig.js'\nexport {getWorkbench} from '../actions/deploy/getWorkbench.js'\n"],"names":["checkBuiltOutput","deployInstallationConfig","resolveInstallationId","summarizeInstallationConfig","getWorkbench"],"mappings":"AAAA,SAAQA,gBAAgB,QAAO,wCAAuC;AACtE,SACEC,wBAAwB,EACxBC,qBAAqB,EACrBC,2BAA2B,QACtB,gDAA+C;AACtD,SAAQC,YAAY,QAAO,oCAAmC"}
@@ -32,6 +32,28 @@ declare const devServerManifestSchema: z.ZodMiniObject<
32
32
  {
33
33
  host: z.ZodMiniString<string>;
34
34
  id: z.ZodMiniOptional<z.ZodMiniString<string>>;
35
+ installationConfigs: z.ZodMiniOptional<
36
+ z.ZodMiniArray<
37
+ z.ZodMiniObject<
38
+ {
39
+ appType: z.ZodMiniOptional<z.ZodMiniString<string>>;
40
+ fields: z.ZodMiniArray<
41
+ z.ZodMiniObject<
42
+ {
43
+ name: z.ZodMiniString<string>;
44
+ public: z.ZodMiniOptional<z.ZodMiniBoolean<boolean>>;
45
+ src: z.ZodMiniString<string>;
46
+ title: z.ZodMiniString<string>;
47
+ },
48
+ z.core.$strip
49
+ >
50
+ >;
51
+ moduleName: z.ZodMiniOptional<z.ZodMiniString<string>>;
52
+ },
53
+ z.core.$strip
54
+ >
55
+ >
56
+ >;
35
57
  interfaces: z.ZodMiniOptional<
36
58
  z.ZodMiniArray<
37
59
  z.ZodMiniObject<
@@ -2,13 +2,14 @@ import { z } from "zod/mini";
2
2
 
3
3
  /**
4
4
  * User-facing input for `unstable_defineApp`. Excludes the internal
5
- * `applicationType` that field is validated by the schema but is not part of
6
- * the public surface (Sanity-owned apps set it via `@ts-expect-error`).
5
+ * `applicationType`, `isSingleton`, and `installationConfig` validated by the
6
+ * schema but not part of the public surface (Sanity-owned apps set them via
7
+ * `@ts-expect-error`).
7
8
  * @public
8
9
  */
9
10
  export declare type DefineAppInput = Omit<
10
11
  z.output<typeof DefineAppInputSchema>,
11
- "applicationType"
12
+ "applicationType" | "installationConfig" | "isSingleton"
12
13
  >;
13
14
 
14
15
  /**
@@ -21,11 +22,11 @@ declare const DefineAppInputSchema: z.ZodMiniObject<
21
22
  {
22
23
  applicationType: z.ZodMiniOptional<
23
24
  z.ZodMiniEnum<{
25
+ "media-library": "media-library";
24
26
  coreApp: "coreApp";
25
27
  studio: "studio";
26
28
  canvas: "canvas";
27
29
  dashboard: "dashboard";
28
- "media-library": "media-library";
29
30
  }>
30
31
  >;
31
32
  entry: z.ZodMiniOptional<z.ZodMiniString<string>>;
@@ -37,6 +38,31 @@ declare const DefineAppInputSchema: z.ZodMiniObject<
37
38
  }>
38
39
  >;
39
40
  icon: z.ZodMiniOptional<z.ZodMiniString<string>>;
41
+ installationConfig: z.ZodMiniOptional<
42
+ z.ZodMiniDiscriminatedUnion<
43
+ [
44
+ z.ZodMiniObject<
45
+ {
46
+ appType: z.ZodMiniLiteral<"media-library">;
47
+ fields: z.ZodMiniArray<
48
+ z.ZodMiniObject<
49
+ {
50
+ public: z.ZodMiniOptional<z.ZodMiniBoolean<boolean>>;
51
+ title: z.ZodMiniString<string>;
52
+ name: z.ZodMiniString<string>;
53
+ src: z.ZodMiniString<string>;
54
+ },
55
+ z.core.$strip
56
+ >
57
+ >;
58
+ },
59
+ z.core.$strip
60
+ >,
61
+ ],
62
+ "appType"
63
+ >
64
+ >;
65
+ isSingleton: z.ZodMiniOptional<z.ZodMiniBoolean<boolean>>;
40
66
  name: z.ZodMiniString<string>;
41
67
  organizationId: z.ZodMiniString<string>;
42
68
  priority: z.ZodMiniOptional<z.ZodMiniNumber<number>>;
@@ -116,6 +142,16 @@ export declare interface DefinedView<
116
142
  readonly version: typeof VIEW_CONTRACT_VERSION;
117
143
  }
118
144
 
145
+ /**
146
+ * Sanity-owned singleton, so authors don't name or title the app — only `organizationId` is required.
147
+ * @public
148
+ */
149
+ export declare interface DefineMediaLibraryInput {
150
+ /** Organization that owns the media library — the CLI runs and deploys against it. */
151
+ organizationId: string;
152
+ fields?: MediaLibraryField[];
153
+ }
154
+
119
155
  /**
120
156
  * Dock group identifier. The API does not block a user app from declaring a
121
157
  * reserved group (e.g. `dock.system`); priority conventions keep Sanity-owned
@@ -131,11 +167,28 @@ declare const DockGroupSchema: z.ZodMiniEnum<{
131
167
  "dock.user": "dock.user";
132
168
  }>;
133
169
 
170
+ /** @public */
171
+ export declare type InterfaceType = keyof typeof VIEW_COMPONENTS;
172
+
134
173
  /**
135
- * Every supported interface type the first argument to `unstable_defineView`.
174
+ * Whether `app` is a branded `unstable_defineApp(...)` result the sole
175
+ * workbench opt-in.
136
176
  * @public
137
177
  */
138
- export declare type InterfaceType = keyof typeof VIEW_COMPONENTS;
178
+ export declare function isWorkbenchApp(app: unknown): app is WorkbenchApp;
179
+
180
+ /**
181
+ * One custom field a media library exposes. `src` default-exports a `defineField(...)` schema type.
182
+ * @public
183
+ */
184
+ export declare interface MediaLibraryField {
185
+ /** Unique within the media library. */
186
+ name: string;
187
+ src: string;
188
+ title: string;
189
+ /** Readable outside the owning organization. */
190
+ public?: boolean;
191
+ }
139
192
 
140
193
  /**
141
194
  * A panel's view-component slot — the module-federation expose for one island.
@@ -166,12 +219,7 @@ export declare type PanelViewProps = ViewComponentBaseProps<{
166
219
  name: string;
167
220
  }>;
168
221
 
169
- /**
170
- * Contract version stamped on every defined service. Lets the workbench host
171
- * and the generated worker artifact evolve the service contract without
172
- * breaking already-deployed services; bumped only on a breaking change.
173
- * @internal
174
- */
222
+ /** @internal */
175
223
  declare const SERVICE_CONTRACT_VERSION = 1;
176
224
 
177
225
  /**
@@ -206,12 +254,7 @@ export declare interface ServiceInfo {
206
254
  readonly type: string;
207
255
  }
208
256
 
209
- /**
210
- * Every supported service type — the first argument to `unstable_defineService`.
211
- * Add a service type by adding its declaration schema below and registering it
212
- * here.
213
- * @public
214
- */
257
+ /** @public */
215
258
  export declare type ServiceType = "worker";
216
259
 
217
260
  /**
@@ -225,6 +268,14 @@ export declare function unstable_defineApp(
225
268
  input: DefineAppInput,
226
269
  ): DefineAppResult;
227
270
 
271
+ /**
272
+ * Declare the Sanity Media Library as a workbench app — a singleton whose `fields` become its installation config.
273
+ * @public
274
+ */
275
+ export declare function unstable_defineMediaLibrary(
276
+ input: DefineMediaLibraryInput,
277
+ ): DefineAppResult;
278
+
228
279
  /**
229
280
  * Define a Sanity Workbench background service. The first argument narrows the
230
281
  * callback shape — `"worker"` runs the callback inside a Web Worker, where it
@@ -256,20 +307,15 @@ export declare function unstable_defineView<TType extends InterfaceType>(
256
307
  ): DefinedView<TType>;
257
308
 
258
309
  /**
259
- * Component slots each interface type exposes, in render order the source of
260
- * truth for {@link InterfaceType} and for the build (the vite plugin expands a
261
- * view into one render artifact per component). Add a type by registering it here.
310
+ * Component slots each interface type exposes, in render order. Source of truth
311
+ * for {@link InterfaceType} and the build; add a type by registering it here.
262
312
  * @internal
263
313
  */
264
314
  declare const VIEW_COMPONENTS: {
265
315
  readonly panel: readonly ["title", "panel"];
266
316
  };
267
317
 
268
- /**
269
- * Contract version stamped on every defined view — lets the host and the
270
- * generated artifact evolve the contract without breaking deployed views.
271
- * @internal
272
- */
318
+ /** @internal */
273
319
  declare const VIEW_CONTRACT_VERSION = 1;
274
320
 
275
321
  /**
@@ -279,11 +325,7 @@ declare const VIEW_CONTRACT_VERSION = 1;
279
325
  */
280
326
  declare type ViewComponent<TProps> = (props: TProps) => unknown;
281
327
 
282
- /**
283
- * Props every view component receives, whatever its type. Per-type props
284
- * compose from this, so a prop added here reaches every view.
285
- * @public
286
- */
328
+ /** @public */
287
329
  declare interface ViewComponentBaseProps<TView> {
288
330
  view: TView;
289
331
  }
@@ -304,4 +346,13 @@ export declare interface ViewComponentsByType {
304
346
  */
305
347
  declare const WORKBENCH_APP: unique symbol;
306
348
 
349
+ /**
350
+ * A branded app as the CLI reads it — the full schema shape, including the
351
+ * internal fields `DefineAppInput` omits. Schema-derived so the narrowing
352
+ * can't drift from what the schema validates.
353
+ * @public
354
+ */
355
+ export declare type WorkbenchApp = DefineAppResult &
356
+ z.output<typeof DefineAppInputSchema>;
357
+
307
358
  export {};
@@ -1,14 +1,4 @@
1
- // Public, browser-safe entry for `@sanity/workbench-cli` — the authoring API app
2
- // authors call from `sanity.cli.ts` (re-exported by `sanity/cli` and the
3
- // `sanity` runtime entry). Calling `unstable_defineApp` is the *sole* workbench
4
- // opt-in: it stamps the global brand `Symbol.for('sanity.workbench.defineApp')`,
5
- // which the CLI discriminates on (see `isWorkbenchApp` in `@sanity/cli-core`).
6
- //
7
- // This module graph must stay browser-safe: zod-only, no `node:*`, no vite, no
8
- // `@sanity/cli-core`. View/service `src` files bundle to the browser, so anything
9
- // reachable from here ships in the frontend bundle. The Node-only build glue
10
- // lives behind the separate `./vite` entry and never leaks in.
11
- export { unstable_defineApp } from '../defineApp.js';
1
+ export { isWorkbenchApp, unstable_defineApp, unstable_defineMediaLibrary } from '../defineApp.js';
12
2
  export { unstable_defineService } from '../defineService.js';
13
3
  export { unstable_defineView } from '../defineView.js';
14
4
 
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/_exports/index.ts"],"sourcesContent":["// Public, browser-safe entry for `@sanity/workbench-cli` — the authoring API app\n// authors call from `sanity.cli.ts` (re-exported by `sanity/cli` and the\n// `sanity` runtime entry). Calling `unstable_defineApp` is the *sole* workbench\n// opt-in: it stamps the global brand `Symbol.for('sanity.workbench.defineApp')`,\n// which the CLI discriminates on (see `isWorkbenchApp` in `@sanity/cli-core`).\n//\n// This module graph must stay browser-safe: zod-only, no `node:*`, no vite, no\n// `@sanity/cli-core`. View/service `src` files bundle to the browser, so anything\n// reachable from here ships in the frontend bundle. The Node-only build glue\n// lives behind the separate `./vite` entry and never leaks in.\nexport type {InterfaceType, ServiceType} from '../contract.js'\nexport {unstable_defineApp} from '../defineApp.js'\nexport type {DefineAppInput, DefineAppResult, DockGroup} 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":["unstable_defineApp","unstable_defineService","unstable_defineView"],"mappings":"AAAA,iFAAiF;AACjF,yEAAyE;AACzE,gFAAgF;AAChF,iFAAiF;AACjF,+EAA+E;AAC/E,EAAE;AACF,+EAA+E;AAC/E,kFAAkF;AAClF,6EAA6E;AAC7E,+DAA+D;AAE/D,SAAQA,kBAAkB,QAAO,kBAAiB;AAElD,SAAQC,sBAAsB,QAAO,sBAAqB;AAO1D,SAAQC,mBAAmB,QAAO,mBAAkB"}
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":"AACA,SAAQA,cAAc,EAAEC,kBAAkB,EAAEC,2BAA2B,QAAO,kBAAiB;AAS/F,SAAQC,sBAAsB,QAAO,sBAAqB;AAO1D,SAAQC,mBAAmB,QAAO,mBAAkB"}
@@ -1,3 +1,4 @@
1
+ import { installationConfigArtifacts } from './configs/artifact.js';
1
2
  import { serviceArtifacts } from './services/artifact.js';
2
3
  import { viewArtifacts } from './views/artifact.js';
3
4
  /**
@@ -15,14 +16,14 @@ import { viewArtifacts } from './views/artifact.js';
15
16
  return exposes;
16
17
  }
17
18
  /**
18
- * Expand a workbench app's declared views and services into the flat artifact
19
- * set the federation build writes and exposes — the single place that composes
20
- * the per-type expanders, so the expose mapping and the file writing read from
21
- * one expansion rather than re-deriving it.
22
- */ export function workbenchArtifacts(options) {
19
+ * Expand what the app exposes into the flat artifact set the federation build
20
+ * writes — the single place that composes the per-type expanders, so the expose
21
+ * mapping and the file writing read from one expansion.
22
+ */ export function workbenchArtifacts(exposes) {
23
23
  return [
24
- ...viewArtifacts(options.views),
25
- ...serviceArtifacts(options.services ?? [])
24
+ ...viewArtifacts(exposes.views ?? []),
25
+ ...serviceArtifacts(exposes.services ?? []),
26
+ ...installationConfigArtifacts(exposes.installationConfig)
26
27
  ];
27
28
  }
28
29