@sanity/cli-build 0.0.0-20260612071721 → 0.0.0-20260612080517

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 (38) hide show
  1. package/dist/_exports/_internal/build.d.ts +46 -2
  2. package/dist/_exports/_internal/build.js.map +1 -1
  3. package/dist/_exports/_internal/federation.d.ts +308 -0
  4. package/dist/_exports/_internal/federation.js +15 -0
  5. package/dist/_exports/_internal/federation.js.map +1 -0
  6. package/dist/actions/build/getViteConfig.js +1 -1
  7. package/dist/actions/build/getViteConfig.js.map +1 -1
  8. package/dist/workbench/artifact.js +20 -0
  9. package/dist/workbench/artifact.js.map +1 -0
  10. package/dist/workbench/contract.js +66 -0
  11. package/dist/workbench/contract.js.map +1 -0
  12. package/dist/workbench/defineApp.js +83 -0
  13. package/dist/workbench/defineApp.js.map +1 -0
  14. package/dist/workbench/defineService.js +19 -0
  15. package/dist/workbench/defineService.js.map +1 -0
  16. package/dist/workbench/defineView.js +19 -0
  17. package/dist/workbench/defineView.js.map +1 -0
  18. package/dist/workbench/render-remote.js +69 -0
  19. package/dist/workbench/render-remote.js.map +1 -0
  20. package/dist/workbench/services/artifact.js +122 -0
  21. package/dist/workbench/services/artifact.js.map +1 -0
  22. package/dist/workbench/views/artifact.js +31 -0
  23. package/dist/workbench/views/artifact.js.map +1 -0
  24. package/dist/workbench/vite/constants.js +5 -0
  25. package/dist/workbench/vite/constants.js.map +1 -0
  26. package/dist/workbench/vite/plugin.js +73 -0
  27. package/dist/workbench/vite/plugin.js.map +1 -0
  28. package/dist/workbench/vite/plugins/plugin-module-federation.js +38 -0
  29. package/dist/workbench/vite/plugins/plugin-module-federation.js.map +1 -0
  30. package/dist/workbench/vite/plugins/plugin-sanity-environment.js +29 -0
  31. package/dist/workbench/vite/plugins/plugin-sanity-environment.js.map +1 -0
  32. package/dist/workbench/vite/plugins/plugin-sanity-extension-artifacts.js +43 -0
  33. package/dist/workbench/vite/plugins/plugin-sanity-extension-artifacts.js.map +1 -0
  34. package/dist/workbench/vite/plugins/plugin-sanity-federation-runtime.js +83 -0
  35. package/dist/workbench/vite/plugins/plugin-sanity-federation-runtime.js.map +1 -0
  36. package/dist/workbench/vite/utils/invariant.js +5 -0
  37. package/dist/workbench/vite/utils/invariant.js.map +1 -0
  38. package/package.json +8 -4
@@ -4,11 +4,9 @@ import { Debugger } from "debug";
4
4
  import { DefinedTelemetryTrace } from "@sanity/telemetry";
5
5
  import { FSWatcher } from "chokidar";
6
6
  import { InlineConfig } from "vite";
7
- import { InterfaceArtifact } from "@sanity/federation/vite";
8
7
  import { Output } from "@sanity/cli-core";
9
8
  import { Plugin as Plugin_2 } from "vite";
10
9
  import { PluginOptions } from "babel-plugin-react-compiler";
11
- import { ServiceArtifact } from "@sanity/federation/vite";
12
10
  import { UserViteConfig } from "@sanity/cli-core";
13
11
 
14
12
  export declare const AppBuildTrace: DefinedTelemetryTrace<
@@ -112,6 +110,27 @@ export declare function getViteConfig(
112
110
  options: ViteOptions,
113
111
  ): Promise<InlineConfig>;
114
112
 
113
+ /**
114
+ * An interface to generate render artifacts for. The `src` file default-exports
115
+ * an `unstable_defineView(...)` result; the build emits one render-contract
116
+ * artifact per component the interface type exposes.
117
+ * @public
118
+ */
119
+ export declare interface InterfaceArtifact {
120
+ /** Interface name, unique within the app. */
121
+ name: string;
122
+ /** Path to the interface `src` file, relative to the app root (or absolute). */
123
+ src: string;
124
+ /** Interface type — selects which components the build expands. */
125
+ type: InterfaceType;
126
+ }
127
+
128
+ /**
129
+ * Every supported interface type — the first argument to `unstable_defineView`.
130
+ * @public
131
+ */
132
+ declare type InterfaceType = keyof typeof VIEW_COMPONENTS;
133
+
115
134
  /**
116
135
  * Resolves the relative entry paths for a Sanity project without writing any
117
136
  * runtime files to disk. Used by federation builds that skip the full runtime
@@ -162,6 +181,21 @@ declare interface RuntimeOptions {
162
181
  */
163
182
  export declare const SANITY_CACHE_DIR = "node_modules/.sanity";
164
183
 
184
+ /**
185
+ * A service to generate a worker artifact for. The `src` file default-exports
186
+ * an `unstable_defineService(...)` result; the build emits a self-contained Web
187
+ * Worker bundle plus a loader module that hands the host its URL.
188
+ * @public
189
+ */
190
+ export declare interface ServiceArtifact {
191
+ /** Service name, unique within the app. */
192
+ name: string;
193
+ /** Path to the service `src` file, relative to the app root (or absolute). */
194
+ src: string;
195
+ /** Service type, e.g. `"worker"`. */
196
+ type: string;
197
+ }
198
+
165
199
  export declare const StudioBuildTrace: DefinedTelemetryTrace<
166
200
  {
167
201
  outputSize: number;
@@ -184,6 +218,16 @@ export declare interface VendorBuildConfig {
184
218
  specifiersByChunkName: Record<string, string>;
185
219
  }
186
220
 
221
+ /**
222
+ * Component slots each interface type exposes, in render order — the source of
223
+ * truth for {@link InterfaceType} and for the build (the vite plugin expands a
224
+ * view into one render artifact per component). Add a type by registering it here.
225
+ * @internal
226
+ */
227
+ declare const VIEW_COMPONENTS: {
228
+ readonly panel: readonly ["title", "panel"];
229
+ };
230
+
187
231
  declare interface ViteOptions extends Pick<CliConfig, "schemaExtraction"> {
188
232
  /**
189
233
  * Root path of the studio/sanity app
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/_exports/_internal/build.ts"],"sourcesContent":["export {type AutoUpdatesBuildConfig} from '../../actions/build/autoUpdates.js'\nexport {buildDebug} from '../../actions/build/buildDebug.js'\nexport {checkStudioDependencyVersions} from '../../actions/build/checkStudioDependencyVersions.js'\nexport {\n extendViteConfigWithUserConfig,\n finalizeViteConfig,\n getViteConfig,\n} from '../../actions/build/getViteConfig.js'\nexport {\n resolveVendorBuildConfig,\n type VendorBuildConfig,\n} from '../../actions/build/resolveVendorBuildConfig.js'\nexport {writeFavicons} from '../../actions/build/writeFavicons.js'\nexport {resolveEntries, writeSanityRuntime} from '../../actions/build/writeSanityRuntime.js'\nexport {SANITY_CACHE_DIR} from '../../constants.js'\nexport {AppBuildTrace, StudioBuildTrace} from '../../telemetry/build.telemetry.js'\nexport {copyDir} from '../../util/copyDir.js'\n"],"names":["buildDebug","checkStudioDependencyVersions","extendViteConfigWithUserConfig","finalizeViteConfig","getViteConfig","resolveVendorBuildConfig","writeFavicons","resolveEntries","writeSanityRuntime","SANITY_CACHE_DIR","AppBuildTrace","StudioBuildTrace","copyDir"],"mappings":"AACA,SAAQA,UAAU,QAAO,oCAAmC;AAC5D,SAAQC,6BAA6B,QAAO,uDAAsD;AAClG,SACEC,8BAA8B,EAC9BC,kBAAkB,EAClBC,aAAa,QACR,uCAAsC;AAC7C,SACEC,wBAAwB,QAEnB,kDAAiD;AACxD,SAAQC,aAAa,QAAO,uCAAsC;AAClE,SAAQC,cAAc,EAAEC,kBAAkB,QAAO,4CAA2C;AAC5F,SAAQC,gBAAgB,QAAO,qBAAoB;AACnD,SAAQC,aAAa,EAAEC,gBAAgB,QAAO,qCAAoC;AAClF,SAAQC,OAAO,QAAO,wBAAuB"}
1
+ {"version":3,"sources":["../../../src/_exports/_internal/build.ts"],"sourcesContent":["export {type AutoUpdatesBuildConfig} from '../../actions/build/autoUpdates.js'\nexport {buildDebug} from '../../actions/build/buildDebug.js'\nexport {checkStudioDependencyVersions} from '../../actions/build/checkStudioDependencyVersions.js'\nexport {\n extendViteConfigWithUserConfig,\n finalizeViteConfig,\n getViteConfig,\n} from '../../actions/build/getViteConfig.js'\nexport {\n resolveVendorBuildConfig,\n type VendorBuildConfig,\n} from '../../actions/build/resolveVendorBuildConfig.js'\nexport {writeFavicons} from '../../actions/build/writeFavicons.js'\nexport {resolveEntries, writeSanityRuntime} from '../../actions/build/writeSanityRuntime.js'\nexport {SANITY_CACHE_DIR} from '../../constants.js'\nexport {AppBuildTrace, StudioBuildTrace} from '../../telemetry/build.telemetry.js'\nexport {copyDir} from '../../util/copyDir.js'\nexport {type ServiceArtifact} from '../../workbench/services/artifact.js'\nexport {type InterfaceArtifact} from '../../workbench/views/artifact.js'\n"],"names":["buildDebug","checkStudioDependencyVersions","extendViteConfigWithUserConfig","finalizeViteConfig","getViteConfig","resolveVendorBuildConfig","writeFavicons","resolveEntries","writeSanityRuntime","SANITY_CACHE_DIR","AppBuildTrace","StudioBuildTrace","copyDir"],"mappings":"AACA,SAAQA,UAAU,QAAO,oCAAmC;AAC5D,SAAQC,6BAA6B,QAAO,uDAAsD;AAClG,SACEC,8BAA8B,EAC9BC,kBAAkB,EAClBC,aAAa,QACR,uCAAsC;AAC7C,SACEC,wBAAwB,QAEnB,kDAAiD;AACxD,SAAQC,aAAa,QAAO,uCAAsC;AAClE,SAAQC,cAAc,EAAEC,kBAAkB,QAAO,4CAA2C;AAC5F,SAAQC,gBAAgB,QAAO,qBAAoB;AACnD,SAAQC,aAAa,EAAEC,gBAAgB,QAAO,qCAAoC;AAClF,SAAQC,OAAO,QAAO,wBAAuB"}
@@ -0,0 +1,308 @@
1
+ import { z } from "zod/mini";
2
+
3
+ /**
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`).
7
+ * @public
8
+ */
9
+ export declare type DefineAppInput = Omit<
10
+ z.output<typeof DefineAppInputSchema>,
11
+ "applicationType"
12
+ >;
13
+
14
+ /**
15
+ * Runtime-validation schema for `unstable_defineApp`. Validates the full shape
16
+ * including the internal `applicationType`; the user-facing `DefineAppInput`
17
+ * type below omits that field.
18
+ * @internal
19
+ */
20
+ declare const DefineAppInputSchema: z.ZodMiniObject<
21
+ {
22
+ applicationType: z.ZodMiniOptional<
23
+ z.ZodMiniEnum<{
24
+ coreApp: "coreApp";
25
+ studio: "studio";
26
+ canvas: "canvas";
27
+ dashboard: "dashboard";
28
+ "media-library": "media-library";
29
+ system: "system";
30
+ }>
31
+ >;
32
+ entry: z.ZodMiniOptional<z.ZodMiniString<string>>;
33
+ group: z.ZodMiniOptional<
34
+ z.ZodMiniEnum<{
35
+ "dock.system": "dock.system";
36
+ "dock.applications": "dock.applications";
37
+ "dock.user": "dock.user";
38
+ }>
39
+ >;
40
+ icon: z.ZodMiniOptional<z.ZodMiniString<string>>;
41
+ name: z.ZodMiniString<string>;
42
+ organizationId: z.ZodMiniOptional<z.ZodMiniString<string>>;
43
+ priority: z.ZodMiniOptional<z.ZodMiniNumber<number>>;
44
+ services: z.ZodMiniOptional<
45
+ z.ZodMiniArray<
46
+ z.ZodMiniDiscriminatedUnion<
47
+ [
48
+ z.ZodMiniObject<
49
+ {
50
+ name: z.ZodMiniString<string>;
51
+ src: z.ZodMiniString<string>;
52
+ type: z.ZodMiniLiteral<"worker">;
53
+ },
54
+ z.core.$strip
55
+ >,
56
+ ],
57
+ "type"
58
+ >
59
+ >
60
+ >;
61
+ title: z.ZodMiniString<string>;
62
+ views: z.ZodMiniOptional<
63
+ z.ZodMiniArray<
64
+ z.ZodMiniDiscriminatedUnion<
65
+ [
66
+ z.ZodMiniObject<
67
+ {
68
+ name: z.ZodMiniString<string>;
69
+ src: z.ZodMiniString<string>;
70
+ type: z.ZodMiniLiteral<"panel">;
71
+ },
72
+ z.core.$strip
73
+ >,
74
+ ],
75
+ "type"
76
+ >
77
+ >
78
+ >;
79
+ },
80
+ z.core.$strip
81
+ >;
82
+
83
+ /**
84
+ * The branded result of `unstable_defineApp`. Carries the same fields as the
85
+ * input plus the internal brand — users only ever see `DefineAppInput`.
86
+ * @public
87
+ */
88
+ export declare interface DefineAppResult extends DefineAppInput {
89
+ readonly [WORKBENCH_APP]: true;
90
+ }
91
+
92
+ /**
93
+ * The result of `unstable_defineService`: the author's callback, the service
94
+ * type, and the internal contract version the worker artifact targets.
95
+ * @public
96
+ */
97
+ export declare interface DefinedService<
98
+ TType extends ServiceType = ServiceType,
99
+ > {
100
+ readonly run: ServiceCallbacksByType[TType];
101
+ readonly type: TType;
102
+ /** @internal */
103
+ readonly version: typeof SERVICE_CONTRACT_VERSION;
104
+ }
105
+
106
+ /**
107
+ * The result of `unstable_defineView`: the author's component(s), the view type,
108
+ * and the internal contract version the build artifact targets.
109
+ * @public
110
+ */
111
+ export declare interface DefinedView<
112
+ TType extends InterfaceType = InterfaceType,
113
+ > {
114
+ readonly components: ViewComponentsByType[TType];
115
+ readonly type: TType;
116
+ /** @internal */
117
+ readonly version: typeof VIEW_CONTRACT_VERSION;
118
+ }
119
+
120
+ /**
121
+ * Dock group identifier. The API does not block a user app from declaring a
122
+ * reserved group (e.g. `dock.system`); priority conventions keep Sanity-owned
123
+ * apps ahead.
124
+ * @public
125
+ */
126
+ export declare type DockGroup = z.output<typeof DockGroupSchema>;
127
+
128
+ /** Dock groups an app can place itself into. */
129
+ declare const DockGroupSchema: z.ZodMiniEnum<{
130
+ "dock.system": "dock.system";
131
+ "dock.applications": "dock.applications";
132
+ "dock.user": "dock.user";
133
+ }>;
134
+
135
+ /**
136
+ * Every supported interface type — the first argument to `unstable_defineView`.
137
+ * @public
138
+ */
139
+ export declare type InterfaceType = keyof typeof VIEW_COMPONENTS;
140
+
141
+ /**
142
+ * A panel's view-component slot — the module-federation expose for one island.
143
+ * @public
144
+ */
145
+ export declare type PanelComponent = keyof PanelViewComponents;
146
+
147
+ /**
148
+ * The component slots a `panel` view exposes — each its own module-federation
149
+ * island, typed with the panel props.
150
+ * @public
151
+ */
152
+ export declare interface PanelViewComponents {
153
+ panel: ViewComponent<PanelViewProps>;
154
+ title: ViewComponent<PanelViewProps>;
155
+ }
156
+
157
+ /**
158
+ * Props a panel component receives: its interface record, minus the
159
+ * service-assigned `id`/`deployment_id` a local dev server can't provide. Mirrors
160
+ * the `panel` record the workbench host renders from (the wire format owned by
161
+ * `@sanity/workbench`); drift is guarded by the stamped contract version.
162
+ * @public
163
+ */
164
+ export declare type PanelViewProps = ViewComponentBaseProps<{
165
+ entry_point: string;
166
+ interface_type: "panel";
167
+ name: string;
168
+ }>;
169
+
170
+ /**
171
+ * Contract version stamped on every defined service. Lets the workbench host
172
+ * and the generated worker artifact evolve the service contract without
173
+ * breaking already-deployed services; bumped only on a breaking change.
174
+ * @internal
175
+ */
176
+ declare const SERVICE_CONTRACT_VERSION = 1;
177
+
178
+ /**
179
+ * A service callback. Runs once inside the worker on start; returns an optional
180
+ * disposer the host calls before terminating the worker.
181
+ * @public
182
+ */
183
+ export declare type ServiceCallback = (
184
+ context: ServiceContext,
185
+ ) => (() => void) | void;
186
+
187
+ /** The callback shape each service type defines, keyed by type. */
188
+ declare interface ServiceCallbacksByType {
189
+ worker: ServiceCallback;
190
+ }
191
+
192
+ /**
193
+ * Context every service callback receives when its worker starts. Mirrors how a
194
+ * view component receives its `view` — the service receives its own `service`.
195
+ * @public
196
+ */
197
+ export declare interface ServiceContext {
198
+ readonly service: ServiceInfo;
199
+ }
200
+
201
+ /**
202
+ * The service's own declaration, surfaced to the callback.
203
+ * @public
204
+ */
205
+ export declare interface ServiceInfo {
206
+ readonly name: string;
207
+ readonly type: string;
208
+ }
209
+
210
+ /**
211
+ * Every supported service type — the first argument to `unstable_defineService`.
212
+ * Add a service type by adding its declaration schema below and registering it
213
+ * here.
214
+ * @public
215
+ */
216
+ export declare type ServiceType = "worker";
217
+
218
+ /**
219
+ * Declare a Sanity Workbench application. Identity at runtime — returns the same
220
+ * object reference, tagged with the workbench brand. Field validation (the
221
+ * `name` pattern etc.) runs at build time in the CLI via `DefineAppInputSchema`;
222
+ * this helper stays a thin, pure identity wrapper.
223
+ * @public
224
+ */
225
+ export declare function unstable_defineApp(
226
+ input: DefineAppInput,
227
+ ): DefineAppResult;
228
+
229
+ /**
230
+ * Define a Sanity Workbench background service. The first argument narrows the
231
+ * callback shape — `"worker"` runs the callback inside a Web Worker, where it
232
+ * can emit dock-badge updates and return a disposer.
233
+ *
234
+ * Identity at runtime: returns the callback tagged with its type and the contract
235
+ * version, for the CLI build to generate a worker artifact from. Used as the
236
+ * default export of a service's `src` file.
237
+ * @public
238
+ */
239
+ export declare function unstable_defineService<TType extends ServiceType>(
240
+ type: TType,
241
+ run: ServiceCallbacksByType[TType],
242
+ ): DefinedService<TType>;
243
+
244
+ /**
245
+ * Define a Sanity Workbench view. The first argument narrows the component shape
246
+ * and the props each component receives — `"panel"` yields a `{title, panel}`
247
+ * record whose components are typed with the panel props.
248
+ *
249
+ * Returns the component(s) tagged with their type and the contract version, for
250
+ * the CLI build to generate render artifacts from. Used as the default export of
251
+ * a view's `src` file.
252
+ * @public
253
+ */
254
+ export declare function unstable_defineView<TType extends InterfaceType>(
255
+ type: TType,
256
+ components: ViewComponentsByType[TType],
257
+ ): DefinedView<TType>;
258
+
259
+ /**
260
+ * Component slots each interface type exposes, in render order — the source of
261
+ * truth for {@link InterfaceType} and for the build (the vite plugin expands a
262
+ * view into one render artifact per component). Add a type by registering it here.
263
+ * @internal
264
+ */
265
+ declare const VIEW_COMPONENTS: {
266
+ readonly panel: readonly ["title", "panel"];
267
+ };
268
+
269
+ /**
270
+ * Contract version stamped on every defined view — lets the host and the
271
+ * generated artifact evolve the contract without breaking deployed views.
272
+ * @internal
273
+ */
274
+ declare const VIEW_CONTRACT_VERSION = 1;
275
+
276
+ /**
277
+ * A view component. The return is opaque so the runtime helpers carry no React
278
+ * dependency — the generated artifact renders it with the app's own React.
279
+ * @public
280
+ */
281
+ declare type ViewComponent<TProps> = (props: TProps) => unknown;
282
+
283
+ /**
284
+ * Props every view component receives, whatever its type. Per-type props
285
+ * compose from this, so a prop added here reaches every view.
286
+ * @public
287
+ */
288
+ declare interface ViewComponentBaseProps<TView> {
289
+ view: TView;
290
+ }
291
+
292
+ /**
293
+ * The components each interface type exposes, keyed by type.
294
+ * @public
295
+ */
296
+ export declare interface ViewComponentsByType {
297
+ panel: PanelViewComponents;
298
+ }
299
+
300
+ /**
301
+ * Nominal brand the CLI discriminates on to enable the workbench build/deploy
302
+ * codepath. Registered via `Symbol.for` so the marker survives module-realm
303
+ * boundaries — `@sanity/cli-core` re-derives the same global symbol with
304
+ * `Symbol.for` rather than importing it, so it stays internal to this module.
305
+ */
306
+ declare const WORKBENCH_APP: unique symbol;
307
+
308
+ export {};
@@ -0,0 +1,15 @@
1
+ // Browser-safe module-federation extension API — the canonical source for the
2
+ // `unstable_define*` authoring helpers and their contract. Lives in
3
+ // `@sanity/cli-build` (alongside the vite plugin that consumes the same
4
+ // contract) so there is a single source of truth; `@sanity/cli` re-exports it on
5
+ // its public `.` and `/runtime` entries (→ `sanity/cli` and `sanity`).
6
+ //
7
+ // This entry's module graph is zod-only — no `node:*`, no `@sanity/cli-core`, no
8
+ // vite — so `@sanity/cli/runtime` re-exporting it stays browser-safe under
9
+ // per-entry resolution, exactly as the Node-only `./vite` and `./_internal/*`
10
+ // entries don't leak into it.
11
+ export { unstable_defineApp } from '../../workbench/defineApp.js';
12
+ export { unstable_defineService } from '../../workbench/defineService.js';
13
+ export { unstable_defineView } from '../../workbench/defineView.js';
14
+
15
+ //# sourceMappingURL=federation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/_exports/_internal/federation.ts"],"sourcesContent":["// Browser-safe module-federation extension API — the canonical source for the\n// `unstable_define*` authoring helpers and their contract. Lives in\n// `@sanity/cli-build` (alongside the vite plugin that consumes the same\n// contract) so there is a single source of truth; `@sanity/cli` re-exports it on\n// its public `.` and `/runtime` entries (→ `sanity/cli` and `sanity`).\n//\n// This entry's module graph is zod-only — no `node:*`, no `@sanity/cli-core`, no\n// vite — so `@sanity/cli/runtime` re-exporting it stays browser-safe under\n// per-entry resolution, exactly as the Node-only `./vite` and `./_internal/*`\n// entries don't leak into it.\nexport type {InterfaceType, ServiceType} from '../../workbench/contract.js'\nexport {unstable_defineApp} from '../../workbench/defineApp.js'\nexport type {DefineAppInput, DefineAppResult, DockGroup} from '../../workbench/defineApp.js'\nexport {unstable_defineService} from '../../workbench/defineService.js'\nexport type {\n DefinedService,\n ServiceCallback,\n ServiceContext,\n ServiceInfo,\n} from '../../workbench/defineService.js'\nexport {unstable_defineView} from '../../workbench/defineView.js'\nexport type {\n DefinedView,\n PanelComponent,\n PanelViewComponents,\n PanelViewProps,\n ViewComponentsByType,\n} from '../../workbench/defineView.js'\n"],"names":["unstable_defineApp","unstable_defineService","unstable_defineView"],"mappings":"AAAA,8EAA8E;AAC9E,oEAAoE;AACpE,wEAAwE;AACxE,iFAAiF;AACjF,uEAAuE;AACvE,EAAE;AACF,iFAAiF;AACjF,2EAA2E;AAC3E,8EAA8E;AAC9E,8BAA8B;AAE9B,SAAQA,kBAAkB,QAAO,+BAA8B;AAE/D,SAAQC,sBAAsB,QAAO,mCAAkC;AAOvE,SAAQC,mBAAmB,QAAO,gCAA+B"}
@@ -1,11 +1,11 @@
1
1
  import path from 'node:path';
2
2
  import babel from '@rolldown/plugin-babel';
3
3
  import { findProjectRoot, getCliTelemetry, readPackageJson } from '@sanity/cli-core';
4
- import { federation as viteFederation } from '@sanity/federation/vite';
5
4
  import viteReact, { reactCompilerPreset } from '@vitejs/plugin-react';
6
5
  import debug from 'debug';
7
6
  import { esmExternalRequirePlugin, mergeConfig } from 'vite';
8
7
  import { SANITY_CACHE_DIR } from '../../constants.js';
8
+ import { federation as viteFederation } from '../../workbench/vite/plugin.js';
9
9
  import { sanitySchemaExtractionPlugin } from '../schema/vite/plugin-schema-extraction.js';
10
10
  import { VENDOR_DIR } from './constants.js';
11
11
  import { createExternalFromImportMap } from './createExternalFromImportMap.js';
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/actions/build/getViteConfig.ts"],"sourcesContent":["import path from 'node:path'\n\nimport babel from '@rolldown/plugin-babel'\nimport {\n type CliConfig,\n findProjectRoot,\n getCliTelemetry,\n readPackageJson,\n type UserViteConfig,\n} from '@sanity/cli-core'\nimport {\n type InterfaceArtifact,\n type ServiceArtifact,\n federation as viteFederation,\n} from '@sanity/federation/vite'\nimport viteReact, {reactCompilerPreset} from '@vitejs/plugin-react'\nimport {type PluginOptions as ReactCompilerConfig} from 'babel-plugin-react-compiler'\nimport debug from 'debug'\nimport {\n type ConfigEnv,\n esmExternalRequirePlugin,\n type InlineConfig,\n mergeConfig,\n type Plugin,\n type PluginOption,\n type Rolldown,\n} from 'vite'\n\nimport {SANITY_CACHE_DIR} from '../../constants.js'\nimport {sanitySchemaExtractionPlugin} from '../schema/vite/plugin-schema-extraction.js'\nimport {type AutoUpdatesBuildConfig} from './autoUpdates.js'\nimport {VENDOR_DIR} from './constants.js'\nimport {createExternalFromImportMap} from './createExternalFromImportMap.js'\nimport {normalizeBasePath} from './normalizeBasePath.js'\nimport {sanityBuildEntries} from './vite/plugin-sanity-build-entries.js'\nimport {sanityFaviconsPlugin} from './vite/plugin-sanity-favicons.js'\nimport {sanityRuntimeRewritePlugin} from './vite/plugin-sanity-runtime-rewrite.js'\nimport {createVendorNamedExportsPlugin} from './vite/plugin-sanity-vendor-named-exports.js'\nimport {getDefaultFaviconsPath} from './writeFavicons.js'\n\ninterface ViteOptions extends Pick<CliConfig, 'schemaExtraction'> {\n /**\n * Root path of the studio/sanity app\n */\n cwd: string\n\n entries: {\n relativeConfigLocation: string | null\n // `null` when a branded app declares no `entry` (sanity-io/workbench spec 002-workbench-extension-api, US5) — no app view.\n relativeEntry: string | null\n }\n\n /**\n * Returns the environment variables to be injected into the config.\n */\n getEnvironmentVariables(): Record<string, string>\n\n /**\n * Mode to run vite in - eg development or production\n */\n mode: 'development' | 'production'\n\n reactCompiler: ReactCompilerConfig | undefined\n\n /**\n * Additional plugins when configured, eg. typegen\n */\n additionalPlugins?: Plugin[]\n\n /**\n * Auto-updates configuration (production builds only). When set, vendor\n * packages are emitted as hashed ESM chunks by this build and the import map\n * in `index.html` is derived from the build output.\n */\n autoUpdates?: AutoUpdatesBuildConfig\n\n /**\n * Base path (eg under where to serve the app - `/studio` or similar)\n * Will be normalized to ensure it starts and ends with a `/`\n */\n basePath?: string\n\n isApp?: boolean\n\n /**\n * Whether this is a workbench app (opted in via `unstable_defineApp`). Drives\n * the module-federation build — replaces the old `federation.enabled` flag.\n */\n isWorkbenchApp?: boolean\n\n /**\n * Whether or not to minify the output (only used in `mode: 'production'`)\n */\n minify?: boolean\n\n /**\n * Output directory (eg where to place the built files, if any)\n */\n outputDir?: string\n /**\n * HTTP development server configuration\n */\n server?: {host?: string; port?: number}\n /**\n * Background services the workbench app declares. Built into self-contained\n * worker bundles and exposed through module federation as `./services/<name>`.\n */\n services?: readonly ServiceArtifact[]\n\n /**\n * Whether or not to enable source maps\n */\n sourceMap?: boolean\n\n /**\n * Views the workbench app declares. Built into render-contract artifacts and\n * exposed through module federation as `./views/<name>`.\n */\n views?: readonly InterfaceArtifact[]\n}\n\n/**\n * Get a configuration object for Vite based on the passed options\n *\n * @internal Only meant for consumption inside of Sanity modules, do not depend on this externally\n */\nexport async function getViteConfig(options: ViteOptions): Promise<InlineConfig> {\n const {\n additionalPlugins,\n autoUpdates,\n basePath: rawBasePath = '/',\n cwd,\n entries,\n isApp,\n isWorkbenchApp,\n minify,\n mode,\n outputDir,\n reactCompiler,\n schemaExtraction,\n server,\n services,\n // default to `true` when `mode=development`\n sourceMap = options.mode === 'development',\n views,\n } = options\n\n const basePath = normalizeBasePath(rawBasePath)\n\n const configPath = (await findProjectRoot(cwd)).path\n\n const customFaviconsPath = path.join(cwd, 'static')\n const defaultFaviconsPath = await getDefaultFaviconsPath()\n const staticPath = `${basePath}static`\n\n const envVars = options.getEnvironmentVariables()\n\n const sharedPlugins: PluginOption = [\n viteReact(),\n ...(reactCompiler ? [babel({presets: [reactCompilerPreset(reactCompiler)]})] : []),\n ...(schemaExtraction?.enabled\n ? [\n sanitySchemaExtractionPlugin({\n additionalPatterns: schemaExtraction.watchPatterns,\n configPath,\n enforceRequiredFields: schemaExtraction.enforceRequiredFields,\n outputPath: schemaExtraction.path,\n telemetryLogger: getCliTelemetry(),\n workDir: cwd,\n workspaceName: schemaExtraction.workspace,\n }),\n ]\n : []),\n ]\n\n const viteConfig: InlineConfig = {\n base: basePath,\n build: {\n outDir: outputDir || path.resolve(cwd, 'dist'),\n sourcemap: sourceMap,\n },\n // Define a custom cache directory so that sanity's vite cache\n // does not conflict with any potential local vite projects\n cacheDir: `${SANITY_CACHE_DIR}/vite`,\n configFile: false,\n define: {\n __SANITY_BUILD_TIMESTAMP__: JSON.stringify(Date.now()),\n __SANITY_STAGING__: process.env.SANITY_INTERNAL_ENV === 'staging',\n 'process.env.MODE': JSON.stringify(mode),\n 'process.env.PKG_BUILD_VERSION': JSON.stringify(process.env.PKG_BUILD_VERSION),\n /**\n * Yes, double negatives are confusing.\n * The default value of `SC_DISABLE_SPEEDY` is `process.env.NODE_ENV === 'production'`: https://github.com/styled-components/styled-components/blob/99c02f52d69e8e509c0bf012cadee7f8e819a6dd/packages/styled-components/src/constants.ts#L34\n * Which means that in production, use the much faster way of inserting CSS rules, based on the CSSStyleSheet API (https://developer.mozilla.org/en-US/docs/Web/API/CSSStyleSheet/insertRule)\n * while in dev mode, use the slower way of inserting CSS rules, which appends text nodes to the `<style>` tag: https://github.com/styled-components/styled-components/blob/99c02f52d69e8e509c0bf012cadee7f8e819a6dd/packages/styled-components/src/sheet/Tag.ts#L74-L76\n * There are historical reasons for this, primarily that browsers initially did not support editing CSS rules in the DevTools inspector if `CSSStyleSheet.insetRule` were used.\n * However, that's no longer the case (since Chrome 81 back in April 2020: https://developer.chrome.com/docs/css-ui/css-in-js), the latest version of FireFox also supports it,\n * and there is no longer any reason to use the much slower method in dev mode.\n */\n 'process.env.SC_DISABLE_SPEEDY': JSON.stringify('false'),\n ...envVars,\n },\n envPrefix: isApp ? 'SANITY_APP_' : 'SANITY_STUDIO_',\n logLevel: mode === 'production' ? 'silent' : 'info',\n mode,\n plugins: [\n // Federation builds only need the federation plugin — skip client-specific\n // plugins (favicons, runtime rewrite, build entries)\n ...(isWorkbenchApp\n ? [\n ...sharedPlugins,\n viteFederation({\n ...(isApp\n ? {\n // `null` relativeEntry (a branded app with no `entry`, sanity-io/workbench spec 002-workbench-extension-api, US5)\n // → omit `appEntry` so the plugin exposes no `./App`.\n ...(entries.relativeEntry ? {appEntry: entries.relativeEntry} : {}),\n isApp: true as const,\n }\n : {\n isApp: false as const,\n // TODO: fix this non-null assertion\n studioConfigPath: entries.relativeConfigLocation!,\n }),\n pkgJson: await readPackageJson(path.join(cwd, 'package.json')),\n services,\n views,\n workDir: cwd,\n }),\n ]\n : [\n ...sharedPlugins,\n sanityFaviconsPlugin({\n customFaviconsPath,\n defaultFaviconsPath,\n staticUrlPath: staticPath,\n }),\n sanityRuntimeRewritePlugin(),\n sanityBuildEntries({autoUpdates, basePath, cwd, isApp}),\n ...(additionalPlugins || []),\n ]),\n ],\n resolve: {\n dedupe: ['react', 'react-dom', 'sanity', 'styled-components'],\n // Honor the studio's tsconfig `paths`, consistent with studioWorkerLoader.worker.ts.\n tsconfigPaths: true,\n },\n root: cwd,\n server: {\n host: server?.host,\n port: server?.port || 3333,\n // Apps drift to a free port (the reported URL embeds whichever port was\n // claimed), and workbench runs stack servers on adjacent ports — both\n // need the fallback. Studios fail fast on a busy port.\n strictPort: !isApp && !isWorkbenchApp,\n\n /**\n * Significantly speed up startup time,\n * and most importantly eliminates the `new dependencies optimized: foobar. optimized dependencies changed. reloading`\n * types of initial reload loops that otherwise happen as vite discovers deps that need to be optimized.\n * This option starts the traversal up front, and warms up the dep tree required to render the userland sanity.config.ts file,\n * and thus avoids frustrating reload loops.\n */\n warmup: {\n clientFiles: ['./.sanity/runtime/app.js'],\n },\n },\n }\n\n // Federation builds don't produce a client bundle — the federation\n // plugin configures its own environment and build entry point.\n if (mode === 'production' && !isWorkbenchApp) {\n if (autoUpdates) {\n viteConfig.plugins!.push(\n // Re-expose CommonJS named exports (react, react-dom) as real ESM exports\n // on the emitted vendor chunks; Rolldown only emits `export default` for a\n // CommonJS entry.\n createVendorNamedExportsPlugin(autoUpdates.vendor.namesByChunkName),\n // The import map and vendor specifiers are externals of the studio/app\n // bundle, resolved by the browser at runtime. They are handed to\n // `esmExternalRequirePlugin` rather than `rolldownOptions.external`: the\n // plugin both marks them external AND rewrites bundled CommonJS\n // `require()` calls of an external (e.g. react-dom requiring react) into\n // ESM imports, while `rolldownOptions.external` would short-circuit that\n // rewrite and leave a runtime `require` shim that throws in the browser.\n esmExternalRequirePlugin({\n external: createExternalFromImportMap({\n imports: {\n ...autoUpdates.imports,\n ...Object.fromEntries(\n Object.values(autoUpdates.vendor.specifiersByChunkName).map((specifier) => [\n specifier,\n '',\n ]),\n ),\n },\n }),\n }),\n )\n }\n\n const vendorChunkNames = autoUpdates\n ? new Set(Object.keys(autoUpdates.vendor.specifiersByChunkName))\n : null\n\n viteConfig.build = {\n ...viteConfig.build,\n\n assetsDir: 'static',\n emptyOutDir: false, // Rely on CLI to do this\n minify: minify ? 'oxc' : false,\n\n rolldownOptions: {\n input: {\n sanity: path.join(cwd, '.sanity', 'runtime', 'app.js'),\n ...autoUpdates?.vendor.entries,\n },\n onwarn: onRolldownWarn,\n ...(autoUpdates\n ? {\n // Expose Rolldown's native MagicString on `renderChunk`'s `meta` so\n // the vendor named-exports plugin can edit chunks without a JS\n // dependency.\n experimental: {nativeMagicString: true},\n output: {\n entryFileNames: (chunk) =>\n vendorChunkNames!.has(chunk.name)\n ? `${VENDOR_DIR}/[name]-[hash].mjs`\n : 'static/[name]-[hash].js',\n exports: 'named',\n },\n // App-style builds default to `preserveEntrySignatures: false`, which\n // treeshakes the exports off entry chunks. Vendor chunks are loaded by\n // the browser via the import map, so their exports must survive (e.g.\n // styled-components' native ESM exports). `exports-only` keeps exports\n // for entries that have them, while the export-less `sanity` app entry\n // still bundles as before.\n preserveEntrySignatures: 'exports-only',\n }\n : {}),\n },\n }\n }\n\n return viteConfig\n}\n\nfunction onRolldownWarn(warning: Rolldown.RolldownLog, warn: Rolldown.LoggingFunction) {\n if (suppressUnusedImport(warning)) {\n return\n }\n\n warn(warning)\n}\n\nfunction suppressUnusedImport(warning: Rolldown.RolldownLog & {ids?: string[]}): boolean {\n if (warning.code !== 'UNUSED_EXTERNAL_IMPORT') return false\n\n // Suppress:\n // ```\n // \"useDebugValue\" is imported from external module \"react\"…\n // ```\n if (warning.names?.includes('useDebugValue')) {\n warning.names = warning.names.filter((n) => n !== 'useDebugValue')\n if (warning.names.length === 0) return true\n }\n\n // If some library does something unexpected, we suppress since it isn't actionable\n if (warning.ids?.every((id) => id.includes('/node_modules/') || id.includes('\\\\node_modules\\\\')))\n return true\n\n return false\n}\n\n/**\n * Re-asserts the critical parts of the default config after a userland vite\n * config (`vite` in `sanity.cli.ts`) has been applied.\n *\n * Everything `getViteConfig` sets under `build.rolldownOptions` is load-bearing:\n * the `input` entries (the studio entry plus, for auto-updating studios/apps,\n * the vendor entries), `preserveEntrySignatures`, the `experimental` flags the\n * vendor plugins rely on, and the `output` chunk naming. A userland config that\n * returns a brand-new object for any of these would silently break the build\n * (e.g. vendor chunks never emitted while the bundle still treats them as\n * external), so the default `rolldownOptions` are deep-merged back over the\n * userland config: userland additions survive, replacements of critical\n * options are healed.\n *\n * @param config - User-modified configuration\n * @param defaultConfig - The configuration produced by `getViteConfig`, before the userland config was applied\n * @returns Merged configuration\n * @internal\n */\nexport async function finalizeViteConfig(\n config: InlineConfig,\n defaultConfig: InlineConfig,\n): Promise<InlineConfig> {\n if (typeof config.build?.rolldownOptions?.input !== 'object') {\n throw new TypeError(\n 'Vite config must contain `build.rolldownOptions.input`, and it must be an object',\n )\n }\n\n if (!config.root) {\n throw new Error(\n 'Vite config must contain `root` property, and must point to the Sanity root directory',\n )\n }\n\n return mergeConfig(config, {\n build: {\n rolldownOptions: defaultConfig.build?.rolldownOptions ?? {},\n },\n })\n}\n\n/**\n * Merge user-provided Vite configuration object or function\n *\n * @param defaultConfig - Default configuration object\n * @param userConfig - User-provided configuration object or function\n * @returns Merged configuration\n * @internal\n */\nexport async function extendViteConfigWithUserConfig(\n env: ConfigEnv,\n defaultConfig: InlineConfig,\n userConfig: UserViteConfig,\n): Promise<InlineConfig> {\n let config = defaultConfig\n\n if (typeof userConfig === 'function') {\n debug('Extending vite config using user-specified function')\n config = await userConfig(config, env)\n } else if (typeof userConfig === 'object') {\n debug('Merging vite config using user-specified object')\n config = mergeConfig(config, userConfig)\n }\n\n return config\n}\n"],"names":["path","babel","findProjectRoot","getCliTelemetry","readPackageJson","federation","viteFederation","viteReact","reactCompilerPreset","debug","esmExternalRequirePlugin","mergeConfig","SANITY_CACHE_DIR","sanitySchemaExtractionPlugin","VENDOR_DIR","createExternalFromImportMap","normalizeBasePath","sanityBuildEntries","sanityFaviconsPlugin","sanityRuntimeRewritePlugin","createVendorNamedExportsPlugin","getDefaultFaviconsPath","getViteConfig","options","additionalPlugins","autoUpdates","basePath","rawBasePath","cwd","entries","isApp","isWorkbenchApp","minify","mode","outputDir","reactCompiler","schemaExtraction","server","services","sourceMap","views","configPath","customFaviconsPath","join","defaultFaviconsPath","staticPath","envVars","getEnvironmentVariables","sharedPlugins","presets","enabled","additionalPatterns","watchPatterns","enforceRequiredFields","outputPath","telemetryLogger","workDir","workspaceName","workspace","viteConfig","base","build","outDir","resolve","sourcemap","cacheDir","configFile","define","__SANITY_BUILD_TIMESTAMP__","JSON","stringify","Date","now","__SANITY_STAGING__","process","env","SANITY_INTERNAL_ENV","PKG_BUILD_VERSION","envPrefix","logLevel","plugins","relativeEntry","appEntry","studioConfigPath","relativeConfigLocation","pkgJson","staticUrlPath","dedupe","tsconfigPaths","root","host","port","strictPort","warmup","clientFiles","push","vendor","namesByChunkName","external","imports","Object","fromEntries","values","specifiersByChunkName","map","specifier","vendorChunkNames","Set","keys","assetsDir","emptyOutDir","rolldownOptions","input","sanity","onwarn","onRolldownWarn","experimental","nativeMagicString","output","entryFileNames","chunk","has","name","exports","preserveEntrySignatures","warning","warn","suppressUnusedImport","code","names","includes","filter","n","length","ids","every","id","finalizeViteConfig","config","defaultConfig","TypeError","Error","extendViteConfigWithUserConfig","userConfig"],"mappings":"AAAA,OAAOA,UAAU,YAAW;AAE5B,OAAOC,WAAW,yBAAwB;AAC1C,SAEEC,eAAe,EACfC,eAAe,EACfC,eAAe,QAEV,mBAAkB;AACzB,SAGEC,cAAcC,cAAc,QACvB,0BAAyB;AAChC,OAAOC,aAAYC,mBAAmB,QAAO,uBAAsB;AAEnE,OAAOC,WAAW,QAAO;AACzB,SAEEC,wBAAwB,EAExBC,WAAW,QAIN,OAAM;AAEb,SAAQC,gBAAgB,QAAO,qBAAoB;AACnD,SAAQC,4BAA4B,QAAO,6CAA4C;AAEvF,SAAQC,UAAU,QAAO,iBAAgB;AACzC,SAAQC,2BAA2B,QAAO,mCAAkC;AAC5E,SAAQC,iBAAiB,QAAO,yBAAwB;AACxD,SAAQC,kBAAkB,QAAO,wCAAuC;AACxE,SAAQC,oBAAoB,QAAO,mCAAkC;AACrE,SAAQC,0BAA0B,QAAO,0CAAyC;AAClF,SAAQC,8BAA8B,QAAO,+CAA8C;AAC3F,SAAQC,sBAAsB,QAAO,qBAAoB;AAmFzD;;;;CAIC,GACD,OAAO,eAAeC,cAAcC,OAAoB;IACtD,MAAM,EACJC,iBAAiB,EACjBC,WAAW,EACXC,UAAUC,cAAc,GAAG,EAC3BC,GAAG,EACHC,OAAO,EACPC,KAAK,EACLC,cAAc,EACdC,MAAM,EACNC,IAAI,EACJC,SAAS,EACTC,aAAa,EACbC,gBAAgB,EAChBC,MAAM,EACNC,QAAQ,EACR,4CAA4C;IAC5CC,YAAYhB,QAAQU,IAAI,KAAK,aAAa,EAC1CO,KAAK,EACN,GAAGjB;IAEJ,MAAMG,WAAWV,kBAAkBW;IAEnC,MAAMc,aAAa,AAAC,CAAA,MAAMvC,gBAAgB0B,IAAG,EAAG5B,IAAI;IAEpD,MAAM0C,qBAAqB1C,KAAK2C,IAAI,CAACf,KAAK;IAC1C,MAAMgB,sBAAsB,MAAMvB;IAClC,MAAMwB,aAAa,GAAGnB,SAAS,MAAM,CAAC;IAEtC,MAAMoB,UAAUvB,QAAQwB,uBAAuB;IAE/C,MAAMC,gBAA8B;QAClCzC;WACI4B,gBAAgB;YAAClC,MAAM;gBAACgD,SAAS;oBAACzC,oBAAoB2B;iBAAe;YAAA;SAAG,GAAG,EAAE;WAC7EC,kBAAkBc,UAClB;YACErC,6BAA6B;gBAC3BsC,oBAAoBf,iBAAiBgB,aAAa;gBAClDX;gBACAY,uBAAuBjB,iBAAiBiB,qBAAqB;gBAC7DC,YAAYlB,iBAAiBpC,IAAI;gBACjCuD,iBAAiBpD;gBACjBqD,SAAS5B;gBACT6B,eAAerB,iBAAiBsB,SAAS;YAC3C;SACD,GACD,EAAE;KACP;IAED,MAAMC,aAA2B;QAC/BC,MAAMlC;QACNmC,OAAO;YACLC,QAAQ5B,aAAalC,KAAK+D,OAAO,CAACnC,KAAK;YACvCoC,WAAWzB;QACb;QACA,8DAA8D;QAC9D,2DAA2D;QAC3D0B,UAAU,GAAGrD,iBAAiB,KAAK,CAAC;QACpCsD,YAAY;QACZC,QAAQ;YACNC,4BAA4BC,KAAKC,SAAS,CAACC,KAAKC,GAAG;YACnDC,oBAAoBC,QAAQC,GAAG,CAACC,mBAAmB,KAAK;YACxD,oBAAoBP,KAAKC,SAAS,CAACrC;YACnC,iCAAiCoC,KAAKC,SAAS,CAACI,QAAQC,GAAG,CAACE,iBAAiB;YAC7E;;;;;;;;OAQC,GACD,iCAAiCR,KAAKC,SAAS,CAAC;YAChD,GAAGxB,OAAO;QACZ;QACAgC,WAAWhD,QAAQ,gBAAgB;QACnCiD,UAAU9C,SAAS,eAAe,WAAW;QAC7CA;QACA+C,SAAS;YACP,2EAA2E;YAC3E,qDAAqD;eACjDjD,iBACA;mBACKiB;gBACH1C,eAAe;oBACb,GAAIwB,QACA;wBACE,kHAAkH;wBAClH,sDAAsD;wBACtD,GAAID,QAAQoD,aAAa,GAAG;4BAACC,UAAUrD,QAAQoD,aAAa;wBAAA,IAAI,CAAC,CAAC;wBAClEnD,OAAO;oBACT,IACA;wBACEA,OAAO;wBACP,oCAAoC;wBACpCqD,kBAAkBtD,QAAQuD,sBAAsB;oBAClD,CAAC;oBACLC,SAAS,MAAMjF,gBAAgBJ,KAAK2C,IAAI,CAACf,KAAK;oBAC9CU;oBACAE;oBACAgB,SAAS5B;gBACX;aACD,GACD;mBACKoB;gBACH9B,qBAAqB;oBACnBwB;oBACAE;oBACA0C,eAAezC;gBACjB;gBACA1B;gBACAF,mBAAmB;oBAACQ;oBAAaC;oBAAUE;oBAAKE;gBAAK;mBACjDN,qBAAqB,EAAE;aAC5B;SACN;QACDuC,SAAS;YACPwB,QAAQ;gBAAC;gBAAS;gBAAa;gBAAU;aAAoB;YAC7D,qFAAqF;YACrFC,eAAe;QACjB;QACAC,MAAM7D;QACNS,QAAQ;YACNqD,MAAMrD,QAAQqD;YACdC,MAAMtD,QAAQsD,QAAQ;YACtB,wEAAwE;YACxE,sEAAsE;YACtE,uDAAuD;YACvDC,YAAY,CAAC9D,SAAS,CAACC;YAEvB;;;;;;OAMC,GACD8D,QAAQ;gBACNC,aAAa;oBAAC;iBAA2B;YAC3C;QACF;IACF;IAEA,mEAAmE;IACnE,+DAA+D;IAC/D,IAAI7D,SAAS,gBAAgB,CAACF,gBAAgB;QAC5C,IAAIN,aAAa;YACfkC,WAAWqB,OAAO,CAAEe,IAAI,CACtB,0EAA0E;YAC1E,2EAA2E;YAC3E,kBAAkB;YAClB3E,+BAA+BK,YAAYuE,MAAM,CAACC,gBAAgB,GAClE,uEAAuE;YACvE,iEAAiE;YACjE,yEAAyE;YACzE,gEAAgE;YAChE,yEAAyE;YACzE,yEAAyE;YACzE,yEAAyE;YACzEvF,yBAAyB;gBACvBwF,UAAUnF,4BAA4B;oBACpCoF,SAAS;wBACP,GAAG1E,YAAY0E,OAAO;wBACtB,GAAGC,OAAOC,WAAW,CACnBD,OAAOE,MAAM,CAAC7E,YAAYuE,MAAM,CAACO,qBAAqB,EAAEC,GAAG,CAAC,CAACC,YAAc;gCACzEA;gCACA;6BACD,EACF;oBACH;gBACF;YACF;QAEJ;QAEA,MAAMC,mBAAmBjF,cACrB,IAAIkF,IAAIP,OAAOQ,IAAI,CAACnF,YAAYuE,MAAM,CAACO,qBAAqB,KAC5D;QAEJ5C,WAAWE,KAAK,GAAG;YACjB,GAAGF,WAAWE,KAAK;YAEnBgD,WAAW;YACXC,aAAa;YACb9E,QAAQA,SAAS,QAAQ;YAEzB+E,iBAAiB;gBACfC,OAAO;oBACLC,QAAQjH,KAAK2C,IAAI,CAACf,KAAK,WAAW,WAAW;oBAC7C,GAAGH,aAAauE,OAAOnE,OAAO;gBAChC;gBACAqF,QAAQC;gBACR,GAAI1F,cACA;oBACE,oEAAoE;oBACpE,+DAA+D;oBAC/D,cAAc;oBACd2F,cAAc;wBAACC,mBAAmB;oBAAI;oBACtCC,QAAQ;wBACNC,gBAAgB,CAACC,QACfd,iBAAkBe,GAAG,CAACD,MAAME,IAAI,IAC5B,GAAG5G,WAAW,kBAAkB,CAAC,GACjC;wBACN6G,SAAS;oBACX;oBACA,sEAAsE;oBACtE,uEAAuE;oBACvE,sEAAsE;oBACtE,uEAAuE;oBACvE,uEAAuE;oBACvE,2BAA2B;oBAC3BC,yBAAyB;gBAC3B,IACA,CAAC,CAAC;YACR;QACF;IACF;IAEA,OAAOjE;AACT;AAEA,SAASwD,eAAeU,OAA6B,EAAEC,IAA8B;IACnF,IAAIC,qBAAqBF,UAAU;QACjC;IACF;IAEAC,KAAKD;AACP;AAEA,SAASE,qBAAqBF,OAAgD;IAC5E,IAAIA,QAAQG,IAAI,KAAK,0BAA0B,OAAO;IAEtD,YAAY;IACZ,MAAM;IACN,4DAA4D;IAC5D,MAAM;IACN,IAAIH,QAAQI,KAAK,EAAEC,SAAS,kBAAkB;QAC5CL,QAAQI,KAAK,GAAGJ,QAAQI,KAAK,CAACE,MAAM,CAAC,CAACC,IAAMA,MAAM;QAClD,IAAIP,QAAQI,KAAK,CAACI,MAAM,KAAK,GAAG,OAAO;IACzC;IAEA,mFAAmF;IACnF,IAAIR,QAAQS,GAAG,EAAEC,MAAM,CAACC,KAAOA,GAAGN,QAAQ,CAAC,qBAAqBM,GAAGN,QAAQ,CAAC,sBAC1E,OAAO;IAET,OAAO;AACT;AAEA;;;;;;;;;;;;;;;;;;CAkBC,GACD,OAAO,eAAeO,mBACpBC,MAAoB,EACpBC,aAA2B;IAE3B,IAAI,OAAOD,OAAO7E,KAAK,EAAEkD,iBAAiBC,UAAU,UAAU;QAC5D,MAAM,IAAI4B,UACR;IAEJ;IAEA,IAAI,CAACF,OAAOjD,IAAI,EAAE;QAChB,MAAM,IAAIoD,MACR;IAEJ;IAEA,OAAOlI,YAAY+H,QAAQ;QACzB7E,OAAO;YACLkD,iBAAiB4B,cAAc9E,KAAK,EAAEkD,mBAAmB,CAAC;QAC5D;IACF;AACF;AAEA;;;;;;;CAOC,GACD,OAAO,eAAe+B,+BACpBnE,GAAc,EACdgE,aAA2B,EAC3BI,UAA0B;IAE1B,IAAIL,SAASC;IAEb,IAAI,OAAOI,eAAe,YAAY;QACpCtI,MAAM;QACNiI,SAAS,MAAMK,WAAWL,QAAQ/D;IACpC,OAAO,IAAI,OAAOoE,eAAe,UAAU;QACzCtI,MAAM;QACNiI,SAAS/H,YAAY+H,QAAQK;IAC/B;IAEA,OAAOL;AACT"}
1
+ {"version":3,"sources":["../../../src/actions/build/getViteConfig.ts"],"sourcesContent":["import path from 'node:path'\n\nimport babel from '@rolldown/plugin-babel'\nimport {\n type CliConfig,\n findProjectRoot,\n getCliTelemetry,\n readPackageJson,\n type UserViteConfig,\n} from '@sanity/cli-core'\nimport viteReact, {reactCompilerPreset} from '@vitejs/plugin-react'\nimport {type PluginOptions as ReactCompilerConfig} from 'babel-plugin-react-compiler'\nimport debug from 'debug'\nimport {\n type ConfigEnv,\n esmExternalRequirePlugin,\n type InlineConfig,\n mergeConfig,\n type Plugin,\n type PluginOption,\n type Rolldown,\n} from 'vite'\n\nimport {SANITY_CACHE_DIR} from '../../constants.js'\nimport {type ServiceArtifact} from '../../workbench/services/artifact.js'\nimport {type InterfaceArtifact} from '../../workbench/views/artifact.js'\nimport {federation as viteFederation} from '../../workbench/vite/plugin.js'\nimport {sanitySchemaExtractionPlugin} from '../schema/vite/plugin-schema-extraction.js'\nimport {type AutoUpdatesBuildConfig} from './autoUpdates.js'\nimport {VENDOR_DIR} from './constants.js'\nimport {createExternalFromImportMap} from './createExternalFromImportMap.js'\nimport {normalizeBasePath} from './normalizeBasePath.js'\nimport {sanityBuildEntries} from './vite/plugin-sanity-build-entries.js'\nimport {sanityFaviconsPlugin} from './vite/plugin-sanity-favicons.js'\nimport {sanityRuntimeRewritePlugin} from './vite/plugin-sanity-runtime-rewrite.js'\nimport {createVendorNamedExportsPlugin} from './vite/plugin-sanity-vendor-named-exports.js'\nimport {getDefaultFaviconsPath} from './writeFavicons.js'\n\ninterface ViteOptions extends Pick<CliConfig, 'schemaExtraction'> {\n /**\n * Root path of the studio/sanity app\n */\n cwd: string\n\n entries: {\n relativeConfigLocation: string | null\n // `null` when a branded app declares no `entry` (sanity-io/workbench spec 002-workbench-extension-api, US5) — no app view.\n relativeEntry: string | null\n }\n\n /**\n * Returns the environment variables to be injected into the config.\n */\n getEnvironmentVariables(): Record<string, string>\n\n /**\n * Mode to run vite in - eg development or production\n */\n mode: 'development' | 'production'\n\n reactCompiler: ReactCompilerConfig | undefined\n\n /**\n * Additional plugins when configured, eg. typegen\n */\n additionalPlugins?: Plugin[]\n\n /**\n * Auto-updates configuration (production builds only). When set, vendor\n * packages are emitted as hashed ESM chunks by this build and the import map\n * in `index.html` is derived from the build output.\n */\n autoUpdates?: AutoUpdatesBuildConfig\n\n /**\n * Base path (eg under where to serve the app - `/studio` or similar)\n * Will be normalized to ensure it starts and ends with a `/`\n */\n basePath?: string\n\n isApp?: boolean\n\n /**\n * Whether this is a workbench app (opted in via `unstable_defineApp`). Drives\n * the module-federation build — replaces the old `federation.enabled` flag.\n */\n isWorkbenchApp?: boolean\n\n /**\n * Whether or not to minify the output (only used in `mode: 'production'`)\n */\n minify?: boolean\n\n /**\n * Output directory (eg where to place the built files, if any)\n */\n outputDir?: string\n /**\n * HTTP development server configuration\n */\n server?: {host?: string; port?: number}\n /**\n * Background services the workbench app declares. Built into self-contained\n * worker bundles and exposed through module federation as `./services/<name>`.\n */\n services?: readonly ServiceArtifact[]\n\n /**\n * Whether or not to enable source maps\n */\n sourceMap?: boolean\n\n /**\n * Views the workbench app declares. Built into render-contract artifacts and\n * exposed through module federation as `./views/<name>`.\n */\n views?: readonly InterfaceArtifact[]\n}\n\n/**\n * Get a configuration object for Vite based on the passed options\n *\n * @internal Only meant for consumption inside of Sanity modules, do not depend on this externally\n */\nexport async function getViteConfig(options: ViteOptions): Promise<InlineConfig> {\n const {\n additionalPlugins,\n autoUpdates,\n basePath: rawBasePath = '/',\n cwd,\n entries,\n isApp,\n isWorkbenchApp,\n minify,\n mode,\n outputDir,\n reactCompiler,\n schemaExtraction,\n server,\n services,\n // default to `true` when `mode=development`\n sourceMap = options.mode === 'development',\n views,\n } = options\n\n const basePath = normalizeBasePath(rawBasePath)\n\n const configPath = (await findProjectRoot(cwd)).path\n\n const customFaviconsPath = path.join(cwd, 'static')\n const defaultFaviconsPath = await getDefaultFaviconsPath()\n const staticPath = `${basePath}static`\n\n const envVars = options.getEnvironmentVariables()\n\n const sharedPlugins: PluginOption = [\n viteReact(),\n ...(reactCompiler ? [babel({presets: [reactCompilerPreset(reactCompiler)]})] : []),\n ...(schemaExtraction?.enabled\n ? [\n sanitySchemaExtractionPlugin({\n additionalPatterns: schemaExtraction.watchPatterns,\n configPath,\n enforceRequiredFields: schemaExtraction.enforceRequiredFields,\n outputPath: schemaExtraction.path,\n telemetryLogger: getCliTelemetry(),\n workDir: cwd,\n workspaceName: schemaExtraction.workspace,\n }),\n ]\n : []),\n ]\n\n const viteConfig: InlineConfig = {\n base: basePath,\n build: {\n outDir: outputDir || path.resolve(cwd, 'dist'),\n sourcemap: sourceMap,\n },\n // Define a custom cache directory so that sanity's vite cache\n // does not conflict with any potential local vite projects\n cacheDir: `${SANITY_CACHE_DIR}/vite`,\n configFile: false,\n define: {\n __SANITY_BUILD_TIMESTAMP__: JSON.stringify(Date.now()),\n __SANITY_STAGING__: process.env.SANITY_INTERNAL_ENV === 'staging',\n 'process.env.MODE': JSON.stringify(mode),\n 'process.env.PKG_BUILD_VERSION': JSON.stringify(process.env.PKG_BUILD_VERSION),\n /**\n * Yes, double negatives are confusing.\n * The default value of `SC_DISABLE_SPEEDY` is `process.env.NODE_ENV === 'production'`: https://github.com/styled-components/styled-components/blob/99c02f52d69e8e509c0bf012cadee7f8e819a6dd/packages/styled-components/src/constants.ts#L34\n * Which means that in production, use the much faster way of inserting CSS rules, based on the CSSStyleSheet API (https://developer.mozilla.org/en-US/docs/Web/API/CSSStyleSheet/insertRule)\n * while in dev mode, use the slower way of inserting CSS rules, which appends text nodes to the `<style>` tag: https://github.com/styled-components/styled-components/blob/99c02f52d69e8e509c0bf012cadee7f8e819a6dd/packages/styled-components/src/sheet/Tag.ts#L74-L76\n * There are historical reasons for this, primarily that browsers initially did not support editing CSS rules in the DevTools inspector if `CSSStyleSheet.insetRule` were used.\n * However, that's no longer the case (since Chrome 81 back in April 2020: https://developer.chrome.com/docs/css-ui/css-in-js), the latest version of FireFox also supports it,\n * and there is no longer any reason to use the much slower method in dev mode.\n */\n 'process.env.SC_DISABLE_SPEEDY': JSON.stringify('false'),\n ...envVars,\n },\n envPrefix: isApp ? 'SANITY_APP_' : 'SANITY_STUDIO_',\n logLevel: mode === 'production' ? 'silent' : 'info',\n mode,\n plugins: [\n // Federation builds only need the federation plugin — skip client-specific\n // plugins (favicons, runtime rewrite, build entries)\n ...(isWorkbenchApp\n ? [\n ...sharedPlugins,\n viteFederation({\n ...(isApp\n ? {\n // `null` relativeEntry (a branded app with no `entry`, sanity-io/workbench spec 002-workbench-extension-api, US5)\n // → omit `appEntry` so the plugin exposes no `./App`.\n ...(entries.relativeEntry ? {appEntry: entries.relativeEntry} : {}),\n isApp: true as const,\n }\n : {\n isApp: false as const,\n // TODO: fix this non-null assertion\n studioConfigPath: entries.relativeConfigLocation!,\n }),\n pkgJson: await readPackageJson(path.join(cwd, 'package.json')),\n services,\n views,\n workDir: cwd,\n }),\n ]\n : [\n ...sharedPlugins,\n sanityFaviconsPlugin({\n customFaviconsPath,\n defaultFaviconsPath,\n staticUrlPath: staticPath,\n }),\n sanityRuntimeRewritePlugin(),\n sanityBuildEntries({autoUpdates, basePath, cwd, isApp}),\n ...(additionalPlugins || []),\n ]),\n ],\n resolve: {\n dedupe: ['react', 'react-dom', 'sanity', 'styled-components'],\n // Honor the studio's tsconfig `paths`, consistent with studioWorkerLoader.worker.ts.\n tsconfigPaths: true,\n },\n root: cwd,\n server: {\n host: server?.host,\n port: server?.port || 3333,\n // Apps drift to a free port (the reported URL embeds whichever port was\n // claimed), and workbench runs stack servers on adjacent ports — both\n // need the fallback. Studios fail fast on a busy port.\n strictPort: !isApp && !isWorkbenchApp,\n\n /**\n * Significantly speed up startup time,\n * and most importantly eliminates the `new dependencies optimized: foobar. optimized dependencies changed. reloading`\n * types of initial reload loops that otherwise happen as vite discovers deps that need to be optimized.\n * This option starts the traversal up front, and warms up the dep tree required to render the userland sanity.config.ts file,\n * and thus avoids frustrating reload loops.\n */\n warmup: {\n clientFiles: ['./.sanity/runtime/app.js'],\n },\n },\n }\n\n // Federation builds don't produce a client bundle — the federation\n // plugin configures its own environment and build entry point.\n if (mode === 'production' && !isWorkbenchApp) {\n if (autoUpdates) {\n viteConfig.plugins!.push(\n // Re-expose CommonJS named exports (react, react-dom) as real ESM exports\n // on the emitted vendor chunks; Rolldown only emits `export default` for a\n // CommonJS entry.\n createVendorNamedExportsPlugin(autoUpdates.vendor.namesByChunkName),\n // The import map and vendor specifiers are externals of the studio/app\n // bundle, resolved by the browser at runtime. They are handed to\n // `esmExternalRequirePlugin` rather than `rolldownOptions.external`: the\n // plugin both marks them external AND rewrites bundled CommonJS\n // `require()` calls of an external (e.g. react-dom requiring react) into\n // ESM imports, while `rolldownOptions.external` would short-circuit that\n // rewrite and leave a runtime `require` shim that throws in the browser.\n esmExternalRequirePlugin({\n external: createExternalFromImportMap({\n imports: {\n ...autoUpdates.imports,\n ...Object.fromEntries(\n Object.values(autoUpdates.vendor.specifiersByChunkName).map((specifier) => [\n specifier,\n '',\n ]),\n ),\n },\n }),\n }),\n )\n }\n\n const vendorChunkNames = autoUpdates\n ? new Set(Object.keys(autoUpdates.vendor.specifiersByChunkName))\n : null\n\n viteConfig.build = {\n ...viteConfig.build,\n\n assetsDir: 'static',\n emptyOutDir: false, // Rely on CLI to do this\n minify: minify ? 'oxc' : false,\n\n rolldownOptions: {\n input: {\n sanity: path.join(cwd, '.sanity', 'runtime', 'app.js'),\n ...autoUpdates?.vendor.entries,\n },\n onwarn: onRolldownWarn,\n ...(autoUpdates\n ? {\n // Expose Rolldown's native MagicString on `renderChunk`'s `meta` so\n // the vendor named-exports plugin can edit chunks without a JS\n // dependency.\n experimental: {nativeMagicString: true},\n output: {\n entryFileNames: (chunk) =>\n vendorChunkNames!.has(chunk.name)\n ? `${VENDOR_DIR}/[name]-[hash].mjs`\n : 'static/[name]-[hash].js',\n exports: 'named',\n },\n // App-style builds default to `preserveEntrySignatures: false`, which\n // treeshakes the exports off entry chunks. Vendor chunks are loaded by\n // the browser via the import map, so their exports must survive (e.g.\n // styled-components' native ESM exports). `exports-only` keeps exports\n // for entries that have them, while the export-less `sanity` app entry\n // still bundles as before.\n preserveEntrySignatures: 'exports-only',\n }\n : {}),\n },\n }\n }\n\n return viteConfig\n}\n\nfunction onRolldownWarn(warning: Rolldown.RolldownLog, warn: Rolldown.LoggingFunction) {\n if (suppressUnusedImport(warning)) {\n return\n }\n\n warn(warning)\n}\n\nfunction suppressUnusedImport(warning: Rolldown.RolldownLog & {ids?: string[]}): boolean {\n if (warning.code !== 'UNUSED_EXTERNAL_IMPORT') return false\n\n // Suppress:\n // ```\n // \"useDebugValue\" is imported from external module \"react\"…\n // ```\n if (warning.names?.includes('useDebugValue')) {\n warning.names = warning.names.filter((n) => n !== 'useDebugValue')\n if (warning.names.length === 0) return true\n }\n\n // If some library does something unexpected, we suppress since it isn't actionable\n if (warning.ids?.every((id) => id.includes('/node_modules/') || id.includes('\\\\node_modules\\\\')))\n return true\n\n return false\n}\n\n/**\n * Re-asserts the critical parts of the default config after a userland vite\n * config (`vite` in `sanity.cli.ts`) has been applied.\n *\n * Everything `getViteConfig` sets under `build.rolldownOptions` is load-bearing:\n * the `input` entries (the studio entry plus, for auto-updating studios/apps,\n * the vendor entries), `preserveEntrySignatures`, the `experimental` flags the\n * vendor plugins rely on, and the `output` chunk naming. A userland config that\n * returns a brand-new object for any of these would silently break the build\n * (e.g. vendor chunks never emitted while the bundle still treats them as\n * external), so the default `rolldownOptions` are deep-merged back over the\n * userland config: userland additions survive, replacements of critical\n * options are healed.\n *\n * @param config - User-modified configuration\n * @param defaultConfig - The configuration produced by `getViteConfig`, before the userland config was applied\n * @returns Merged configuration\n * @internal\n */\nexport async function finalizeViteConfig(\n config: InlineConfig,\n defaultConfig: InlineConfig,\n): Promise<InlineConfig> {\n if (typeof config.build?.rolldownOptions?.input !== 'object') {\n throw new TypeError(\n 'Vite config must contain `build.rolldownOptions.input`, and it must be an object',\n )\n }\n\n if (!config.root) {\n throw new Error(\n 'Vite config must contain `root` property, and must point to the Sanity root directory',\n )\n }\n\n return mergeConfig(config, {\n build: {\n rolldownOptions: defaultConfig.build?.rolldownOptions ?? {},\n },\n })\n}\n\n/**\n * Merge user-provided Vite configuration object or function\n *\n * @param defaultConfig - Default configuration object\n * @param userConfig - User-provided configuration object or function\n * @returns Merged configuration\n * @internal\n */\nexport async function extendViteConfigWithUserConfig(\n env: ConfigEnv,\n defaultConfig: InlineConfig,\n userConfig: UserViteConfig,\n): Promise<InlineConfig> {\n let config = defaultConfig\n\n if (typeof userConfig === 'function') {\n debug('Extending vite config using user-specified function')\n config = await userConfig(config, env)\n } else if (typeof userConfig === 'object') {\n debug('Merging vite config using user-specified object')\n config = mergeConfig(config, userConfig)\n }\n\n return config\n}\n"],"names":["path","babel","findProjectRoot","getCliTelemetry","readPackageJson","viteReact","reactCompilerPreset","debug","esmExternalRequirePlugin","mergeConfig","SANITY_CACHE_DIR","federation","viteFederation","sanitySchemaExtractionPlugin","VENDOR_DIR","createExternalFromImportMap","normalizeBasePath","sanityBuildEntries","sanityFaviconsPlugin","sanityRuntimeRewritePlugin","createVendorNamedExportsPlugin","getDefaultFaviconsPath","getViteConfig","options","additionalPlugins","autoUpdates","basePath","rawBasePath","cwd","entries","isApp","isWorkbenchApp","minify","mode","outputDir","reactCompiler","schemaExtraction","server","services","sourceMap","views","configPath","customFaviconsPath","join","defaultFaviconsPath","staticPath","envVars","getEnvironmentVariables","sharedPlugins","presets","enabled","additionalPatterns","watchPatterns","enforceRequiredFields","outputPath","telemetryLogger","workDir","workspaceName","workspace","viteConfig","base","build","outDir","resolve","sourcemap","cacheDir","configFile","define","__SANITY_BUILD_TIMESTAMP__","JSON","stringify","Date","now","__SANITY_STAGING__","process","env","SANITY_INTERNAL_ENV","PKG_BUILD_VERSION","envPrefix","logLevel","plugins","relativeEntry","appEntry","studioConfigPath","relativeConfigLocation","pkgJson","staticUrlPath","dedupe","tsconfigPaths","root","host","port","strictPort","warmup","clientFiles","push","vendor","namesByChunkName","external","imports","Object","fromEntries","values","specifiersByChunkName","map","specifier","vendorChunkNames","Set","keys","assetsDir","emptyOutDir","rolldownOptions","input","sanity","onwarn","onRolldownWarn","experimental","nativeMagicString","output","entryFileNames","chunk","has","name","exports","preserveEntrySignatures","warning","warn","suppressUnusedImport","code","names","includes","filter","n","length","ids","every","id","finalizeViteConfig","config","defaultConfig","TypeError","Error","extendViteConfigWithUserConfig","userConfig"],"mappings":"AAAA,OAAOA,UAAU,YAAW;AAE5B,OAAOC,WAAW,yBAAwB;AAC1C,SAEEC,eAAe,EACfC,eAAe,EACfC,eAAe,QAEV,mBAAkB;AACzB,OAAOC,aAAYC,mBAAmB,QAAO,uBAAsB;AAEnE,OAAOC,WAAW,QAAO;AACzB,SAEEC,wBAAwB,EAExBC,WAAW,QAIN,OAAM;AAEb,SAAQC,gBAAgB,QAAO,qBAAoB;AAGnD,SAAQC,cAAcC,cAAc,QAAO,iCAAgC;AAC3E,SAAQC,4BAA4B,QAAO,6CAA4C;AAEvF,SAAQC,UAAU,QAAO,iBAAgB;AACzC,SAAQC,2BAA2B,QAAO,mCAAkC;AAC5E,SAAQC,iBAAiB,QAAO,yBAAwB;AACxD,SAAQC,kBAAkB,QAAO,wCAAuC;AACxE,SAAQC,oBAAoB,QAAO,mCAAkC;AACrE,SAAQC,0BAA0B,QAAO,0CAAyC;AAClF,SAAQC,8BAA8B,QAAO,+CAA8C;AAC3F,SAAQC,sBAAsB,QAAO,qBAAoB;AAmFzD;;;;CAIC,GACD,OAAO,eAAeC,cAAcC,OAAoB;IACtD,MAAM,EACJC,iBAAiB,EACjBC,WAAW,EACXC,UAAUC,cAAc,GAAG,EAC3BC,GAAG,EACHC,OAAO,EACPC,KAAK,EACLC,cAAc,EACdC,MAAM,EACNC,IAAI,EACJC,SAAS,EACTC,aAAa,EACbC,gBAAgB,EAChBC,MAAM,EACNC,QAAQ,EACR,4CAA4C;IAC5CC,YAAYhB,QAAQU,IAAI,KAAK,aAAa,EAC1CO,KAAK,EACN,GAAGjB;IAEJ,MAAMG,WAAWV,kBAAkBW;IAEnC,MAAMc,aAAa,AAAC,CAAA,MAAMvC,gBAAgB0B,IAAG,EAAG5B,IAAI;IAEpD,MAAM0C,qBAAqB1C,KAAK2C,IAAI,CAACf,KAAK;IAC1C,MAAMgB,sBAAsB,MAAMvB;IAClC,MAAMwB,aAAa,GAAGnB,SAAS,MAAM,CAAC;IAEtC,MAAMoB,UAAUvB,QAAQwB,uBAAuB;IAE/C,MAAMC,gBAA8B;QAClC3C;WACI8B,gBAAgB;YAAClC,MAAM;gBAACgD,SAAS;oBAAC3C,oBAAoB6B;iBAAe;YAAA;SAAG,GAAG,EAAE;WAC7EC,kBAAkBc,UAClB;YACErC,6BAA6B;gBAC3BsC,oBAAoBf,iBAAiBgB,aAAa;gBAClDX;gBACAY,uBAAuBjB,iBAAiBiB,qBAAqB;gBAC7DC,YAAYlB,iBAAiBpC,IAAI;gBACjCuD,iBAAiBpD;gBACjBqD,SAAS5B;gBACT6B,eAAerB,iBAAiBsB,SAAS;YAC3C;SACD,GACD,EAAE;KACP;IAED,MAAMC,aAA2B;QAC/BC,MAAMlC;QACNmC,OAAO;YACLC,QAAQ5B,aAAalC,KAAK+D,OAAO,CAACnC,KAAK;YACvCoC,WAAWzB;QACb;QACA,8DAA8D;QAC9D,2DAA2D;QAC3D0B,UAAU,GAAGvD,iBAAiB,KAAK,CAAC;QACpCwD,YAAY;QACZC,QAAQ;YACNC,4BAA4BC,KAAKC,SAAS,CAACC,KAAKC,GAAG;YACnDC,oBAAoBC,QAAQC,GAAG,CAACC,mBAAmB,KAAK;YACxD,oBAAoBP,KAAKC,SAAS,CAACrC;YACnC,iCAAiCoC,KAAKC,SAAS,CAACI,QAAQC,GAAG,CAACE,iBAAiB;YAC7E;;;;;;;;OAQC,GACD,iCAAiCR,KAAKC,SAAS,CAAC;YAChD,GAAGxB,OAAO;QACZ;QACAgC,WAAWhD,QAAQ,gBAAgB;QACnCiD,UAAU9C,SAAS,eAAe,WAAW;QAC7CA;QACA+C,SAAS;YACP,2EAA2E;YAC3E,qDAAqD;eACjDjD,iBACA;mBACKiB;gBACHpC,eAAe;oBACb,GAAIkB,QACA;wBACE,kHAAkH;wBAClH,sDAAsD;wBACtD,GAAID,QAAQoD,aAAa,GAAG;4BAACC,UAAUrD,QAAQoD,aAAa;wBAAA,IAAI,CAAC,CAAC;wBAClEnD,OAAO;oBACT,IACA;wBACEA,OAAO;wBACP,oCAAoC;wBACpCqD,kBAAkBtD,QAAQuD,sBAAsB;oBAClD,CAAC;oBACLC,SAAS,MAAMjF,gBAAgBJ,KAAK2C,IAAI,CAACf,KAAK;oBAC9CU;oBACAE;oBACAgB,SAAS5B;gBACX;aACD,GACD;mBACKoB;gBACH9B,qBAAqB;oBACnBwB;oBACAE;oBACA0C,eAAezC;gBACjB;gBACA1B;gBACAF,mBAAmB;oBAACQ;oBAAaC;oBAAUE;oBAAKE;gBAAK;mBACjDN,qBAAqB,EAAE;aAC5B;SACN;QACDuC,SAAS;YACPwB,QAAQ;gBAAC;gBAAS;gBAAa;gBAAU;aAAoB;YAC7D,qFAAqF;YACrFC,eAAe;QACjB;QACAC,MAAM7D;QACNS,QAAQ;YACNqD,MAAMrD,QAAQqD;YACdC,MAAMtD,QAAQsD,QAAQ;YACtB,wEAAwE;YACxE,sEAAsE;YACtE,uDAAuD;YACvDC,YAAY,CAAC9D,SAAS,CAACC;YAEvB;;;;;;OAMC,GACD8D,QAAQ;gBACNC,aAAa;oBAAC;iBAA2B;YAC3C;QACF;IACF;IAEA,mEAAmE;IACnE,+DAA+D;IAC/D,IAAI7D,SAAS,gBAAgB,CAACF,gBAAgB;QAC5C,IAAIN,aAAa;YACfkC,WAAWqB,OAAO,CAAEe,IAAI,CACtB,0EAA0E;YAC1E,2EAA2E;YAC3E,kBAAkB;YAClB3E,+BAA+BK,YAAYuE,MAAM,CAACC,gBAAgB,GAClE,uEAAuE;YACvE,iEAAiE;YACjE,yEAAyE;YACzE,gEAAgE;YAChE,yEAAyE;YACzE,yEAAyE;YACzE,yEAAyE;YACzEzF,yBAAyB;gBACvB0F,UAAUnF,4BAA4B;oBACpCoF,SAAS;wBACP,GAAG1E,YAAY0E,OAAO;wBACtB,GAAGC,OAAOC,WAAW,CACnBD,OAAOE,MAAM,CAAC7E,YAAYuE,MAAM,CAACO,qBAAqB,EAAEC,GAAG,CAAC,CAACC,YAAc;gCACzEA;gCACA;6BACD,EACF;oBACH;gBACF;YACF;QAEJ;QAEA,MAAMC,mBAAmBjF,cACrB,IAAIkF,IAAIP,OAAOQ,IAAI,CAACnF,YAAYuE,MAAM,CAACO,qBAAqB,KAC5D;QAEJ5C,WAAWE,KAAK,GAAG;YACjB,GAAGF,WAAWE,KAAK;YAEnBgD,WAAW;YACXC,aAAa;YACb9E,QAAQA,SAAS,QAAQ;YAEzB+E,iBAAiB;gBACfC,OAAO;oBACLC,QAAQjH,KAAK2C,IAAI,CAACf,KAAK,WAAW,WAAW;oBAC7C,GAAGH,aAAauE,OAAOnE,OAAO;gBAChC;gBACAqF,QAAQC;gBACR,GAAI1F,cACA;oBACE,oEAAoE;oBACpE,+DAA+D;oBAC/D,cAAc;oBACd2F,cAAc;wBAACC,mBAAmB;oBAAI;oBACtCC,QAAQ;wBACNC,gBAAgB,CAACC,QACfd,iBAAkBe,GAAG,CAACD,MAAME,IAAI,IAC5B,GAAG5G,WAAW,kBAAkB,CAAC,GACjC;wBACN6G,SAAS;oBACX;oBACA,sEAAsE;oBACtE,uEAAuE;oBACvE,sEAAsE;oBACtE,uEAAuE;oBACvE,uEAAuE;oBACvE,2BAA2B;oBAC3BC,yBAAyB;gBAC3B,IACA,CAAC,CAAC;YACR;QACF;IACF;IAEA,OAAOjE;AACT;AAEA,SAASwD,eAAeU,OAA6B,EAAEC,IAA8B;IACnF,IAAIC,qBAAqBF,UAAU;QACjC;IACF;IAEAC,KAAKD;AACP;AAEA,SAASE,qBAAqBF,OAAgD;IAC5E,IAAIA,QAAQG,IAAI,KAAK,0BAA0B,OAAO;IAEtD,YAAY;IACZ,MAAM;IACN,4DAA4D;IAC5D,MAAM;IACN,IAAIH,QAAQI,KAAK,EAAEC,SAAS,kBAAkB;QAC5CL,QAAQI,KAAK,GAAGJ,QAAQI,KAAK,CAACE,MAAM,CAAC,CAACC,IAAMA,MAAM;QAClD,IAAIP,QAAQI,KAAK,CAACI,MAAM,KAAK,GAAG,OAAO;IACzC;IAEA,mFAAmF;IACnF,IAAIR,QAAQS,GAAG,EAAEC,MAAM,CAACC,KAAOA,GAAGN,QAAQ,CAAC,qBAAqBM,GAAGN,QAAQ,CAAC,sBAC1E,OAAO;IAET,OAAO;AACT;AAEA;;;;;;;;;;;;;;;;;;CAkBC,GACD,OAAO,eAAeO,mBACpBC,MAAoB,EACpBC,aAA2B;IAE3B,IAAI,OAAOD,OAAO7E,KAAK,EAAEkD,iBAAiBC,UAAU,UAAU;QAC5D,MAAM,IAAI4B,UACR;IAEJ;IAEA,IAAI,CAACF,OAAOjD,IAAI,EAAE;QAChB,MAAM,IAAIoD,MACR;IAEJ;IAEA,OAAOpI,YAAYiI,QAAQ;QACzB7E,OAAO;YACLkD,iBAAiB4B,cAAc9E,KAAK,EAAEkD,mBAAmB,CAAC;QAC5D;IACF;AACF;AAEA;;;;;;;CAOC,GACD,OAAO,eAAe+B,+BACpBnE,GAAc,EACdgE,aAA2B,EAC3BI,UAA0B;IAE1B,IAAIL,SAASC;IAEb,IAAI,OAAOI,eAAe,YAAY;QACpCxI,MAAM;QACNmI,SAAS,MAAMK,WAAWL,QAAQ/D;IACpC,OAAO,IAAI,OAAOoE,eAAe,UAAU;QACzCxI,MAAM;QACNmI,SAASjI,YAAYiI,QAAQK;IAC/B;IAEA,OAAOL;AACT"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * What a {@link GeneratedArtifact.source} builder receives from the build — the
3
+ * one thing it can't compute on its own, since only the build knows where the
4
+ * runtime dir sits relative to the app's `src`.
5
+ */ /**
6
+ * Map the artifacts the host loads directly (those with an `expose`) to their
7
+ * runtime-dir paths, for the module-federation `exposes` field. `toExposePath`
8
+ * turns a runtime-relative artifact path into the value federation wants — the
9
+ * caller owns the runtime-dir location and any entry resolution.
10
+ */ export function artifactExposes(artifacts, toExposePath) {
11
+ const exposes = {};
12
+ for (const artifact of artifacts){
13
+ if (artifact.expose) {
14
+ exposes[artifact.expose] = toExposePath(artifact.path);
15
+ }
16
+ }
17
+ return exposes;
18
+ }
19
+
20
+ //# sourceMappingURL=artifact.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/workbench/artifact.ts"],"sourcesContent":["/**\n * What a {@link GeneratedArtifact.source} builder receives from the build — the\n * one thing it can't compute on its own, since only the build knows where the\n * runtime dir sits relative to the app's `src`.\n */\ninterface ArtifactContext {\n /** Import specifier for an app `src` file, relative to this artifact. */\n resolveImport: (src: string) => string\n}\n\n/**\n * One file the federation build generates into the runtime dir for a declared\n * interface. Each interface type — views, services — expands its declarations\n * into a flat list of these; the build then writes them and maps the ones the\n * host loads directly into the module-federation manifest.\n *\n * Adding an interface type is adding a builder that returns\n * `GeneratedArtifact[]` — the write loop and the expose mapping never change.\n */\nexport interface GeneratedArtifact {\n /** Path relative to the federation runtime dir, e.g. `views/feed/panel.js`. */\n path: string\n /** Build the file's contents. */\n source: (context: ArtifactContext) => string\n\n /**\n * Module-federation expose key when the host loads this artifact directly —\n * a view component `./views/feed/panel`, a service loader `./services/unread`.\n * Omitted for a file the host never loads on its own, like a worker bundle\n * (reached through its sibling loader).\n */\n expose?: string\n}\n\n/**\n * Map the artifacts the host loads directly (those with an `expose`) to their\n * runtime-dir paths, for the module-federation `exposes` field. `toExposePath`\n * turns a runtime-relative artifact path into the value federation wants — the\n * caller owns the runtime-dir location and any entry resolution.\n */\nexport function artifactExposes(\n artifacts: readonly GeneratedArtifact[],\n toExposePath: (artifactPath: string) => string,\n): Record<string, string> {\n const exposes: Record<string, string> = {}\n for (const artifact of artifacts) {\n if (artifact.expose) {\n exposes[artifact.expose] = toExposePath(artifact.path)\n }\n }\n return exposes\n}\n"],"names":["artifactExposes","artifacts","toExposePath","exposes","artifact","expose","path"],"mappings":"AAAA;;;;CAIC,GA8BD;;;;;CAKC,GACD,OAAO,SAASA,gBACdC,SAAuC,EACvCC,YAA8C;IAE9C,MAAMC,UAAkC,CAAC;IACzC,KAAK,MAAMC,YAAYH,UAAW;QAChC,IAAIG,SAASC,MAAM,EAAE;YACnBF,OAAO,CAACC,SAASC,MAAM,CAAC,GAAGH,aAAaE,SAASE,IAAI;QACvD;IACF;IACA,OAAOH;AACT"}
@@ -0,0 +1,66 @@
1
+ import { z } from 'zod/mini';
2
+ // The shared kernel of the module-federation extension contract: the supported
3
+ // view/service types, the contract versions the helpers stamp, and the
4
+ // declaration schemas an app author writes in `unstable_defineApp({views, services})`.
5
+ //
6
+ // Lives in `@sanity/cli-build` (alongside the vite plugin that consumes the same
7
+ // contract) so there is a single source of truth. `zod/mini` is used throughout
8
+ // cli-build to keep bundles small.
9
+ /**
10
+ * Contract version stamped on every defined view — lets the host and the
11
+ * generated artifact evolve the contract without breaking deployed views.
12
+ * @internal
13
+ */ export const VIEW_CONTRACT_VERSION = 1;
14
+ /**
15
+ * Contract version stamped on every defined service. Lets the workbench host
16
+ * and the generated worker artifact evolve the service contract without
17
+ * breaking already-deployed services; bumped only on a breaking change.
18
+ * @internal
19
+ */ export const SERVICE_CONTRACT_VERSION = 1;
20
+ /**
21
+ * Component slots each interface type exposes, in render order — the source of
22
+ * truth for {@link InterfaceType} and for the build (the vite plugin expands a
23
+ * view into one render artifact per component). Add a type by registering it here.
24
+ * @internal
25
+ */ export const VIEW_COMPONENTS = {
26
+ panel: [
27
+ 'title',
28
+ 'panel'
29
+ ]
30
+ };
31
+ /**
32
+ * Fields every extension declaration shares — a view or a service. The shape is
33
+ * identical (`name` + `src`); `kind` only tailors the validation message. Each
34
+ * declaration adds its `type` discriminator on top.
35
+ */ function extensionDeclarationFields(kind) {
36
+ const pattern = /^[a-zA-Z0-9_-]+$/;
37
+ return {
38
+ name: z.string().check(z.regex(pattern, `${kind} \`name\` must match ${pattern}`)),
39
+ src: z.string()
40
+ };
41
+ }
42
+ /** What an author writes for a `panel` in `unstable_defineApp({views})`. */ const PanelViewSchema = z.object({
43
+ type: z.literal('panel'),
44
+ ...extensionDeclarationFields('View')
45
+ });
46
+ /**
47
+ * The `{type, name, src}` an app declares for a view, discriminated by `type`.
48
+ * Persisted to the application service on deploy; never part of the app manifest.
49
+ * @internal
50
+ */ export const InterfaceDeclarationSchema = z.discriminatedUnion('type', [
51
+ PanelViewSchema
52
+ ]);
53
+ /** Declaration schema for a `worker` service — what a developer writes in `unstable_defineApp({services})`. */ const WorkerServiceSchema = z.object({
54
+ type: z.literal('worker'),
55
+ ...extensionDeclarationFields('Service')
56
+ });
57
+ /**
58
+ * A service declared on an app, discriminated by `type`. Metadata only; built
59
+ * into a worker artifact and persisted to the application service on deploy,
60
+ * never part of the app manifest.
61
+ * @internal
62
+ */ export const ServiceDeclarationSchema = z.discriminatedUnion('type', [
63
+ WorkerServiceSchema
64
+ ]);
65
+
66
+ //# sourceMappingURL=contract.js.map