@sanity/cli-build 7.1.1 → 7.1.2

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.
@@ -11,9 +11,18 @@ interface UnresolvedPrerelease {
11
11
  pkg: string;
12
12
  version: string;
13
13
  }
14
+ /**
15
+ * A package whose runtime version Module Server did not report, because of a network error,
16
+ * a timeout or a 5xx.
17
+ */
18
+ interface UnavailableDependencyVersion {
19
+ pkg: string;
20
+ reason: string;
21
+ }
14
22
  interface CompareDependencyVersionsResult {
15
23
  mismatched: Array<CompareDependencyVersions>;
16
24
  unresolvedPrerelease: Array<UnresolvedPrerelease>;
25
+ unavailable?: Array<UnavailableDependencyVersion>;
17
26
  }
18
27
  interface CompareDependencyVersionsOptions {
19
28
  /** When provided, uses the app-specific module endpoint instead of the default endpoint. */
@@ -35,16 +44,21 @@ interface CompareDependencyVersionsOptions {
35
44
  * @param workDir - The path to the working directory containing the package.json file.
36
45
  * @param options - Optional configuration for version comparison.
37
46
  *
38
- * @returns A promise that resolves to an object containing `mismatched` (packages whose local and remote versions differ)
39
- * and `unresolvedPrerelease` (packages with prerelease versions that could not be resolved remotely).
47
+ * @returns A promise that resolves to an object containing `mismatched` (packages whose local and remote versions differ),
48
+ * `unresolvedPrerelease` (packages with prerelease versions that could not be resolved remotely) and `unavailable`
49
+ * (packages Module Server did not answer for, because of a network error, a timeout or a 5xx).
40
50
  *
41
- * @throws Throws an error if the remote version of a non-prerelease package cannot be fetched, or if the local version
42
- * of a package cannot be parsed.
51
+ * @throws Throws an error if a non-prerelease package is not found remotely, if Module Server answers with an unexpected
52
+ * response, or if the local version of a package cannot be parsed.
43
53
  */
44
54
  declare function compareDependencyVersions(packages: {
45
55
  name: string;
46
56
  version: string;
47
57
  }[], workDir: string, { appId }?: CompareDependencyVersionsOptions): Promise<CompareDependencyVersionsResult>;
58
+ /**
59
+ * @internal
60
+ */
61
+ declare function getUnavailableVersionsWarning(unavailable: UnavailableDependencyVersion[]): string;
48
62
  type MessageFunc = ({ message }: {
49
63
  message: string;
50
64
  }) => void;
@@ -397,5 +411,5 @@ declare function writeSanityRuntime(options: RuntimeOptions): Promise<{
397
411
  * ignored by default in typical `.gitignore` files.
398
412
  */
399
413
  declare const SANITY_CACHE_DIR = "node_modules/.sanity";
400
- export { type BuildAppEventListener, type BuildStudioEventListener, type CompareDependencyVersions, type CompareDependencyVersionsResult, SANITY_CACHE_DIR, type UnresolvedPrerelease, buildApp, buildStaticFiles, buildStudio, checkRequiredDependencies, checkStudioDependencyVersions, compareDependencyVersions, extendViteConfigWithUserConfig, getViteConfig, resolveVendorBuildConfig, writeSanityRuntime };
414
+ export { type BuildAppEventListener, type BuildStudioEventListener, type CompareDependencyVersions, type CompareDependencyVersionsResult, SANITY_CACHE_DIR, type UnavailableDependencyVersion, type UnresolvedPrerelease, buildApp, buildStaticFiles, buildStudio, checkRequiredDependencies, checkStudioDependencyVersions, compareDependencyVersions, extendViteConfigWithUserConfig, getUnavailableVersionsWarning, getViteConfig, resolveVendorBuildConfig, writeSanityRuntime };
401
415
  //# sourceMappingURL=build.d.ts.map
@@ -7,6 +7,6 @@ export { extendViteConfigWithUserConfig, getViteConfig } from '../../actions/bui
7
7
  export { resolveVendorBuildConfig } from '../../actions/build/resolveVendorBuildConfig.js';
8
8
  export { writeSanityRuntime } from '../../actions/build/writeSanityRuntime.js';
9
9
  export { SANITY_CACHE_DIR } from '../../constants.js';
10
- export { compareDependencyVersions } from '../../util/compareDependencyVersions.js';
10
+ export { compareDependencyVersions, getUnavailableVersionsWarning } from '../../util/compareDependencyVersions.js';
11
11
 
12
12
  //# sourceMappingURL=build.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/_exports/_internal/build.ts"],"sourcesContent":["export {buildApp, type BuildAppEventListener} from '../../actions/build/buildApp.js'\nexport {buildStaticFiles} from '../../actions/build/buildStaticFiles.js'\nexport {buildStudio, type BuildStudioEventListener} from '../../actions/build/buildStudio.js'\nexport {checkRequiredDependencies} from '../../actions/build/checkRequiredDependencies.js'\nexport {checkStudioDependencyVersions} from '../../actions/build/checkStudioDependencyVersions.js'\nexport {extendViteConfigWithUserConfig, getViteConfig} from '../../actions/build/getViteConfig.js'\nexport {resolveVendorBuildConfig} from '../../actions/build/resolveVendorBuildConfig.js'\nexport {writeSanityRuntime} from '../../actions/build/writeSanityRuntime.js'\nexport {SANITY_CACHE_DIR} from '../../constants.js'\nexport {\n compareDependencyVersions,\n type CompareDependencyVersions,\n type CompareDependencyVersionsResult,\n type UnresolvedPrerelease,\n} from '../../util/compareDependencyVersions.js'\n"],"names":["buildApp","buildStaticFiles","buildStudio","checkRequiredDependencies","checkStudioDependencyVersions","extendViteConfigWithUserConfig","getViteConfig","resolveVendorBuildConfig","writeSanityRuntime","SANITY_CACHE_DIR","compareDependencyVersions"],"mappings":"AAAA,SAAQA,QAAQ,QAAmC,kCAAiC;AACpF,SAAQC,gBAAgB,QAAO,0CAAyC;AACxE,SAAQC,WAAW,QAAsC,qCAAoC;AAC7F,SAAQC,yBAAyB,QAAO,mDAAkD;AAC1F,SAAQC,6BAA6B,QAAO,uDAAsD;AAClG,SAAQC,8BAA8B,EAAEC,aAAa,QAAO,uCAAsC;AAClG,SAAQC,wBAAwB,QAAO,kDAAiD;AACxF,SAAQC,kBAAkB,QAAO,4CAA2C;AAC5E,SAAQC,gBAAgB,QAAO,qBAAoB;AACnD,SACEC,yBAAyB,QAIpB,0CAAyC"}
1
+ {"version":3,"sources":["../../../src/_exports/_internal/build.ts"],"sourcesContent":["export {buildApp, type BuildAppEventListener} from '../../actions/build/buildApp.js'\nexport {buildStaticFiles} from '../../actions/build/buildStaticFiles.js'\nexport {buildStudio, type BuildStudioEventListener} from '../../actions/build/buildStudio.js'\nexport {checkRequiredDependencies} from '../../actions/build/checkRequiredDependencies.js'\nexport {checkStudioDependencyVersions} from '../../actions/build/checkStudioDependencyVersions.js'\nexport {extendViteConfigWithUserConfig, getViteConfig} from '../../actions/build/getViteConfig.js'\nexport {resolveVendorBuildConfig} from '../../actions/build/resolveVendorBuildConfig.js'\nexport {writeSanityRuntime} from '../../actions/build/writeSanityRuntime.js'\nexport {SANITY_CACHE_DIR} from '../../constants.js'\nexport {\n compareDependencyVersions,\n type CompareDependencyVersions,\n type CompareDependencyVersionsResult,\n getUnavailableVersionsWarning,\n type UnavailableDependencyVersion,\n type UnresolvedPrerelease,\n} from '../../util/compareDependencyVersions.js'\n"],"names":["buildApp","buildStaticFiles","buildStudio","checkRequiredDependencies","checkStudioDependencyVersions","extendViteConfigWithUserConfig","getViteConfig","resolveVendorBuildConfig","writeSanityRuntime","SANITY_CACHE_DIR","compareDependencyVersions","getUnavailableVersionsWarning"],"mappings":"AAAA,SAAQA,QAAQ,QAAmC,kCAAiC;AACpF,SAAQC,gBAAgB,QAAO,0CAAyC;AACxE,SAAQC,WAAW,QAAsC,qCAAoC;AAC7F,SAAQC,yBAAyB,QAAO,mDAAkD;AAC1F,SAAQC,6BAA6B,QAAO,uDAAsD;AAClG,SAAQC,8BAA8B,EAAEC,aAAa,QAAO,uCAAsC;AAClG,SAAQC,wBAAwB,QAAO,kDAAiD;AACxF,SAAQC,kBAAkB,QAAO,4CAA2C;AAC5E,SAAQC,gBAAgB,QAAO,qBAAoB;AACnD,SACEC,yBAAyB,EAGzBC,6BAA6B,QAGxB,0CAAyC"}
@@ -9,6 +9,7 @@ import { confirm, getTimer, logSymbols, spinner } from '@sanity/cli-core/ux';
9
9
  import { readBuiltManifest } from '@sanity/workbench-cli/build';
10
10
  import { parse as semverParse } from 'semver';
11
11
  import { AppBuildTrace } from '../../telemetry/build.telemetry.js';
12
+ import { getUnavailableVersionsWarning } from '../../util/compareDependencyVersions.js';
12
13
  import { formatModuleSizes, sortModulesBySize } from '../../util/moduleFormatUtils.js';
13
14
  import { buildDebug } from './buildDebug.js';
14
15
  import { buildStaticFiles } from './buildStaticFiles.js';
@@ -93,7 +94,10 @@ import { resolveVendorBuildConfig } from './resolveVendorBuildConfig.js';
93
94
  // Warn if auto updates enabled but no appId configured.
94
95
  options.checkAppId();
95
96
  // Check the versions
96
- const { mismatched, unresolvedPrerelease } = await options.compareDependencyVersions(autoUpdatedPackages);
97
+ const { mismatched, unavailable = [], unresolvedPrerelease } = await options.compareDependencyVersions(autoUpdatedPackages);
98
+ if (unavailable.length > 0) {
99
+ output.warn(getUnavailableVersionsWarning(unavailable));
100
+ }
97
101
  if (unresolvedPrerelease.length > 0) {
98
102
  await handlePrereleaseVersions({
99
103
  onPreReleaseInInteractiveAutoUpdate: eventListener.onPreReleaseInInteractiveAutoUpdate,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/actions/build/buildApp.ts"],"sourcesContent":["import {rm} from 'node:fs/promises'\nimport path from 'node:path'\nimport {styleText} from 'node:util'\n\nimport {exitCodes} from '@sanity/cli-core/ExitCodes'\nimport {getLocalPackageVersion} from '@sanity/cli-core/package-manager'\nimport {getCliTelemetry} from '@sanity/cli-core/telemetry'\nimport {type CliConfig, type Output, type UserViteConfig} from '@sanity/cli-core/types'\nimport {isInteractive} from '@sanity/cli-core/util'\nimport {confirm, getTimer, logSymbols, spinner, type SpinnerInstance} from '@sanity/cli-core/ux'\nimport {readBuiltManifest, type WorkbenchExposes} from '@sanity/workbench-cli/build'\nimport {parse as semverParse} from 'semver'\n\nimport {AppBuildTrace} from '../../telemetry/build.telemetry.js'\nimport {CompareDependencyVersionsResult} from '../../util/compareDependencyVersions.js'\nimport {formatModuleSizes, sortModulesBySize} from '../../util/moduleFormatUtils.js'\nimport {buildDebug} from './buildDebug.js'\nimport {buildStaticFiles} from './buildStaticFiles.js'\nimport {BuildEventListener} from './eventListener.js'\nimport {getAutoUpdatesCssUrls, getAutoUpdatesImportMap} from './getAutoUpdatesImportMap.js'\nimport {getAppEnvironmentVariables} from './getEnvironmentVariables.js'\nimport {handlePrereleaseVersions} from './handlePrereleaseVersions.js'\nimport {resolveVendorBuildConfig} from './resolveVendorBuildConfig.js'\n\nexport type BuildAppEventListener = BuildEventListener\nexport interface BuildOptions {\n appId: string | undefined\n appTitle: string | undefined\n autoUpdatesEnabled: boolean\n checkAppId: () => void\n compareDependencyVersions: (\n packages: {name: string; version: string}[],\n ) => Promise<CompareDependencyVersionsResult>\n determineBasePath: () => string\n entry: string | undefined\n eventListener: Partial<BuildAppEventListener>\n isWorkbenchApp: boolean\n minify: boolean\n outDir: string | undefined\n output: Output\n reactCompiler: CliConfig['reactCompiler']\n schemaExtraction: CliConfig['schemaExtraction']\n sourceMap: boolean\n stats: boolean\n unattendedMode: boolean\n vite: UserViteConfig | undefined\n workDir: string\n\n exposes?: WorkbenchExposes\n /**\n * The build is running under Sanity Blueprints (invoked programmatically by\n * `@sanity/runtime-cli`), so emit the statically-imported resource-bindings\n * module Brett rewrites at deploy. Defaults to `false`, so a normal\n * `sanity build`/`dev`/`preview` never emits it.\n */\n isBlueprints?: boolean\n\n /** The workbench app's bus identity (`__SANITY_APP_ID__`). */\n workbenchAppId?: string\n}\n\n/**\n * Internal build app that avoids depending on flags for CLI config.\n * @param options - options for the build\n */\nexport async function buildApp(\n options: BuildOptions,\n): Promise<{mfManifest: Record<string, unknown> | undefined}> {\n buildDebug(`Building app`)\n\n const {appId, determineBasePath, eventListener, outDir, output, workDir} = options\n let {autoUpdatesEnabled} = options\n const unattendedMode = options.unattendedMode\n\n const timer = getTimer()\n\n const defaultOutputDir = path.resolve(path.join(workDir, 'dist'))\n const outputDir = path.resolve(outDir || defaultOutputDir)\n\n const installedSdkVersion = await getLocalPackageVersion('@sanity/sdk-react', workDir)\n const installedSanityVersion = await getLocalPackageVersion('sanity', workDir)\n\n // A Media Library config ships no SDK app — its inputs are island-rendered\n // by `sanity`, so verify that instead and skip the SDK auto-update\n // machinery. Checked via the `appType` discriminator, not the mere presence\n // of a config: a future `ConfigSchema` member must not inherit these\n // media-library build semantics by default.\n const isMediaLibraryConfigBuild = options.exposes?.config?.appType === 'media-library'\n\n if (!installedSdkVersion && !isMediaLibraryConfigBuild) {\n output.error(`Failed to find installed @sanity/sdk-react version`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n return {mfManifest: undefined}\n }\n\n if (isMediaLibraryConfigBuild && !installedSanityVersion) {\n output.error(`Failed to find installed sanity version`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n return {mfManifest: undefined}\n }\n\n let autoUpdatesImports = {}\n let autoUpdatesCssUrls: string[] = []\n\n if (autoUpdatesEnabled && !isMediaLibraryConfigBuild) {\n // Get the clean version without build metadata: https://semver.org/#spec-item-10\n const cleanSDKVersion = semverParse(installedSdkVersion)?.version\n if (!cleanSDKVersion) {\n output.error(`Failed to parse installed SDK version: ${installedSdkVersion}`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n return {mfManifest: undefined}\n }\n\n // Sanity might not be installed, but if it is, we want to auto update it.\n const cleanSanityVersion = semverParse(installedSanityVersion)?.version\n\n const autoUpdatedPackages = [\n {name: '@sanity/sdk', version: cleanSDKVersion},\n {name: '@sanity/sdk-react', version: cleanSDKVersion},\n ...(cleanSanityVersion\n ? [{cssFile: 'index.css', name: 'sanity' as const, version: cleanSanityVersion}]\n : []),\n ]\n autoUpdatesImports = getAutoUpdatesImportMap(autoUpdatedPackages, {appId})\n autoUpdatesCssUrls = getAutoUpdatesCssUrls(autoUpdatedPackages, {appId})\n\n output.log(`${logSymbols.info} Building with auto-updates enabled`)\n\n // Warn if auto updates enabled but no appId configured.\n options.checkAppId()\n\n // Check the versions\n const {mismatched, unresolvedPrerelease} =\n await options.compareDependencyVersions(autoUpdatedPackages)\n\n if (unresolvedPrerelease.length > 0) {\n await handlePrereleaseVersions({\n onPreReleaseInInteractiveAutoUpdate: eventListener.onPreReleaseInInteractiveAutoUpdate,\n onPreReleaseInNonInteractiveAutoUpdate:\n eventListener.onPreReleaseInNonInteractiveAutoUpdate,\n unattendedMode,\n unresolvedPrerelease,\n })\n autoUpdatesImports = {}\n autoUpdatesCssUrls = []\n autoUpdatesEnabled = false\n }\n\n if (mismatched.length > 0 && autoUpdatesEnabled) {\n const versionMismatchWarning =\n `The following local package versions are different from the versions currently served at runtime.\\n` +\n `When using auto updates, we recommend that you test locally with the same versions before deploying. \\n\\n` +\n `${mismatched.map((mod) => ` - ${mod.pkg} (local version: ${mod.installed}, runtime version: ${mod.remote})`).join('\\n')}`\n\n // If it is non-interactive or in unattended mode, we don't want to prompt\n if (isInteractive() && !unattendedMode) {\n const shouldContinue = await confirm({\n default: false,\n message: styleText('yellow', `${versionMismatchWarning} \\n\\nContinue anyway?`),\n })\n\n if (!shouldContinue) {\n output.error('Declined to continue with build', {exit: exitCodes.RUNTIME_ERROR})\n return {mfManifest: undefined}\n }\n } else {\n // if non-interactive or unattended, just show the warning\n output.warn(versionMismatchWarning)\n }\n }\n }\n\n const envVarKeys = Object.keys(getAppEnvironmentVariables())\n if (envVarKeys.length > 0) {\n output.log('\\nIncluding the following environment variables as part of the JavaScript bundle:')\n for (const key of envVarKeys) output.log(`- ${key}`)\n output.log('')\n }\n\n let shouldClean = true\n if (outputDir !== defaultOutputDir && !unattendedMode && isInteractive()) {\n shouldClean = await confirm({\n default: true,\n message: `Do you want to delete the existing directory (${outputDir}) first?`,\n })\n }\n\n const basePath = determineBasePath()\n\n let spin: SpinnerInstance\n if (shouldClean) {\n timer.start('cleanOutputFolder')\n spin = spinner('Clean output folder').start()\n await rm(outputDir, {force: true, recursive: true})\n const cleanDuration = timer.end('cleanOutputFolder')\n spin.text = `Clean output folder (${cleanDuration.toFixed(0)}ms)`\n spin.succeed()\n }\n\n spin = spinner(`Building Sanity application`).start()\n\n const trace = getCliTelemetry().trace(AppBuildTrace)\n trace.start()\n\n let autoUpdates\n if (autoUpdatesEnabled && !isMediaLibraryConfigBuild) {\n autoUpdates = {\n cssUrls: autoUpdatesCssUrls,\n imports: autoUpdatesImports,\n // Module server `sanity` imports `styled-components` by name, so the app provides it when it has it.\n vendor: await resolveVendorBuildConfig({\n cwd: workDir,\n isApp: !(await getLocalPackageVersion('styled-components', workDir)),\n }),\n }\n }\n\n try {\n timer.start('bundleStudio')\n\n const bundle = await buildStaticFiles({\n appTitle: options.appTitle,\n autoUpdates,\n basePath,\n cwd: workDir,\n entry: options.entry,\n exposes: options.exposes,\n isApp: true,\n isBlueprints: options.isBlueprints,\n isWorkbenchApp: options.isWorkbenchApp,\n minify: options.minify,\n outputDir,\n reactCompiler: options.reactCompiler,\n schemaExtraction: options.schemaExtraction,\n sourceMap: options.sourceMap,\n vite: options.vite,\n workbenchAppId: options.workbenchAppId,\n })\n const mfManifest = options.isWorkbenchApp ? await readBuiltManifest(outputDir) : undefined\n\n trace.log({\n outputSize: bundle.chunks\n .flatMap((chunk) => chunk.modules.flatMap((mod) => mod.renderedLength))\n .reduce((sum, n) => sum + n, 0),\n })\n const buildDuration = timer.end('bundleStudio')\n\n spin.text = `Build Sanity application (${buildDuration.toFixed(0)}ms)`\n spin.succeed()\n\n if (options.stats) {\n output.log('\\nLargest module files:')\n output.log(formatModuleSizes(sortModulesBySize(bundle.chunks).slice(0, 15)))\n }\n\n trace.complete()\n return {mfManifest}\n } catch (error) {\n spin.fail()\n trace.error(error)\n const message = error instanceof Error ? error.message : String(error)\n buildDebug(`Failed to build Sanity application`, {error})\n output.error(`Failed to build Sanity application: ${message}`, {exit: exitCodes.RUNTIME_ERROR})\n return {mfManifest: undefined}\n }\n}\n"],"names":["rm","path","styleText","exitCodes","getLocalPackageVersion","getCliTelemetry","isInteractive","confirm","getTimer","logSymbols","spinner","readBuiltManifest","parse","semverParse","AppBuildTrace","formatModuleSizes","sortModulesBySize","buildDebug","buildStaticFiles","getAutoUpdatesCssUrls","getAutoUpdatesImportMap","getAppEnvironmentVariables","handlePrereleaseVersions","resolveVendorBuildConfig","buildApp","options","appId","determineBasePath","eventListener","outDir","output","workDir","autoUpdatesEnabled","unattendedMode","timer","defaultOutputDir","resolve","join","outputDir","installedSdkVersion","installedSanityVersion","isMediaLibraryConfigBuild","exposes","config","appType","error","exit","RUNTIME_ERROR","mfManifest","undefined","autoUpdatesImports","autoUpdatesCssUrls","cleanSDKVersion","version","cleanSanityVersion","autoUpdatedPackages","name","cssFile","log","info","checkAppId","mismatched","unresolvedPrerelease","compareDependencyVersions","length","onPreReleaseInInteractiveAutoUpdate","onPreReleaseInNonInteractiveAutoUpdate","versionMismatchWarning","map","mod","pkg","installed","remote","shouldContinue","default","message","warn","envVarKeys","Object","keys","key","shouldClean","basePath","spin","start","force","recursive","cleanDuration","end","text","toFixed","succeed","trace","autoUpdates","cssUrls","imports","vendor","cwd","isApp","bundle","appTitle","entry","isBlueprints","isWorkbenchApp","minify","reactCompiler","schemaExtraction","sourceMap","vite","workbenchAppId","outputSize","chunks","flatMap","chunk","modules","renderedLength","reduce","sum","n","buildDuration","stats","slice","complete","fail","Error","String"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/actions/build/buildApp.ts"],"sourcesContent":["import {rm} from 'node:fs/promises'\nimport path from 'node:path'\nimport {styleText} from 'node:util'\n\nimport {exitCodes} from '@sanity/cli-core/ExitCodes'\nimport {getLocalPackageVersion} from '@sanity/cli-core/package-manager'\nimport {getCliTelemetry} from '@sanity/cli-core/telemetry'\nimport {type CliConfig, type Output, type UserViteConfig} from '@sanity/cli-core/types'\nimport {isInteractive} from '@sanity/cli-core/util'\nimport {confirm, getTimer, logSymbols, spinner, type SpinnerInstance} from '@sanity/cli-core/ux'\nimport {readBuiltManifest, type WorkbenchExposes} from '@sanity/workbench-cli/build'\nimport {parse as semverParse} from 'semver'\n\nimport {AppBuildTrace} from '../../telemetry/build.telemetry.js'\nimport {\n CompareDependencyVersionsResult,\n getUnavailableVersionsWarning,\n} from '../../util/compareDependencyVersions.js'\nimport {formatModuleSizes, sortModulesBySize} from '../../util/moduleFormatUtils.js'\nimport {buildDebug} from './buildDebug.js'\nimport {buildStaticFiles} from './buildStaticFiles.js'\nimport {BuildEventListener} from './eventListener.js'\nimport {getAutoUpdatesCssUrls, getAutoUpdatesImportMap} from './getAutoUpdatesImportMap.js'\nimport {getAppEnvironmentVariables} from './getEnvironmentVariables.js'\nimport {handlePrereleaseVersions} from './handlePrereleaseVersions.js'\nimport {resolveVendorBuildConfig} from './resolveVendorBuildConfig.js'\n\nexport type BuildAppEventListener = BuildEventListener\nexport interface BuildOptions {\n appId: string | undefined\n appTitle: string | undefined\n autoUpdatesEnabled: boolean\n checkAppId: () => void\n compareDependencyVersions: (\n packages: {name: string; version: string}[],\n ) => Promise<CompareDependencyVersionsResult>\n determineBasePath: () => string\n entry: string | undefined\n eventListener: Partial<BuildAppEventListener>\n isWorkbenchApp: boolean\n minify: boolean\n outDir: string | undefined\n output: Output\n reactCompiler: CliConfig['reactCompiler']\n schemaExtraction: CliConfig['schemaExtraction']\n sourceMap: boolean\n stats: boolean\n unattendedMode: boolean\n vite: UserViteConfig | undefined\n workDir: string\n\n exposes?: WorkbenchExposes\n /**\n * The build is running under Sanity Blueprints (invoked programmatically by\n * `@sanity/runtime-cli`), so emit the statically-imported resource-bindings\n * module Brett rewrites at deploy. Defaults to `false`, so a normal\n * `sanity build`/`dev`/`preview` never emits it.\n */\n isBlueprints?: boolean\n\n /** The workbench app's bus identity (`__SANITY_APP_ID__`). */\n workbenchAppId?: string\n}\n\n/**\n * Internal build app that avoids depending on flags for CLI config.\n * @param options - options for the build\n */\nexport async function buildApp(\n options: BuildOptions,\n): Promise<{mfManifest: Record<string, unknown> | undefined}> {\n buildDebug(`Building app`)\n\n const {appId, determineBasePath, eventListener, outDir, output, workDir} = options\n let {autoUpdatesEnabled} = options\n const unattendedMode = options.unattendedMode\n\n const timer = getTimer()\n\n const defaultOutputDir = path.resolve(path.join(workDir, 'dist'))\n const outputDir = path.resolve(outDir || defaultOutputDir)\n\n const installedSdkVersion = await getLocalPackageVersion('@sanity/sdk-react', workDir)\n const installedSanityVersion = await getLocalPackageVersion('sanity', workDir)\n\n // A Media Library config ships no SDK app — its inputs are island-rendered\n // by `sanity`, so verify that instead and skip the SDK auto-update\n // machinery. Checked via the `appType` discriminator, not the mere presence\n // of a config: a future `ConfigSchema` member must not inherit these\n // media-library build semantics by default.\n const isMediaLibraryConfigBuild = options.exposes?.config?.appType === 'media-library'\n\n if (!installedSdkVersion && !isMediaLibraryConfigBuild) {\n output.error(`Failed to find installed @sanity/sdk-react version`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n return {mfManifest: undefined}\n }\n\n if (isMediaLibraryConfigBuild && !installedSanityVersion) {\n output.error(`Failed to find installed sanity version`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n return {mfManifest: undefined}\n }\n\n let autoUpdatesImports = {}\n let autoUpdatesCssUrls: string[] = []\n\n if (autoUpdatesEnabled && !isMediaLibraryConfigBuild) {\n // Get the clean version without build metadata: https://semver.org/#spec-item-10\n const cleanSDKVersion = semverParse(installedSdkVersion)?.version\n if (!cleanSDKVersion) {\n output.error(`Failed to parse installed SDK version: ${installedSdkVersion}`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n return {mfManifest: undefined}\n }\n\n // Sanity might not be installed, but if it is, we want to auto update it.\n const cleanSanityVersion = semverParse(installedSanityVersion)?.version\n\n const autoUpdatedPackages = [\n {name: '@sanity/sdk', version: cleanSDKVersion},\n {name: '@sanity/sdk-react', version: cleanSDKVersion},\n ...(cleanSanityVersion\n ? [{cssFile: 'index.css', name: 'sanity' as const, version: cleanSanityVersion}]\n : []),\n ]\n autoUpdatesImports = getAutoUpdatesImportMap(autoUpdatedPackages, {appId})\n autoUpdatesCssUrls = getAutoUpdatesCssUrls(autoUpdatedPackages, {appId})\n\n output.log(`${logSymbols.info} Building with auto-updates enabled`)\n\n // Warn if auto updates enabled but no appId configured.\n options.checkAppId()\n\n // Check the versions\n const {\n mismatched,\n unavailable = [],\n unresolvedPrerelease,\n } = await options.compareDependencyVersions(autoUpdatedPackages)\n\n if (unavailable.length > 0) {\n output.warn(getUnavailableVersionsWarning(unavailable))\n }\n\n if (unresolvedPrerelease.length > 0) {\n await handlePrereleaseVersions({\n onPreReleaseInInteractiveAutoUpdate: eventListener.onPreReleaseInInteractiveAutoUpdate,\n onPreReleaseInNonInteractiveAutoUpdate:\n eventListener.onPreReleaseInNonInteractiveAutoUpdate,\n unattendedMode,\n unresolvedPrerelease,\n })\n autoUpdatesImports = {}\n autoUpdatesCssUrls = []\n autoUpdatesEnabled = false\n }\n\n if (mismatched.length > 0 && autoUpdatesEnabled) {\n const versionMismatchWarning =\n `The following local package versions are different from the versions currently served at runtime.\\n` +\n `When using auto updates, we recommend that you test locally with the same versions before deploying. \\n\\n` +\n `${mismatched.map((mod) => ` - ${mod.pkg} (local version: ${mod.installed}, runtime version: ${mod.remote})`).join('\\n')}`\n\n // If it is non-interactive or in unattended mode, we don't want to prompt\n if (isInteractive() && !unattendedMode) {\n const shouldContinue = await confirm({\n default: false,\n message: styleText('yellow', `${versionMismatchWarning} \\n\\nContinue anyway?`),\n })\n\n if (!shouldContinue) {\n output.error('Declined to continue with build', {exit: exitCodes.RUNTIME_ERROR})\n return {mfManifest: undefined}\n }\n } else {\n // if non-interactive or unattended, just show the warning\n output.warn(versionMismatchWarning)\n }\n }\n }\n\n const envVarKeys = Object.keys(getAppEnvironmentVariables())\n if (envVarKeys.length > 0) {\n output.log('\\nIncluding the following environment variables as part of the JavaScript bundle:')\n for (const key of envVarKeys) output.log(`- ${key}`)\n output.log('')\n }\n\n let shouldClean = true\n if (outputDir !== defaultOutputDir && !unattendedMode && isInteractive()) {\n shouldClean = await confirm({\n default: true,\n message: `Do you want to delete the existing directory (${outputDir}) first?`,\n })\n }\n\n const basePath = determineBasePath()\n\n let spin: SpinnerInstance\n if (shouldClean) {\n timer.start('cleanOutputFolder')\n spin = spinner('Clean output folder').start()\n await rm(outputDir, {force: true, recursive: true})\n const cleanDuration = timer.end('cleanOutputFolder')\n spin.text = `Clean output folder (${cleanDuration.toFixed(0)}ms)`\n spin.succeed()\n }\n\n spin = spinner(`Building Sanity application`).start()\n\n const trace = getCliTelemetry().trace(AppBuildTrace)\n trace.start()\n\n let autoUpdates\n if (autoUpdatesEnabled && !isMediaLibraryConfigBuild) {\n autoUpdates = {\n cssUrls: autoUpdatesCssUrls,\n imports: autoUpdatesImports,\n // Module server `sanity` imports `styled-components` by name, so the app provides it when it has it.\n vendor: await resolveVendorBuildConfig({\n cwd: workDir,\n isApp: !(await getLocalPackageVersion('styled-components', workDir)),\n }),\n }\n }\n\n try {\n timer.start('bundleStudio')\n\n const bundle = await buildStaticFiles({\n appTitle: options.appTitle,\n autoUpdates,\n basePath,\n cwd: workDir,\n entry: options.entry,\n exposes: options.exposes,\n isApp: true,\n isBlueprints: options.isBlueprints,\n isWorkbenchApp: options.isWorkbenchApp,\n minify: options.minify,\n outputDir,\n reactCompiler: options.reactCompiler,\n schemaExtraction: options.schemaExtraction,\n sourceMap: options.sourceMap,\n vite: options.vite,\n workbenchAppId: options.workbenchAppId,\n })\n const mfManifest = options.isWorkbenchApp ? await readBuiltManifest(outputDir) : undefined\n\n trace.log({\n outputSize: bundle.chunks\n .flatMap((chunk) => chunk.modules.flatMap((mod) => mod.renderedLength))\n .reduce((sum, n) => sum + n, 0),\n })\n const buildDuration = timer.end('bundleStudio')\n\n spin.text = `Build Sanity application (${buildDuration.toFixed(0)}ms)`\n spin.succeed()\n\n if (options.stats) {\n output.log('\\nLargest module files:')\n output.log(formatModuleSizes(sortModulesBySize(bundle.chunks).slice(0, 15)))\n }\n\n trace.complete()\n return {mfManifest}\n } catch (error) {\n spin.fail()\n trace.error(error)\n const message = error instanceof Error ? error.message : String(error)\n buildDebug(`Failed to build Sanity application`, {error})\n output.error(`Failed to build Sanity application: ${message}`, {exit: exitCodes.RUNTIME_ERROR})\n return {mfManifest: undefined}\n }\n}\n"],"names":["rm","path","styleText","exitCodes","getLocalPackageVersion","getCliTelemetry","isInteractive","confirm","getTimer","logSymbols","spinner","readBuiltManifest","parse","semverParse","AppBuildTrace","getUnavailableVersionsWarning","formatModuleSizes","sortModulesBySize","buildDebug","buildStaticFiles","getAutoUpdatesCssUrls","getAutoUpdatesImportMap","getAppEnvironmentVariables","handlePrereleaseVersions","resolveVendorBuildConfig","buildApp","options","appId","determineBasePath","eventListener","outDir","output","workDir","autoUpdatesEnabled","unattendedMode","timer","defaultOutputDir","resolve","join","outputDir","installedSdkVersion","installedSanityVersion","isMediaLibraryConfigBuild","exposes","config","appType","error","exit","RUNTIME_ERROR","mfManifest","undefined","autoUpdatesImports","autoUpdatesCssUrls","cleanSDKVersion","version","cleanSanityVersion","autoUpdatedPackages","name","cssFile","log","info","checkAppId","mismatched","unavailable","unresolvedPrerelease","compareDependencyVersions","length","warn","onPreReleaseInInteractiveAutoUpdate","onPreReleaseInNonInteractiveAutoUpdate","versionMismatchWarning","map","mod","pkg","installed","remote","shouldContinue","default","message","envVarKeys","Object","keys","key","shouldClean","basePath","spin","start","force","recursive","cleanDuration","end","text","toFixed","succeed","trace","autoUpdates","cssUrls","imports","vendor","cwd","isApp","bundle","appTitle","entry","isBlueprints","isWorkbenchApp","minify","reactCompiler","schemaExtraction","sourceMap","vite","workbenchAppId","outputSize","chunks","flatMap","chunk","modules","renderedLength","reduce","sum","n","buildDuration","stats","slice","complete","fail","Error","String"],"mappings":"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"}
@@ -7,6 +7,7 @@ import { getTimer, logSymbols } from '@sanity/cli-core/ux';
7
7
  import { readBuiltManifest } from '@sanity/workbench-cli/build';
8
8
  import { parse as semverParse } from 'semver';
9
9
  import { StudioBuildTrace } from '../../telemetry/build.telemetry.js';
10
+ import { getUnavailableVersionsWarning } from '../../util/compareDependencyVersions.js';
10
11
  import { formatModuleSizes, sortModulesBySize } from '../../util/moduleFormatUtils.js';
11
12
  import { buildDebug } from './buildDebug.js';
12
13
  import { buildStaticFiles } from './buildStaticFiles.js';
@@ -73,7 +74,10 @@ import { resolveVendorBuildConfig } from './resolveVendorBuildConfig.js';
73
74
  appId
74
75
  });
75
76
  // Check the versions
76
- const { mismatched, unresolvedPrerelease } = await options.compareDependencyVersions(sanityDependencies);
77
+ const { mismatched, unavailable = [], unresolvedPrerelease } = await options.compareDependencyVersions(sanityDependencies);
78
+ if (unavailable.length > 0) {
79
+ output.warn(getUnavailableVersionsWarning(unavailable));
80
+ }
77
81
  if (unresolvedPrerelease.length > 0) {
78
82
  await handlePrereleaseVersions({
79
83
  unattendedMode,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/actions/build/buildStudio.ts"],"sourcesContent":["import {rm} from 'node:fs/promises'\nimport path from 'node:path'\n\nimport {getLocalPackageVersion} from '@sanity/cli-core/package-manager'\nimport {getCliTelemetry} from '@sanity/cli-core/telemetry'\nimport {type CliConfig, type Output, type UserViteConfig} from '@sanity/cli-core/types'\nimport {isInteractive} from '@sanity/cli-core/util'\nimport {getTimer, logSymbols} from '@sanity/cli-core/ux'\nimport {readBuiltManifest, type WorkbenchExposes} from '@sanity/workbench-cli/build'\nimport {parse as semverParse} from 'semver'\n\nimport {StudioBuildTrace} from '../../telemetry/build.telemetry.js'\nimport {\n CompareDependencyVersions,\n CompareDependencyVersionsResult,\n} from '../../util/compareDependencyVersions.js'\nimport {formatModuleSizes, sortModulesBySize} from '../../util/moduleFormatUtils.js'\nimport {buildDebug} from './buildDebug.js'\nimport {buildStaticFiles} from './buildStaticFiles.js'\nimport {checkRequiredDependencies} from './checkRequiredDependencies.js'\nimport {checkStudioDependencyVersions} from './checkStudioDependencyVersions.js'\nimport {type BuildEventListener, type MessageFunc} from './eventListener.js'\nimport {getAutoUpdatesCssUrls, getAutoUpdatesImportMap} from './getAutoUpdatesImportMap.js'\nimport {getStudioEnvironmentVariables} from './getEnvironmentVariables.js'\nimport {handlePrereleaseVersions} from './handlePrereleaseVersions.js'\nimport {resolveVendorBuildConfig} from './resolveVendorBuildConfig.js'\n\nexport interface BuildStudioEventListener extends BuildEventListener {\n onBuildEnd: MessageFunc\n onBuildFail: MessageFunc\n onBuildStart: MessageFunc\n onCleanOutputDirEnd: MessageFunc\n onCleanOutputDirStart: MessageFunc\n onIncompatibleDeclaredStyledComponentsVersionRange: MessageFunc\n onIncompatibleInstalledStyledComponentsVersionRange: MessageFunc\n onInteractiveNonDefaultOutputDir({message}: {message: string}): Promise<{shouldClean: boolean}>\n onInvalidStyledComponentsVersionRange: MessageFunc\n onNoDeclaredStyledComponentsVersion: MessageFunc\n onNoInstalledSanityVersion: MessageFunc\n onNoInstalledStyledComponentsVersion: MessageFunc\n onVersionMismatchInInteractiveAutoUpdate(params: {\n mismatched: CompareDependencyVersions[]\n versionMismatchWarning: string\n }): Promise<{stopBuild: boolean}>\n onVersionMismatchInNonInteractiveAutoUpdate(params: {versionMismatchWarning: string}): void\n}\n\nexport interface BuildOptions {\n appId: string | undefined\n autoUpdatesEnabled: boolean\n checkAppId: () => void\n compareDependencyVersions: (\n packages: {name: string; version: string}[],\n ) => Promise<CompareDependencyVersionsResult>\n determineBasePath: () => string\n eventListener: Partial<BuildStudioEventListener>\n isApp: boolean\n isWorkbenchApp: boolean\n minify: boolean\n outDir: string | undefined\n output: Output\n reactCompiler: boolean | CliConfig['reactCompiler'] | undefined\n schemaExtraction: CliConfig['schemaExtraction']\n sourceMap: boolean\n stats: boolean\n unattendedMode: boolean\n vite: UserViteConfig | undefined\n workDir: string\n\n exposes?: WorkbenchExposes\n /**\n * The build is running under Sanity Blueprints (invoked programmatically by\n * `@sanity/runtime-cli`), so emit the statically-imported resource-bindings\n * module Brett rewrites at deploy. Defaults to `false`, so a normal\n * `sanity build`/`dev`/`preview` never emits it.\n */\n isBlueprints?: boolean\n\n /** The workbench app's bus identity (`__SANITY_APP_ID__`). */\n workbenchAppId?: string\n}\n\n/**\n * Internal build studio that avoids depending on flags for CLI config.\n * @param options - options for the build\n */\nexport async function buildStudio(\n options: BuildOptions,\n): Promise<{mfManifest: Record<string, unknown> | undefined}> {\n buildDebug(`Building studio`)\n\n const timer = getTimer()\n const {\n appId,\n determineBasePath,\n eventListener,\n exposes,\n isApp,\n minify,\n outDir,\n output,\n reactCompiler,\n schemaExtraction,\n sourceMap,\n stats,\n unattendedMode,\n vite,\n workDir,\n } = options\n const defaultOutputDir = path.resolve(path.join(workDir, 'dist'))\n const outputDir = path.resolve(outDir || defaultOutputDir)\n\n await checkStudioDependencyVersions(workDir, output)\n\n // If the check resulted in a dependency install, the CLI command will be re-run,\n // thus we want to exit early\n const {installedSanityVersion} = await checkRequiredDependencies({\n isApp,\n workDir,\n\n ...eventListener,\n })\n\n let autoUpdatesEnabled = options.autoUpdatesEnabled\n\n let autoUpdatesImports = {}\n let autoUpdatesCssUrls: string[] = []\n\n if (autoUpdatesEnabled) {\n // Get the clean version without build metadata: https://semver.org/#spec-item-10\n const cleanSanityVersion = semverParse(installedSanityVersion)?.version\n if (!cleanSanityVersion) {\n throw new Error(`Failed to parse installed Sanity version: ${installedSanityVersion}`)\n }\n\n output.log(`${logSymbols.info} Building with auto-updates enabled`)\n\n // Warn if auto updates enabled but no appId configured\n options.checkAppId()\n\n const installedVisionVersion = await getLocalPackageVersion('@sanity/vision', workDir)\n const cleanVisionVersion = installedVisionVersion\n ? semverParse(installedVisionVersion)?.version\n : undefined\n\n const sanityDependencies = [\n {cssFile: 'index.css', name: 'sanity', version: cleanSanityVersion},\n ...(cleanVisionVersion\n ? [{cssFile: 'index.css', name: '@sanity/vision' as const, version: cleanVisionVersion}]\n : [{name: '@sanity/vision' as const, version: cleanSanityVersion}]),\n ]\n autoUpdatesImports = getAutoUpdatesImportMap(sanityDependencies, {appId})\n\n autoUpdatesCssUrls = getAutoUpdatesCssUrls(sanityDependencies, {appId})\n\n // Check the versions\n const {mismatched, unresolvedPrerelease} =\n await options.compareDependencyVersions(sanityDependencies)\n\n if (unresolvedPrerelease.length > 0) {\n await handlePrereleaseVersions({\n unattendedMode,\n unresolvedPrerelease,\n\n ...eventListener,\n })\n autoUpdatesImports = {}\n autoUpdatesCssUrls = []\n autoUpdatesEnabled = false\n }\n\n if (mismatched.length > 0 && autoUpdatesEnabled) {\n const versionMismatchWarning =\n `The following local package versions are different from the versions currently served at runtime.\\n` +\n `When using auto updates, we recommend that you test locally with the same versions before deploying. \\n\\n` +\n `${mismatched.map((mod) => ` - ${mod.pkg} (local version: ${mod.installed}, runtime version: ${mod.remote})`).join('\\n')}`\n\n const {\n onVersionMismatchInInteractiveAutoUpdate = () => ({stopBuild: true}),\n onVersionMismatchInNonInteractiveAutoUpdate = () => {},\n } = eventListener\n\n // If it is non-interactive or in unattended mode, we don't want to prompt\n if (isInteractive() && !unattendedMode) {\n const {stopBuild} = await onVersionMismatchInInteractiveAutoUpdate({\n mismatched,\n versionMismatchWarning,\n })\n if (stopBuild) return {mfManifest: undefined}\n } else {\n // if non-interactive or unattended, just show the warning\n onVersionMismatchInNonInteractiveAutoUpdate({versionMismatchWarning})\n }\n }\n }\n\n const envVarKeys = Object.keys(getStudioEnvironmentVariables())\n if (envVarKeys.length > 0) {\n output.log('\\nIncluding the following environment variables as part of the JavaScript bundle:')\n for (const key of envVarKeys) {\n output.log(`- ${key}`)\n }\n output.log('')\n }\n\n let shouldClean = true\n if (outputDir !== defaultOutputDir && !unattendedMode && isInteractive()) {\n const {onInteractiveNonDefaultOutputDir = () => ({shouldClean: true})} = eventListener\n ;({shouldClean} = await onInteractiveNonDefaultOutputDir({\n message: `Do you want to delete the existing directory (${outputDir}) first?`,\n }))\n }\n\n // Determine base path for built studio\n const basePath = determineBasePath()\n\n if (schemaExtraction?.enabled) {\n output.log(`${logSymbols.info} Building with schema extraction enabled`)\n }\n\n if (shouldClean) {\n const {onCleanOutputDirEnd = () => {}, onCleanOutputDirStart = () => {}} = eventListener\n timer.start('cleanOutputFolder')\n onCleanOutputDirStart({message: 'Clean output folder'})\n\n await rm(outputDir, {force: true, recursive: true})\n const cleanDuration = timer.end('cleanOutputFolder')\n\n onCleanOutputDirEnd({\n message: `Clean output folder (${cleanDuration.toFixed(0)}ms)`,\n })\n }\n\n const {onBuildEnd = () => {}, onBuildFail = () => {}, onBuildStart = () => {}} = eventListener\n\n onBuildStart({message: `Build Sanity Studio`})\n\n const trace = getCliTelemetry().trace(StudioBuildTrace)\n trace.start()\n\n let autoUpdates\n if (autoUpdatesEnabled) {\n autoUpdates = {\n cssUrls: autoUpdatesCssUrls,\n imports: autoUpdatesImports,\n vendor: await resolveVendorBuildConfig({cwd: workDir, isApp: false}),\n }\n }\n\n try {\n timer.start('bundleStudio')\n\n const bundle = await buildStaticFiles({\n autoUpdates,\n basePath,\n cwd: workDir,\n exposes,\n isBlueprints: options.isBlueprints,\n isWorkbenchApp: options.isWorkbenchApp,\n minify,\n outputDir,\n reactCompiler,\n schemaExtraction,\n sourceMap,\n vite,\n workbenchAppId: options.workbenchAppId,\n })\n const mfManifest = options.isWorkbenchApp ? await readBuiltManifest(outputDir) : undefined\n\n trace.log({\n outputSize: bundle.chunks\n .flatMap((chunk) => chunk.modules.flatMap((mod) => mod.renderedLength))\n .reduce((sum, n) => sum + n, 0),\n })\n const buildDuration = timer.end('bundleStudio')\n\n onBuildEnd({message: `Build Sanity Studio (${buildDuration.toFixed(0)}ms)`})\n\n trace.complete()\n if (stats) {\n output.log('\\nLargest module files:')\n output.log(formatModuleSizes(sortModulesBySize(bundle.chunks).slice(0, 15)))\n }\n return {mfManifest}\n } catch (error) {\n trace.error(error)\n const message = error instanceof Error ? error.message : String(error)\n buildDebug(`Failed to build Sanity Studio`, {error})\n onBuildFail({message: `Failed to build Sanity Studio: ${message}`})\n return {mfManifest: undefined}\n }\n}\n"],"names":["rm","path","getLocalPackageVersion","getCliTelemetry","isInteractive","getTimer","logSymbols","readBuiltManifest","parse","semverParse","StudioBuildTrace","formatModuleSizes","sortModulesBySize","buildDebug","buildStaticFiles","checkRequiredDependencies","checkStudioDependencyVersions","getAutoUpdatesCssUrls","getAutoUpdatesImportMap","getStudioEnvironmentVariables","handlePrereleaseVersions","resolveVendorBuildConfig","buildStudio","options","timer","appId","determineBasePath","eventListener","exposes","isApp","minify","outDir","output","reactCompiler","schemaExtraction","sourceMap","stats","unattendedMode","vite","workDir","defaultOutputDir","resolve","join","outputDir","installedSanityVersion","autoUpdatesEnabled","autoUpdatesImports","autoUpdatesCssUrls","cleanSanityVersion","version","Error","log","info","checkAppId","installedVisionVersion","cleanVisionVersion","undefined","sanityDependencies","cssFile","name","mismatched","unresolvedPrerelease","compareDependencyVersions","length","versionMismatchWarning","map","mod","pkg","installed","remote","onVersionMismatchInInteractiveAutoUpdate","stopBuild","onVersionMismatchInNonInteractiveAutoUpdate","mfManifest","envVarKeys","Object","keys","key","shouldClean","onInteractiveNonDefaultOutputDir","message","basePath","enabled","onCleanOutputDirEnd","onCleanOutputDirStart","start","force","recursive","cleanDuration","end","toFixed","onBuildEnd","onBuildFail","onBuildStart","trace","autoUpdates","cssUrls","imports","vendor","cwd","bundle","isBlueprints","isWorkbenchApp","workbenchAppId","outputSize","chunks","flatMap","chunk","modules","renderedLength","reduce","sum","n","buildDuration","complete","slice","error","String"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/actions/build/buildStudio.ts"],"sourcesContent":["import {rm} from 'node:fs/promises'\nimport path from 'node:path'\n\nimport {getLocalPackageVersion} from '@sanity/cli-core/package-manager'\nimport {getCliTelemetry} from '@sanity/cli-core/telemetry'\nimport {type CliConfig, type Output, type UserViteConfig} from '@sanity/cli-core/types'\nimport {isInteractive} from '@sanity/cli-core/util'\nimport {getTimer, logSymbols} from '@sanity/cli-core/ux'\nimport {readBuiltManifest, type WorkbenchExposes} from '@sanity/workbench-cli/build'\nimport {parse as semverParse} from 'semver'\n\nimport {StudioBuildTrace} from '../../telemetry/build.telemetry.js'\nimport {\n CompareDependencyVersions,\n CompareDependencyVersionsResult,\n getUnavailableVersionsWarning,\n} from '../../util/compareDependencyVersions.js'\nimport {formatModuleSizes, sortModulesBySize} from '../../util/moduleFormatUtils.js'\nimport {buildDebug} from './buildDebug.js'\nimport {buildStaticFiles} from './buildStaticFiles.js'\nimport {checkRequiredDependencies} from './checkRequiredDependencies.js'\nimport {checkStudioDependencyVersions} from './checkStudioDependencyVersions.js'\nimport {type BuildEventListener, type MessageFunc} from './eventListener.js'\nimport {getAutoUpdatesCssUrls, getAutoUpdatesImportMap} from './getAutoUpdatesImportMap.js'\nimport {getStudioEnvironmentVariables} from './getEnvironmentVariables.js'\nimport {handlePrereleaseVersions} from './handlePrereleaseVersions.js'\nimport {resolveVendorBuildConfig} from './resolveVendorBuildConfig.js'\n\nexport interface BuildStudioEventListener extends BuildEventListener {\n onBuildEnd: MessageFunc\n onBuildFail: MessageFunc\n onBuildStart: MessageFunc\n onCleanOutputDirEnd: MessageFunc\n onCleanOutputDirStart: MessageFunc\n onIncompatibleDeclaredStyledComponentsVersionRange: MessageFunc\n onIncompatibleInstalledStyledComponentsVersionRange: MessageFunc\n onInteractiveNonDefaultOutputDir({message}: {message: string}): Promise<{shouldClean: boolean}>\n onInvalidStyledComponentsVersionRange: MessageFunc\n onNoDeclaredStyledComponentsVersion: MessageFunc\n onNoInstalledSanityVersion: MessageFunc\n onNoInstalledStyledComponentsVersion: MessageFunc\n onVersionMismatchInInteractiveAutoUpdate(params: {\n mismatched: CompareDependencyVersions[]\n versionMismatchWarning: string\n }): Promise<{stopBuild: boolean}>\n onVersionMismatchInNonInteractiveAutoUpdate(params: {versionMismatchWarning: string}): void\n}\n\nexport interface BuildOptions {\n appId: string | undefined\n autoUpdatesEnabled: boolean\n checkAppId: () => void\n compareDependencyVersions: (\n packages: {name: string; version: string}[],\n ) => Promise<CompareDependencyVersionsResult>\n determineBasePath: () => string\n eventListener: Partial<BuildStudioEventListener>\n isApp: boolean\n isWorkbenchApp: boolean\n minify: boolean\n outDir: string | undefined\n output: Output\n reactCompiler: boolean | CliConfig['reactCompiler'] | undefined\n schemaExtraction: CliConfig['schemaExtraction']\n sourceMap: boolean\n stats: boolean\n unattendedMode: boolean\n vite: UserViteConfig | undefined\n workDir: string\n\n exposes?: WorkbenchExposes\n /**\n * The build is running under Sanity Blueprints (invoked programmatically by\n * `@sanity/runtime-cli`), so emit the statically-imported resource-bindings\n * module Brett rewrites at deploy. Defaults to `false`, so a normal\n * `sanity build`/`dev`/`preview` never emits it.\n */\n isBlueprints?: boolean\n\n /** The workbench app's bus identity (`__SANITY_APP_ID__`). */\n workbenchAppId?: string\n}\n\n/**\n * Internal build studio that avoids depending on flags for CLI config.\n * @param options - options for the build\n */\nexport async function buildStudio(\n options: BuildOptions,\n): Promise<{mfManifest: Record<string, unknown> | undefined}> {\n buildDebug(`Building studio`)\n\n const timer = getTimer()\n const {\n appId,\n determineBasePath,\n eventListener,\n exposes,\n isApp,\n minify,\n outDir,\n output,\n reactCompiler,\n schemaExtraction,\n sourceMap,\n stats,\n unattendedMode,\n vite,\n workDir,\n } = options\n const defaultOutputDir = path.resolve(path.join(workDir, 'dist'))\n const outputDir = path.resolve(outDir || defaultOutputDir)\n\n await checkStudioDependencyVersions(workDir, output)\n\n // If the check resulted in a dependency install, the CLI command will be re-run,\n // thus we want to exit early\n const {installedSanityVersion} = await checkRequiredDependencies({\n isApp,\n workDir,\n\n ...eventListener,\n })\n\n let autoUpdatesEnabled = options.autoUpdatesEnabled\n\n let autoUpdatesImports = {}\n let autoUpdatesCssUrls: string[] = []\n\n if (autoUpdatesEnabled) {\n // Get the clean version without build metadata: https://semver.org/#spec-item-10\n const cleanSanityVersion = semverParse(installedSanityVersion)?.version\n if (!cleanSanityVersion) {\n throw new Error(`Failed to parse installed Sanity version: ${installedSanityVersion}`)\n }\n\n output.log(`${logSymbols.info} Building with auto-updates enabled`)\n\n // Warn if auto updates enabled but no appId configured\n options.checkAppId()\n\n const installedVisionVersion = await getLocalPackageVersion('@sanity/vision', workDir)\n const cleanVisionVersion = installedVisionVersion\n ? semverParse(installedVisionVersion)?.version\n : undefined\n\n const sanityDependencies = [\n {cssFile: 'index.css', name: 'sanity', version: cleanSanityVersion},\n ...(cleanVisionVersion\n ? [{cssFile: 'index.css', name: '@sanity/vision' as const, version: cleanVisionVersion}]\n : [{name: '@sanity/vision' as const, version: cleanSanityVersion}]),\n ]\n autoUpdatesImports = getAutoUpdatesImportMap(sanityDependencies, {appId})\n\n autoUpdatesCssUrls = getAutoUpdatesCssUrls(sanityDependencies, {appId})\n\n // Check the versions\n const {\n mismatched,\n unavailable = [],\n unresolvedPrerelease,\n } = await options.compareDependencyVersions(sanityDependencies)\n\n if (unavailable.length > 0) {\n output.warn(getUnavailableVersionsWarning(unavailable))\n }\n\n if (unresolvedPrerelease.length > 0) {\n await handlePrereleaseVersions({\n unattendedMode,\n unresolvedPrerelease,\n\n ...eventListener,\n })\n autoUpdatesImports = {}\n autoUpdatesCssUrls = []\n autoUpdatesEnabled = false\n }\n\n if (mismatched.length > 0 && autoUpdatesEnabled) {\n const versionMismatchWarning =\n `The following local package versions are different from the versions currently served at runtime.\\n` +\n `When using auto updates, we recommend that you test locally with the same versions before deploying. \\n\\n` +\n `${mismatched.map((mod) => ` - ${mod.pkg} (local version: ${mod.installed}, runtime version: ${mod.remote})`).join('\\n')}`\n\n const {\n onVersionMismatchInInteractiveAutoUpdate = () => ({stopBuild: true}),\n onVersionMismatchInNonInteractiveAutoUpdate = () => {},\n } = eventListener\n\n // If it is non-interactive or in unattended mode, we don't want to prompt\n if (isInteractive() && !unattendedMode) {\n const {stopBuild} = await onVersionMismatchInInteractiveAutoUpdate({\n mismatched,\n versionMismatchWarning,\n })\n if (stopBuild) return {mfManifest: undefined}\n } else {\n // if non-interactive or unattended, just show the warning\n onVersionMismatchInNonInteractiveAutoUpdate({versionMismatchWarning})\n }\n }\n }\n\n const envVarKeys = Object.keys(getStudioEnvironmentVariables())\n if (envVarKeys.length > 0) {\n output.log('\\nIncluding the following environment variables as part of the JavaScript bundle:')\n for (const key of envVarKeys) {\n output.log(`- ${key}`)\n }\n output.log('')\n }\n\n let shouldClean = true\n if (outputDir !== defaultOutputDir && !unattendedMode && isInteractive()) {\n const {onInteractiveNonDefaultOutputDir = () => ({shouldClean: true})} = eventListener\n ;({shouldClean} = await onInteractiveNonDefaultOutputDir({\n message: `Do you want to delete the existing directory (${outputDir}) first?`,\n }))\n }\n\n // Determine base path for built studio\n const basePath = determineBasePath()\n\n if (schemaExtraction?.enabled) {\n output.log(`${logSymbols.info} Building with schema extraction enabled`)\n }\n\n if (shouldClean) {\n const {onCleanOutputDirEnd = () => {}, onCleanOutputDirStart = () => {}} = eventListener\n timer.start('cleanOutputFolder')\n onCleanOutputDirStart({message: 'Clean output folder'})\n\n await rm(outputDir, {force: true, recursive: true})\n const cleanDuration = timer.end('cleanOutputFolder')\n\n onCleanOutputDirEnd({\n message: `Clean output folder (${cleanDuration.toFixed(0)}ms)`,\n })\n }\n\n const {onBuildEnd = () => {}, onBuildFail = () => {}, onBuildStart = () => {}} = eventListener\n\n onBuildStart({message: `Build Sanity Studio`})\n\n const trace = getCliTelemetry().trace(StudioBuildTrace)\n trace.start()\n\n let autoUpdates\n if (autoUpdatesEnabled) {\n autoUpdates = {\n cssUrls: autoUpdatesCssUrls,\n imports: autoUpdatesImports,\n vendor: await resolveVendorBuildConfig({cwd: workDir, isApp: false}),\n }\n }\n\n try {\n timer.start('bundleStudio')\n\n const bundle = await buildStaticFiles({\n autoUpdates,\n basePath,\n cwd: workDir,\n exposes,\n isBlueprints: options.isBlueprints,\n isWorkbenchApp: options.isWorkbenchApp,\n minify,\n outputDir,\n reactCompiler,\n schemaExtraction,\n sourceMap,\n vite,\n workbenchAppId: options.workbenchAppId,\n })\n const mfManifest = options.isWorkbenchApp ? await readBuiltManifest(outputDir) : undefined\n\n trace.log({\n outputSize: bundle.chunks\n .flatMap((chunk) => chunk.modules.flatMap((mod) => mod.renderedLength))\n .reduce((sum, n) => sum + n, 0),\n })\n const buildDuration = timer.end('bundleStudio')\n\n onBuildEnd({message: `Build Sanity Studio (${buildDuration.toFixed(0)}ms)`})\n\n trace.complete()\n if (stats) {\n output.log('\\nLargest module files:')\n output.log(formatModuleSizes(sortModulesBySize(bundle.chunks).slice(0, 15)))\n }\n return {mfManifest}\n } catch (error) {\n trace.error(error)\n const message = error instanceof Error ? error.message : String(error)\n buildDebug(`Failed to build Sanity Studio`, {error})\n onBuildFail({message: `Failed to build Sanity Studio: ${message}`})\n return {mfManifest: undefined}\n }\n}\n"],"names":["rm","path","getLocalPackageVersion","getCliTelemetry","isInteractive","getTimer","logSymbols","readBuiltManifest","parse","semverParse","StudioBuildTrace","getUnavailableVersionsWarning","formatModuleSizes","sortModulesBySize","buildDebug","buildStaticFiles","checkRequiredDependencies","checkStudioDependencyVersions","getAutoUpdatesCssUrls","getAutoUpdatesImportMap","getStudioEnvironmentVariables","handlePrereleaseVersions","resolveVendorBuildConfig","buildStudio","options","timer","appId","determineBasePath","eventListener","exposes","isApp","minify","outDir","output","reactCompiler","schemaExtraction","sourceMap","stats","unattendedMode","vite","workDir","defaultOutputDir","resolve","join","outputDir","installedSanityVersion","autoUpdatesEnabled","autoUpdatesImports","autoUpdatesCssUrls","cleanSanityVersion","version","Error","log","info","checkAppId","installedVisionVersion","cleanVisionVersion","undefined","sanityDependencies","cssFile","name","mismatched","unavailable","unresolvedPrerelease","compareDependencyVersions","length","warn","versionMismatchWarning","map","mod","pkg","installed","remote","onVersionMismatchInInteractiveAutoUpdate","stopBuild","onVersionMismatchInNonInteractiveAutoUpdate","mfManifest","envVarKeys","Object","keys","key","shouldClean","onInteractiveNonDefaultOutputDir","message","basePath","enabled","onCleanOutputDirEnd","onCleanOutputDirStart","start","force","recursive","cleanDuration","end","toFixed","onBuildEnd","onBuildFail","onBuildStart","trace","autoUpdates","cssUrls","imports","vendor","cwd","bundle","isBlueprints","isWorkbenchApp","workbenchAppId","outputSize","chunks","flatMap","chunk","modules","renderedLength","reduce","sum","n","buildDuration","complete","slice","error","String"],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ import { gte, parse } from 'semver';
2
+ /**
3
+ * The first `sanity` release that reads `globalThis.__SANITY_AUTH_HASH_PARAMS__`
4
+ * (sanity-io/sanity#15337). Older studios only read the URL hash, so stripping the params
5
+ * would break their login. Must match the release that ships that PR.
6
+ *
7
+ * @internal
8
+ */ export const MIN_SANITY_VERSION_READING_AUTH_HASH_STASH = '6.22.0';
9
+ /**
10
+ * Removes the `sid`, `token` and `claim` params from the URL hash and stores their raw values
11
+ * on `globalThis.__SANITY_AUTH_HASH_PARAMS__`, where the studio reads them. Running this before
12
+ * the bundle means the secrets are gone from the address bar even if the bundle fails to load.
13
+ */ const authHashScript = `try {
14
+ const params = location.hash.slice(1).split('&');
15
+ const kept = params.filter(function (param) {
16
+ var match = /^(sid|token|claim)=(.*)$/.exec(param);
17
+ if (!match) return true;
18
+ var found = (globalThis.__SANITY_AUTH_HASH_PARAMS__ = globalThis.__SANITY_AUTH_HASH_PARAMS__ || {});
19
+ if (!(match[1] in found)) found[match[1]] = match[2];
20
+ return false;
21
+ });
22
+ if (kept.length !== params.length) {
23
+ history.replaceState(history.state, '', location.pathname + location.search + (kept.length ? '#' + kept.join('&') : ''));
24
+ }
25
+ } catch (err) {}`;
26
+ /**
27
+ * Decorates the given HTML template with a script tag that removes auth
28
+ * secrets from the URL hash. The script is injected as the first child
29
+ * of `<head>` so it runs before any other script. Studio documents only:
30
+ * apps rely on `@sanity/sdk` reading `sid` from the hash itself. Returns
31
+ * the template unchanged unless `sanityVersion` reads the stashed params.
32
+ *
33
+ * @internal
34
+ */ export function decorateIndexWithAuthHashScript(template, sanityVersion) {
35
+ const parsed = sanityVersion ? parse(sanityVersion) : null;
36
+ if (!parsed || !gte(parsed, MIN_SANITY_VERSION_READING_AUTH_HASH_STASH)) {
37
+ return template;
38
+ }
39
+ return template.replace(/<head([^>]*)>/, (_, attributes)=>`<head${attributes}>\n<script>${authHashScript}</script>`);
40
+ }
41
+
42
+ //# sourceMappingURL=decorateIndexWithAuthHashScript.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/actions/build/decorateIndexWithAuthHashScript.ts"],"sourcesContent":["import {gte, parse} from 'semver'\n\n/**\n * The first `sanity` release that reads `globalThis.__SANITY_AUTH_HASH_PARAMS__`\n * (sanity-io/sanity#15337). Older studios only read the URL hash, so stripping the params\n * would break their login. Must match the release that ships that PR.\n *\n * @internal\n */\nexport const MIN_SANITY_VERSION_READING_AUTH_HASH_STASH = '6.22.0'\n\n/**\n * Removes the `sid`, `token` and `claim` params from the URL hash and stores their raw values\n * on `globalThis.__SANITY_AUTH_HASH_PARAMS__`, where the studio reads them. Running this before\n * the bundle means the secrets are gone from the address bar even if the bundle fails to load.\n */\nconst authHashScript = `try {\n const params = location.hash.slice(1).split('&');\n const kept = params.filter(function (param) {\n var match = /^(sid|token|claim)=(.*)$/.exec(param);\n if (!match) return true;\n var found = (globalThis.__SANITY_AUTH_HASH_PARAMS__ = globalThis.__SANITY_AUTH_HASH_PARAMS__ || {});\n if (!(match[1] in found)) found[match[1]] = match[2];\n return false;\n });\n if (kept.length !== params.length) {\n history.replaceState(history.state, '', location.pathname + location.search + (kept.length ? '#' + kept.join('&') : ''));\n }\n} catch (err) {}`\n\n/**\n * Decorates the given HTML template with a script tag that removes auth\n * secrets from the URL hash. The script is injected as the first child\n * of `<head>` so it runs before any other script. Studio documents only:\n * apps rely on `@sanity/sdk` reading `sid` from the hash itself. Returns\n * the template unchanged unless `sanityVersion` reads the stashed params.\n *\n * @internal\n */\nexport function decorateIndexWithAuthHashScript(\n template: string,\n sanityVersion: string | null,\n): string {\n const parsed = sanityVersion ? parse(sanityVersion) : null\n if (!parsed || !gte(parsed, MIN_SANITY_VERSION_READING_AUTH_HASH_STASH)) {\n return template\n }\n\n return template.replace(\n /<head([^>]*)>/,\n (_, attributes) => `<head${attributes}>\\n<script>${authHashScript}</script>`,\n )\n}\n"],"names":["gte","parse","MIN_SANITY_VERSION_READING_AUTH_HASH_STASH","authHashScript","decorateIndexWithAuthHashScript","template","sanityVersion","parsed","replace","_","attributes"],"mappings":"AAAA,SAAQA,GAAG,EAAEC,KAAK,QAAO,SAAQ;AAEjC;;;;;;CAMC,GACD,OAAO,MAAMC,6CAA6C,SAAQ;AAElE;;;;CAIC,GACD,MAAMC,iBAAiB,CAAC;;;;;;;;;;;;gBAYR,CAAC;AAEjB;;;;;;;;CAQC,GACD,OAAO,SAASC,gCACdC,QAAgB,EAChBC,aAA4B;IAE5B,MAAMC,SAASD,gBAAgBL,MAAMK,iBAAiB;IACtD,IAAI,CAACC,UAAU,CAACP,IAAIO,QAAQL,6CAA6C;QACvE,OAAOG;IACT;IAEA,OAAOA,SAASG,OAAO,CACrB,iBACA,CAACC,GAAGC,aAAe,CAAC,KAAK,EAAEA,WAAW,WAAW,EAAEP,eAAe,SAAS,CAAC;AAEhF"}
@@ -1,4 +1,6 @@
1
+ import { getLocalPackageVersion } from '@sanity/cli-core/package-manager';
1
2
  import { createVendorImportMapFromBundle } from '../createVendorImportMapFromBundle.js';
3
+ import { decorateIndexWithAuthHashScript } from '../decorateIndexWithAuthHashScript.js';
2
4
  import { decorateIndexWithBridgeScript } from '../decorateIndexWithBridgeScript.js';
3
5
  import { decorateIndexWithStagingScript } from '../decorateIndexWithStagingScript.js';
4
6
  import { renderDocument } from '../renderDocument.js';
@@ -49,9 +51,10 @@ export function sanityBuildEntries(options) {
49
51
  },
50
52
  studioRootPath: cwd
51
53
  });
54
+ const source = decorateIndexWithStagingScript(bridge ? decorateIndexWithBridgeScript(html) : html);
52
55
  this.emitFile({
53
56
  fileName: 'index.html',
54
- source: decorateIndexWithStagingScript(bridge ? decorateIndexWithBridgeScript(html) : html),
57
+ source: isApp ? source : decorateIndexWithAuthHashScript(source, await getLocalPackageVersion('sanity', cwd)),
55
58
  type: 'asset'
56
59
  });
57
60
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/actions/build/vite/plugin-sanity-build-entries.ts"],"sourcesContent":["import {type ChunkMetadata, type Plugin} from 'vite'\n\nimport {type AutoUpdatesBuildConfig} from '../autoUpdates.js'\nimport {createVendorImportMapFromBundle} from '../createVendorImportMapFromBundle.js'\nimport {decorateIndexWithBridgeScript} from '../decorateIndexWithBridgeScript.js'\nimport {decorateIndexWithStagingScript} from '../decorateIndexWithStagingScript.js'\nimport {renderDocument} from '../renderDocument.js'\n\ninterface ViteOutputBundle {\n [fileName: string]: ViteRenderedAsset | ViteRenderedChunk\n}\n\ninterface ViteRenderedAsset {\n type: 'asset'\n\n fileName?: string\n name?: string | null\n names?: string[]\n}\n\ninterface ViteRenderedChunk {\n code: string\n facadeModuleId: string | null\n fileName: string\n imports: string[]\n isEntry: boolean\n name: string\n type: 'chunk'\n\n /**\n * Populated by Vite when `build.cssCodeSplit` is true. Rolldown-based Vite\n * (Vite 7/8 and `rolldown-vite`) may omit it, or leave `importedCss` empty,\n * for the single stylesheet emitted when code splitting is disabled.\n */\n viteMetadata?: ChunkMetadata\n}\n\nconst entryChunkId = '.sanity/runtime/app.js'\n\n/**\n * Logical name Vite gives the single CSS asset emitted when\n * `build.cssCodeSplit` is false. `assetFileNames` can change the file written\n * to disk; `names` still carries this value.\n */\nconst CSS_BUNDLE_NAME = 'style.css'\n\nexport function sanityBuildEntries(options: {\n autoUpdates?: AutoUpdatesBuildConfig\n basePath: string\n /**\n * Injects the core-ui bridge script into the emitted `index.html`. Defaults to\n * `true`. Workbench remotes serve themselves standalone and pass `false`.\n */\n bridge?: boolean\n cwd: string\n isApp?: boolean\n}): Plugin {\n const {autoUpdates, basePath, bridge = true, cwd, isApp} = options\n // Vite's default. `configResolved` replaces this with the resolved value,\n // including a userland `vite` config that sets `build.cssCodeSplit: false`.\n let cssCodeSplit = true\n\n const generateBundle: Extract<Plugin['generateBundle'], {handler: unknown}> = {\n async handler(_options, outputBundle) {\n const bundle = outputBundle as unknown as ViteOutputBundle\n const entryFile = Object.values(bundle).find(\n (file) =>\n file.type === 'chunk' &&\n file.name === 'sanity' &&\n file.facadeModuleId?.endsWith(entryChunkId),\n )\n\n if (!entryFile) {\n throw new Error(`Failed to find entry file in bundle (${entryChunkId})`)\n }\n\n if (entryFile.type !== 'chunk') {\n throw new Error('Entry file is not a chunk')\n }\n\n const entryFileName = entryFile.fileName\n const entryPath = [basePath.replace(/\\/+$/, ''), entryFileName].join('/')\n const css = collectStylesheets(entryFile, bundle, cssCodeSplit)\n\n // For auto-updating studios/apps the import map combines the vendor\n // chunks emitted by this very build (hashed filenames, resolved from the\n // bundle) with the module-CDN imports for auto-updated packages.\n const importMap = autoUpdates\n ? {\n imports: {\n ...createVendorImportMapFromBundle(\n bundle,\n autoUpdates.vendor.specifiersByChunkName,\n basePath,\n ),\n ...autoUpdates.imports,\n },\n }\n : undefined\n\n const html = await renderDocument({\n autoUpdatesCssUrls: autoUpdates?.cssUrls,\n importMap,\n isApp,\n props: {\n basePath,\n css,\n entryPath,\n },\n studioRootPath: cwd,\n })\n\n this.emitFile({\n fileName: 'index.html',\n source: decorateIndexWithStagingScript(bridge ? decorateIndexWithBridgeScript(html) : html),\n type: 'asset',\n })\n },\n }\n\n return {\n apply: 'build',\n name: 'sanity/server/build-entries',\n\n configResolved(resolved) {\n cssCodeSplit = resolved.build.cssCodeSplit\n // `vite:css-post` emits the combined stylesheet during its own unordered\n // `generateBundle`, so with `cssCodeSplit: false` this hook has to run\n // after it. Default builds keep the normal order so user plugins with an\n // unordered `generateBundle` (HTML minifiers, SRI) still see `index.html`.\n generateBundle.order = cssCodeSplit ? undefined : 'post'\n },\n\n buildStart() {\n this.emitFile({\n id: entryChunkId,\n name: 'sanity',\n type: 'chunk',\n })\n },\n\n generateBundle,\n }\n}\n\n/**\n * Stylesheets the document should link.\n *\n * With CSS code splitting, Vite records each chunk's styles on\n * `viteMetadata.importedCss` (including the chunks the entry statically\n * imports). With `cssCodeSplit: false`, Vite emits one combined asset instead\n * and never adds it to `importedCss`. `vite:build-html` finds that asset by\n * its bundle name (`style.css`); mirror that. Other CSS assets (e.g. `?url`\n * imports) are not stylesheets for the document and must not be linked.\n */\nfunction collectStylesheets(\n entryFile: ViteRenderedChunk,\n bundle: ViteOutputBundle,\n cssCodeSplit: boolean,\n): string[] {\n const css = collectImportedCss(entryFile, bundle)\n if (cssCodeSplit) return css\n\n const seen = new Set(css)\n for (const fileName of collectCombinedStylesheets(bundle)) {\n if (seen.has(fileName)) continue\n seen.add(fileName)\n css.push(fileName)\n }\n return css\n}\n\nfunction collectImportedCss(entryFile: ViteRenderedChunk, bundle: ViteOutputBundle): string[] {\n const css = cssFilesFromChunk(entryFile)\n for (const key of entryFile.imports) {\n const imported = bundle[key]\n if (imported?.type === 'chunk') css.push(...cssFilesFromChunk(imported))\n }\n return css\n}\n\nfunction cssFilesFromChunk(chunk: ViteRenderedChunk): string[] {\n const imported = chunk.viteMetadata?.importedCss\n if (!imported) return []\n return [...imported]\n}\n\nfunction collectCombinedStylesheets(bundle: ViteOutputBundle): string[] {\n return Object.values(bundle).flatMap((file) =>\n file.type === 'asset' && file.fileName && isCombinedCssBundle(file) ? [file.fileName] : [],\n )\n}\n\nfunction isCombinedCssBundle(asset: ViteRenderedAsset): boolean {\n return asset.names ? asset.names.includes(CSS_BUNDLE_NAME) : asset.name === CSS_BUNDLE_NAME\n}\n"],"names":["createVendorImportMapFromBundle","decorateIndexWithBridgeScript","decorateIndexWithStagingScript","renderDocument","entryChunkId","CSS_BUNDLE_NAME","sanityBuildEntries","options","autoUpdates","basePath","bridge","cwd","isApp","cssCodeSplit","generateBundle","handler","_options","outputBundle","bundle","entryFile","Object","values","find","file","type","name","facadeModuleId","endsWith","Error","entryFileName","fileName","entryPath","replace","join","css","collectStylesheets","importMap","imports","vendor","specifiersByChunkName","undefined","html","autoUpdatesCssUrls","cssUrls","props","studioRootPath","emitFile","source","apply","configResolved","resolved","build","order","buildStart","id","collectImportedCss","seen","Set","collectCombinedStylesheets","has","add","push","cssFilesFromChunk","key","imported","chunk","viteMetadata","importedCss","flatMap","isCombinedCssBundle","asset","names","includes"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../src/actions/build/vite/plugin-sanity-build-entries.ts"],"sourcesContent":["import {getLocalPackageVersion} from '@sanity/cli-core/package-manager'\nimport {type ChunkMetadata, type Plugin} from 'vite'\n\nimport {type AutoUpdatesBuildConfig} from '../autoUpdates.js'\nimport {createVendorImportMapFromBundle} from '../createVendorImportMapFromBundle.js'\nimport {decorateIndexWithAuthHashScript} from '../decorateIndexWithAuthHashScript.js'\nimport {decorateIndexWithBridgeScript} from '../decorateIndexWithBridgeScript.js'\nimport {decorateIndexWithStagingScript} from '../decorateIndexWithStagingScript.js'\nimport {renderDocument} from '../renderDocument.js'\n\ninterface ViteOutputBundle {\n [fileName: string]: ViteRenderedAsset | ViteRenderedChunk\n}\n\ninterface ViteRenderedAsset {\n type: 'asset'\n\n fileName?: string\n name?: string | null\n names?: string[]\n}\n\ninterface ViteRenderedChunk {\n code: string\n facadeModuleId: string | null\n fileName: string\n imports: string[]\n isEntry: boolean\n name: string\n type: 'chunk'\n\n /**\n * Populated by Vite when `build.cssCodeSplit` is true. Rolldown-based Vite\n * (Vite 7/8 and `rolldown-vite`) may omit it, or leave `importedCss` empty,\n * for the single stylesheet emitted when code splitting is disabled.\n */\n viteMetadata?: ChunkMetadata\n}\n\nconst entryChunkId = '.sanity/runtime/app.js'\n\n/**\n * Logical name Vite gives the single CSS asset emitted when\n * `build.cssCodeSplit` is false. `assetFileNames` can change the file written\n * to disk; `names` still carries this value.\n */\nconst CSS_BUNDLE_NAME = 'style.css'\n\nexport function sanityBuildEntries(options: {\n autoUpdates?: AutoUpdatesBuildConfig\n basePath: string\n /**\n * Injects the core-ui bridge script into the emitted `index.html`. Defaults to\n * `true`. Workbench remotes serve themselves standalone and pass `false`.\n */\n bridge?: boolean\n cwd: string\n isApp?: boolean\n}): Plugin {\n const {autoUpdates, basePath, bridge = true, cwd, isApp} = options\n // Vite's default. `configResolved` replaces this with the resolved value,\n // including a userland `vite` config that sets `build.cssCodeSplit: false`.\n let cssCodeSplit = true\n\n const generateBundle: Extract<Plugin['generateBundle'], {handler: unknown}> = {\n async handler(_options, outputBundle) {\n const bundle = outputBundle as unknown as ViteOutputBundle\n const entryFile = Object.values(bundle).find(\n (file) =>\n file.type === 'chunk' &&\n file.name === 'sanity' &&\n file.facadeModuleId?.endsWith(entryChunkId),\n )\n\n if (!entryFile) {\n throw new Error(`Failed to find entry file in bundle (${entryChunkId})`)\n }\n\n if (entryFile.type !== 'chunk') {\n throw new Error('Entry file is not a chunk')\n }\n\n const entryFileName = entryFile.fileName\n const entryPath = [basePath.replace(/\\/+$/, ''), entryFileName].join('/')\n const css = collectStylesheets(entryFile, bundle, cssCodeSplit)\n\n // For auto-updating studios/apps the import map combines the vendor\n // chunks emitted by this very build (hashed filenames, resolved from the\n // bundle) with the module-CDN imports for auto-updated packages.\n const importMap = autoUpdates\n ? {\n imports: {\n ...createVendorImportMapFromBundle(\n bundle,\n autoUpdates.vendor.specifiersByChunkName,\n basePath,\n ),\n ...autoUpdates.imports,\n },\n }\n : undefined\n\n const html = await renderDocument({\n autoUpdatesCssUrls: autoUpdates?.cssUrls,\n importMap,\n isApp,\n props: {\n basePath,\n css,\n entryPath,\n },\n studioRootPath: cwd,\n })\n\n const source = decorateIndexWithStagingScript(\n bridge ? decorateIndexWithBridgeScript(html) : html,\n )\n\n this.emitFile({\n fileName: 'index.html',\n source: isApp\n ? source\n : decorateIndexWithAuthHashScript(source, await getLocalPackageVersion('sanity', cwd)),\n type: 'asset',\n })\n },\n }\n\n return {\n apply: 'build',\n name: 'sanity/server/build-entries',\n\n configResolved(resolved) {\n cssCodeSplit = resolved.build.cssCodeSplit\n // `vite:css-post` emits the combined stylesheet during its own unordered\n // `generateBundle`, so with `cssCodeSplit: false` this hook has to run\n // after it. Default builds keep the normal order so user plugins with an\n // unordered `generateBundle` (HTML minifiers, SRI) still see `index.html`.\n generateBundle.order = cssCodeSplit ? undefined : 'post'\n },\n\n buildStart() {\n this.emitFile({\n id: entryChunkId,\n name: 'sanity',\n type: 'chunk',\n })\n },\n\n generateBundle,\n }\n}\n\n/**\n * Stylesheets the document should link.\n *\n * With CSS code splitting, Vite records each chunk's styles on\n * `viteMetadata.importedCss` (including the chunks the entry statically\n * imports). With `cssCodeSplit: false`, Vite emits one combined asset instead\n * and never adds it to `importedCss`. `vite:build-html` finds that asset by\n * its bundle name (`style.css`); mirror that. Other CSS assets (e.g. `?url`\n * imports) are not stylesheets for the document and must not be linked.\n */\nfunction collectStylesheets(\n entryFile: ViteRenderedChunk,\n bundle: ViteOutputBundle,\n cssCodeSplit: boolean,\n): string[] {\n const css = collectImportedCss(entryFile, bundle)\n if (cssCodeSplit) return css\n\n const seen = new Set(css)\n for (const fileName of collectCombinedStylesheets(bundle)) {\n if (seen.has(fileName)) continue\n seen.add(fileName)\n css.push(fileName)\n }\n return css\n}\n\nfunction collectImportedCss(entryFile: ViteRenderedChunk, bundle: ViteOutputBundle): string[] {\n const css = cssFilesFromChunk(entryFile)\n for (const key of entryFile.imports) {\n const imported = bundle[key]\n if (imported?.type === 'chunk') css.push(...cssFilesFromChunk(imported))\n }\n return css\n}\n\nfunction cssFilesFromChunk(chunk: ViteRenderedChunk): string[] {\n const imported = chunk.viteMetadata?.importedCss\n if (!imported) return []\n return [...imported]\n}\n\nfunction collectCombinedStylesheets(bundle: ViteOutputBundle): string[] {\n return Object.values(bundle).flatMap((file) =>\n file.type === 'asset' && file.fileName && isCombinedCssBundle(file) ? [file.fileName] : [],\n )\n}\n\nfunction isCombinedCssBundle(asset: ViteRenderedAsset): boolean {\n return asset.names ? asset.names.includes(CSS_BUNDLE_NAME) : asset.name === CSS_BUNDLE_NAME\n}\n"],"names":["getLocalPackageVersion","createVendorImportMapFromBundle","decorateIndexWithAuthHashScript","decorateIndexWithBridgeScript","decorateIndexWithStagingScript","renderDocument","entryChunkId","CSS_BUNDLE_NAME","sanityBuildEntries","options","autoUpdates","basePath","bridge","cwd","isApp","cssCodeSplit","generateBundle","handler","_options","outputBundle","bundle","entryFile","Object","values","find","file","type","name","facadeModuleId","endsWith","Error","entryFileName","fileName","entryPath","replace","join","css","collectStylesheets","importMap","imports","vendor","specifiersByChunkName","undefined","html","autoUpdatesCssUrls","cssUrls","props","studioRootPath","source","emitFile","apply","configResolved","resolved","build","order","buildStart","id","collectImportedCss","seen","Set","collectCombinedStylesheets","has","add","push","cssFilesFromChunk","key","imported","chunk","viteMetadata","importedCss","flatMap","isCombinedCssBundle","asset","names","includes"],"mappings":"AAAA,SAAQA,sBAAsB,QAAO,mCAAkC;AAIvE,SAAQC,+BAA+B,QAAO,wCAAuC;AACrF,SAAQC,+BAA+B,QAAO,wCAAuC;AACrF,SAAQC,6BAA6B,QAAO,sCAAqC;AACjF,SAAQC,8BAA8B,QAAO,uCAAsC;AACnF,SAAQC,cAAc,QAAO,uBAAsB;AA+BnD,MAAMC,eAAe;AAErB;;;;CAIC,GACD,MAAMC,kBAAkB;AAExB,OAAO,SAASC,mBAAmBC,OAUlC;IACC,MAAM,EAACC,WAAW,EAAEC,QAAQ,EAAEC,SAAS,IAAI,EAAEC,GAAG,EAAEC,KAAK,EAAC,GAAGL;IAC3D,0EAA0E;IAC1E,4EAA4E;IAC5E,IAAIM,eAAe;IAEnB,MAAMC,iBAAwE;QAC5E,MAAMC,SAAQC,QAAQ,EAAEC,YAAY;YAClC,MAAMC,SAASD;YACf,MAAME,YAAYC,OAAOC,MAAM,CAACH,QAAQI,IAAI,CAC1C,CAACC,OACCA,KAAKC,IAAI,KAAK,WACdD,KAAKE,IAAI,KAAK,YACdF,KAAKG,cAAc,EAAEC,SAASvB;YAGlC,IAAI,CAACe,WAAW;gBACd,MAAM,IAAIS,MAAM,CAAC,qCAAqC,EAAExB,aAAa,CAAC,CAAC;YACzE;YAEA,IAAIe,UAAUK,IAAI,KAAK,SAAS;gBAC9B,MAAM,IAAII,MAAM;YAClB;YAEA,MAAMC,gBAAgBV,UAAUW,QAAQ;YACxC,MAAMC,YAAY;gBAACtB,SAASuB,OAAO,CAAC,QAAQ;gBAAKH;aAAc,CAACI,IAAI,CAAC;YACrE,MAAMC,MAAMC,mBAAmBhB,WAAWD,QAAQL;YAElD,oEAAoE;YACpE,yEAAyE;YACzE,iEAAiE;YACjE,MAAMuB,YAAY5B,cACd;gBACE6B,SAAS;oBACP,GAAGtC,gCACDmB,QACAV,YAAY8B,MAAM,CAACC,qBAAqB,EACxC9B,SACD;oBACD,GAAGD,YAAY6B,OAAO;gBACxB;YACF,IACAG;YAEJ,MAAMC,OAAO,MAAMtC,eAAe;gBAChCuC,oBAAoBlC,aAAamC;gBACjCP;gBACAxB;gBACAgC,OAAO;oBACLnC;oBACAyB;oBACAH;gBACF;gBACAc,gBAAgBlC;YAClB;YAEA,MAAMmC,SAAS5C,+BACbQ,SAAST,8BAA8BwC,QAAQA;YAGjD,IAAI,CAACM,QAAQ,CAAC;gBACZjB,UAAU;gBACVgB,QAAQlC,QACJkC,SACA9C,gCAAgC8C,QAAQ,MAAMhD,uBAAuB,UAAUa;gBACnFa,MAAM;YACR;QACF;IACF;IAEA,OAAO;QACLwB,OAAO;QACPvB,MAAM;QAENwB,gBAAeC,QAAQ;YACrBrC,eAAeqC,SAASC,KAAK,CAACtC,YAAY;YAC1C,yEAAyE;YACzE,uEAAuE;YACvE,yEAAyE;YACzE,2EAA2E;YAC3EC,eAAesC,KAAK,GAAGvC,eAAe2B,YAAY;QACpD;QAEAa;YACE,IAAI,CAACN,QAAQ,CAAC;gBACZO,IAAIlD;gBACJqB,MAAM;gBACND,MAAM;YACR;QACF;QAEAV;IACF;AACF;AAEA;;;;;;;;;CASC,GACD,SAASqB,mBACPhB,SAA4B,EAC5BD,MAAwB,EACxBL,YAAqB;IAErB,MAAMqB,MAAMqB,mBAAmBpC,WAAWD;IAC1C,IAAIL,cAAc,OAAOqB;IAEzB,MAAMsB,OAAO,IAAIC,IAAIvB;IACrB,KAAK,MAAMJ,YAAY4B,2BAA2BxC,QAAS;QACzD,IAAIsC,KAAKG,GAAG,CAAC7B,WAAW;QACxB0B,KAAKI,GAAG,CAAC9B;QACTI,IAAI2B,IAAI,CAAC/B;IACX;IACA,OAAOI;AACT;AAEA,SAASqB,mBAAmBpC,SAA4B,EAAED,MAAwB;IAChF,MAAMgB,MAAM4B,kBAAkB3C;IAC9B,KAAK,MAAM4C,OAAO5C,UAAUkB,OAAO,CAAE;QACnC,MAAM2B,WAAW9C,MAAM,CAAC6C,IAAI;QAC5B,IAAIC,UAAUxC,SAAS,SAASU,IAAI2B,IAAI,IAAIC,kBAAkBE;IAChE;IACA,OAAO9B;AACT;AAEA,SAAS4B,kBAAkBG,KAAwB;IACjD,MAAMD,WAAWC,MAAMC,YAAY,EAAEC;IACrC,IAAI,CAACH,UAAU,OAAO,EAAE;IACxB,OAAO;WAAIA;KAAS;AACtB;AAEA,SAASN,2BAA2BxC,MAAwB;IAC1D,OAAOE,OAAOC,MAAM,CAACH,QAAQkD,OAAO,CAAC,CAAC7C,OACpCA,KAAKC,IAAI,KAAK,WAAWD,KAAKO,QAAQ,IAAIuC,oBAAoB9C,QAAQ;YAACA,KAAKO,QAAQ;SAAC,GAAG,EAAE;AAE9F;AAEA,SAASuC,oBAAoBC,KAAwB;IACnD,OAAOA,MAAMC,KAAK,GAAGD,MAAMC,KAAK,CAACC,QAAQ,CAACnE,mBAAmBiE,MAAM7C,IAAI,KAAKpB;AAC9E"}
@@ -1,9 +1,11 @@
1
1
  import { mkdir, writeFile } from 'node:fs/promises';
2
2
  import path from 'node:path';
3
3
  import { tryFindStudioConfigPath } from '@sanity/cli-core/config';
4
+ import { getLocalPackageVersion } from '@sanity/cli-core/package-manager';
4
5
  import { RESOURCE_BINDINGS_FILENAME, RESOURCE_BINDINGS_MODULE_SOURCE } from '@sanity/workbench-cli/build';
5
6
  import { watch as chokidarWatch } from 'chokidar';
6
7
  import { buildDebug } from './buildDebug.js';
8
+ import { decorateIndexWithAuthHashScript } from './decorateIndexWithAuthHashScript.js';
7
9
  import { decorateIndexWithAutoGeneratedWarning } from './decorateIndexWithAutoGeneratedWarning.js';
8
10
  import { decorateIndexWithBridgeScript } from './decorateIndexWithBridgeScript.js';
9
11
  import { decorateIndexWithStagingScript } from './decorateIndexWithStagingScript.js';
@@ -24,9 +26,10 @@ import { renderDocument } from './renderDocument.js';
24
26
  await mkdir(runtimeDir, {
25
27
  recursive: true
26
28
  });
29
+ const sanityVersion = isApp ? null : await getLocalPackageVersion('sanity', cwd);
27
30
  async function renderAndWriteDocument() {
28
31
  buildDebug('Rendering document template');
29
- const indexHtml = decorateIndexWithStagingScript(decorateIndexWithBridgeScript(decorateIndexWithAutoGeneratedWarning(await renderDocument({
32
+ const html = decorateIndexWithStagingScript(decorateIndexWithBridgeScript(decorateIndexWithAutoGeneratedWarning(await renderDocument({
30
33
  isApp,
31
34
  props: {
32
35
  basePath: basePath || '/',
@@ -35,6 +38,7 @@ import { renderDocument } from './renderDocument.js';
35
38
  },
36
39
  studioRootPath: cwd
37
40
  }))));
41
+ const indexHtml = isApp ? html : decorateIndexWithAuthHashScript(html, sanityVersion);
38
42
  buildDebug('Writing index.html to runtime directory');
39
43
  await writeFile(path.join(runtimeDir, 'index.html'), indexHtml);
40
44
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/actions/build/writeSanityRuntime.ts"],"sourcesContent":["import {mkdir, writeFile} from 'node:fs/promises'\nimport path from 'node:path'\n\nimport {tryFindStudioConfigPath} from '@sanity/cli-core/config'\nimport {\n RESOURCE_BINDINGS_FILENAME,\n RESOURCE_BINDINGS_MODULE_SOURCE,\n} from '@sanity/workbench-cli/build'\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 /** Blueprints build (via `@sanity/runtime-cli`) — emit the resource-bindings module. */\n isBlueprints?: 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 {\n appTitle,\n basePath,\n cwd,\n entry,\n isApp,\n isBlueprints,\n isWorkbenchApp,\n reactStrictMode,\n watch,\n } = options\n const runtimeDir = path.join(cwd, '.sanity', 'runtime')\n\n buildDebug('Making runtime directory')\n await 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 writeFile(path.join(runtimeDir, 'index.html'), indexHtml)\n }\n\n let watcher: FSWatcher | undefined\n\n if (watch) {\n // Skip the initial scan; the explicit renderAndWriteDocument() below handles first generation.\n watcher = chokidarWatch(getPossibleDocumentComponentLocations(cwd), {ignoreInitial: true}).on(\n '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 isBlueprints,\n reactStrictMode,\n relativeConfigLocation,\n })\n await writeFile(path.join(runtimeDir, 'app.js'), appJsContent)\n\n // Resource bindings ride in their own statically-imported module (see\n // resource-bindings.ts) so a federated host and a standalone studio resolve\n // them the same way. Brett bakes the resolved values in at deploy. Only a\n // Blueprints build emits it (and imports it — see getEntryModule); a normal\n // `sanity build`/`dev`/`preview` skips it entirely.\n if (isBlueprints) {\n buildDebug('Writing resource bindings module to runtime directory')\n await writeFile(\n path.join(runtimeDir, RESOURCE_BINDINGS_FILENAME),\n RESOURCE_BINDINGS_MODULE_SOURCE,\n )\n }\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 (`defineApplication`) 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":["mkdir","writeFile","path","tryFindStudioConfigPath","RESOURCE_BINDINGS_FILENAME","RESOURCE_BINDINGS_MODULE_SOURCE","watch","chokidarWatch","buildDebug","decorateIndexWithAutoGeneratedWarning","decorateIndexWithBridgeScript","decorateIndexWithStagingScript","getEntryModule","getPossibleDocumentComponentLocations","renderDocument","writeSanityRuntime","options","appTitle","basePath","cwd","entry","isApp","isBlueprints","isWorkbenchApp","reactStrictMode","runtimeDir","join","recursive","renderAndWriteDocument","indexHtml","props","entryPath","toForwardSlashes","relative","title","studioRootPath","watcher","ignoreInitial","on","relativeConfigLocation","relativeEntry","resolveEntries","appJsContent","undefined","entries","studioConfigPath","resolve","filePath","replaceAll"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/actions/build/writeSanityRuntime.ts"],"sourcesContent":["import {mkdir, writeFile} from 'node:fs/promises'\nimport path from 'node:path'\n\nimport {tryFindStudioConfigPath} from '@sanity/cli-core/config'\nimport {getLocalPackageVersion} from '@sanity/cli-core/package-manager'\nimport {\n RESOURCE_BINDINGS_FILENAME,\n RESOURCE_BINDINGS_MODULE_SOURCE,\n} from '@sanity/workbench-cli/build'\nimport {watch as chokidarWatch, type FSWatcher} from 'chokidar'\n\nimport {buildDebug} from './buildDebug.js'\nimport {decorateIndexWithAuthHashScript} from './decorateIndexWithAuthHashScript.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 /** Blueprints build (via `@sanity/runtime-cli`) — emit the resource-bindings module. */\n isBlueprints?: 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 {\n appTitle,\n basePath,\n cwd,\n entry,\n isApp,\n isBlueprints,\n isWorkbenchApp,\n reactStrictMode,\n watch,\n } = options\n const runtimeDir = path.join(cwd, '.sanity', 'runtime')\n\n buildDebug('Making runtime directory')\n await mkdir(runtimeDir, {recursive: true})\n\n const sanityVersion = isApp ? null : await getLocalPackageVersion('sanity', cwd)\n\n async function renderAndWriteDocument() {\n buildDebug('Rendering document template')\n const html = 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 const indexHtml = isApp ? html : decorateIndexWithAuthHashScript(html, sanityVersion)\n\n buildDebug('Writing index.html to runtime directory')\n await writeFile(path.join(runtimeDir, 'index.html'), indexHtml)\n }\n\n let watcher: FSWatcher | undefined\n\n if (watch) {\n // Skip the initial scan; the explicit renderAndWriteDocument() below handles first generation.\n watcher = chokidarWatch(getPossibleDocumentComponentLocations(cwd), {ignoreInitial: true}).on(\n '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 isBlueprints,\n reactStrictMode,\n relativeConfigLocation,\n })\n await writeFile(path.join(runtimeDir, 'app.js'), appJsContent)\n\n // Resource bindings ride in their own statically-imported module (see\n // resource-bindings.ts) so a federated host and a standalone studio resolve\n // them the same way. Brett bakes the resolved values in at deploy. Only a\n // Blueprints build emits it (and imports it — see getEntryModule); a normal\n // `sanity build`/`dev`/`preview` skips it entirely.\n if (isBlueprints) {\n buildDebug('Writing resource bindings module to runtime directory')\n await writeFile(\n path.join(runtimeDir, RESOURCE_BINDINGS_FILENAME),\n RESOURCE_BINDINGS_MODULE_SOURCE,\n )\n }\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 (`defineApplication`) 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":["mkdir","writeFile","path","tryFindStudioConfigPath","getLocalPackageVersion","RESOURCE_BINDINGS_FILENAME","RESOURCE_BINDINGS_MODULE_SOURCE","watch","chokidarWatch","buildDebug","decorateIndexWithAuthHashScript","decorateIndexWithAutoGeneratedWarning","decorateIndexWithBridgeScript","decorateIndexWithStagingScript","getEntryModule","getPossibleDocumentComponentLocations","renderDocument","writeSanityRuntime","options","appTitle","basePath","cwd","entry","isApp","isBlueprints","isWorkbenchApp","reactStrictMode","runtimeDir","join","recursive","sanityVersion","renderAndWriteDocument","html","props","entryPath","toForwardSlashes","relative","title","studioRootPath","indexHtml","watcher","ignoreInitial","on","relativeConfigLocation","relativeEntry","resolveEntries","appJsContent","undefined","entries","studioConfigPath","resolve","filePath","replaceAll"],"mappings":"AAAA,SAAQA,KAAK,EAAEC,SAAS,QAAO,mBAAkB;AACjD,OAAOC,UAAU,YAAW;AAE5B,SAAQC,uBAAuB,QAAO,0BAAyB;AAC/D,SAAQC,sBAAsB,QAAO,mCAAkC;AACvE,SACEC,0BAA0B,EAC1BC,+BAA+B,QAC1B,8BAA6B;AACpC,SAAQC,SAASC,aAAa,QAAuB,WAAU;AAE/D,SAAQC,UAAU,QAAO,kBAAiB;AAC1C,SAAQC,+BAA+B,QAAO,uCAAsC;AACpF,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;AAgBlD;;;;;;;CAOC,GACD,OAAO,eAAeC,mBAAmBC,OAAuB;IAI9D,MAAM,EACJC,QAAQ,EACRC,QAAQ,EACRC,GAAG,EACHC,KAAK,EACLC,KAAK,EACLC,YAAY,EACZC,cAAc,EACdC,eAAe,EACfnB,KAAK,EACN,GAAGW;IACJ,MAAMS,aAAazB,KAAK0B,IAAI,CAACP,KAAK,WAAW;IAE7CZ,WAAW;IACX,MAAMT,MAAM2B,YAAY;QAACE,WAAW;IAAI;IAExC,MAAMC,gBAAgBP,QAAQ,OAAO,MAAMnB,uBAAuB,UAAUiB;IAE5E,eAAeU;QACbtB,WAAW;QACX,MAAMuB,OAAOnB,+BACXD,8BACED,sCACE,MAAMK,eAAe;YACnBO;YACAU,OAAO;gBACLb,UAAUA,YAAY;gBACtBc,WAAW,CAAC,CAAC,EAAEC,iBAAiBjC,KAAKkC,QAAQ,CAACf,KAAKnB,KAAK0B,IAAI,CAACD,YAAY,aAAa;gBACtFU,OAAOlB;YACT;YACAmB,gBAAgBjB;QAClB;QAIN,MAAMkB,YAAYhB,QAAQS,OAAOtB,gCAAgCsB,MAAMF;QAEvErB,WAAW;QACX,MAAMR,UAAUC,KAAK0B,IAAI,CAACD,YAAY,eAAeY;IACvD;IAEA,IAAIC;IAEJ,IAAIjC,OAAO;QACT,+FAA+F;QAC/FiC,UAAUhC,cAAcO,sCAAsCM,MAAM;YAACoB,eAAe;QAAI,GAAGC,EAAE,CAC3F,OACA,IAAMX;IAEV;IAEA,MAAMA;IAENtB,WAAW;IACX,MAAM,EAACkC,sBAAsB,EAAEC,aAAa,EAAC,GAAG,MAAMC,eAAe;QACnExB;QACAC;QACAC;QACAE;QACAE;IACF;IACA,MAAMmB,eAAehC,eAAe;QAClCM;QACAE,OAAOsB,iBAAiBG;QACxBxB;QACAC;QACAE;QACAiB;IACF;IACA,MAAM1C,UAAUC,KAAK0B,IAAI,CAACD,YAAY,WAAWmB;IAEjD,sEAAsE;IACtE,4EAA4E;IAC5E,0EAA0E;IAC1E,4EAA4E;IAC5E,oDAAoD;IACpD,IAAItB,cAAc;QAChBf,WAAW;QACX,MAAMR,UACJC,KAAK0B,IAAI,CAACD,YAAYtB,6BACtBC;IAEJ;IAEA,OAAO;QACL0C,SAAS;YACPL;YACAC;QACF;QACAJ;IACF;AACF;AAEA;;;;CAIC,GACD,OAAO,eAAeK,eAAe3B,OAMpC;IACC,MAAM,EAACG,GAAG,EAAEC,KAAK,EAAEC,KAAK,EAAEE,cAAc,EAAC,GAAGP;IAC5C,MAAMS,aAAaT,QAAQS,UAAU,IAAIzB,KAAK0B,IAAI,CAACP,KAAK,WAAW;IAEnE,IAAIsB,yBAAwC;IAC5C,IAAI,CAACpB,OAAO;QACV,MAAM0B,mBAAmB,MAAM9C,wBAAwBkB;QACvDsB,yBAAyBM,mBACrBd,iBAAiBjC,KAAKkC,QAAQ,CAACT,YAAYsB,qBAC3C;IACN;IAEA,6EAA6E;IAC7E,4EAA4E;IAC5E,6EAA6E;IAC7E,+EAA+E;IAC/E,+EAA+E;IAC/E,2CAA2C;IAC3C,MAAML,gBACJnB,kBAAkB,CAACH,QACf,OACAa,iBAAiBjC,KAAKkC,QAAQ,CAACT,YAAYzB,KAAKgD,OAAO,CAAC7B,KAAKC,SAAS;IAE5E,OAAO;QAACqB;QAAwBC;IAAa;AAC/C;AAEA,SAAST,iBAAiBgB,QAAgB;IACxC,OAAOA,SAASC,UAAU,CAAC,MAAM;AACnC"}
@@ -22,89 +22,40 @@ const debug = subdebug('buildStudioSchemasAndManifests.worker');
22
22
  // still live. Both writeWorkspaceToDist and updateWorkspacesSchemas consume the result.
23
23
  const workspaceManifests = await extractWorkspaceManifest(workspaces, workDir);
24
24
  debug('Handling build for %s', isExternal ? 'external' : 'internal');
25
- async function workspaceManifestsHandler(workspaceManifests) {
26
- if (!isExternal || schemaRequired) {
27
- const schemaInputs = workspaceManifests.map((manifest)=>({
28
- dataset: manifest.dataset,
29
- manifestSchema: manifest.schema,
30
- name: manifest.name,
31
- projectId: manifest.projectId,
32
- title: manifest.title
33
- }));
34
- if (workspaceSchemaHandler) {
35
- await workspaceSchemaHandler(schemaInputs);
36
- }
37
- return schemaInputs;
38
- }
39
- return null;
40
- }
41
- const result = isExternal ? await handleExternalStudio({
25
+ const uploadToLexiconPromise = uploadSchemaToLexicon({
42
26
  projectId,
43
27
  verbose,
44
28
  workDir,
45
- workspaceManifests,
46
- workspaceManifestsHandler,
47
29
  workspaces
48
- }) : await handleInternalStudio({
30
+ });
31
+ let writeManifestPromise;
32
+ if (!isExternal) writeManifestPromise = writeManifestFile({
49
33
  outPath,
50
- projectId,
51
- verbose,
52
34
  workDir,
53
- workspaceManifests,
54
- workspaceManifestsHandler,
55
- workspaces
35
+ workspaceManifests
56
36
  });
57
- return {
58
- schemaInputs: result.schemaInputs,
59
- studioManifest: result.studioManifest,
60
- type: 'success'
61
- };
62
- }
63
- /**
64
- * External deployments:
65
- * 1. Update the workspace schemas to the /schemas endpoint IF --schema-required is passed
66
- * 2. Call the workspace manifest handler if provided to update server-side schemas
67
- */ async function handleExternalStudio({ projectId, verbose, workDir, workspaceManifests, workspaceManifestsHandler, workspaces }) {
68
- const [studioManifest, schemaInputs] = await Promise.all([
69
- uploadSchemaToLexicon({
70
- projectId,
71
- verbose,
72
- workDir,
73
- workspaces
74
- }),
75
- workspaceManifestsHandler(workspaceManifests)
76
- ]);
77
- return {
78
- schemaInputs,
79
- studioManifest
80
- };
81
- }
82
- /**
83
- *
84
- * Internal deployments:
85
- * 1. Write the workspace manifests to the dist directory
86
- * 2. Update the workspaces schemas to the /schemas endpoint
87
- * 3. Call the workspace manifest handler if provided to update server-side schemas
88
- *
89
- * @param workspaces - The workspaces to deploy
90
- */ async function handleInternalStudio({ outPath, projectId, verbose, workDir, workspaceManifests, workspaceManifestsHandler, workspaces }) {
91
- const [studioManifest, schemaInputs] = await Promise.all([
92
- uploadSchemaToLexicon({
93
- projectId,
94
- verbose,
95
- workDir,
96
- workspaces
97
- }),
98
- workspaceManifestsHandler(workspaceManifests),
99
- writeManifestFile({
100
- outPath,
101
- workDir,
102
- workspaceManifests
103
- })
104
- ]);
37
+ let schemaInputs = null;
38
+ let workspaceSchemaPromise;
39
+ if (!isExternal || schemaRequired) {
40
+ schemaInputs = workspaceManifests.map((manifest)=>({
41
+ dataset: manifest.dataset,
42
+ manifestSchema: manifest.schema,
43
+ name: manifest.name,
44
+ projectId: manifest.projectId,
45
+ title: manifest.title
46
+ }));
47
+ if (workspaceSchemaHandler) workspaceSchemaPromise = workspaceSchemaHandler(schemaInputs);
48
+ }
49
+ const promises = [
50
+ uploadToLexiconPromise
51
+ ];
52
+ if (writeManifestPromise) promises.push(writeManifestPromise);
53
+ if (workspaceSchemaPromise) promises.push(workspaceSchemaPromise);
54
+ await Promise.all(promises);
105
55
  return {
106
56
  schemaInputs,
107
- studioManifest
57
+ studioManifest: await uploadToLexiconPromise,
58
+ type: 'success'
108
59
  };
109
60
  }
110
61
 
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/actions/schema/buildStudioSchemasAndManifestsWorker.ts"],"sourcesContent":["import {isMainThread} from 'node:worker_threads'\n\nimport {getStudioWorkspaces, subdebug} from '@sanity/cli-core'\nimport {type StudioManifest, type Workspace} from 'sanity'\n\nimport {extractWorkspaceManifest} from '../manifest/extractWorkspaceManifest.js'\nimport {type CreateWorkspaceManifest, WorkspaceSchemaInput} from '../manifest/types.js'\nimport {writeManifestFile} from '../manifest/writeManifestFile.js'\nimport {type BuildStudioSchemasAndManifestsWorkerSuccess} from './buildStudioSchemasAndManifests.js'\nimport {type BuildStudioSchemasAndManifestsWorkerData} from './types.js'\nimport {uploadSchemaToLexicon} from './uploadSchemaToLexicon.js'\n\nconst debug = subdebug('buildStudioSchemasAndManifests.worker')\n\n/**\n * This function must only be called from another worker process.\n * @param options - The worker options\n */\nexport async function workerBuildStudioSchemasAndManifests(\n options: BuildStudioSchemasAndManifestsWorkerData & {\n workspaceSchemaHandler?: (workspaces: WorkspaceSchemaInput[]) => Promise<void>\n },\n): Promise<BuildStudioSchemasAndManifestsWorkerSuccess> {\n if (isMainThread) {\n throw new Error(\n 'workerBuildStudioSchemasAndManifests should only be called from a worker thread',\n )\n }\n\n const {\n configPath,\n isExternal,\n outPath,\n projectId,\n schemaRequired,\n verbose,\n workDir,\n workspaceSchemaHandler,\n } = options\n\n debug('Building studio schemas and manifests from config path %s', configPath)\n const workspaces = await getStudioWorkspaces(configPath)\n debug('Workspaces %o', workspaces)\n\n if (workspaces.length === 0) {\n throw new Error('No workspaces found')\n }\n\n // Extract manifest data (including ManifestSchemaType[]) once, while Schema objects are\n // still live. Both writeWorkspaceToDist and updateWorkspacesSchemas consume the result.\n const workspaceManifests = await extractWorkspaceManifest(workspaces, workDir)\n\n debug('Handling build for %s', isExternal ? 'external' : 'internal')\n\n async function workspaceManifestsHandler(\n workspaceManifests: CreateWorkspaceManifest[],\n ): Promise<WorkspaceSchemaInput[] | null> {\n if (!isExternal || schemaRequired) {\n const schemaInputs: WorkspaceSchemaInput[] = workspaceManifests.map((manifest) => ({\n dataset: manifest.dataset,\n manifestSchema: manifest.schema,\n name: manifest.name,\n projectId: manifest.projectId,\n title: manifest.title,\n }))\n\n if (workspaceSchemaHandler) {\n await workspaceSchemaHandler(schemaInputs)\n }\n\n return schemaInputs\n }\n\n return null\n }\n\n const result = isExternal\n ? await handleExternalStudio({\n projectId,\n verbose,\n workDir,\n workspaceManifests,\n workspaceManifestsHandler,\n workspaces,\n })\n : await handleInternalStudio({\n outPath,\n projectId,\n verbose,\n workDir,\n workspaceManifests,\n workspaceManifestsHandler,\n workspaces,\n })\n\n return {\n schemaInputs: result.schemaInputs,\n studioManifest: result.studioManifest,\n type: 'success',\n }\n}\n\ntype HandleStudioResult = {\n schemaInputs: WorkspaceSchemaInput[] | null\n studioManifest: StudioManifest | null\n}\n\n/**\n * External deployments:\n * 1. Update the workspace schemas to the /schemas endpoint IF --schema-required is passed\n * 2. Call the workspace manifest handler if provided to update server-side schemas\n */\nasync function handleExternalStudio({\n projectId,\n verbose,\n workDir,\n workspaceManifests,\n workspaceManifestsHandler,\n workspaces,\n}: {\n projectId: string\n verbose: boolean\n workDir: string\n workspaceManifests: CreateWorkspaceManifest[]\n workspaceManifestsHandler: (\n workspaceManifests: CreateWorkspaceManifest[],\n ) => Promise<WorkspaceSchemaInput[] | null>\n workspaces: Workspace[]\n}): Promise<HandleStudioResult> {\n const [studioManifest, schemaInputs] = await Promise.all([\n uploadSchemaToLexicon({\n projectId,\n verbose,\n workDir,\n workspaces,\n }),\n workspaceManifestsHandler(workspaceManifests),\n ])\n\n return {schemaInputs, studioManifest}\n}\n\n/**\n *\n * Internal deployments:\n * 1. Write the workspace manifests to the dist directory\n * 2. Update the workspaces schemas to the /schemas endpoint\n * 3. Call the workspace manifest handler if provided to update server-side schemas\n *\n * @param workspaces - The workspaces to deploy\n */\nasync function handleInternalStudio({\n outPath,\n projectId,\n verbose,\n workDir,\n workspaceManifests,\n workspaceManifestsHandler,\n workspaces,\n}: {\n outPath: string\n projectId: string\n verbose: boolean\n workDir: string\n workspaceManifests: CreateWorkspaceManifest[]\n workspaceManifestsHandler: (\n workspaceManifests: CreateWorkspaceManifest[],\n ) => Promise<WorkspaceSchemaInput[] | null>\n workspaces: Workspace[]\n}): Promise<HandleStudioResult> {\n const [studioManifest, schemaInputs] = await Promise.all([\n uploadSchemaToLexicon({\n projectId,\n verbose,\n workDir,\n workspaces,\n }),\n workspaceManifestsHandler(workspaceManifests),\n writeManifestFile({outPath, workDir, workspaceManifests}),\n ])\n\n return {schemaInputs, studioManifest}\n}\n"],"names":["isMainThread","getStudioWorkspaces","subdebug","extractWorkspaceManifest","writeManifestFile","uploadSchemaToLexicon","debug","workerBuildStudioSchemasAndManifests","options","Error","configPath","isExternal","outPath","projectId","schemaRequired","verbose","workDir","workspaceSchemaHandler","workspaces","length","workspaceManifests","workspaceManifestsHandler","schemaInputs","map","manifest","dataset","manifestSchema","schema","name","title","result","handleExternalStudio","handleInternalStudio","studioManifest","type","Promise","all"],"mappings":"AAAA,SAAQA,YAAY,QAAO,sBAAqB;AAEhD,SAAQC,mBAAmB,EAAEC,QAAQ,QAAO,mBAAkB;AAG9D,SAAQC,wBAAwB,QAAO,0CAAyC;AAEhF,SAAQC,iBAAiB,QAAO,mCAAkC;AAGlE,SAAQC,qBAAqB,QAAO,6BAA4B;AAEhE,MAAMC,QAAQJ,SAAS;AAEvB;;;CAGC,GACD,OAAO,eAAeK,qCACpBC,OAEC;IAED,IAAIR,cAAc;QAChB,MAAM,IAAIS,MACR;IAEJ;IAEA,MAAM,EACJC,UAAU,EACVC,UAAU,EACVC,OAAO,EACPC,SAAS,EACTC,cAAc,EACdC,OAAO,EACPC,OAAO,EACPC,sBAAsB,EACvB,GAAGT;IAEJF,MAAM,6DAA6DI;IACnE,MAAMQ,aAAa,MAAMjB,oBAAoBS;IAC7CJ,MAAM,iBAAiBY;IAEvB,IAAIA,WAAWC,MAAM,KAAK,GAAG;QAC3B,MAAM,IAAIV,MAAM;IAClB;IAEA,wFAAwF;IACxF,wFAAwF;IACxF,MAAMW,qBAAqB,MAAMjB,yBAAyBe,YAAYF;IAEtEV,MAAM,yBAAyBK,aAAa,aAAa;IAEzD,eAAeU,0BACbD,kBAA6C;QAE7C,IAAI,CAACT,cAAcG,gBAAgB;YACjC,MAAMQ,eAAuCF,mBAAmBG,GAAG,CAAC,CAACC,WAAc,CAAA;oBACjFC,SAASD,SAASC,OAAO;oBACzBC,gBAAgBF,SAASG,MAAM;oBAC/BC,MAAMJ,SAASI,IAAI;oBACnBf,WAAWW,SAASX,SAAS;oBAC7BgB,OAAOL,SAASK,KAAK;gBACvB,CAAA;YAEA,IAAIZ,wBAAwB;gBAC1B,MAAMA,uBAAuBK;YAC/B;YAEA,OAAOA;QACT;QAEA,OAAO;IACT;IAEA,MAAMQ,SAASnB,aACX,MAAMoB,qBAAqB;QACzBlB;QACAE;QACAC;QACAI;QACAC;QACAH;IACF,KACA,MAAMc,qBAAqB;QACzBpB;QACAC;QACAE;QACAC;QACAI;QACAC;QACAH;IACF;IAEJ,OAAO;QACLI,cAAcQ,OAAOR,YAAY;QACjCW,gBAAgBH,OAAOG,cAAc;QACrCC,MAAM;IACR;AACF;AAOA;;;;CAIC,GACD,eAAeH,qBAAqB,EAClClB,SAAS,EACTE,OAAO,EACPC,OAAO,EACPI,kBAAkB,EAClBC,yBAAyB,EACzBH,UAAU,EAUX;IACC,MAAM,CAACe,gBAAgBX,aAAa,GAAG,MAAMa,QAAQC,GAAG,CAAC;QACvD/B,sBAAsB;YACpBQ;YACAE;YACAC;YACAE;QACF;QACAG,0BAA0BD;KAC3B;IAED,OAAO;QAACE;QAAcW;IAAc;AACtC;AAEA;;;;;;;;CAQC,GACD,eAAeD,qBAAqB,EAClCpB,OAAO,EACPC,SAAS,EACTE,OAAO,EACPC,OAAO,EACPI,kBAAkB,EAClBC,yBAAyB,EACzBH,UAAU,EAWX;IACC,MAAM,CAACe,gBAAgBX,aAAa,GAAG,MAAMa,QAAQC,GAAG,CAAC;QACvD/B,sBAAsB;YACpBQ;YACAE;YACAC;YACAE;QACF;QACAG,0BAA0BD;QAC1BhB,kBAAkB;YAACQ;YAASI;YAASI;QAAkB;KACxD;IAED,OAAO;QAACE;QAAcW;IAAc;AACtC"}
1
+ {"version":3,"sources":["../../../src/actions/schema/buildStudioSchemasAndManifestsWorker.ts"],"sourcesContent":["import {isMainThread} from 'node:worker_threads'\n\nimport {getStudioWorkspaces, subdebug} from '@sanity/cli-core'\n\nimport {extractWorkspaceManifest} from '../manifest/extractWorkspaceManifest.js'\nimport {type WorkspaceSchemaInput} from '../manifest/types.js'\nimport {writeManifestFile} from '../manifest/writeManifestFile.js'\nimport {type BuildStudioSchemasAndManifestsWorkerSuccess} from './buildStudioSchemasAndManifests.js'\nimport {type BuildStudioSchemasAndManifestsWorkerData} from './types.js'\nimport {uploadSchemaToLexicon} from './uploadSchemaToLexicon.js'\n\nconst debug = subdebug('buildStudioSchemasAndManifests.worker')\n\n/**\n * This function must only be called from another worker process.\n * @param options - The worker options\n */\nexport async function workerBuildStudioSchemasAndManifests(\n options: BuildStudioSchemasAndManifestsWorkerData & {\n workspaceSchemaHandler?: (workspaces: WorkspaceSchemaInput[]) => Promise<void>\n },\n): Promise<BuildStudioSchemasAndManifestsWorkerSuccess> {\n if (isMainThread) {\n throw new Error(\n 'workerBuildStudioSchemasAndManifests should only be called from a worker thread',\n )\n }\n\n const {\n configPath,\n isExternal,\n outPath,\n projectId,\n schemaRequired,\n verbose,\n workDir,\n workspaceSchemaHandler,\n } = options\n\n debug('Building studio schemas and manifests from config path %s', configPath)\n const workspaces = await getStudioWorkspaces(configPath)\n debug('Workspaces %o', workspaces)\n\n if (workspaces.length === 0) {\n throw new Error('No workspaces found')\n }\n\n // Extract manifest data (including ManifestSchemaType[]) once, while Schema objects are\n // still live. Both writeWorkspaceToDist and updateWorkspacesSchemas consume the result.\n const workspaceManifests = await extractWorkspaceManifest(workspaces, workDir)\n\n debug('Handling build for %s', isExternal ? 'external' : 'internal')\n\n const uploadToLexiconPromise = uploadSchemaToLexicon({\n projectId,\n verbose,\n workDir,\n workspaces,\n })\n\n let writeManifestPromise: Promise<void> | undefined\n if (!isExternal) writeManifestPromise = writeManifestFile({outPath, workDir, workspaceManifests})\n\n let schemaInputs: WorkspaceSchemaInput[] | null = null\n let workspaceSchemaPromise: Promise<void> | undefined\n if (!isExternal || schemaRequired) {\n schemaInputs = workspaceManifests.map((manifest) => ({\n dataset: manifest.dataset,\n manifestSchema: manifest.schema,\n name: manifest.name,\n projectId: manifest.projectId,\n title: manifest.title,\n }))\n\n if (workspaceSchemaHandler) workspaceSchemaPromise = workspaceSchemaHandler(schemaInputs)\n }\n\n const promises: Promise<unknown>[] = [uploadToLexiconPromise]\n if (writeManifestPromise) promises.push(writeManifestPromise)\n if (workspaceSchemaPromise) promises.push(workspaceSchemaPromise)\n await Promise.all(promises)\n\n return {\n schemaInputs,\n studioManifest: await uploadToLexiconPromise,\n type: 'success',\n }\n}\n"],"names":["isMainThread","getStudioWorkspaces","subdebug","extractWorkspaceManifest","writeManifestFile","uploadSchemaToLexicon","debug","workerBuildStudioSchemasAndManifests","options","Error","configPath","isExternal","outPath","projectId","schemaRequired","verbose","workDir","workspaceSchemaHandler","workspaces","length","workspaceManifests","uploadToLexiconPromise","writeManifestPromise","schemaInputs","workspaceSchemaPromise","map","manifest","dataset","manifestSchema","schema","name","title","promises","push","Promise","all","studioManifest","type"],"mappings":"AAAA,SAAQA,YAAY,QAAO,sBAAqB;AAEhD,SAAQC,mBAAmB,EAAEC,QAAQ,QAAO,mBAAkB;AAE9D,SAAQC,wBAAwB,QAAO,0CAAyC;AAEhF,SAAQC,iBAAiB,QAAO,mCAAkC;AAGlE,SAAQC,qBAAqB,QAAO,6BAA4B;AAEhE,MAAMC,QAAQJ,SAAS;AAEvB;;;CAGC,GACD,OAAO,eAAeK,qCACpBC,OAEC;IAED,IAAIR,cAAc;QAChB,MAAM,IAAIS,MACR;IAEJ;IAEA,MAAM,EACJC,UAAU,EACVC,UAAU,EACVC,OAAO,EACPC,SAAS,EACTC,cAAc,EACdC,OAAO,EACPC,OAAO,EACPC,sBAAsB,EACvB,GAAGT;IAEJF,MAAM,6DAA6DI;IACnE,MAAMQ,aAAa,MAAMjB,oBAAoBS;IAC7CJ,MAAM,iBAAiBY;IAEvB,IAAIA,WAAWC,MAAM,KAAK,GAAG;QAC3B,MAAM,IAAIV,MAAM;IAClB;IAEA,wFAAwF;IACxF,wFAAwF;IACxF,MAAMW,qBAAqB,MAAMjB,yBAAyBe,YAAYF;IAEtEV,MAAM,yBAAyBK,aAAa,aAAa;IAEzD,MAAMU,yBAAyBhB,sBAAsB;QACnDQ;QACAE;QACAC;QACAE;IACF;IAEA,IAAII;IACJ,IAAI,CAACX,YAAYW,uBAAuBlB,kBAAkB;QAACQ;QAASI;QAASI;IAAkB;IAE/F,IAAIG,eAA8C;IAClD,IAAIC;IACJ,IAAI,CAACb,cAAcG,gBAAgB;QACjCS,eAAeH,mBAAmBK,GAAG,CAAC,CAACC,WAAc,CAAA;gBACnDC,SAASD,SAASC,OAAO;gBACzBC,gBAAgBF,SAASG,MAAM;gBAC/BC,MAAMJ,SAASI,IAAI;gBACnBjB,WAAWa,SAASb,SAAS;gBAC7BkB,OAAOL,SAASK,KAAK;YACvB,CAAA;QAEA,IAAId,wBAAwBO,yBAAyBP,uBAAuBM;IAC9E;IAEA,MAAMS,WAA+B;QAACX;KAAuB;IAC7D,IAAIC,sBAAsBU,SAASC,IAAI,CAACX;IACxC,IAAIE,wBAAwBQ,SAASC,IAAI,CAACT;IAC1C,MAAMU,QAAQC,GAAG,CAACH;IAElB,OAAO;QACLT;QACAa,gBAAgB,MAAMf;QACtBgB,MAAM;IACR;AACF"}
@@ -3,8 +3,10 @@ import { getLocalPackageVersion, readPackageJson } from '@sanity/cli-core';
3
3
  import { createRequester } from '@sanity/cli-core/request';
4
4
  import { coerce, eq, prerelease, parse as semverParse } from 'semver';
5
5
  import { getModuleUrl } from '../actions/build/getAutoUpdatesImportMap.js';
6
+ const REMOTE_VERSION_TIMEOUT_MS = 5000;
6
7
  const defaultRequester = createRequester({
7
- httpErrors: false
8
+ httpErrors: false,
9
+ timeout: REMOTE_VERSION_TIMEOUT_MS
8
10
  });
9
11
  /**
10
12
  * @internal
@@ -22,11 +24,12 @@ const defaultRequester = createRequester({
22
24
  * @param workDir - The path to the working directory containing the package.json file.
23
25
  * @param options - Optional configuration for version comparison.
24
26
  *
25
- * @returns A promise that resolves to an object containing `mismatched` (packages whose local and remote versions differ)
26
- * and `unresolvedPrerelease` (packages with prerelease versions that could not be resolved remotely).
27
+ * @returns A promise that resolves to an object containing `mismatched` (packages whose local and remote versions differ),
28
+ * `unresolvedPrerelease` (packages with prerelease versions that could not be resolved remotely) and `unavailable`
29
+ * (packages Module Server did not answer for, because of a network error, a timeout or a 5xx).
27
30
  *
28
- * @throws Throws an error if the remote version of a non-prerelease package cannot be fetched, or if the local version
29
- * of a package cannot be parsed.
31
+ * @throws Throws an error if a non-prerelease package is not found remotely, if Module Server answers with an unexpected
32
+ * response, or if the local version of a package cannot be parsed.
30
33
  */ export async function compareDependencyVersions(packages, workDir, { appId } = {}) {
31
34
  const manifest = await readPackageJson(path.join(workDir, 'package.json'), {
32
35
  skipSchemaValidation: true
@@ -35,43 +38,70 @@ const defaultRequester = createRequester({
35
38
  ...manifest?.dependencies,
36
39
  ...manifest?.devDependencies
37
40
  };
38
- const mismatched = [];
39
- const unresolvedPrerelease = [];
40
- for (const pkg of packages){
41
- // Skip packages that are not declared in the local package.json
42
- if (!dependencies[pkg.name]) {
43
- continue;
44
- }
45
- const resolvedVersion = await getRemoteResolvedVersion(getModuleUrl(pkg, {
46
- appId
47
- }));
48
- if (resolvedVersion === null) {
49
- if (prerelease(pkg.version)) {
50
- unresolvedPrerelease.push({
41
+ const comparisons = await Promise.all(packages.filter((pkg)=>Boolean(dependencies[pkg.name])).map((pkg)=>comparePackageVersion(pkg, dependencies[pkg.name], {
42
+ appId,
43
+ workDir
44
+ })));
45
+ return {
46
+ mismatched: comparisons.flatMap((result)=>result.type === 'mismatched' ? [
47
+ result.mismatch
48
+ ] : []),
49
+ unavailable: comparisons.flatMap((result)=>result.type === 'unavailable' ? [
50
+ result.unavailable
51
+ ] : []),
52
+ unresolvedPrerelease: comparisons.flatMap((result)=>result.type === 'unresolvedPrerelease' ? [
53
+ result.prerelease
54
+ ] : [])
55
+ };
56
+ }
57
+ /**
58
+ * @internal
59
+ */ export function getUnavailableVersionsWarning(unavailable) {
60
+ const packageNames = unavailable.map((entry)=>entry.pkg).join(', ');
61
+ const reasons = [
62
+ ...new Set(unavailable.map((entry)=>entry.reason))
63
+ ].join('; ');
64
+ return `Could not check the runtime version of ${packageNames}: ` + `the Sanity module CDN request failed (${reasons}). Continuing without the check.`;
65
+ }
66
+ async function comparePackageVersion(pkg, manifestVersion, { appId, workDir }) {
67
+ const remote = await getRemoteResolvedVersion(getModuleUrl(pkg, {
68
+ appId
69
+ }));
70
+ if (remote.type !== 'found') {
71
+ if (prerelease(pkg.version)) {
72
+ return {
73
+ prerelease: {
51
74
  pkg: pkg.name,
52
75
  version: pkg.version
53
- });
54
- continue;
55
- }
56
- throw new Error(`Failed to resolve remote version for ${pkg.name}@${pkg.version}: package not found`);
76
+ },
77
+ type: 'unresolvedPrerelease'
78
+ };
57
79
  }
58
- const packageVersion = await getLocalPackageVersion(pkg.name, workDir);
59
- const manifestVersion = dependencies[pkg.name];
60
- const installed = coerce(packageVersion ? semverParse(packageVersion) : coerce(manifestVersion));
61
- if (!installed) {
62
- throw new Error(`Failed to parse installed version for ${pkg.name}`);
63
- }
64
- if (!eq(resolvedVersion, installed.version)) {
65
- mismatched.push({
66
- installed: installed.version,
67
- pkg: pkg.name,
68
- remote: resolvedVersion
69
- });
80
+ if (remote.type === 'unavailable') {
81
+ return {
82
+ type: 'unavailable',
83
+ unavailable: {
84
+ pkg: pkg.name,
85
+ reason: remote.reason
86
+ }
87
+ };
70
88
  }
89
+ throw new Error(`Failed to resolve remote version for ${pkg.name}@${pkg.version}: package not found`);
71
90
  }
72
- return {
73
- mismatched,
74
- unresolvedPrerelease
91
+ const packageVersion = await getLocalPackageVersion(pkg.name, workDir);
92
+ const installed = coerce(packageVersion ? semverParse(packageVersion) : coerce(manifestVersion));
93
+ if (!installed) {
94
+ throw new Error(`Failed to parse installed version for ${pkg.name}`);
95
+ }
96
+ return eq(remote.version, installed.version) ? {
97
+ type: 'matched'
98
+ } : {
99
+ mismatch: {
100
+ installed: installed.version,
101
+ pkg: pkg.name,
102
+ remote: remote.version
103
+ },
104
+ type: 'mismatched'
75
105
  };
76
106
  }
77
107
  async function getRemoteResolvedVersion(url) {
@@ -83,10 +113,10 @@ async function getRemoteResolvedVersion(url) {
83
113
  url
84
114
  });
85
115
  } catch (err) {
86
- const message = err instanceof Error ? err.message : String(err);
87
- throw new Error(`Failed to fetch remote version for ${url}: ${message}`, {
88
- cause: err
89
- });
116
+ return {
117
+ reason: err instanceof Error ? err.message : String(err),
118
+ type: 'unavailable'
119
+ };
90
120
  }
91
121
  // 302 is expected, but lets also handle 2xx
92
122
  if (response.status < 400) {
@@ -94,10 +124,21 @@ async function getRemoteResolvedVersion(url) {
94
124
  if (!resolved) {
95
125
  throw new Error(`Missing 'x-resolved-version' header on response from HEAD ${url}`);
96
126
  }
97
- return resolved;
127
+ return {
128
+ type: 'found',
129
+ version: resolved
130
+ };
98
131
  }
99
132
  if (response.status === 404) {
100
- return null;
133
+ return {
134
+ type: 'not-found'
135
+ };
136
+ }
137
+ if (response.status === 429 || response.status >= 500) {
138
+ return {
139
+ reason: `HTTP ${response.status} ${response.statusText}`,
140
+ type: 'unavailable'
141
+ };
101
142
  }
102
143
  throw new Error(`Unexpected HTTP response: ${response.status} ${response.statusText}`);
103
144
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/util/compareDependencyVersions.ts"],"sourcesContent":["import path from 'node:path'\n\nimport {getLocalPackageVersion, readPackageJson} from '@sanity/cli-core'\nimport {createRequester} from '@sanity/cli-core/request'\nimport {coerce, eq, prerelease, parse as semverParse} from 'semver'\n\nimport {getModuleUrl} from '../actions/build/getAutoUpdatesImportMap.js'\n\nexport interface CompareDependencyVersions {\n installed: string\n pkg: string\n remote: string\n}\n\nexport interface UnresolvedPrerelease {\n pkg: string\n version: string\n}\n\nexport interface CompareDependencyVersionsResult {\n mismatched: Array<CompareDependencyVersions>\n unresolvedPrerelease: Array<UnresolvedPrerelease>\n}\n\nconst defaultRequester = createRequester({\n httpErrors: false,\n})\n\ninterface CompareDependencyVersionsOptions {\n /** When provided, uses the app-specific module endpoint instead of the default endpoint. */\n appId?: string\n}\n\n/**\n * @internal\n *\n * Compares the versions of dependencies in the studio or app with their remote versions.\n *\n * This function reads the package.json file in the provided working directory, and compares the versions of the dependencies\n * specified in the `autoUpdatesImports` parameter with their remote versions. If the versions do not match, the dependency is\n * added to a list of failed dependencies, which is returned by the function.\n *\n * The failed dependencies are anything that does not strictly match the remote version.\n * This means that if a version is lower or greater by even a patch it will be marked as failed.\n *\n * @param packages - An array of packages with their name and version to compare against remote.\n * @param workDir - The path to the working directory containing the package.json file.\n * @param options - Optional configuration for version comparison.\n *\n * @returns A promise that resolves to an object containing `mismatched` (packages whose local and remote versions differ)\n * and `unresolvedPrerelease` (packages with prerelease versions that could not be resolved remotely).\n *\n * @throws Throws an error if the remote version of a non-prerelease package cannot be fetched, or if the local version\n * of a package cannot be parsed.\n */\nexport async function compareDependencyVersions(\n packages: {name: string; version: string}[],\n workDir: string,\n {appId}: CompareDependencyVersionsOptions = {},\n): Promise<CompareDependencyVersionsResult> {\n const manifest = await readPackageJson(path.join(workDir, 'package.json'), {\n skipSchemaValidation: true,\n })\n const dependencies = {...manifest?.dependencies, ...manifest?.devDependencies}\n\n const mismatched: Array<CompareDependencyVersions> = []\n const unresolvedPrerelease: Array<UnresolvedPrerelease> = []\n\n for (const pkg of packages) {\n // Skip packages that are not declared in the local package.json\n if (!dependencies[pkg.name]) {\n continue\n }\n\n const resolvedVersion = await getRemoteResolvedVersion(getModuleUrl(pkg, {appId}))\n\n if (resolvedVersion === null) {\n if (prerelease(pkg.version)) {\n unresolvedPrerelease.push({pkg: pkg.name, version: pkg.version})\n continue\n }\n throw new Error(\n `Failed to resolve remote version for ${pkg.name}@${pkg.version}: package not found`,\n )\n }\n\n const packageVersion = await getLocalPackageVersion(pkg.name, workDir)\n\n const manifestVersion = dependencies[pkg.name]\n\n const installed = coerce(packageVersion ? semverParse(packageVersion) : coerce(manifestVersion))\n\n if (!installed) {\n throw new Error(`Failed to parse installed version for ${pkg.name}`)\n }\n\n if (!eq(resolvedVersion, installed.version)) {\n mismatched.push({\n installed: installed.version,\n pkg: pkg.name,\n remote: resolvedVersion,\n })\n }\n }\n\n return {mismatched, unresolvedPrerelease}\n}\n\nasync function getRemoteResolvedVersion(url: string): Promise<string | null> {\n let response\n try {\n response = await defaultRequester({\n method: 'HEAD',\n redirect: 'manual',\n url,\n })\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n throw new Error(`Failed to fetch remote version for ${url}: ${message}`, {cause: err})\n }\n\n // 302 is expected, but lets also handle 2xx\n if (response.status < 400) {\n const resolved = response.headers.get('x-resolved-version')\n if (!resolved) {\n throw new Error(`Missing 'x-resolved-version' header on response from HEAD ${url}`)\n }\n return resolved\n }\n\n if (response.status === 404) {\n return null\n }\n\n throw new Error(`Unexpected HTTP response: ${response.status} ${response.statusText}`)\n}\n"],"names":["path","getLocalPackageVersion","readPackageJson","createRequester","coerce","eq","prerelease","parse","semverParse","getModuleUrl","defaultRequester","httpErrors","compareDependencyVersions","packages","workDir","appId","manifest","join","skipSchemaValidation","dependencies","devDependencies","mismatched","unresolvedPrerelease","pkg","name","resolvedVersion","getRemoteResolvedVersion","version","push","Error","packageVersion","manifestVersion","installed","remote","url","response","method","redirect","err","message","String","cause","status","resolved","headers","get","statusText"],"mappings":"AAAA,OAAOA,UAAU,YAAW;AAE5B,SAAQC,sBAAsB,EAAEC,eAAe,QAAO,mBAAkB;AACxE,SAAQC,eAAe,QAAO,2BAA0B;AACxD,SAAQC,MAAM,EAAEC,EAAE,EAAEC,UAAU,EAAEC,SAASC,WAAW,QAAO,SAAQ;AAEnE,SAAQC,YAAY,QAAO,8CAA6C;AAkBxE,MAAMC,mBAAmBP,gBAAgB;IACvCQ,YAAY;AACd;AAOA;;;;;;;;;;;;;;;;;;;;;CAqBC,GACD,OAAO,eAAeC,0BACpBC,QAA2C,EAC3CC,OAAe,EACf,EAACC,KAAK,EAAmC,GAAG,CAAC,CAAC;IAE9C,MAAMC,WAAW,MAAMd,gBAAgBF,KAAKiB,IAAI,CAACH,SAAS,iBAAiB;QACzEI,sBAAsB;IACxB;IACA,MAAMC,eAAe;QAAC,GAAGH,UAAUG,YAAY;QAAE,GAAGH,UAAUI,eAAe;IAAA;IAE7E,MAAMC,aAA+C,EAAE;IACvD,MAAMC,uBAAoD,EAAE;IAE5D,KAAK,MAAMC,OAAOV,SAAU;QAC1B,gEAAgE;QAChE,IAAI,CAACM,YAAY,CAACI,IAAIC,IAAI,CAAC,EAAE;YAC3B;QACF;QAEA,MAAMC,kBAAkB,MAAMC,yBAAyBjB,aAAac,KAAK;YAACR;QAAK;QAE/E,IAAIU,oBAAoB,MAAM;YAC5B,IAAInB,WAAWiB,IAAII,OAAO,GAAG;gBAC3BL,qBAAqBM,IAAI,CAAC;oBAACL,KAAKA,IAAIC,IAAI;oBAAEG,SAASJ,IAAII,OAAO;gBAAA;gBAC9D;YACF;YACA,MAAM,IAAIE,MACR,CAAC,qCAAqC,EAAEN,IAAIC,IAAI,CAAC,CAAC,EAAED,IAAII,OAAO,CAAC,mBAAmB,CAAC;QAExF;QAEA,MAAMG,iBAAiB,MAAM7B,uBAAuBsB,IAAIC,IAAI,EAAEV;QAE9D,MAAMiB,kBAAkBZ,YAAY,CAACI,IAAIC,IAAI,CAAC;QAE9C,MAAMQ,YAAY5B,OAAO0B,iBAAiBtB,YAAYsB,kBAAkB1B,OAAO2B;QAE/E,IAAI,CAACC,WAAW;YACd,MAAM,IAAIH,MAAM,CAAC,sCAAsC,EAAEN,IAAIC,IAAI,EAAE;QACrE;QAEA,IAAI,CAACnB,GAAGoB,iBAAiBO,UAAUL,OAAO,GAAG;YAC3CN,WAAWO,IAAI,CAAC;gBACdI,WAAWA,UAAUL,OAAO;gBAC5BJ,KAAKA,IAAIC,IAAI;gBACbS,QAAQR;YACV;QACF;IACF;IAEA,OAAO;QAACJ;QAAYC;IAAoB;AAC1C;AAEA,eAAeI,yBAAyBQ,GAAW;IACjD,IAAIC;IACJ,IAAI;QACFA,WAAW,MAAMzB,iBAAiB;YAChC0B,QAAQ;YACRC,UAAU;YACVH;QACF;IACF,EAAE,OAAOI,KAAK;QACZ,MAAMC,UAAUD,eAAeT,QAAQS,IAAIC,OAAO,GAAGC,OAAOF;QAC5D,MAAM,IAAIT,MAAM,CAAC,mCAAmC,EAAEK,IAAI,EAAE,EAAEK,SAAS,EAAE;YAACE,OAAOH;QAAG;IACtF;IAEA,4CAA4C;IAC5C,IAAIH,SAASO,MAAM,GAAG,KAAK;QACzB,MAAMC,WAAWR,SAASS,OAAO,CAACC,GAAG,CAAC;QACtC,IAAI,CAACF,UAAU;YACb,MAAM,IAAId,MAAM,CAAC,0DAA0D,EAAEK,KAAK;QACpF;QACA,OAAOS;IACT;IAEA,IAAIR,SAASO,MAAM,KAAK,KAAK;QAC3B,OAAO;IACT;IAEA,MAAM,IAAIb,MAAM,CAAC,0BAA0B,EAAEM,SAASO,MAAM,CAAC,CAAC,EAAEP,SAASW,UAAU,EAAE;AACvF"}
1
+ {"version":3,"sources":["../../src/util/compareDependencyVersions.ts"],"sourcesContent":["import path from 'node:path'\n\nimport {getLocalPackageVersion, readPackageJson} from '@sanity/cli-core'\nimport {createRequester} from '@sanity/cli-core/request'\nimport {coerce, eq, prerelease, parse as semverParse} from 'semver'\n\nimport {getModuleUrl} from '../actions/build/getAutoUpdatesImportMap.js'\n\nexport interface CompareDependencyVersions {\n installed: string\n pkg: string\n remote: string\n}\n\nexport interface UnresolvedPrerelease {\n pkg: string\n version: string\n}\n\n/**\n * A package whose runtime version Module Server did not report, because of a network error,\n * a timeout or a 5xx.\n */\nexport interface UnavailableDependencyVersion {\n pkg: string\n reason: string\n}\n\nexport interface CompareDependencyVersionsResult {\n mismatched: Array<CompareDependencyVersions>\n unresolvedPrerelease: Array<UnresolvedPrerelease>\n\n unavailable?: Array<UnavailableDependencyVersion>\n}\n\nconst REMOTE_VERSION_TIMEOUT_MS = 5000\n\nconst defaultRequester = createRequester({\n httpErrors: false,\n timeout: REMOTE_VERSION_TIMEOUT_MS,\n})\n\ninterface CompareDependencyVersionsOptions {\n /** When provided, uses the app-specific module endpoint instead of the default endpoint. */\n appId?: string\n}\n\ntype PackageComparison =\n | {mismatch: CompareDependencyVersions; type: 'mismatched'}\n | {prerelease: UnresolvedPrerelease; type: 'unresolvedPrerelease'}\n | {type: 'matched'}\n | {type: 'unavailable'; unavailable: UnavailableDependencyVersion}\n\ntype RemoteVersion =\n | {reason: string; type: 'unavailable'}\n | {type: 'found'; version: string}\n | {type: 'not-found'}\n\n/**\n * @internal\n *\n * Compares the versions of dependencies in the studio or app with their remote versions.\n *\n * This function reads the package.json file in the provided working directory, and compares the versions of the dependencies\n * specified in the `autoUpdatesImports` parameter with their remote versions. If the versions do not match, the dependency is\n * added to a list of failed dependencies, which is returned by the function.\n *\n * The failed dependencies are anything that does not strictly match the remote version.\n * This means that if a version is lower or greater by even a patch it will be marked as failed.\n *\n * @param packages - An array of packages with their name and version to compare against remote.\n * @param workDir - The path to the working directory containing the package.json file.\n * @param options - Optional configuration for version comparison.\n *\n * @returns A promise that resolves to an object containing `mismatched` (packages whose local and remote versions differ),\n * `unresolvedPrerelease` (packages with prerelease versions that could not be resolved remotely) and `unavailable`\n * (packages Module Server did not answer for, because of a network error, a timeout or a 5xx).\n *\n * @throws Throws an error if a non-prerelease package is not found remotely, if Module Server answers with an unexpected\n * response, or if the local version of a package cannot be parsed.\n */\nexport async function compareDependencyVersions(\n packages: {name: string; version: string}[],\n workDir: string,\n {appId}: CompareDependencyVersionsOptions = {},\n): Promise<CompareDependencyVersionsResult> {\n const manifest = await readPackageJson(path.join(workDir, 'package.json'), {\n skipSchemaValidation: true,\n })\n const dependencies = {...manifest?.dependencies, ...manifest?.devDependencies}\n\n const comparisons = await Promise.all(\n packages\n .filter((pkg) => Boolean(dependencies[pkg.name]))\n .map((pkg) => comparePackageVersion(pkg, dependencies[pkg.name], {appId, workDir})),\n )\n\n return {\n mismatched: comparisons.flatMap((result) =>\n result.type === 'mismatched' ? [result.mismatch] : [],\n ),\n unavailable: comparisons.flatMap((result) =>\n result.type === 'unavailable' ? [result.unavailable] : [],\n ),\n unresolvedPrerelease: comparisons.flatMap((result) =>\n result.type === 'unresolvedPrerelease' ? [result.prerelease] : [],\n ),\n }\n}\n\n/**\n * @internal\n */\nexport function getUnavailableVersionsWarning(unavailable: UnavailableDependencyVersion[]): string {\n const packageNames = unavailable.map((entry) => entry.pkg).join(', ')\n const reasons = [...new Set(unavailable.map((entry) => entry.reason))].join('; ')\n return (\n `Could not check the runtime version of ${packageNames}: ` +\n `the Sanity module CDN request failed (${reasons}). Continuing without the check.`\n )\n}\n\nasync function comparePackageVersion(\n pkg: {name: string; version: string},\n manifestVersion: string,\n {appId, workDir}: {appId?: string; workDir: string},\n): Promise<PackageComparison> {\n const remote = await getRemoteResolvedVersion(getModuleUrl(pkg, {appId}))\n\n if (remote.type !== 'found') {\n if (prerelease(pkg.version)) {\n return {prerelease: {pkg: pkg.name, version: pkg.version}, type: 'unresolvedPrerelease'}\n }\n if (remote.type === 'unavailable') {\n return {type: 'unavailable', unavailable: {pkg: pkg.name, reason: remote.reason}}\n }\n throw new Error(\n `Failed to resolve remote version for ${pkg.name}@${pkg.version}: package not found`,\n )\n }\n\n const packageVersion = await getLocalPackageVersion(pkg.name, workDir)\n\n const installed = coerce(packageVersion ? semverParse(packageVersion) : coerce(manifestVersion))\n\n if (!installed) {\n throw new Error(`Failed to parse installed version for ${pkg.name}`)\n }\n\n return eq(remote.version, installed.version)\n ? {type: 'matched'}\n : {\n mismatch: {installed: installed.version, pkg: pkg.name, remote: remote.version},\n type: 'mismatched',\n }\n}\n\nasync function getRemoteResolvedVersion(url: string): Promise<RemoteVersion> {\n let response\n try {\n response = await defaultRequester({\n method: 'HEAD',\n redirect: 'manual',\n url,\n })\n } catch (err) {\n return {reason: err instanceof Error ? err.message : String(err), type: 'unavailable'}\n }\n\n // 302 is expected, but lets also handle 2xx\n if (response.status < 400) {\n const resolved = response.headers.get('x-resolved-version')\n if (!resolved) {\n throw new Error(`Missing 'x-resolved-version' header on response from HEAD ${url}`)\n }\n return {type: 'found', version: resolved}\n }\n\n if (response.status === 404) {\n return {type: 'not-found'}\n }\n\n if (response.status === 429 || response.status >= 500) {\n return {reason: `HTTP ${response.status} ${response.statusText}`, type: 'unavailable'}\n }\n\n throw new Error(`Unexpected HTTP response: ${response.status} ${response.statusText}`)\n}\n"],"names":["path","getLocalPackageVersion","readPackageJson","createRequester","coerce","eq","prerelease","parse","semverParse","getModuleUrl","REMOTE_VERSION_TIMEOUT_MS","defaultRequester","httpErrors","timeout","compareDependencyVersions","packages","workDir","appId","manifest","join","skipSchemaValidation","dependencies","devDependencies","comparisons","Promise","all","filter","pkg","Boolean","name","map","comparePackageVersion","mismatched","flatMap","result","type","mismatch","unavailable","unresolvedPrerelease","getUnavailableVersionsWarning","packageNames","entry","reasons","Set","reason","manifestVersion","remote","getRemoteResolvedVersion","version","Error","packageVersion","installed","url","response","method","redirect","err","message","String","status","resolved","headers","get","statusText"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sanity/cli-build",
3
- "version": "7.1.1",
3
+ "version": "7.1.2",
4
4
  "description": "Internal Sanity package for building studios and apps",
5
5
  "keywords": [
6
6
  "cli",
@@ -52,16 +52,16 @@
52
52
  "dependencies": {
53
53
  "@oclif/core": "^4.11.14",
54
54
  "@rolldown/plugin-babel": "^0.2.4",
55
- "@sanity/cli-core": "^3.14.1",
55
+ "@sanity/cli-core": "^3.14.2",
56
56
  "@sanity/generate-help-url": "^4.0.0",
57
57
  "@sanity/schema": "^6.22.0",
58
58
  "@sanity/telemetry": "^1.1.0",
59
59
  "@sanity/types": "^6.22.0",
60
- "@sanity/workbench-cli": "^2.15.1",
60
+ "@sanity/workbench-cli": "^2.15.2",
61
61
  "@vitejs/plugin-react": "^6.2.1",
62
62
  "chokidar": "^5.0.0",
63
63
  "cjs-module-lexer": "^2.2.1",
64
- "dompurify": "^3.4.14",
64
+ "dompurify": "^3.4.17",
65
65
  "empathic": "^2.0.1",
66
66
  "jsdom": "^29.1.1",
67
67
  "lightningcss": "^1.33.0",
@@ -73,13 +73,13 @@
73
73
  "react-is": "^19.3.0",
74
74
  "semver": "^7.8.1",
75
75
  "vite": "^8.3.6",
76
- "zod": "^4.5.2"
76
+ "zod": "^4.6.7"
77
77
  },
78
78
  "devDependencies": {
79
79
  "@eslint/compat": "^2.1.0",
80
80
  "@repo/package.config": "0.0.1",
81
81
  "@repo/tsconfig": "3.70.0",
82
- "@sanity/cli-test": "24.0.2",
82
+ "@sanity/cli-test": "24.0.3",
83
83
  "@sanity/eslint-config-cli": "^1.1.3",
84
84
  "@sanity/pkg-utils": "^12.3.4",
85
85
  "@sanity/ui": "^4.4.10",