@sanity/cli-build 1.0.4 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_exports/_internal/build.d.ts +126 -3
- package/dist/_exports/_internal/build.js +4 -1
- package/dist/_exports/_internal/build.js.map +1 -1
- package/dist/actions/build/checkRequiredDependencies.js +124 -0
- package/dist/actions/build/checkRequiredDependencies.js.map +1 -0
- package/dist/actions/build/getAutoUpdatesImportMap.js +66 -0
- package/dist/actions/build/getAutoUpdatesImportMap.js.map +1 -0
- package/dist/actions/build/getEntryModule.js +12 -1
- package/dist/actions/build/getEntryModule.js.map +1 -1
- package/dist/actions/build/getViteConfig.js +57 -36
- package/dist/actions/build/getViteConfig.js.map +1 -1
- package/dist/actions/build/renderDocumentWorker/addTimestampImportMapScriptToHtml.js +37 -1
- package/dist/actions/build/renderDocumentWorker/addTimestampImportMapScriptToHtml.js.map +1 -1
- package/dist/actions/build/writeSanityRuntime.js +40 -9
- package/dist/actions/build/writeSanityRuntime.js.map +1 -1
- package/package.json +19 -14
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { CliConfig } from "@sanity/cli-core";
|
|
2
2
|
import { ConfigEnv } from "vite";
|
|
3
3
|
import { Debugger } from "debug";
|
|
4
|
+
import { DefineAppInput } from "@sanity/workbench-cli";
|
|
4
5
|
import { DefinedTelemetryTrace } from "@sanity/telemetry";
|
|
5
6
|
import { FSWatcher } from "chokidar";
|
|
6
7
|
import { InlineConfig } from "vite";
|
|
@@ -38,6 +39,31 @@ export declare interface AutoUpdatesBuildConfig {
|
|
|
38
39
|
|
|
39
40
|
export declare const buildDebug: Debugger;
|
|
40
41
|
|
|
42
|
+
/**
|
|
43
|
+
* Checks that the studio has declared and installed the required dependencies
|
|
44
|
+
* needed by the Sanity modules. While we generally use regular, explicit
|
|
45
|
+
* dependencies in modules, there are certain dependencies that are better
|
|
46
|
+
* served being peer dependencies, such as react and styled-components.
|
|
47
|
+
*
|
|
48
|
+
* If these dependencies are not installed/declared, we report an error
|
|
49
|
+
* and instruct the user to install them manually.
|
|
50
|
+
*
|
|
51
|
+
* Additionally, returns the version of the 'sanity' dependency from the package.json.
|
|
52
|
+
*/
|
|
53
|
+
export declare function checkRequiredDependencies(
|
|
54
|
+
options: CheckRequiredDependenciesOptions,
|
|
55
|
+
): Promise<CheckResult>;
|
|
56
|
+
|
|
57
|
+
declare interface CheckRequiredDependenciesOptions {
|
|
58
|
+
isApp: boolean;
|
|
59
|
+
output: Output;
|
|
60
|
+
workDir: string;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
declare interface CheckResult {
|
|
64
|
+
installedSanityVersion: string;
|
|
65
|
+
}
|
|
66
|
+
|
|
41
67
|
export declare function checkStudioDependencyVersions(
|
|
42
68
|
workDir: string,
|
|
43
69
|
output: Output,
|
|
@@ -101,6 +127,46 @@ export declare function finalizeViteConfig(
|
|
|
101
127
|
defaultConfig: InlineConfig,
|
|
102
128
|
): Promise<InlineConfig>;
|
|
103
129
|
|
|
130
|
+
/**
|
|
131
|
+
* Generate CDN CSS URLs for auto-updated packages.
|
|
132
|
+
* Uses the same URL pattern as JS module URLs so the module server
|
|
133
|
+
* resolves CSS and JS to the same version.
|
|
134
|
+
*
|
|
135
|
+
* @internal
|
|
136
|
+
*/
|
|
137
|
+
export declare function getAutoUpdatesCssUrls<const Pkg extends PackageWithCss>(
|
|
138
|
+
packages: Pkg[],
|
|
139
|
+
options?: {
|
|
140
|
+
appId?: string;
|
|
141
|
+
baseUrl?: string;
|
|
142
|
+
timestamp?: number;
|
|
143
|
+
},
|
|
144
|
+
): string[];
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* @internal
|
|
148
|
+
*/
|
|
149
|
+
export declare function getAutoUpdatesImportMap<const Pkg extends Package>(
|
|
150
|
+
packages: Pkg[],
|
|
151
|
+
options?: {
|
|
152
|
+
appId?: string;
|
|
153
|
+
baseUrl?: string;
|
|
154
|
+
timestamp?: number;
|
|
155
|
+
},
|
|
156
|
+
): { [K in `${Pkg["name"]}/` | Pkg["name"]]: string };
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* @internal
|
|
160
|
+
*/
|
|
161
|
+
export declare function getModuleUrl(
|
|
162
|
+
pkg: Package,
|
|
163
|
+
options?: {
|
|
164
|
+
appId?: string;
|
|
165
|
+
baseUrl?: string;
|
|
166
|
+
timestamp?: number;
|
|
167
|
+
},
|
|
168
|
+
): string;
|
|
169
|
+
|
|
104
170
|
/**
|
|
105
171
|
* Get a configuration object for Vite based on the passed options
|
|
106
172
|
*
|
|
@@ -110,6 +176,31 @@ export declare function getViteConfig(
|
|
|
110
176
|
options: ViteOptions,
|
|
111
177
|
): Promise<InlineConfig>;
|
|
112
178
|
|
|
179
|
+
declare type Package = {
|
|
180
|
+
name: string;
|
|
181
|
+
version: string;
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
declare type PackageWithCss = Package & {
|
|
185
|
+
cssFile?: string;
|
|
186
|
+
};
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Resolves the relative entry paths for a Sanity project without writing any
|
|
190
|
+
* runtime files to disk. Used by federation builds that skip the full runtime
|
|
191
|
+
* generation but still need entry metadata for the vite plugin.
|
|
192
|
+
*/
|
|
193
|
+
export declare function resolveEntries(options: {
|
|
194
|
+
cwd: string;
|
|
195
|
+
entry?: string;
|
|
196
|
+
isApp?: boolean;
|
|
197
|
+
isWorkbenchApp?: boolean;
|
|
198
|
+
runtimeDir?: string;
|
|
199
|
+
}): Promise<{
|
|
200
|
+
relativeConfigLocation: string | null;
|
|
201
|
+
relativeEntry: string | null;
|
|
202
|
+
}>;
|
|
203
|
+
|
|
113
204
|
/**
|
|
114
205
|
* Resolves vendor package entry points and metadata for a combined studio/app build.
|
|
115
206
|
* Does not run a build — callers add `entries` to the main Vite/Rolldown input and
|
|
@@ -135,8 +226,17 @@ declare interface RuntimeOptions {
|
|
|
135
226
|
basePath?: string;
|
|
136
227
|
entry?: string;
|
|
137
228
|
isApp?: boolean;
|
|
229
|
+
isWorkbenchApp?: boolean;
|
|
138
230
|
}
|
|
139
231
|
|
|
232
|
+
/**
|
|
233
|
+
* Root directory (relative to the project) used by Sanity tooling for
|
|
234
|
+
* build-time artifacts and caches — Vite's `cacheDir` and the dev-time
|
|
235
|
+
* manifest output. Lives under `node_modules/` so it's out of `dist` and
|
|
236
|
+
* ignored by default in typical `.gitignore` files.
|
|
237
|
+
*/
|
|
238
|
+
export declare const SANITY_CACHE_DIR = "node_modules/.sanity";
|
|
239
|
+
|
|
140
240
|
export declare const StudioBuildTrace: DefinedTelemetryTrace<
|
|
141
241
|
{
|
|
142
242
|
outputSize: number;
|
|
@@ -164,6 +264,10 @@ declare interface ViteOptions {
|
|
|
164
264
|
* Root path of the studio/sanity app
|
|
165
265
|
*/
|
|
166
266
|
cwd: string;
|
|
267
|
+
entries: {
|
|
268
|
+
relativeConfigLocation: string | null;
|
|
269
|
+
relativeEntry: string | null;
|
|
270
|
+
};
|
|
167
271
|
/**
|
|
168
272
|
* Returns the environment variables to be injected into the config.
|
|
169
273
|
*/
|
|
@@ -189,6 +293,11 @@ declare interface ViteOptions {
|
|
|
189
293
|
*/
|
|
190
294
|
basePath?: string;
|
|
191
295
|
isApp?: boolean;
|
|
296
|
+
/**
|
|
297
|
+
* Whether this is a workbench app (opted in via `unstable_defineApp`). Drives
|
|
298
|
+
* the module-federation build.
|
|
299
|
+
*/
|
|
300
|
+
isWorkbenchApp?: boolean;
|
|
192
301
|
/**
|
|
193
302
|
* Whether or not to minify the output (only used in `mode: 'production'`)
|
|
194
303
|
*/
|
|
@@ -208,10 +317,20 @@ declare interface ViteOptions {
|
|
|
208
317
|
host?: string;
|
|
209
318
|
port?: number;
|
|
210
319
|
};
|
|
320
|
+
/**
|
|
321
|
+
* Background services the workbench app declares. Built into self-contained
|
|
322
|
+
* worker bundles and exposed through module federation as `./services/<name>`.
|
|
323
|
+
*/
|
|
324
|
+
services?: DefineAppInput["services"];
|
|
211
325
|
/**
|
|
212
326
|
* Whether or not to enable source maps
|
|
213
327
|
*/
|
|
214
328
|
sourceMap?: boolean;
|
|
329
|
+
/**
|
|
330
|
+
* Views the workbench app declares. Built into render-contract artifacts and
|
|
331
|
+
* exposed through module federation as `./views/<name>`.
|
|
332
|
+
*/
|
|
333
|
+
views?: DefineAppInput["views"];
|
|
215
334
|
}
|
|
216
335
|
|
|
217
336
|
/**
|
|
@@ -230,8 +349,12 @@ export declare function writeFavicons(
|
|
|
230
349
|
* @returns A watcher instance if watch is enabled, undefined otherwise
|
|
231
350
|
* @internal
|
|
232
351
|
*/
|
|
233
|
-
export declare function writeSanityRuntime(
|
|
234
|
-
|
|
235
|
-
|
|
352
|
+
export declare function writeSanityRuntime(options: RuntimeOptions): Promise<{
|
|
353
|
+
entries: {
|
|
354
|
+
relativeConfigLocation: string | null;
|
|
355
|
+
relativeEntry: string | null;
|
|
356
|
+
};
|
|
357
|
+
watcher: FSWatcher | undefined;
|
|
358
|
+
}>;
|
|
236
359
|
|
|
237
360
|
export {};
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
export { buildDebug } from '../../actions/build/buildDebug.js';
|
|
2
|
+
export { checkRequiredDependencies } from '../../actions/build/checkRequiredDependencies.js';
|
|
2
3
|
export { checkStudioDependencyVersions } from '../../actions/build/checkStudioDependencyVersions.js';
|
|
4
|
+
export { getAutoUpdatesCssUrls, getAutoUpdatesImportMap, getModuleUrl } from '../../actions/build/getAutoUpdatesImportMap.js';
|
|
3
5
|
export { extendViteConfigWithUserConfig, finalizeViteConfig, getViteConfig } from '../../actions/build/getViteConfig.js';
|
|
4
6
|
export { resolveVendorBuildConfig } from '../../actions/build/resolveVendorBuildConfig.js';
|
|
5
7
|
export { writeFavicons } from '../../actions/build/writeFavicons.js';
|
|
6
|
-
export { writeSanityRuntime } from '../../actions/build/writeSanityRuntime.js';
|
|
8
|
+
export { resolveEntries, writeSanityRuntime } from '../../actions/build/writeSanityRuntime.js';
|
|
9
|
+
export { SANITY_CACHE_DIR } from '../../constants.js';
|
|
7
10
|
export { AppBuildTrace, StudioBuildTrace } from '../../telemetry/build.telemetry.js';
|
|
8
11
|
export { copyDir } from '../../util/copyDir.js';
|
|
9
12
|
|
|
@@ -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 {writeSanityRuntime} from '../../actions/build/writeSanityRuntime.js'\nexport {AppBuildTrace, StudioBuildTrace} from '../../telemetry/build.telemetry.js'\nexport {copyDir} from '../../util/copyDir.js'\n"],"names":["buildDebug","checkStudioDependencyVersions","extendViteConfigWithUserConfig","finalizeViteConfig","getViteConfig","resolveVendorBuildConfig","writeFavicons","writeSanityRuntime","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,kBAAkB,QAAO,4CAA2C;
|
|
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 {checkRequiredDependencies} from '../../actions/build/checkRequiredDependencies.js'\nexport {checkStudioDependencyVersions} from '../../actions/build/checkStudioDependencyVersions.js'\nexport {\n getAutoUpdatesCssUrls,\n getAutoUpdatesImportMap,\n getModuleUrl,\n} from '../../actions/build/getAutoUpdatesImportMap.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","checkRequiredDependencies","checkStudioDependencyVersions","getAutoUpdatesCssUrls","getAutoUpdatesImportMap","getModuleUrl","extendViteConfigWithUserConfig","finalizeViteConfig","getViteConfig","resolveVendorBuildConfig","writeFavicons","resolveEntries","writeSanityRuntime","SANITY_CACHE_DIR","AppBuildTrace","StudioBuildTrace","copyDir"],"mappings":"AACA,SAAQA,UAAU,QAAO,oCAAmC;AAC5D,SAAQC,yBAAyB,QAAO,mDAAkD;AAC1F,SAAQC,6BAA6B,QAAO,uDAAsD;AAClG,SACEC,qBAAqB,EACrBC,uBAAuB,EACvBC,YAAY,QACP,iDAAgD;AACvD,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,124 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import { getLocalPackageVersion, readPackageJson } from '@sanity/cli-core';
|
|
3
|
+
import { oneline } from 'oneline';
|
|
4
|
+
import { minVersion, satisfies } from 'semver';
|
|
5
|
+
const defaultStudioManifestProps = {
|
|
6
|
+
name: 'studio',
|
|
7
|
+
version: '1.0.0'
|
|
8
|
+
};
|
|
9
|
+
const styledComponentsVersionRange = '^6.1.15';
|
|
10
|
+
/**
|
|
11
|
+
* Checks that the studio has declared and installed the required dependencies
|
|
12
|
+
* needed by the Sanity modules. While we generally use regular, explicit
|
|
13
|
+
* dependencies in modules, there are certain dependencies that are better
|
|
14
|
+
* served being peer dependencies, such as react and styled-components.
|
|
15
|
+
*
|
|
16
|
+
* If these dependencies are not installed/declared, we report an error
|
|
17
|
+
* and instruct the user to install them manually.
|
|
18
|
+
*
|
|
19
|
+
* Additionally, returns the version of the 'sanity' dependency from the package.json.
|
|
20
|
+
*/ export async function checkRequiredDependencies(options) {
|
|
21
|
+
const { isApp, output, workDir: studioPath } = options;
|
|
22
|
+
// currently there's no check needed for core apps,
|
|
23
|
+
// but this should be removed once they are more mature
|
|
24
|
+
if (isApp) {
|
|
25
|
+
return {
|
|
26
|
+
installedSanityVersion: ''
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
const [studioPackageManifest, installedStyledComponentsVersion, installedSanityVersion] = await Promise.all([
|
|
30
|
+
readPackageJson(path.join(studioPath, 'package.json'), {
|
|
31
|
+
defaults: defaultStudioManifestProps,
|
|
32
|
+
skipSchemaValidation: true
|
|
33
|
+
}),
|
|
34
|
+
getLocalPackageVersion('styled-components', studioPath),
|
|
35
|
+
getLocalPackageVersion('sanity', studioPath)
|
|
36
|
+
]);
|
|
37
|
+
const wantedStyledComponentsVersionRange = styledComponentsVersionRange;
|
|
38
|
+
// Retrieve the version of the 'sanity' dependency
|
|
39
|
+
if (!installedSanityVersion) {
|
|
40
|
+
output.error('Failed to read the installed sanity version.', {
|
|
41
|
+
exit: 1
|
|
42
|
+
});
|
|
43
|
+
return {
|
|
44
|
+
installedSanityVersion: ''
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
// The studio _must_ now declare `styled-components` as a dependency. If it's not there,
|
|
48
|
+
// we'll want to automatically _add it_ to the manifest and tell the user to reinstall
|
|
49
|
+
// dependencies before running whatever command was being run
|
|
50
|
+
const declaredStyledComponentsVersion = studioPackageManifest.dependencies?.['styled-components'] || studioPackageManifest?.devDependencies?.['styled-components'];
|
|
51
|
+
if (!declaredStyledComponentsVersion) {
|
|
52
|
+
output.error(oneline`
|
|
53
|
+
Declared dependency \`styled-components\` is not installed - run
|
|
54
|
+
\`npm install\`, \`yarn install\` or \`pnpm install\` to install it before re-running this command.
|
|
55
|
+
`, {
|
|
56
|
+
exit: 1
|
|
57
|
+
});
|
|
58
|
+
return {
|
|
59
|
+
installedSanityVersion
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
// We ignore catalog identifiers since we check the actual version anyway
|
|
63
|
+
const isStyledComponentsVersionRangeInCatalog = declaredStyledComponentsVersion.startsWith('catalog:');
|
|
64
|
+
// Theoretically the version specified in package.json could be incorrect, eg `foo`
|
|
65
|
+
let minDeclaredStyledComponentsVersion = null;
|
|
66
|
+
try {
|
|
67
|
+
minDeclaredStyledComponentsVersion = minVersion(declaredStyledComponentsVersion);
|
|
68
|
+
} catch {
|
|
69
|
+
// Intentional fall-through (variable will be left as null, throwing below)
|
|
70
|
+
}
|
|
71
|
+
if (!minDeclaredStyledComponentsVersion && !isStyledComponentsVersionRangeInCatalog) {
|
|
72
|
+
output.error(oneline`
|
|
73
|
+
Declared dependency \`styled-components\` has an invalid version range:
|
|
74
|
+
\`${declaredStyledComponentsVersion}\`.
|
|
75
|
+
`, {
|
|
76
|
+
exit: 1
|
|
77
|
+
});
|
|
78
|
+
return {
|
|
79
|
+
installedSanityVersion
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
// The declared version should be semver-compatible with the version specified as a
|
|
83
|
+
// peer dependency in `sanity`. If not, we should tell the user to change it.
|
|
84
|
+
//
|
|
85
|
+
// Exception: Ranges are hard to compare. `>=5.0.0 && <=5.3.2 || ^6`... Comparing this
|
|
86
|
+
// to anything is going to be challenging, so only compare "simple" ranges/versions
|
|
87
|
+
// (^x.x.x / ~x.x.x / x.x.x)
|
|
88
|
+
if (!isStyledComponentsVersionRangeInCatalog && isComparableRange(declaredStyledComponentsVersion) && !satisfies(minDeclaredStyledComponentsVersion, wantedStyledComponentsVersionRange)) {
|
|
89
|
+
output.warn(oneline`
|
|
90
|
+
Declared version of styled-components (${declaredStyledComponentsVersion})
|
|
91
|
+
is not compatible with the version required by sanity (${wantedStyledComponentsVersionRange}).
|
|
92
|
+
This might cause problems!
|
|
93
|
+
`);
|
|
94
|
+
}
|
|
95
|
+
// Ensure the studio has _installed_ a version of `styled-components`
|
|
96
|
+
if (!installedStyledComponentsVersion) {
|
|
97
|
+
output.error(oneline`
|
|
98
|
+
Declared dependency \`styled-components\` is not installed - run
|
|
99
|
+
\`npm install\`, \`yarn install\` or \`pnpm install\` to install it before re-running this command.
|
|
100
|
+
`, {
|
|
101
|
+
exit: 1
|
|
102
|
+
});
|
|
103
|
+
return {
|
|
104
|
+
installedSanityVersion
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
// The studio should have an _installed_ version of `styled-components`, and it should
|
|
108
|
+
// be semver compatible with the version specified in `sanity` peer dependencies.
|
|
109
|
+
if (!satisfies(installedStyledComponentsVersion, wantedStyledComponentsVersionRange)) {
|
|
110
|
+
output.warn(oneline`
|
|
111
|
+
Installed version of styled-components (${installedStyledComponentsVersion})
|
|
112
|
+
is not compatible with the version required by sanity (${wantedStyledComponentsVersionRange}).
|
|
113
|
+
This might cause problems!
|
|
114
|
+
`);
|
|
115
|
+
}
|
|
116
|
+
return {
|
|
117
|
+
installedSanityVersion
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
function isComparableRange(range) {
|
|
121
|
+
return /^[\^~]?\d+(\.\d+)?(\.\d+)?$/.test(range);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
//# sourceMappingURL=checkRequiredDependencies.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/actions/build/checkRequiredDependencies.ts"],"sourcesContent":["import path from 'node:path'\n\nimport {\n getLocalPackageVersion,\n type Output,\n type PackageJson,\n readPackageJson,\n} from '@sanity/cli-core'\nimport {oneline} from 'oneline'\nimport {minVersion, satisfies, type SemVer} from 'semver'\n\nconst defaultStudioManifestProps: Partial<PackageJson> = {\n name: 'studio',\n version: '1.0.0',\n}\n\ninterface CheckResult {\n installedSanityVersion: string\n}\n\ninterface CheckRequiredDependenciesOptions {\n isApp: boolean\n output: Output\n workDir: string\n}\n\nconst styledComponentsVersionRange = '^6.1.15'\n\n/**\n * Checks that the studio has declared and installed the required dependencies\n * needed by the Sanity modules. While we generally use regular, explicit\n * dependencies in modules, there are certain dependencies that are better\n * served being peer dependencies, such as react and styled-components.\n *\n * If these dependencies are not installed/declared, we report an error\n * and instruct the user to install them manually.\n *\n * Additionally, returns the version of the 'sanity' dependency from the package.json.\n */\nexport async function checkRequiredDependencies(\n options: CheckRequiredDependenciesOptions,\n): Promise<CheckResult> {\n const {isApp, output, workDir: studioPath} = options\n // currently there's no check needed for core apps,\n // but this should be removed once they are more mature\n if (isApp) {\n return {installedSanityVersion: ''}\n }\n\n const [studioPackageManifest, installedStyledComponentsVersion, installedSanityVersion] =\n await Promise.all([\n readPackageJson(path.join(studioPath, 'package.json'), {\n defaults: defaultStudioManifestProps,\n skipSchemaValidation: true,\n }),\n getLocalPackageVersion('styled-components', studioPath),\n getLocalPackageVersion('sanity', studioPath),\n ])\n\n const wantedStyledComponentsVersionRange = styledComponentsVersionRange\n\n // Retrieve the version of the 'sanity' dependency\n if (!installedSanityVersion) {\n output.error('Failed to read the installed sanity version.', {exit: 1})\n return {installedSanityVersion: ''}\n }\n\n // The studio _must_ now declare `styled-components` as a dependency. If it's not there,\n // we'll want to automatically _add it_ to the manifest and tell the user to reinstall\n // dependencies before running whatever command was being run\n const declaredStyledComponentsVersion =\n studioPackageManifest.dependencies?.['styled-components'] ||\n studioPackageManifest?.devDependencies?.['styled-components']\n\n if (!declaredStyledComponentsVersion) {\n output.error(\n oneline`\n Declared dependency \\`styled-components\\` is not installed - run\n \\`npm install\\`, \\`yarn install\\` or \\`pnpm install\\` to install it before re-running this command.\n `,\n {exit: 1},\n )\n return {installedSanityVersion}\n }\n\n // We ignore catalog identifiers since we check the actual version anyway\n const isStyledComponentsVersionRangeInCatalog =\n declaredStyledComponentsVersion.startsWith('catalog:')\n // Theoretically the version specified in package.json could be incorrect, eg `foo`\n let minDeclaredStyledComponentsVersion: SemVer | null = null\n try {\n minDeclaredStyledComponentsVersion = minVersion(declaredStyledComponentsVersion)\n } catch {\n // Intentional fall-through (variable will be left as null, throwing below)\n }\n\n if (!minDeclaredStyledComponentsVersion && !isStyledComponentsVersionRangeInCatalog) {\n output.error(\n oneline`\n Declared dependency \\`styled-components\\` has an invalid version range:\n \\`${declaredStyledComponentsVersion}\\`.\n `,\n {exit: 1},\n )\n return {installedSanityVersion}\n }\n\n // The declared version should be semver-compatible with the version specified as a\n // peer dependency in `sanity`. If not, we should tell the user to change it.\n //\n // Exception: Ranges are hard to compare. `>=5.0.0 && <=5.3.2 || ^6`... Comparing this\n // to anything is going to be challenging, so only compare \"simple\" ranges/versions\n // (^x.x.x / ~x.x.x / x.x.x)\n if (\n !isStyledComponentsVersionRangeInCatalog &&\n isComparableRange(declaredStyledComponentsVersion) &&\n !satisfies(minDeclaredStyledComponentsVersion!, wantedStyledComponentsVersionRange)\n ) {\n output.warn(oneline`\n Declared version of styled-components (${declaredStyledComponentsVersion})\n is not compatible with the version required by sanity (${wantedStyledComponentsVersionRange}).\n This might cause problems!\n `)\n }\n\n // Ensure the studio has _installed_ a version of `styled-components`\n if (!installedStyledComponentsVersion) {\n output.error(\n oneline`\n Declared dependency \\`styled-components\\` is not installed - run\n \\`npm install\\`, \\`yarn install\\` or \\`pnpm install\\` to install it before re-running this command.\n `,\n {exit: 1},\n )\n return {installedSanityVersion}\n }\n\n // The studio should have an _installed_ version of `styled-components`, and it should\n // be semver compatible with the version specified in `sanity` peer dependencies.\n if (!satisfies(installedStyledComponentsVersion, wantedStyledComponentsVersionRange)) {\n output.warn(oneline`\n Installed version of styled-components (${installedStyledComponentsVersion})\n is not compatible with the version required by sanity (${wantedStyledComponentsVersionRange}).\n This might cause problems!\n `)\n }\n\n return {installedSanityVersion}\n}\n\nfunction isComparableRange(range: string): boolean {\n return /^[\\^~]?\\d+(\\.\\d+)?(\\.\\d+)?$/.test(range)\n}\n"],"names":["path","getLocalPackageVersion","readPackageJson","oneline","minVersion","satisfies","defaultStudioManifestProps","name","version","styledComponentsVersionRange","checkRequiredDependencies","options","isApp","output","workDir","studioPath","installedSanityVersion","studioPackageManifest","installedStyledComponentsVersion","Promise","all","join","defaults","skipSchemaValidation","wantedStyledComponentsVersionRange","error","exit","declaredStyledComponentsVersion","dependencies","devDependencies","isStyledComponentsVersionRangeInCatalog","startsWith","minDeclaredStyledComponentsVersion","isComparableRange","warn","range","test"],"mappings":"AAAA,OAAOA,UAAU,YAAW;AAE5B,SACEC,sBAAsB,EAGtBC,eAAe,QACV,mBAAkB;AACzB,SAAQC,OAAO,QAAO,UAAS;AAC/B,SAAQC,UAAU,EAAEC,SAAS,QAAoB,SAAQ;AAEzD,MAAMC,6BAAmD;IACvDC,MAAM;IACNC,SAAS;AACX;AAYA,MAAMC,+BAA+B;AAErC;;;;;;;;;;CAUC,GACD,OAAO,eAAeC,0BACpBC,OAAyC;IAEzC,MAAM,EAACC,KAAK,EAAEC,MAAM,EAAEC,SAASC,UAAU,EAAC,GAAGJ;IAC7C,mDAAmD;IACnD,uDAAuD;IACvD,IAAIC,OAAO;QACT,OAAO;YAACI,wBAAwB;QAAE;IACpC;IAEA,MAAM,CAACC,uBAAuBC,kCAAkCF,uBAAuB,GACrF,MAAMG,QAAQC,GAAG,CAAC;QAChBlB,gBAAgBF,KAAKqB,IAAI,CAACN,YAAY,iBAAiB;YACrDO,UAAUhB;YACViB,sBAAsB;QACxB;QACAtB,uBAAuB,qBAAqBc;QAC5Cd,uBAAuB,UAAUc;KAClC;IAEH,MAAMS,qCAAqCf;IAE3C,kDAAkD;IAClD,IAAI,CAACO,wBAAwB;QAC3BH,OAAOY,KAAK,CAAC,gDAAgD;YAACC,MAAM;QAAC;QACrE,OAAO;YAACV,wBAAwB;QAAE;IACpC;IAEA,wFAAwF;IACxF,sFAAsF;IACtF,6DAA6D;IAC7D,MAAMW,kCACJV,sBAAsBW,YAAY,EAAE,CAAC,oBAAoB,IACzDX,uBAAuBY,iBAAiB,CAAC,oBAAoB;IAE/D,IAAI,CAACF,iCAAiC;QACpCd,OAAOY,KAAK,CACVtB,OAAO,CAAC;;;IAGV,CAAC,EACC;YAACuB,MAAM;QAAC;QAEV,OAAO;YAACV;QAAsB;IAChC;IAEA,yEAAyE;IACzE,MAAMc,0CACJH,gCAAgCI,UAAU,CAAC;IAC7C,mFAAmF;IACnF,IAAIC,qCAAoD;IACxD,IAAI;QACFA,qCAAqC5B,WAAWuB;IAClD,EAAE,OAAM;IACN,2EAA2E;IAC7E;IAEA,IAAI,CAACK,sCAAsC,CAACF,yCAAyC;QACnFjB,OAAOY,KAAK,CACVtB,OAAO,CAAC;;QAEN,EAAEwB,gCAAgC;IACtC,CAAC,EACC;YAACD,MAAM;QAAC;QAEV,OAAO;YAACV;QAAsB;IAChC;IAEA,mFAAmF;IACnF,6EAA6E;IAC7E,EAAE;IACF,sFAAsF;IACtF,mFAAmF;IACnF,4BAA4B;IAC5B,IACE,CAACc,2CACDG,kBAAkBN,oCAClB,CAACtB,UAAU2B,oCAAqCR,qCAChD;QACAX,OAAOqB,IAAI,CAAC/B,OAAO,CAAC;6CACqB,EAAEwB,gCAAgC;6DAClB,EAAEH,mCAAmC;;IAE9F,CAAC;IACH;IAEA,qEAAqE;IACrE,IAAI,CAACN,kCAAkC;QACrCL,OAAOY,KAAK,CACVtB,OAAO,CAAC;;;IAGV,CAAC,EACC;YAACuB,MAAM;QAAC;QAEV,OAAO;YAACV;QAAsB;IAChC;IAEA,sFAAsF;IACtF,iFAAiF;IACjF,IAAI,CAACX,UAAUa,kCAAkCM,qCAAqC;QACpFX,OAAOqB,IAAI,CAAC/B,OAAO,CAAC;8CACsB,EAAEe,iCAAiC;6DACpB,EAAEM,mCAAmC;;IAE9F,CAAC;IACH;IAEA,OAAO;QAACR;IAAsB;AAChC;AAEA,SAASiB,kBAAkBE,KAAa;IACtC,OAAO,8BAA8BC,IAAI,CAACD;AAC5C"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
const MODULES_HOST = process.env.SANITY_MODULES_HOST || (process.env.SANITY_INTERNAL_ENV === 'staging' ? 'https://sanity-cdn.work' : 'https://sanity-cdn.com');
|
|
2
|
+
function currentUnixTime() {
|
|
3
|
+
return Math.floor(Date.now() / 1000);
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* @internal
|
|
7
|
+
*/ export function getAutoUpdatesImportMap(packages, options = {}) {
|
|
8
|
+
return Object.fromEntries(packages.flatMap((pkg)=>getAppAutoUpdateImportMapForPackage(pkg, options)));
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* @internal
|
|
12
|
+
*/ function getAppAutoUpdateImportMapForPackage(pkg, options = {}) {
|
|
13
|
+
const moduleUrl = getModuleUrl(pkg, options);
|
|
14
|
+
return [
|
|
15
|
+
[
|
|
16
|
+
pkg.name,
|
|
17
|
+
moduleUrl
|
|
18
|
+
],
|
|
19
|
+
[
|
|
20
|
+
`${pkg.name}/`,
|
|
21
|
+
`${moduleUrl}/`
|
|
22
|
+
]
|
|
23
|
+
];
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* @internal
|
|
27
|
+
*/ export function getModuleUrl(pkg, options = {}) {
|
|
28
|
+
const { timestamp = currentUnixTime() } = options;
|
|
29
|
+
return options.appId ? getByAppModuleUrl(pkg, {
|
|
30
|
+
appId: options.appId,
|
|
31
|
+
baseUrl: options.baseUrl,
|
|
32
|
+
timestamp
|
|
33
|
+
}) : getLegacyModuleUrl(pkg, {
|
|
34
|
+
baseUrl: options.baseUrl,
|
|
35
|
+
timestamp
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
function getLegacyModuleUrl(pkg, options) {
|
|
39
|
+
const encodedMinVer = encodeURIComponent(`^${pkg.version}`);
|
|
40
|
+
return `${options.baseUrl || MODULES_HOST}/v1/modules/${rewriteScopedPackage(pkg.name)}/default/${encodedMinVer}/t${options.timestamp}`;
|
|
41
|
+
}
|
|
42
|
+
function getByAppModuleUrl(pkg, options) {
|
|
43
|
+
const encodedMinVer = encodeURIComponent(`^${pkg.version}`);
|
|
44
|
+
return `${options.baseUrl || MODULES_HOST}/v1/modules/by-app/${options.appId}/t${options.timestamp}/${encodedMinVer}/${rewriteScopedPackage(pkg.name)}`;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* replaces '/' with '__' similar to how eg `@types/scope__pkg` are rewritten
|
|
48
|
+
* scoped packages are stored this way both in the manifest and in the cloud storage bucket
|
|
49
|
+
*/ function rewriteScopedPackage(pkgName) {
|
|
50
|
+
if (!pkgName.includes('@')) {
|
|
51
|
+
return pkgName;
|
|
52
|
+
}
|
|
53
|
+
const [scope, ...pkg] = pkgName.split('/');
|
|
54
|
+
return `${scope}__${pkg.join('')}`;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Generate CDN CSS URLs for auto-updated packages.
|
|
58
|
+
* Uses the same URL pattern as JS module URLs so the module server
|
|
59
|
+
* resolves CSS and JS to the same version.
|
|
60
|
+
*
|
|
61
|
+
* @internal
|
|
62
|
+
*/ export function getAutoUpdatesCssUrls(packages, options = {}) {
|
|
63
|
+
return packages.filter((pkg)=>Boolean(pkg.cssFile)).map((pkg)=>`${getModuleUrl(pkg, options)}/${pkg.cssFile}`);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
//# sourceMappingURL=getAutoUpdatesImportMap.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/actions/build/getAutoUpdatesImportMap.ts"],"sourcesContent":["const MODULES_HOST =\n process.env.SANITY_MODULES_HOST ||\n (process.env.SANITY_INTERNAL_ENV === 'staging'\n ? 'https://sanity-cdn.work'\n : 'https://sanity-cdn.com')\n\nfunction currentUnixTime(): number {\n return Math.floor(Date.now() / 1000)\n}\n\ntype Package = {name: string; version: string}\n/**\n * @internal\n */\nexport function getAutoUpdatesImportMap<const Pkg extends Package>(\n packages: Pkg[],\n options: {appId?: string; baseUrl?: string; timestamp?: number} = {},\n) {\n return Object.fromEntries(\n packages.flatMap((pkg) => getAppAutoUpdateImportMapForPackage(pkg, options)),\n ) as {[K in `${Pkg['name']}/` | Pkg['name']]: string}\n}\n\n/**\n * @internal\n */\nfunction getAppAutoUpdateImportMapForPackage<const Pkg extends Package>(\n pkg: Pkg,\n options: {appId?: string; baseUrl?: string; timestamp?: number} = {},\n): [[Pkg['name'], string], [`${Pkg['name']}/`, string]] {\n const moduleUrl = getModuleUrl(pkg, options)\n\n return [\n [pkg.name, moduleUrl],\n [`${pkg.name}/`, `${moduleUrl}/`],\n ]\n}\n\n/**\n * @internal\n */\nexport function getModuleUrl(\n pkg: Package,\n options: {appId?: string; baseUrl?: string; timestamp?: number} = {},\n) {\n const {timestamp = currentUnixTime()} = options\n return options.appId\n ? getByAppModuleUrl(pkg, {appId: options.appId, baseUrl: options.baseUrl, timestamp})\n : getLegacyModuleUrl(pkg, {baseUrl: options.baseUrl, timestamp})\n}\n\nfunction getLegacyModuleUrl(pkg: Package, options: {baseUrl?: string; timestamp: number}) {\n const encodedMinVer = encodeURIComponent(`^${pkg.version}`)\n return `${options.baseUrl || MODULES_HOST}/v1/modules/${rewriteScopedPackage(pkg.name)}/default/${encodedMinVer}/t${options.timestamp}`\n}\n\nfunction getByAppModuleUrl(\n pkg: Package,\n options: {appId: string; baseUrl?: string; timestamp: number},\n) {\n const encodedMinVer = encodeURIComponent(`^${pkg.version}`)\n return `${options.baseUrl || MODULES_HOST}/v1/modules/by-app/${options.appId}/t${options.timestamp}/${encodedMinVer}/${rewriteScopedPackage(pkg.name)}`\n}\n\n/**\n * replaces '/' with '__' similar to how eg `@types/scope__pkg` are rewritten\n * scoped packages are stored this way both in the manifest and in the cloud storage bucket\n */\nfunction rewriteScopedPackage(pkgName: string) {\n if (!pkgName.includes('@')) {\n return pkgName\n }\n const [scope, ...pkg] = pkgName.split('/')\n return `${scope}__${pkg.join('')}`\n}\n\ntype PackageWithCss = Package & {cssFile?: string}\n\n/**\n * Generate CDN CSS URLs for auto-updated packages.\n * Uses the same URL pattern as JS module URLs so the module server\n * resolves CSS and JS to the same version.\n *\n * @internal\n */\nexport function getAutoUpdatesCssUrls<const Pkg extends PackageWithCss>(\n packages: Pkg[],\n options: {appId?: string; baseUrl?: string; timestamp?: number} = {},\n): string[] {\n return packages\n .filter((pkg) => Boolean(pkg.cssFile))\n .map((pkg) => `${getModuleUrl(pkg, options)}/${pkg.cssFile}`)\n}\n"],"names":["MODULES_HOST","process","env","SANITY_MODULES_HOST","SANITY_INTERNAL_ENV","currentUnixTime","Math","floor","Date","now","getAutoUpdatesImportMap","packages","options","Object","fromEntries","flatMap","pkg","getAppAutoUpdateImportMapForPackage","moduleUrl","getModuleUrl","name","timestamp","appId","getByAppModuleUrl","baseUrl","getLegacyModuleUrl","encodedMinVer","encodeURIComponent","version","rewriteScopedPackage","pkgName","includes","scope","split","join","getAutoUpdatesCssUrls","filter","Boolean","cssFile","map"],"mappings":"AAAA,MAAMA,eACJC,QAAQC,GAAG,CAACC,mBAAmB,IAC9BF,CAAAA,QAAQC,GAAG,CAACE,mBAAmB,KAAK,YACjC,4BACA,wBAAuB;AAE7B,SAASC;IACP,OAAOC,KAAKC,KAAK,CAACC,KAAKC,GAAG,KAAK;AACjC;AAGA;;CAEC,GACD,OAAO,SAASC,wBACdC,QAAe,EACfC,UAAkE,CAAC,CAAC;IAEpE,OAAOC,OAAOC,WAAW,CACvBH,SAASI,OAAO,CAAC,CAACC,MAAQC,oCAAoCD,KAAKJ;AAEvE;AAEA;;CAEC,GACD,SAASK,oCACPD,GAAQ,EACRJ,UAAkE,CAAC,CAAC;IAEpE,MAAMM,YAAYC,aAAaH,KAAKJ;IAEpC,OAAO;QACL;YAACI,IAAII,IAAI;YAAEF;SAAU;QACrB;YAAC,GAAGF,IAAII,IAAI,CAAC,CAAC,CAAC;YAAE,GAAGF,UAAU,CAAC,CAAC;SAAC;KAClC;AACH;AAEA;;CAEC,GACD,OAAO,SAASC,aACdH,GAAY,EACZJ,UAAkE,CAAC,CAAC;IAEpE,MAAM,EAACS,YAAYhB,iBAAiB,EAAC,GAAGO;IACxC,OAAOA,QAAQU,KAAK,GAChBC,kBAAkBP,KAAK;QAACM,OAAOV,QAAQU,KAAK;QAAEE,SAASZ,QAAQY,OAAO;QAAEH;IAAS,KACjFI,mBAAmBT,KAAK;QAACQ,SAASZ,QAAQY,OAAO;QAAEH;IAAS;AAClE;AAEA,SAASI,mBAAmBT,GAAY,EAAEJ,OAA8C;IACtF,MAAMc,gBAAgBC,mBAAmB,CAAC,CAAC,EAAEX,IAAIY,OAAO,EAAE;IAC1D,OAAO,GAAGhB,QAAQY,OAAO,IAAIxB,aAAa,YAAY,EAAE6B,qBAAqBb,IAAII,IAAI,EAAE,SAAS,EAAEM,cAAc,EAAE,EAAEd,QAAQS,SAAS,EAAE;AACzI;AAEA,SAASE,kBACPP,GAAY,EACZJ,OAA6D;IAE7D,MAAMc,gBAAgBC,mBAAmB,CAAC,CAAC,EAAEX,IAAIY,OAAO,EAAE;IAC1D,OAAO,GAAGhB,QAAQY,OAAO,IAAIxB,aAAa,mBAAmB,EAAEY,QAAQU,KAAK,CAAC,EAAE,EAAEV,QAAQS,SAAS,CAAC,CAAC,EAAEK,cAAc,CAAC,EAAEG,qBAAqBb,IAAII,IAAI,GAAG;AACzJ;AAEA;;;CAGC,GACD,SAASS,qBAAqBC,OAAe;IAC3C,IAAI,CAACA,QAAQC,QAAQ,CAAC,MAAM;QAC1B,OAAOD;IACT;IACA,MAAM,CAACE,OAAO,GAAGhB,IAAI,GAAGc,QAAQG,KAAK,CAAC;IACtC,OAAO,GAAGD,MAAM,EAAE,EAAEhB,IAAIkB,IAAI,CAAC,KAAK;AACpC;AAIA;;;;;;CAMC,GACD,OAAO,SAASC,sBACdxB,QAAe,EACfC,UAAkE,CAAC,CAAC;IAEpE,OAAOD,SACJyB,MAAM,CAAC,CAACpB,MAAQqB,QAAQrB,IAAIsB,OAAO,GACnCC,GAAG,CAAC,CAACvB,MAAQ,GAAGG,aAAaH,KAAKJ,SAAS,CAAC,EAAEI,IAAIsB,OAAO,EAAE;AAChE"}
|
|
@@ -34,10 +34,21 @@ const root = createRoot(document.getElementById('root'))
|
|
|
34
34
|
const element = createElement(App)
|
|
35
35
|
root.render(element)
|
|
36
36
|
`;
|
|
37
|
+
// A branded app with no \`entry\` (sanity-io/workbench spec 002-workbench-extension-api, US5) has no navigable app view, so there's no
|
|
38
|
+
// \`App\` to import or render standalone — it contributes panels/services to the
|
|
39
|
+
// workbench instead. The page stays valid (no broken import) for the dev server.
|
|
40
|
+
const noAppViewEntryModule = `
|
|
41
|
+
// This file is auto-generated on 'sanity dev'
|
|
42
|
+
// Modifications to this file is automatically discarded
|
|
43
|
+
const root = document.getElementById('root')
|
|
44
|
+
if (root) {
|
|
45
|
+
root.textContent = 'This application has no app view.'
|
|
46
|
+
}
|
|
47
|
+
`;
|
|
37
48
|
export function getEntryModule(options) {
|
|
38
49
|
const { basePath, entry, isApp, reactStrictMode, relativeConfigLocation } = options;
|
|
39
50
|
if (isApp) {
|
|
40
|
-
return appEntryModule.replace(/%ENTRY%/, JSON.stringify(entry
|
|
51
|
+
return entry ? appEntryModule.replace(/%ENTRY%/, JSON.stringify(entry)) : noAppViewEntryModule;
|
|
41
52
|
}
|
|
42
53
|
const sourceModule = relativeConfigLocation ? entryModule : noConfigEntryModule;
|
|
43
54
|
return sourceModule.replace(/%STUDIO_REACT_STRICT_MODE%/, reactStrictMode === undefined ? 'undefined' : JSON.stringify(reactStrictMode)).replace(/%STUDIO_CONFIG_LOCATION%/, JSON.stringify(relativeConfigLocation)).replace(/%STUDIO_BASE_PATH%/, JSON.stringify(basePath || '/'));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/actions/build/getEntryModule.ts"],"sourcesContent":["const entryModule = `\n// This file is auto-generated on 'sanity dev'\n// Modifications to this file is automatically discarded\nimport {renderStudio} from \"sanity\"\nimport studioConfig from %STUDIO_CONFIG_LOCATION%\n\nrenderStudio(\n document.getElementById(\"sanity\"),\n studioConfig,\n {reactStrictMode: %STUDIO_REACT_STRICT_MODE%, basePath: %STUDIO_BASE_PATH%}\n)\n`\n\nconst noConfigEntryModule = `\n// This file is auto-generated on 'sanity dev'\n// Modifications to this file is automatically discarded\nimport {renderStudio} from \"sanity\"\n\nconst studioConfig = {missingConfigFile: true}\n\nrenderStudio(\n document.getElementById(\"sanity\"),\n studioConfig,\n {reactStrictMode: %STUDIO_REACT_STRICT_MODE%, basePath: %STUDIO_BASE_PATH%}\n)\n`\n\nconst appEntryModule = `\n// This file is auto-generated on 'sanity dev'\n// Modifications to this file is automatically discarded\nimport {createRoot} from 'react-dom/client'\nimport {createElement} from 'react'\nimport App from %ENTRY%\n\nconst root = createRoot(document.getElementById('root'))\nconst element = createElement(App)\nroot.render(element)\n`\n\nexport function getEntryModule(options: {\n basePath?: string\n entry?: string\n isApp?: boolean\n reactStrictMode: boolean | undefined\n relativeConfigLocation: string | null\n}): string {\n const {basePath, entry, isApp, reactStrictMode, relativeConfigLocation} = options\n\n if (isApp) {\n return appEntryModule.replace(/%ENTRY%/, JSON.stringify(entry
|
|
1
|
+
{"version":3,"sources":["../../../src/actions/build/getEntryModule.ts"],"sourcesContent":["const entryModule = `\n// This file is auto-generated on 'sanity dev'\n// Modifications to this file is automatically discarded\nimport {renderStudio} from \"sanity\"\nimport studioConfig from %STUDIO_CONFIG_LOCATION%\n\nrenderStudio(\n document.getElementById(\"sanity\"),\n studioConfig,\n {reactStrictMode: %STUDIO_REACT_STRICT_MODE%, basePath: %STUDIO_BASE_PATH%}\n)\n`\n\nconst noConfigEntryModule = `\n// This file is auto-generated on 'sanity dev'\n// Modifications to this file is automatically discarded\nimport {renderStudio} from \"sanity\"\n\nconst studioConfig = {missingConfigFile: true}\n\nrenderStudio(\n document.getElementById(\"sanity\"),\n studioConfig,\n {reactStrictMode: %STUDIO_REACT_STRICT_MODE%, basePath: %STUDIO_BASE_PATH%}\n)\n`\n\nconst appEntryModule = `\n// This file is auto-generated on 'sanity dev'\n// Modifications to this file is automatically discarded\nimport {createRoot} from 'react-dom/client'\nimport {createElement} from 'react'\nimport App from %ENTRY%\n\nconst root = createRoot(document.getElementById('root'))\nconst element = createElement(App)\nroot.render(element)\n`\n\n// A branded app with no \\`entry\\` (sanity-io/workbench spec 002-workbench-extension-api, US5) has no navigable app view, so there's no\n// \\`App\\` to import or render standalone — it contributes panels/services to the\n// workbench instead. The page stays valid (no broken import) for the dev server.\nconst noAppViewEntryModule = `\n// This file is auto-generated on 'sanity dev'\n// Modifications to this file is automatically discarded\nconst root = document.getElementById('root')\nif (root) {\n root.textContent = 'This application has no app view.'\n}\n`\n\nexport function getEntryModule(options: {\n basePath?: string\n entry?: string\n isApp?: boolean\n reactStrictMode: boolean | undefined\n relativeConfigLocation: string | null\n}): string {\n const {basePath, entry, isApp, reactStrictMode, relativeConfigLocation} = options\n\n if (isApp) {\n return entry ? appEntryModule.replace(/%ENTRY%/, JSON.stringify(entry)) : noAppViewEntryModule\n }\n\n const sourceModule = relativeConfigLocation ? entryModule : noConfigEntryModule\n\n return sourceModule\n .replace(\n /%STUDIO_REACT_STRICT_MODE%/,\n reactStrictMode === undefined ? 'undefined' : JSON.stringify(reactStrictMode),\n )\n .replace(/%STUDIO_CONFIG_LOCATION%/, JSON.stringify(relativeConfigLocation))\n .replace(/%STUDIO_BASE_PATH%/, JSON.stringify(basePath || '/'))\n}\n"],"names":["entryModule","noConfigEntryModule","appEntryModule","noAppViewEntryModule","getEntryModule","options","basePath","entry","isApp","reactStrictMode","relativeConfigLocation","replace","JSON","stringify","sourceModule","undefined"],"mappings":"AAAA,MAAMA,cAAc,CAAC;;;;;;;;;;;AAWrB,CAAC;AAED,MAAMC,sBAAsB,CAAC;;;;;;;;;;;;AAY7B,CAAC;AAED,MAAMC,iBAAiB,CAAC;;;;;;;;;;AAUxB,CAAC;AAED,uIAAuI;AACvI,iFAAiF;AACjF,iFAAiF;AACjF,MAAMC,uBAAuB,CAAC;;;;;;;AAO9B,CAAC;AAED,OAAO,SAASC,eAAeC,OAM9B;IACC,MAAM,EAACC,QAAQ,EAAEC,KAAK,EAAEC,KAAK,EAAEC,eAAe,EAAEC,sBAAsB,EAAC,GAAGL;IAE1E,IAAIG,OAAO;QACT,OAAOD,QAAQL,eAAeS,OAAO,CAAC,WAAWC,KAAKC,SAAS,CAACN,UAAUJ;IAC5E;IAEA,MAAMW,eAAeJ,yBAAyBV,cAAcC;IAE5D,OAAOa,aACJH,OAAO,CACN,8BACAF,oBAAoBM,YAAY,cAAcH,KAAKC,SAAS,CAACJ,kBAE9DE,OAAO,CAAC,4BAA4BC,KAAKC,SAAS,CAACH,yBACnDC,OAAO,CAAC,sBAAsBC,KAAKC,SAAS,CAACP,YAAY;AAC9D"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import path from 'node:path';
|
|
2
2
|
import babel from '@rolldown/plugin-babel';
|
|
3
3
|
import { findProjectRoot, getCliTelemetry } from '@sanity/cli-core';
|
|
4
|
+
import { workbenchVitePlugins } from '@sanity/workbench-cli/build';
|
|
4
5
|
import viteReact, { reactCompilerPreset } from '@vitejs/plugin-react';
|
|
5
6
|
import debug from 'debug';
|
|
6
7
|
import { esmExternalRequirePlugin, mergeConfig } from 'vite';
|
|
@@ -19,14 +20,35 @@ import { getDefaultFaviconsPath } from './writeFavicons.js';
|
|
|
19
20
|
*
|
|
20
21
|
* @internal Only meant for consumption inside of Sanity modules, do not depend on this externally
|
|
21
22
|
*/ export async function getViteConfig(options) {
|
|
22
|
-
const { additionalPlugins, autoUpdates, basePath: rawBasePath = '/', cwd, isApp, minify, mode, outputDir, reactCompiler, schemaExtraction, server, // default to `true` when `mode=development`
|
|
23
|
-
sourceMap = options.mode === 'development' } = options;
|
|
23
|
+
const { additionalPlugins, autoUpdates, basePath: rawBasePath = '/', cwd, entries, isApp, isWorkbenchApp, minify, mode, outputDir, reactCompiler, schemaExtraction, server, services, // default to `true` when `mode=development`
|
|
24
|
+
sourceMap = options.mode === 'development', views } = options;
|
|
24
25
|
const basePath = normalizeBasePath(rawBasePath);
|
|
25
26
|
const configPath = (await findProjectRoot(cwd)).path;
|
|
26
27
|
const customFaviconsPath = path.join(cwd, 'static');
|
|
27
28
|
const defaultFaviconsPath = await getDefaultFaviconsPath();
|
|
28
29
|
const staticPath = `${basePath}static`;
|
|
29
30
|
const envVars = options.getEnvironmentVariables();
|
|
31
|
+
const sharedPlugins = [
|
|
32
|
+
viteReact(),
|
|
33
|
+
...reactCompiler ? [
|
|
34
|
+
babel({
|
|
35
|
+
presets: [
|
|
36
|
+
reactCompilerPreset(reactCompiler)
|
|
37
|
+
]
|
|
38
|
+
})
|
|
39
|
+
] : [],
|
|
40
|
+
...schemaExtraction?.enabled ? [
|
|
41
|
+
sanitySchemaExtractionPlugin({
|
|
42
|
+
additionalPatterns: schemaExtraction.watchPatterns,
|
|
43
|
+
configPath,
|
|
44
|
+
enforceRequiredFields: schemaExtraction.enforceRequiredFields,
|
|
45
|
+
outputPath: schemaExtraction.path,
|
|
46
|
+
telemetryLogger: getCliTelemetry(),
|
|
47
|
+
workDir: cwd,
|
|
48
|
+
workspaceName: schemaExtraction.workspace
|
|
49
|
+
})
|
|
50
|
+
] : []
|
|
51
|
+
];
|
|
30
52
|
const viteConfig = {
|
|
31
53
|
base: basePath,
|
|
32
54
|
build: {
|
|
@@ -57,38 +79,34 @@ import { getDefaultFaviconsPath } from './writeFavicons.js';
|
|
|
57
79
|
logLevel: mode === 'production' ? 'silent' : 'info',
|
|
58
80
|
mode,
|
|
59
81
|
plugins: [
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
82
|
+
// Federation builds only need the federation plugin — skip client-specific
|
|
83
|
+
// plugins (favicons, runtime rewrite, build entries)
|
|
84
|
+
...isWorkbenchApp ? [
|
|
85
|
+
...sharedPlugins,
|
|
86
|
+
await workbenchVitePlugins({
|
|
87
|
+
cwd,
|
|
88
|
+
entries,
|
|
89
|
+
isApp,
|
|
90
|
+
services,
|
|
91
|
+
views
|
|
66
92
|
})
|
|
67
|
-
] : [
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
// Add schema extraction when enabled
|
|
81
|
-
...schemaExtraction?.enabled ? [
|
|
82
|
-
sanitySchemaExtractionPlugin({
|
|
83
|
-
additionalPatterns: schemaExtraction.watchPatterns,
|
|
84
|
-
configPath,
|
|
85
|
-
enforceRequiredFields: schemaExtraction.enforceRequiredFields,
|
|
86
|
-
outputPath: schemaExtraction.path,
|
|
87
|
-
telemetryLogger: getCliTelemetry(),
|
|
88
|
-
workDir: cwd,
|
|
89
|
-
workspaceName: schemaExtraction.workspace
|
|
93
|
+
] : [
|
|
94
|
+
...sharedPlugins,
|
|
95
|
+
sanityFaviconsPlugin({
|
|
96
|
+
customFaviconsPath,
|
|
97
|
+
defaultFaviconsPath,
|
|
98
|
+
staticUrlPath: staticPath
|
|
99
|
+
}),
|
|
100
|
+
sanityRuntimeRewritePlugin(),
|
|
101
|
+
sanityBuildEntries({
|
|
102
|
+
autoUpdates,
|
|
103
|
+
basePath,
|
|
104
|
+
cwd,
|
|
105
|
+
isApp
|
|
90
106
|
})
|
|
91
|
-
]
|
|
107
|
+
],
|
|
108
|
+
// Caller-provided plugins (e.g. typegen in dev) aren't client-specific,
|
|
109
|
+
// so they apply to federation builds too.
|
|
92
110
|
...additionalPlugins || []
|
|
93
111
|
],
|
|
94
112
|
resolve: {
|
|
@@ -105,9 +123,10 @@ import { getDefaultFaviconsPath } from './writeFavicons.js';
|
|
|
105
123
|
server: {
|
|
106
124
|
host: server?.host,
|
|
107
125
|
port: server?.port || 3333,
|
|
108
|
-
//
|
|
109
|
-
//
|
|
110
|
-
|
|
126
|
+
// Apps drift to a free port (the reported URL embeds whichever port was
|
|
127
|
+
// claimed), and workbench runs stack servers on adjacent ports — both
|
|
128
|
+
// need the fallback. Studios fail fast on a busy port.
|
|
129
|
+
strictPort: !isApp && !isWorkbenchApp,
|
|
111
130
|
/**
|
|
112
131
|
* Significantly speed up startup time,
|
|
113
132
|
* and most importantly eliminates the `new dependencies optimized: foobar. optimized dependencies changed. reloading`
|
|
@@ -121,7 +140,9 @@ import { getDefaultFaviconsPath } from './writeFavicons.js';
|
|
|
121
140
|
}
|
|
122
141
|
}
|
|
123
142
|
};
|
|
124
|
-
|
|
143
|
+
// Federation builds don't produce a client bundle — the federation
|
|
144
|
+
// plugin configures its own environment and build entry point.
|
|
145
|
+
if (mode === 'production' && !isWorkbenchApp) {
|
|
125
146
|
if (autoUpdates) {
|
|
126
147
|
viteConfig.plugins.push(// Re-expose CommonJS named exports (react, react-dom) as real ESM exports
|
|
127
148
|
// on the emitted vendor chunks; Rolldown only emits `export default` for a
|
|
@@ -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 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 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 {\n /**\n * Root path of the studio/sanity app\n */\n cwd: string\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 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 /**\n * Schema extraction configuration\n */\n schemaExtraction?: CliConfig['schemaExtraction']\n /**\n * HTTP development server configuration\n */\n server?: {host?: string; port?: number}\n /**\n * Whether or not to enable source maps\n */\n sourceMap?: boolean\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 isApp,\n minify,\n mode,\n outputDir,\n reactCompiler,\n schemaExtraction,\n server,\n // default to `true` when `mode=development`\n sourceMap = options.mode === 'development',\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 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 viteReact(),\n ...(reactCompiler ? [babel({presets: [reactCompilerPreset(reactCompiler)]})] : []),\n sanityFaviconsPlugin({customFaviconsPath, defaultFaviconsPath, staticUrlPath: staticPath}),\n sanityRuntimeRewritePlugin(),\n sanityBuildEntries({autoUpdates, basePath, cwd, isApp}),\n // Add schema extraction when enabled\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 ...(additionalPlugins || []),\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 // Only enable strict port for studio,\n // since apps can run on any port\n strictPort: isApp ? false : true,\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 if (mode === 'production') {\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","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","isApp","minify","mode","outputDir","reactCompiler","schemaExtraction","server","sourceMap","configPath","customFaviconsPath","join","defaultFaviconsPath","staticPath","envVars","getEnvironmentVariables","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","presets","staticUrlPath","enabled","additionalPatterns","watchPatterns","enforceRequiredFields","outputPath","telemetryLogger","workDir","workspaceName","workspace","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","entries","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":"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"}
|
|
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 type UserViteConfig,\n} from '@sanity/cli-core'\nimport {type DefineAppInput} from '@sanity/workbench-cli'\nimport {workbenchVitePlugins} from '@sanity/workbench-cli/build'\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 {\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.\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 /**\n * Schema extraction configuration\n */\n schemaExtraction?: CliConfig['schemaExtraction']\n\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?: DefineAppInput['services']\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?: DefineAppInput['views']\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 ? [...sharedPlugins, await workbenchVitePlugins({cwd, entries, isApp, services, views})]\n : [\n ...sharedPlugins,\n sanityFaviconsPlugin({\n customFaviconsPath,\n defaultFaviconsPath,\n staticUrlPath: staticPath,\n }),\n sanityRuntimeRewritePlugin(),\n sanityBuildEntries({autoUpdates, basePath, cwd, isApp}),\n ]),\n // Caller-provided plugins (e.g. typegen in dev) aren't client-specific,\n // so they apply to federation builds too.\n ...(additionalPlugins || []),\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","workbenchVitePlugins","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","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":"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"}
|
|
@@ -23,7 +23,7 @@ import { parse as parseHtml } from 'node-html-parser';
|
|
|
23
23
|
function replaceTimestamp(urlStr) {
|
|
24
24
|
try {
|
|
25
25
|
const url = new URL(urlStr);
|
|
26
|
-
if (
|
|
26
|
+
if (isSanityCdnUrl(urlStr)) {
|
|
27
27
|
url.pathname = url.pathname.replace(/\\/t\\d+/, newTimestamp);
|
|
28
28
|
}
|
|
29
29
|
return url.toString();
|
|
@@ -32,6 +32,14 @@ import { parse as parseHtml } from 'node-html-parser';
|
|
|
32
32
|
}
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
+
function isSanityCdnUrl(urlStr) {
|
|
36
|
+
try {
|
|
37
|
+
return /^sanity-cdn\\.[a-zA-Z]+$/.test(new URL(urlStr).hostname);
|
|
38
|
+
} catch {
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
35
43
|
importMapEl.textContent = JSON.stringify({
|
|
36
44
|
imports: Object.fromEntries(
|
|
37
45
|
Object.entries(imports).map(([specifier, path]) => [specifier, replaceTimestamp(path)])
|
|
@@ -47,6 +55,34 @@ import { parse as parseHtml } from 'node-html-parser';
|
|
|
47
55
|
linkEl.href = replaceTimestamp(cssUrl);
|
|
48
56
|
document.head.appendChild(linkEl);
|
|
49
57
|
}
|
|
58
|
+
|
|
59
|
+
// Warm the CDN module connection during head parse so the cross-origin
|
|
60
|
+
// \`sanity\` fetch can start before the entry script discovers the import.
|
|
61
|
+
const firstCdnImport = Object.values(imports).find(isSanityCdnUrl);
|
|
62
|
+
|
|
63
|
+
if (firstCdnImport) {
|
|
64
|
+
const preconnectEl = document.createElement('link');
|
|
65
|
+
preconnectEl.rel = 'preconnect';
|
|
66
|
+
preconnectEl.href = new URL(firstCdnImport).origin;
|
|
67
|
+
// Module fetches are CORS; without crossorigin the warmed socket is not reused.
|
|
68
|
+
preconnectEl.crossOrigin = 'anonymous';
|
|
69
|
+
document.head.appendChild(preconnectEl);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Start downloading the timestamped \`sanity\` module during head parse. The
|
|
73
|
+
// href reuses replaceTimestamp so it matches the importmap entry exactly —
|
|
74
|
+
// a stale timestamp here would double-fetch the largest chunk.
|
|
75
|
+
const sanityModuleUrl = imports['sanity'];
|
|
76
|
+
if (typeof sanityModuleUrl === 'string' && isSanityCdnUrl(sanityModuleUrl)) {
|
|
77
|
+
const preloadEl = document.createElement('link');
|
|
78
|
+
preloadEl.rel = 'modulepreload';
|
|
79
|
+
preloadEl.href = replaceTimestamp(sanityModuleUrl);
|
|
80
|
+
// Must match the preconnect's credentials mode, otherwise the browser
|
|
81
|
+
// treats them as separate connections and the warmed cross-origin socket
|
|
82
|
+
// is not reused for this fetch.
|
|
83
|
+
preloadEl.crossOrigin = 'anonymous';
|
|
84
|
+
document.head.appendChild(preloadEl);
|
|
85
|
+
}
|
|
50
86
|
</script>`;
|
|
51
87
|
/**
|
|
52
88
|
* @internal
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/actions/build/renderDocumentWorker/addTimestampImportMapScriptToHtml.ts"],"sourcesContent":["import {parse as parseHtml} from 'node-html-parser'\n\n/**\n * This script takes the import map from the `#__imports` script tag,\n * modifies relevant URLs that match the sanity-cdn hostname by replacing\n * the existing timestamp in the sanity-cdn URLs with a new runtime timestamp,\n * and injects the modified import map back into the HTML.\n *\n * It also synchronously creates `<link rel=\"stylesheet\">` tags for each CDN\n * CSS URL with a fresh timestamp.\n *\n * This will be injected into the HTML of the user's bundle.\n *\n * Note that this is in a separate constants file to prevent \"Cannot access\n * before initialization\" errors.\n */\nconst TIMESTAMPED_IMPORTMAP_INJECTOR_SCRIPT = `<script>\n // auto-generated script to add import map with timestamp\n const importsJson = document.getElementById('__imports')?.textContent;\n const { imports = {}, css = [], ...rest } = importsJson ? JSON.parse(importsJson) : {};\n const importMapEl = document.createElement('script');\n importMapEl.type = 'importmap';\n const newTimestamp = \\`/t\\${Math.floor(Date.now() / 1000)}\\`;\n\n function replaceTimestamp(urlStr) {\n try {\n const url = new URL(urlStr);\n if (
|
|
1
|
+
{"version":3,"sources":["../../../../src/actions/build/renderDocumentWorker/addTimestampImportMapScriptToHtml.ts"],"sourcesContent":["import {parse as parseHtml} from 'node-html-parser'\n\n/**\n * This script takes the import map from the `#__imports` script tag,\n * modifies relevant URLs that match the sanity-cdn hostname by replacing\n * the existing timestamp in the sanity-cdn URLs with a new runtime timestamp,\n * and injects the modified import map back into the HTML.\n *\n * It also synchronously creates `<link rel=\"stylesheet\">` tags for each CDN\n * CSS URL with a fresh timestamp.\n *\n * This will be injected into the HTML of the user's bundle.\n *\n * Note that this is in a separate constants file to prevent \"Cannot access\n * before initialization\" errors.\n */\nconst TIMESTAMPED_IMPORTMAP_INJECTOR_SCRIPT = `<script>\n // auto-generated script to add import map with timestamp\n const importsJson = document.getElementById('__imports')?.textContent;\n const { imports = {}, css = [], ...rest } = importsJson ? JSON.parse(importsJson) : {};\n const importMapEl = document.createElement('script');\n importMapEl.type = 'importmap';\n const newTimestamp = \\`/t\\${Math.floor(Date.now() / 1000)}\\`;\n\n function replaceTimestamp(urlStr) {\n try {\n const url = new URL(urlStr);\n if (isSanityCdnUrl(urlStr)) {\n url.pathname = url.pathname.replace(/\\\\/t\\\\d+/, newTimestamp);\n }\n return url.toString();\n } catch {\n return urlStr;\n }\n }\n\n function isSanityCdnUrl(urlStr) {\n try {\n return /^sanity-cdn\\\\.[a-zA-Z]+$/.test(new URL(urlStr).hostname);\n } catch {\n return false;\n }\n }\n\n importMapEl.textContent = JSON.stringify({\n imports: Object.fromEntries(\n Object.entries(imports).map(([specifier, path]) => [specifier, replaceTimestamp(path)])\n ),\n ...rest,\n });\n document.head.appendChild(importMapEl);\n\n // Creates <link rel=\"stylesheet\"> tags with fresh timestamps.\n for (const cssUrl of css) {\n const linkEl = document.createElement('link');\n linkEl.rel = 'stylesheet';\n linkEl.href = replaceTimestamp(cssUrl);\n document.head.appendChild(linkEl);\n }\n\n // Warm the CDN module connection during head parse so the cross-origin\n // \\`sanity\\` fetch can start before the entry script discovers the import.\n const firstCdnImport = Object.values(imports).find(isSanityCdnUrl);\n\n if (firstCdnImport) {\n const preconnectEl = document.createElement('link');\n preconnectEl.rel = 'preconnect';\n preconnectEl.href = new URL(firstCdnImport).origin;\n // Module fetches are CORS; without crossorigin the warmed socket is not reused.\n preconnectEl.crossOrigin = 'anonymous';\n document.head.appendChild(preconnectEl);\n }\n\n // Start downloading the timestamped \\`sanity\\` module during head parse. The\n // href reuses replaceTimestamp so it matches the importmap entry exactly —\n // a stale timestamp here would double-fetch the largest chunk.\n const sanityModuleUrl = imports['sanity'];\n if (typeof sanityModuleUrl === 'string' && isSanityCdnUrl(sanityModuleUrl)) {\n const preloadEl = document.createElement('link');\n preloadEl.rel = 'modulepreload';\n preloadEl.href = replaceTimestamp(sanityModuleUrl);\n // Must match the preconnect's credentials mode, otherwise the browser\n // treats them as separate connections and the warmed cross-origin socket\n // is not reused for this fetch.\n preloadEl.crossOrigin = 'anonymous';\n document.head.appendChild(preloadEl);\n }\n</script>`\n\n/**\n * @internal\n */\nexport function addTimestampedImportMapScriptToHtml(\n html: string,\n importMap?: {imports?: Record<string, string>},\n autoUpdatesCssUrls?: string[],\n): string {\n if (!importMap) return html\n\n let root = parseHtml(html)\n let htmlEl = root.querySelector('html')\n if (!htmlEl) {\n const oldRoot = root\n root = parseHtml('<html></html>')\n htmlEl = root.querySelector('html')!\n htmlEl.append(oldRoot)\n }\n\n let headEl = htmlEl.querySelector('head')\n\n if (!headEl) {\n htmlEl.insertAdjacentHTML('afterbegin', '<head></head>')\n headEl = root.querySelector('head')!\n }\n\n // Include CSS URLs in the __imports JSON so the runtime script can create\n // <link> tags with fresh timestamps synchronously during head parsing.\n const importMapWithCss =\n autoUpdatesCssUrls && autoUpdatesCssUrls.length > 0\n ? {...importMap, css: autoUpdatesCssUrls}\n : importMap\n\n headEl.insertAdjacentHTML(\n 'beforeend',\n `<script type=\"application/json\" id=\"__imports\">${JSON.stringify(importMapWithCss)}</script>`,\n )\n\n headEl.insertAdjacentHTML('beforeend', TIMESTAMPED_IMPORTMAP_INJECTOR_SCRIPT)\n return root.outerHTML\n}\n"],"names":["parse","parseHtml","TIMESTAMPED_IMPORTMAP_INJECTOR_SCRIPT","addTimestampedImportMapScriptToHtml","html","importMap","autoUpdatesCssUrls","root","htmlEl","querySelector","oldRoot","append","headEl","insertAdjacentHTML","importMapWithCss","length","css","JSON","stringify","outerHTML"],"mappings":"AAAA,SAAQA,SAASC,SAAS,QAAO,mBAAkB;AAEnD;;;;;;;;;;;;;CAaC,GACD,MAAMC,wCAAwC,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;SAuEtC,CAAC;AAEV;;CAEC,GACD,OAAO,SAASC,oCACdC,IAAY,EACZC,SAA8C,EAC9CC,kBAA6B;IAE7B,IAAI,CAACD,WAAW,OAAOD;IAEvB,IAAIG,OAAON,UAAUG;IACrB,IAAII,SAASD,KAAKE,aAAa,CAAC;IAChC,IAAI,CAACD,QAAQ;QACX,MAAME,UAAUH;QAChBA,OAAON,UAAU;QACjBO,SAASD,KAAKE,aAAa,CAAC;QAC5BD,OAAOG,MAAM,CAACD;IAChB;IAEA,IAAIE,SAASJ,OAAOC,aAAa,CAAC;IAElC,IAAI,CAACG,QAAQ;QACXJ,OAAOK,kBAAkB,CAAC,cAAc;QACxCD,SAASL,KAAKE,aAAa,CAAC;IAC9B;IAEA,0EAA0E;IAC1E,uEAAuE;IACvE,MAAMK,mBACJR,sBAAsBA,mBAAmBS,MAAM,GAAG,IAC9C;QAAC,GAAGV,SAAS;QAAEW,KAAKV;IAAkB,IACtCD;IAENO,OAAOC,kBAAkB,CACvB,aACA,CAAC,+CAA+C,EAAEI,KAAKC,SAAS,CAACJ,kBAAkB,SAAS,CAAC;IAG/FF,OAAOC,kBAAkB,CAAC,aAAaX;IACvC,OAAOK,KAAKY,SAAS;AACvB"}
|
|
@@ -17,7 +17,7 @@ import { renderDocument } from './renderDocument.js';
|
|
|
17
17
|
* @returns A watcher instance if watch is enabled, undefined otherwise
|
|
18
18
|
* @internal
|
|
19
19
|
*/ export async function writeSanityRuntime(options) {
|
|
20
|
-
const { appTitle, basePath, cwd, entry, isApp, reactStrictMode, watch } = options;
|
|
20
|
+
const { appTitle, basePath, cwd, entry, isApp, isWorkbenchApp, reactStrictMode, watch } = options;
|
|
21
21
|
const runtimeDir = path.join(cwd, '.sanity', 'runtime');
|
|
22
22
|
buildDebug('Making runtime directory');
|
|
23
23
|
await fs.mkdir(runtimeDir, {
|
|
@@ -43,21 +43,52 @@ import { renderDocument } from './renderDocument.js';
|
|
|
43
43
|
}
|
|
44
44
|
await renderAndWriteDocument();
|
|
45
45
|
buildDebug('Writing app.js to runtime directory');
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
46
|
+
const { relativeConfigLocation, relativeEntry } = await resolveEntries({
|
|
47
|
+
cwd,
|
|
48
|
+
entry,
|
|
49
|
+
isApp,
|
|
50
|
+
isWorkbenchApp,
|
|
51
|
+
runtimeDir
|
|
52
|
+
});
|
|
52
53
|
const appJsContent = getEntryModule({
|
|
53
54
|
basePath,
|
|
54
|
-
entry: relativeEntry,
|
|
55
|
+
entry: relativeEntry ?? undefined,
|
|
55
56
|
isApp,
|
|
56
57
|
reactStrictMode,
|
|
57
58
|
relativeConfigLocation
|
|
58
59
|
});
|
|
59
60
|
await fs.writeFile(path.join(runtimeDir, 'app.js'), appJsContent);
|
|
60
|
-
return
|
|
61
|
+
return {
|
|
62
|
+
entries: {
|
|
63
|
+
relativeConfigLocation,
|
|
64
|
+
relativeEntry
|
|
65
|
+
},
|
|
66
|
+
watcher
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Resolves the relative entry paths for a Sanity project without writing any
|
|
71
|
+
* runtime files to disk. Used by federation builds that skip the full runtime
|
|
72
|
+
* generation but still need entry metadata for the vite plugin.
|
|
73
|
+
*/ export async function resolveEntries(options) {
|
|
74
|
+
const { cwd, entry, isApp, isWorkbenchApp } = options;
|
|
75
|
+
const runtimeDir = options.runtimeDir ?? path.join(cwd, '.sanity', 'runtime');
|
|
76
|
+
let relativeConfigLocation = null;
|
|
77
|
+
if (!isApp) {
|
|
78
|
+
const studioConfigPath = await tryFindStudioConfigPath(cwd);
|
|
79
|
+
relativeConfigLocation = studioConfigPath ? toForwardSlashes(path.relative(runtimeDir, studioConfigPath)) : null;
|
|
80
|
+
}
|
|
81
|
+
// Only a *branded* app (`unstable_defineApp`) that declares no `entry` has no
|
|
82
|
+
// navigable app view (sanity-io/workbench spec 002-workbench-extension-api,
|
|
83
|
+
// US5): `null` entry tells the runtime/federation to skip the `./App` render
|
|
84
|
+
// path. Non-branded (legacy SDK) apps keep the historical `./src/App` default,
|
|
85
|
+
// and studios ignore `relativeEntry` — so gating on `isApp` here would regress
|
|
86
|
+
// non-opted-in apps to the dock-only stub.
|
|
87
|
+
const relativeEntry = isWorkbenchApp && !entry ? null : toForwardSlashes(path.relative(runtimeDir, path.resolve(cwd, entry || './src/App')));
|
|
88
|
+
return {
|
|
89
|
+
relativeConfigLocation,
|
|
90
|
+
relativeEntry
|
|
91
|
+
};
|
|
61
92
|
}
|
|
62
93
|
function toForwardSlashes(filePath) {
|
|
63
94
|
return filePath.replaceAll('\\', '/');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/actions/build/writeSanityRuntime.ts"],"sourcesContent":["import fs from 'node:fs/promises'\nimport path from 'node:path'\n\nimport {tryFindStudioConfigPath} from '@sanity/cli-core'\nimport {watch as chokidarWatch, type FSWatcher} from 'chokidar'\n\nimport {buildDebug} from './buildDebug.js'\nimport {decorateIndexWithAutoGeneratedWarning} from './decorateIndexWithAutoGeneratedWarning.js'\nimport {decorateIndexWithBridgeScript} from './decorateIndexWithBridgeScript.js'\nimport {decorateIndexWithStagingScript} from './decorateIndexWithStagingScript.js'\nimport {getEntryModule} from './getEntryModule.js'\nimport {getPossibleDocumentComponentLocations} from './getPossibleDocumentComponentLocations.js'\nimport {renderDocument} from './renderDocument.js'\n\ninterface RuntimeOptions {\n cwd: string\n reactStrictMode: boolean | undefined\n watch: boolean\n\n appTitle?: string\n basePath?: string\n entry?: string\n isApp?: boolean\n}\n\n/**\n * Generates the `.sanity/runtime` directory, and optionally watches for custom\n * document files, rebuilding when they change\n *\n * @param options - Current working directory (Sanity root dir), and whether or not to watch\n * @returns A watcher instance if watch is enabled, undefined otherwise\n * @internal\n */\nexport async function writeSanityRuntime(options: RuntimeOptions): Promise<FSWatcher | undefined> {\n const {appTitle, basePath, cwd, entry, isApp, reactStrictMode, watch} = options\n const runtimeDir = path.join(cwd, '.sanity', 'runtime')\n\n buildDebug('Making runtime directory')\n await fs.mkdir(runtimeDir, {recursive: true})\n\n async function renderAndWriteDocument() {\n buildDebug('Rendering document template')\n const indexHtml = decorateIndexWithStagingScript(\n decorateIndexWithBridgeScript(\n decorateIndexWithAutoGeneratedWarning(\n await renderDocument({\n isApp,\n props: {\n basePath: basePath || '/',\n entryPath: `/${toForwardSlashes(path.relative(cwd, path.join(runtimeDir, 'app.js')))}`,\n title: appTitle,\n },\n studioRootPath: cwd,\n }),\n ),\n ),\n )\n\n buildDebug('Writing index.html to runtime directory')\n await fs.writeFile(path.join(runtimeDir, 'index.html'), indexHtml)\n }\n\n let watcher: FSWatcher | undefined\n\n if (watch) {\n watcher = chokidarWatch(getPossibleDocumentComponentLocations(cwd)).on('all', () =>\n renderAndWriteDocument(),\n )\n }\n\n await renderAndWriteDocument()\n\n buildDebug('Writing app.js to runtime directory')\n let relativeConfigLocation: string | null = null\n if (!isApp) {\n const studioConfigPath = await tryFindStudioConfigPath(cwd)\n relativeConfigLocation = studioConfigPath\n ? toForwardSlashes(path.relative(runtimeDir, studioConfigPath))\n : null\n }\n\n
|
|
1
|
+
{"version":3,"sources":["../../../src/actions/build/writeSanityRuntime.ts"],"sourcesContent":["import fs from 'node:fs/promises'\nimport path from 'node:path'\n\nimport {tryFindStudioConfigPath} from '@sanity/cli-core'\nimport {watch as chokidarWatch, type FSWatcher} from 'chokidar'\n\nimport {buildDebug} from './buildDebug.js'\nimport {decorateIndexWithAutoGeneratedWarning} from './decorateIndexWithAutoGeneratedWarning.js'\nimport {decorateIndexWithBridgeScript} from './decorateIndexWithBridgeScript.js'\nimport {decorateIndexWithStagingScript} from './decorateIndexWithStagingScript.js'\nimport {getEntryModule} from './getEntryModule.js'\nimport {getPossibleDocumentComponentLocations} from './getPossibleDocumentComponentLocations.js'\nimport {renderDocument} from './renderDocument.js'\n\ninterface RuntimeOptions {\n cwd: string\n reactStrictMode: boolean | undefined\n watch: boolean\n\n appTitle?: string\n basePath?: string\n entry?: string\n isApp?: boolean\n isWorkbenchApp?: boolean\n}\n\n/**\n * Generates the `.sanity/runtime` directory, and optionally watches for custom\n * document files, rebuilding when they change\n *\n * @param options - Current working directory (Sanity root dir), and whether or not to watch\n * @returns A watcher instance if watch is enabled, undefined otherwise\n * @internal\n */\nexport async function writeSanityRuntime(options: RuntimeOptions): Promise<{\n entries: {relativeConfigLocation: string | null; relativeEntry: string | null}\n watcher: FSWatcher | undefined\n}> {\n const {appTitle, basePath, cwd, entry, isApp, isWorkbenchApp, reactStrictMode, watch} = options\n const runtimeDir = path.join(cwd, '.sanity', 'runtime')\n\n buildDebug('Making runtime directory')\n await fs.mkdir(runtimeDir, {recursive: true})\n\n async function renderAndWriteDocument() {\n buildDebug('Rendering document template')\n const indexHtml = decorateIndexWithStagingScript(\n decorateIndexWithBridgeScript(\n decorateIndexWithAutoGeneratedWarning(\n await renderDocument({\n isApp,\n props: {\n basePath: basePath || '/',\n entryPath: `/${toForwardSlashes(path.relative(cwd, path.join(runtimeDir, 'app.js')))}`,\n title: appTitle,\n },\n studioRootPath: cwd,\n }),\n ),\n ),\n )\n\n buildDebug('Writing index.html to runtime directory')\n await fs.writeFile(path.join(runtimeDir, 'index.html'), indexHtml)\n }\n\n let watcher: FSWatcher | undefined\n\n if (watch) {\n watcher = chokidarWatch(getPossibleDocumentComponentLocations(cwd)).on('all', () =>\n renderAndWriteDocument(),\n )\n }\n\n await renderAndWriteDocument()\n\n buildDebug('Writing app.js to runtime directory')\n const {relativeConfigLocation, relativeEntry} = await resolveEntries({\n cwd,\n entry,\n isApp,\n isWorkbenchApp,\n runtimeDir,\n })\n const appJsContent = getEntryModule({\n basePath,\n entry: relativeEntry ?? undefined,\n isApp,\n reactStrictMode,\n relativeConfigLocation,\n })\n await fs.writeFile(path.join(runtimeDir, 'app.js'), appJsContent)\n\n return {\n entries: {\n relativeConfigLocation,\n relativeEntry,\n },\n watcher,\n }\n}\n\n/**\n * Resolves the relative entry paths for a Sanity project without writing any\n * runtime files to disk. Used by federation builds that skip the full runtime\n * generation but still need entry metadata for the vite plugin.\n */\nexport async function resolveEntries(options: {\n cwd: string\n entry?: string\n isApp?: boolean\n isWorkbenchApp?: boolean\n runtimeDir?: string\n}): Promise<{relativeConfigLocation: string | null; relativeEntry: string | null}> {\n const {cwd, entry, isApp, isWorkbenchApp} = options\n const runtimeDir = options.runtimeDir ?? path.join(cwd, '.sanity', 'runtime')\n\n let relativeConfigLocation: string | null = null\n if (!isApp) {\n const studioConfigPath = await tryFindStudioConfigPath(cwd)\n relativeConfigLocation = studioConfigPath\n ? toForwardSlashes(path.relative(runtimeDir, studioConfigPath))\n : null\n }\n\n // Only a *branded* app (`unstable_defineApp`) that declares no `entry` has no\n // navigable app view (sanity-io/workbench spec 002-workbench-extension-api,\n // US5): `null` entry tells the runtime/federation to skip the `./App` render\n // path. Non-branded (legacy SDK) apps keep the historical `./src/App` default,\n // and studios ignore `relativeEntry` — so gating on `isApp` here would regress\n // non-opted-in apps to the dock-only stub.\n const relativeEntry =\n isWorkbenchApp && !entry\n ? null\n : toForwardSlashes(path.relative(runtimeDir, path.resolve(cwd, entry || './src/App')))\n\n return {relativeConfigLocation, relativeEntry}\n}\n\nfunction toForwardSlashes(filePath: string): string {\n return filePath.replaceAll('\\\\', '/')\n}\n"],"names":["fs","path","tryFindStudioConfigPath","watch","chokidarWatch","buildDebug","decorateIndexWithAutoGeneratedWarning","decorateIndexWithBridgeScript","decorateIndexWithStagingScript","getEntryModule","getPossibleDocumentComponentLocations","renderDocument","writeSanityRuntime","options","appTitle","basePath","cwd","entry","isApp","isWorkbenchApp","reactStrictMode","runtimeDir","join","mkdir","recursive","renderAndWriteDocument","indexHtml","props","entryPath","toForwardSlashes","relative","title","studioRootPath","writeFile","watcher","on","relativeConfigLocation","relativeEntry","resolveEntries","appJsContent","undefined","entries","studioConfigPath","resolve","filePath","replaceAll"],"mappings":"AAAA,OAAOA,QAAQ,mBAAkB;AACjC,OAAOC,UAAU,YAAW;AAE5B,SAAQC,uBAAuB,QAAO,mBAAkB;AACxD,SAAQC,SAASC,aAAa,QAAuB,WAAU;AAE/D,SAAQC,UAAU,QAAO,kBAAiB;AAC1C,SAAQC,qCAAqC,QAAO,6CAA4C;AAChG,SAAQC,6BAA6B,QAAO,qCAAoC;AAChF,SAAQC,8BAA8B,QAAO,sCAAqC;AAClF,SAAQC,cAAc,QAAO,sBAAqB;AAClD,SAAQC,qCAAqC,QAAO,6CAA4C;AAChG,SAAQC,cAAc,QAAO,sBAAqB;AAclD;;;;;;;CAOC,GACD,OAAO,eAAeC,mBAAmBC,OAAuB;IAI9D,MAAM,EAACC,QAAQ,EAAEC,QAAQ,EAAEC,GAAG,EAAEC,KAAK,EAAEC,KAAK,EAAEC,cAAc,EAAEC,eAAe,EAAEjB,KAAK,EAAC,GAAGU;IACxF,MAAMQ,aAAapB,KAAKqB,IAAI,CAACN,KAAK,WAAW;IAE7CX,WAAW;IACX,MAAML,GAAGuB,KAAK,CAACF,YAAY;QAACG,WAAW;IAAI;IAE3C,eAAeC;QACbpB,WAAW;QACX,MAAMqB,YAAYlB,+BAChBD,8BACED,sCACE,MAAMK,eAAe;YACnBO;YACAS,OAAO;gBACLZ,UAAUA,YAAY;gBACtBa,WAAW,CAAC,CAAC,EAAEC,iBAAiB5B,KAAK6B,QAAQ,CAACd,KAAKf,KAAKqB,IAAI,CAACD,YAAY,aAAa;gBACtFU,OAAOjB;YACT;YACAkB,gBAAgBhB;QAClB;QAKNX,WAAW;QACX,MAAML,GAAGiC,SAAS,CAAChC,KAAKqB,IAAI,CAACD,YAAY,eAAeK;IAC1D;IAEA,IAAIQ;IAEJ,IAAI/B,OAAO;QACT+B,UAAU9B,cAAcM,sCAAsCM,MAAMmB,EAAE,CAAC,OAAO,IAC5EV;IAEJ;IAEA,MAAMA;IAENpB,WAAW;IACX,MAAM,EAAC+B,sBAAsB,EAAEC,aAAa,EAAC,GAAG,MAAMC,eAAe;QACnEtB;QACAC;QACAC;QACAC;QACAE;IACF;IACA,MAAMkB,eAAe9B,eAAe;QAClCM;QACAE,OAAOoB,iBAAiBG;QACxBtB;QACAE;QACAgB;IACF;IACA,MAAMpC,GAAGiC,SAAS,CAAChC,KAAKqB,IAAI,CAACD,YAAY,WAAWkB;IAEpD,OAAO;QACLE,SAAS;YACPL;YACAC;QACF;QACAH;IACF;AACF;AAEA;;;;CAIC,GACD,OAAO,eAAeI,eAAezB,OAMpC;IACC,MAAM,EAACG,GAAG,EAAEC,KAAK,EAAEC,KAAK,EAAEC,cAAc,EAAC,GAAGN;IAC5C,MAAMQ,aAAaR,QAAQQ,UAAU,IAAIpB,KAAKqB,IAAI,CAACN,KAAK,WAAW;IAEnE,IAAIoB,yBAAwC;IAC5C,IAAI,CAAClB,OAAO;QACV,MAAMwB,mBAAmB,MAAMxC,wBAAwBc;QACvDoB,yBAAyBM,mBACrBb,iBAAiB5B,KAAK6B,QAAQ,CAACT,YAAYqB,qBAC3C;IACN;IAEA,8EAA8E;IAC9E,4EAA4E;IAC5E,6EAA6E;IAC7E,+EAA+E;IAC/E,+EAA+E;IAC/E,2CAA2C;IAC3C,MAAML,gBACJlB,kBAAkB,CAACF,QACf,OACAY,iBAAiB5B,KAAK6B,QAAQ,CAACT,YAAYpB,KAAK0C,OAAO,CAAC3B,KAAKC,SAAS;IAE5E,OAAO;QAACmB;QAAwBC;IAAa;AAC/C;AAEA,SAASR,iBAAiBe,QAAgB;IACxC,OAAOA,SAASC,UAAU,CAAC,MAAM;AACnC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sanity/cli-build",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "Internal Sanity package for building studios and apps",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cli",
|
|
@@ -45,15 +45,16 @@
|
|
|
45
45
|
"@oclif/core": "^4.11.4",
|
|
46
46
|
"@rolldown/plugin-babel": "^0.2.3",
|
|
47
47
|
"@sanity/generate-help-url": "^4.0.0",
|
|
48
|
-
"@sanity/schema": "^
|
|
48
|
+
"@sanity/schema": "^6.1.0",
|
|
49
49
|
"@sanity/telemetry": "^1.1.0",
|
|
50
|
-
"@sanity/types": "^
|
|
50
|
+
"@sanity/types": "^6.1.0",
|
|
51
51
|
"@vitejs/plugin-react": "^6.0.2",
|
|
52
52
|
"chokidar": "^5.0.0",
|
|
53
53
|
"cjs-module-lexer": "^2.2.0",
|
|
54
54
|
"debug": "^4.4.3",
|
|
55
55
|
"lodash-es": "^4.18.1",
|
|
56
56
|
"node-html-parser": "^7.1.0",
|
|
57
|
+
"oneline": "^2.0.0",
|
|
57
58
|
"picomatch": "^4.0.4",
|
|
58
59
|
"react": "^19.2.7",
|
|
59
60
|
"react-dom": "^19.2.7",
|
|
@@ -61,35 +62,36 @@
|
|
|
61
62
|
"semver": "^7.8.1",
|
|
62
63
|
"vite": "^8.0.16",
|
|
63
64
|
"zod": "^4.4.3",
|
|
64
|
-
"@sanity/cli-core": "^2.0
|
|
65
|
+
"@sanity/cli-core": "^2.1.0",
|
|
66
|
+
"@sanity/workbench-cli": "^1.1.0"
|
|
65
67
|
},
|
|
66
68
|
"devDependencies": {
|
|
67
69
|
"@eslint/compat": "^2.1.0",
|
|
68
|
-
"@sanity/pkg-utils": "^10.5.
|
|
70
|
+
"@sanity/pkg-utils": "^10.5.8",
|
|
69
71
|
"@swc/cli": "^0.8.1",
|
|
70
|
-
"@swc/core": "^1.15.
|
|
72
|
+
"@swc/core": "^1.15.41",
|
|
71
73
|
"@types/debug": "^4.1.13",
|
|
72
74
|
"@types/jsdom": "^28.0.3",
|
|
73
75
|
"@types/lodash-es": "^4.17.12",
|
|
74
|
-
"@types/node": "^20.
|
|
76
|
+
"@types/node": "^22.20.0",
|
|
75
77
|
"@types/picomatch": "^4.0.3",
|
|
76
78
|
"@types/react": "^19.2.16",
|
|
77
79
|
"@types/react-dom": "^19.2.3",
|
|
78
80
|
"@types/semver": "^7.7.1",
|
|
79
|
-
"@vitest/coverage-istanbul": "^4.1.
|
|
81
|
+
"@vitest/coverage-istanbul": "^4.1.9",
|
|
80
82
|
"babel-plugin-react-compiler": "^1.0.0",
|
|
81
83
|
"eslint": "^10.4.1",
|
|
82
84
|
"jsdom": "^29.1.1",
|
|
83
85
|
"magic-string": "^0.30.21",
|
|
84
86
|
"publint": "^0.3.21",
|
|
85
|
-
"sanity": "^
|
|
87
|
+
"sanity": "^6.1.0",
|
|
86
88
|
"styled-components": "^6.4.2",
|
|
87
89
|
"typescript": "^5.9.3",
|
|
88
|
-
"vitest": "^4.1.
|
|
89
|
-
"@
|
|
90
|
+
"vitest": "^4.1.9",
|
|
91
|
+
"@repo/package.config": "0.0.1",
|
|
90
92
|
"@repo/tsconfig": "3.70.0",
|
|
91
|
-
"@sanity/
|
|
92
|
-
"@
|
|
93
|
+
"@sanity/cli-test": "2.0.0",
|
|
94
|
+
"@sanity/eslint-config-cli": "^1.1.2"
|
|
93
95
|
},
|
|
94
96
|
"peerDependencies": {
|
|
95
97
|
"babel-plugin-react-compiler": "*"
|
|
@@ -99,8 +101,11 @@
|
|
|
99
101
|
"optional": true
|
|
100
102
|
}
|
|
101
103
|
},
|
|
104
|
+
"overrides": {
|
|
105
|
+
"rolldown": "1.0.0"
|
|
106
|
+
},
|
|
102
107
|
"engines": {
|
|
103
|
-
"node": ">=
|
|
108
|
+
"node": ">=22.12"
|
|
104
109
|
},
|
|
105
110
|
"scripts": {
|
|
106
111
|
"build": "swc --delete-dir-on-start --strip-leading-paths --out-dir dist/ src --ignore '**/*.test.ts' --ignore '**/__tests__/**'",
|