@sanity/cli-build 5.2.0 → 5.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/actions/build/getViteConfig.ts"],"sourcesContent":["import path from 'node:path'\n\nimport babel from '@rolldown/plugin-babel'\nimport {findProjectRoot} from '@sanity/cli-core/config'\nimport {getCliTelemetry} from '@sanity/cli-core/telemetry'\nimport {type CliConfig, type UserViteConfig} from '@sanity/cli-core/types'\nimport {isStaging} from '@sanity/cli-core/util'\nimport {\n type WorkbenchExposes,\n workbenchOptimizeDeps,\n workbenchVitePlugins,\n} from '@sanity/workbench-cli/build'\nimport viteReact, {reactCompilerPreset} from '@vitejs/plugin-react'\nimport {type PluginOptions as ReactCompilerConfig} from 'babel-plugin-react-compiler'\nimport debug from 'debug'\nimport {\n type ConfigEnv,\n esmExternalRequirePlugin,\n type InlineConfig,\n mergeConfig,\n type Plugin,\n type PluginOption,\n type Rolldown,\n} from 'vite'\n\nimport {SANITY_CACHE_DIR} from '../../constants.js'\nimport {sanitySchemaExtractionPlugin} from '../schema/vite/plugin-schema-extraction.js'\nimport {type AutoUpdatesBuildConfig} from './autoUpdates.js'\nimport {VENDOR_DIR} from './constants.js'\nimport {createExternalFromImportMap} from './createExternalFromImportMap.js'\nimport {normalizeBasePath} from './normalizeBasePath.js'\nimport {sanityBuildEntries} from './vite/plugin-sanity-build-entries.js'\nimport {sanityFaviconsPlugin} from './vite/plugin-sanity-favicons.js'\nimport {sanityRuntimeRewritePlugin} from './vite/plugin-sanity-runtime-rewrite.js'\nimport {createVendorNamedExportsPlugin} from './vite/plugin-sanity-vendor-named-exports.js'\nimport {getDefaultFaviconsPath} from './writeFavicons.js'\n\ninterface ViteOptions {\n /**\n * Root path of the studio/sanity app\n */\n cwd: string\n\n entries: {\n relativeConfigLocation: string | null\n // `null` when a branded app declares no `entry` (sanity-io/workbench spec 002-workbench-extension-api, US5) — no app view.\n relativeEntry: string | null\n }\n\n /**\n * Returns the environment variables to be injected into the config.\n */\n getEnvironmentVariables(): Record<string, string>\n\n /**\n * Mode to run vite in - eg development or production\n */\n mode: 'development' | 'production'\n\n reactCompiler: boolean | ReactCompilerConfig | undefined\n\n /**\n * Additional plugins when configured, eg. typegen\n */\n additionalPlugins?: Plugin[]\n\n /**\n * Auto-updates configuration (production builds only). When set, vendor\n * packages are emitted as hashed ESM chunks by this build and the import map\n * in `index.html` is derived from the build output.\n */\n autoUpdates?: AutoUpdatesBuildConfig\n\n /**\n * Base path (eg under where to serve the app - `/studio` or similar)\n * Will be normalized to ensure it starts and ends with a `/`\n */\n basePath?: string\n\n exposes?: WorkbenchExposes\n\n isApp?: boolean\n\n /**\n * Whether this is a workbench app (opted in via `unstable_defineApp`). Drives\n * the module-federation build.\n */\n isWorkbenchApp?: boolean\n\n /**\n * Whether or not to minify the output (only used in `mode: 'production'`)\n */\n minify?: boolean\n\n /**\n * Output directory (eg where to place the built files, if any)\n */\n outputDir?: string\n\n /**\n * Schema extraction configuration\n */\n schemaExtraction?: CliConfig['schemaExtraction']\n\n /**\n * HTTP development server configuration\n */\n server?: {host?: string; port?: number}\n\n /**\n * Whether or not to enable source maps\n */\n sourceMap?: boolean\n\n /**\n * The workbench app's bus identity, stamped into its modules as\n * `__SANITY_APP_ID__` for `@sanity/runtime`. Only read for workbench apps.\n */\n workbenchAppId?: string\n}\n\n/**\n * Get a configuration object for Vite based on the passed options\n *\n * @internal Only meant for consumption inside of Sanity modules, do not depend on this externally\n */\nexport async function getViteConfig(options: ViteOptions): Promise<InlineConfig> {\n const {\n additionalPlugins,\n autoUpdates,\n basePath: rawBasePath = '/',\n cwd,\n entries,\n exposes,\n isApp,\n isWorkbenchApp,\n minify,\n mode,\n outputDir,\n reactCompiler,\n schemaExtraction,\n server,\n // default to `true` when `mode=development`\n sourceMap = options.mode === 'development',\n workbenchAppId,\n } = options\n\n const basePath = normalizeBasePath(rawBasePath)\n\n const configPath = (await findProjectRoot(cwd)).path\n\n const customFaviconsPath = path.join(cwd, 'static')\n const defaultFaviconsPath = await getDefaultFaviconsPath()\n const staticPath = `${basePath}static`\n\n const envVars = options.getEnvironmentVariables()\n\n const sharedPlugins: PluginOption = [\n viteReact(),\n ...(reactCompiler\n ? [babel({presets: [reactCompilerPreset(reactCompiler === true ? {} : reactCompiler)]})]\n : []),\n ...(schemaExtraction?.enabled\n ? [\n sanitySchemaExtractionPlugin({\n additionalPatterns: schemaExtraction.watchPatterns,\n configPath,\n enforceRequiredFields: schemaExtraction.enforceRequiredFields,\n outputPath: schemaExtraction.path,\n telemetryLogger: getCliTelemetry(),\n workDir: cwd,\n workspaceName: schemaExtraction.workspace,\n }),\n ]\n : []),\n ]\n\n const viteConfig: InlineConfig = {\n base: basePath,\n build: {\n outDir: outputDir || path.resolve(cwd, 'dist'),\n sourcemap: sourceMap,\n },\n // Define a custom cache directory so that sanity's vite cache\n // does not conflict with any potential local vite projects\n cacheDir: `${SANITY_CACHE_DIR}/vite`,\n configFile: false,\n define: {\n __SANITY_BUILD_TIMESTAMP__: JSON.stringify(Date.now()),\n __SANITY_STAGING__: isStaging(),\n 'process.env.MODE': JSON.stringify(mode),\n 'process.env.PKG_BUILD_VERSION': JSON.stringify(process.env.PKG_BUILD_VERSION),\n /**\n * Yes, double negatives are confusing.\n * The default value of `SC_DISABLE_SPEEDY` is `process.env.NODE_ENV === 'production'`: https://github.com/styled-components/styled-components/blob/99c02f52d69e8e509c0bf012cadee7f8e819a6dd/packages/styled-components/src/constants.ts#L34\n * Which means that in production, use the much faster way of inserting CSS rules, based on the CSSStyleSheet API (https://developer.mozilla.org/en-US/docs/Web/API/CSSStyleSheet/insertRule)\n * while in dev mode, use the slower way of inserting CSS rules, which appends text nodes to the `<style>` tag: https://github.com/styled-components/styled-components/blob/99c02f52d69e8e509c0bf012cadee7f8e819a6dd/packages/styled-components/src/sheet/Tag.ts#L74-L76\n * There are historical reasons for this, primarily that browsers initially did not support editing CSS rules in the DevTools inspector if `CSSStyleSheet.insetRule` were used.\n * However, that's no longer the case (since Chrome 81 back in April 2020: https://developer.chrome.com/docs/css-ui/css-in-js), the latest version of FireFox also supports it,\n * and there is no longer any reason to use the much slower method in dev mode.\n */\n 'process.env.SC_DISABLE_SPEEDY': JSON.stringify('false'),\n ...envVars,\n },\n envPrefix: isApp ? 'SANITY_APP_' : 'SANITY_STUDIO_',\n logLevel: mode === 'production' ? 'silent' : 'info',\n mode,\n plugins: [\n // Federation builds skip the serve-only client plugins (favicons, runtime\n // rewrite) — they no-op at build. `sanityBuildEntries` is scoped to the\n // `client` environment so it emits the standalone SPA `index.html`\n // (bridge-free) when the workbench remote SPA is enabled, and no-ops in the\n // federation env / when no client env exists (see plugin-sanity-environment).\n ...(isWorkbenchApp\n ? [\n ...sharedPlugins,\n await workbenchVitePlugins({appId: workbenchAppId, cwd, entries, exposes, isApp}),\n {\n ...sanityBuildEntries({basePath, bridge: false, cwd, isApp}),\n applyToEnvironment: (env) => env.name === 'client',\n } satisfies Plugin,\n ]\n : [\n ...sharedPlugins,\n sanityFaviconsPlugin({\n customFaviconsPath,\n defaultFaviconsPath,\n staticUrlPath: staticPath,\n }),\n sanityRuntimeRewritePlugin(),\n sanityBuildEntries({autoUpdates, basePath, cwd, isApp}),\n ]),\n // Caller-provided plugins (e.g. typegen in dev) aren't client-specific,\n // so they apply to federation builds too.\n ...(additionalPlugins || []),\n ],\n resolve: {\n dedupe: ['react', 'react-dom', 'sanity', 'styled-components'],\n // Honor the studio's tsconfig `paths`, consistent with studioWorkerLoader.worker.ts.\n tsconfigPaths: true,\n },\n root: cwd,\n server: {\n host: server?.host,\n port: server?.port || 3333,\n // Apps drift to a free port (the reported URL embeds whichever port was\n // claimed), and workbench runs stack servers on adjacent ports — both\n // need the fallback. Studios fail fast on a busy port.\n strictPort: !isApp && !isWorkbenchApp,\n\n /**\n * Significantly speed up startup time,\n * and most importantly eliminates the `new dependencies optimized: foobar. optimized dependencies changed. reloading`\n * types of initial reload loops that otherwise happen as vite discovers deps that need to be optimized.\n * This option starts the traversal up front, and warms up the dep tree required to render the userland sanity.config.ts file,\n * and thus avoids frustrating reload loops.\n */\n warmup: {\n clientFiles: ['./.sanity/runtime/app.js'],\n },\n },\n }\n\n // Front-load the deps the federation `exposes` reach only via the host's\n // dynamic imports, which Vite's dep scanner (crawling from the HTML entry)\n // otherwise misses — see `workbenchOptimizeDeps`. Dev-server only; Vite\n // ignores `optimizeDeps` at build. Set before the userland `vite` hook so an\n // app can still extend the list.\n if (isWorkbenchApp && mode === 'development') {\n const runtimeDir = path.join(cwd, '.sanity', 'runtime')\n const appSources = [entries.relativeEntry, entries.relativeConfigLocation]\n .filter((relativePath): relativePath is string => relativePath !== null)\n .map((relativePath) => path.resolve(runtimeDir, relativePath))\n viteConfig.optimizeDeps = workbenchOptimizeDeps({appSources, cwd, exposes})\n }\n\n // Federation builds don't produce a client bundle — the federation\n // plugin configures its own environment and build entry point.\n if (mode === 'production' && !isWorkbenchApp) {\n if (autoUpdates) {\n viteConfig.plugins!.push(\n // Re-expose CommonJS named exports (react, react-dom) as real ESM exports\n // on the emitted vendor chunks; Rolldown only emits `export default` for a\n // CommonJS entry.\n createVendorNamedExportsPlugin(autoUpdates.vendor.namesByChunkName),\n // The import map and vendor specifiers are externals of the studio/app\n // bundle, resolved by the browser at runtime. They are handed to\n // `esmExternalRequirePlugin` rather than `rolldownOptions.external`: the\n // plugin both marks them external AND rewrites bundled CommonJS\n // `require()` calls of an external (e.g. react-dom requiring react) into\n // ESM imports, while `rolldownOptions.external` would short-circuit that\n // rewrite and leave a runtime `require` shim that throws in the browser.\n esmExternalRequirePlugin({\n external: createExternalFromImportMap({\n imports: {\n ...autoUpdates.imports,\n ...Object.fromEntries(\n Object.values(autoUpdates.vendor.specifiersByChunkName).map((specifier) => [\n specifier,\n '',\n ]),\n ),\n },\n }),\n }),\n )\n }\n\n const vendorChunkNames = autoUpdates\n ? new Set(Object.keys(autoUpdates.vendor.specifiersByChunkName))\n : null\n\n viteConfig.build = {\n ...viteConfig.build,\n\n assetsDir: 'static',\n emptyOutDir: false, // Rely on CLI to do this\n minify: minify ? 'oxc' : false,\n\n rolldownOptions: {\n input: {\n sanity: path.join(cwd, '.sanity', 'runtime', 'app.js'),\n ...autoUpdates?.vendor.entries,\n },\n onwarn: onRolldownWarn,\n ...(autoUpdates\n ? {\n // Expose Rolldown's native MagicString on `renderChunk`'s `meta` so\n // the vendor named-exports plugin can edit chunks without a JS\n // dependency.\n experimental: {nativeMagicString: true},\n output: {\n entryFileNames: (chunk) =>\n vendorChunkNames!.has(chunk.name)\n ? `${VENDOR_DIR}/[name]-[hash].mjs`\n : 'static/[name]-[hash].js',\n exports: 'named',\n },\n // App-style builds default to `preserveEntrySignatures: false`, which\n // treeshakes the exports off entry chunks. Vendor chunks are loaded by\n // the browser via the import map, so their exports must survive (e.g.\n // styled-components' native ESM exports). `exports-only` keeps exports\n // for entries that have them, while the export-less `sanity` app entry\n // still bundles as before.\n preserveEntrySignatures: 'exports-only',\n }\n : {}),\n },\n }\n }\n\n return viteConfig\n}\n\nfunction onRolldownWarn(warning: Rolldown.RolldownLog, warn: Rolldown.LoggingFunction) {\n if (suppressUnusedImport(warning)) {\n return\n }\n\n warn(warning)\n}\n\nfunction suppressUnusedImport(warning: Rolldown.RolldownLog & {ids?: string[]}): boolean {\n if (warning.code !== 'UNUSED_EXTERNAL_IMPORT') return false\n\n // Suppress:\n // ```\n // \"useDebugValue\" is imported from external module \"react\"…\n // ```\n if (warning.names?.includes('useDebugValue')) {\n warning.names = warning.names.filter((n) => n !== 'useDebugValue')\n if (warning.names.length === 0) return true\n }\n\n // If some library does something unexpected, we suppress since it isn't actionable\n if (warning.ids?.every((id) => id.includes('/node_modules/') || id.includes('\\\\node_modules\\\\')))\n return true\n\n return false\n}\n\n/**\n * Re-asserts the critical parts of the default config after a userland vite\n * config (`vite` in `sanity.cli.ts`) has been applied.\n *\n * Everything `getViteConfig` sets under `build.rolldownOptions` is load-bearing:\n * the `input` entries (the studio entry plus, for auto-updating studios/apps,\n * the vendor entries), `preserveEntrySignatures`, the `experimental` flags the\n * vendor plugins rely on, and the `output` chunk naming. A userland config that\n * returns a brand-new object for any of these would silently break the build\n * (e.g. vendor chunks never emitted while the bundle still treats them as\n * external), so the default `rolldownOptions` are deep-merged back over the\n * userland config: userland additions survive, replacements of critical\n * options are healed.\n *\n * @param config - User-modified configuration\n * @param defaultConfig - The configuration produced by `getViteConfig`, before the userland config was applied\n * @returns Merged configuration\n * @internal\n */\nexport async function finalizeViteConfig(\n config: InlineConfig,\n defaultConfig: InlineConfig,\n): Promise<InlineConfig> {\n if (typeof config.build?.rolldownOptions?.input !== 'object') {\n throw new TypeError(\n 'Vite config must contain `build.rolldownOptions.input`, and it must be an object',\n )\n }\n\n if (!config.root) {\n throw new Error(\n 'Vite config must contain `root` property, and must point to the Sanity root directory',\n )\n }\n\n return mergeConfig(config, {\n build: {\n rolldownOptions: defaultConfig.build?.rolldownOptions ?? {},\n },\n })\n}\n\n/**\n * Merge user-provided Vite configuration object or function\n *\n * @param defaultConfig - Default configuration object\n * @param userConfig - User-provided configuration object or function\n * @returns Merged configuration\n * @internal\n */\nexport async function extendViteConfigWithUserConfig(\n env: ConfigEnv,\n defaultConfig: InlineConfig,\n userConfig: UserViteConfig,\n): Promise<InlineConfig> {\n let config = defaultConfig\n\n if (typeof userConfig === 'function') {\n debug('Extending vite config using user-specified function')\n config = await userConfig(config, env)\n } else if (typeof userConfig === 'object') {\n debug('Merging vite config using user-specified object')\n config = mergeConfig(config, userConfig)\n }\n\n return config\n}\n"],"names":["path","babel","findProjectRoot","getCliTelemetry","isStaging","workbenchOptimizeDeps","workbenchVitePlugins","viteReact","reactCompilerPreset","debug","esmExternalRequirePlugin","mergeConfig","SANITY_CACHE_DIR","sanitySchemaExtractionPlugin","VENDOR_DIR","createExternalFromImportMap","normalizeBasePath","sanityBuildEntries","sanityFaviconsPlugin","sanityRuntimeRewritePlugin","createVendorNamedExportsPlugin","getDefaultFaviconsPath","getViteConfig","options","additionalPlugins","autoUpdates","basePath","rawBasePath","cwd","entries","exposes","isApp","isWorkbenchApp","minify","mode","outputDir","reactCompiler","schemaExtraction","server","sourceMap","workbenchAppId","configPath","customFaviconsPath","join","defaultFaviconsPath","staticPath","envVars","getEnvironmentVariables","sharedPlugins","presets","enabled","additionalPatterns","watchPatterns","enforceRequiredFields","outputPath","telemetryLogger","workDir","workspaceName","workspace","viteConfig","base","build","outDir","resolve","sourcemap","cacheDir","configFile","define","__SANITY_BUILD_TIMESTAMP__","JSON","stringify","Date","now","__SANITY_STAGING__","process","env","PKG_BUILD_VERSION","envPrefix","logLevel","plugins","appId","bridge","applyToEnvironment","name","staticUrlPath","dedupe","tsconfigPaths","root","host","port","strictPort","warmup","clientFiles","runtimeDir","appSources","relativeEntry","relativeConfigLocation","filter","relativePath","map","optimizeDeps","push","vendor","namesByChunkName","external","imports","Object","fromEntries","values","specifiersByChunkName","specifier","vendorChunkNames","Set","keys","assetsDir","emptyOutDir","rolldownOptions","input","sanity","onwarn","onRolldownWarn","experimental","nativeMagicString","output","entryFileNames","chunk","has","exports","preserveEntrySignatures","warning","warn","suppressUnusedImport","code","names","includes","n","length","ids","every","id","finalizeViteConfig","config","defaultConfig","TypeError","Error","extendViteConfigWithUserConfig","userConfig"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/actions/build/getViteConfig.ts"],"sourcesContent":["import path from 'node:path'\n\nimport babel from '@rolldown/plugin-babel'\nimport {findProjectRoot} from '@sanity/cli-core/config'\nimport {getCliTelemetry} from '@sanity/cli-core/telemetry'\nimport {type CliConfig, type ReactCompilerConfig, type UserViteConfig} from '@sanity/cli-core/types'\nimport {isStaging} from '@sanity/cli-core/util'\nimport {\n type WorkbenchExposes,\n workbenchOptimizeDeps,\n workbenchVitePlugins,\n} from '@sanity/workbench-cli/build'\nimport viteReact, {reactCompilerPreset} from '@vitejs/plugin-react'\nimport {\n type ConfigEnv,\n esmExternalRequirePlugin,\n type InlineConfig,\n mergeConfig,\n type Plugin,\n type PluginOption,\n type Rolldown,\n} from 'vite'\n\nimport {SANITY_CACHE_DIR} from '../../constants.js'\nimport {sanitySchemaExtractionPlugin} from '../schema/vite/plugin-schema-extraction.js'\nimport {type AutoUpdatesBuildConfig} from './autoUpdates.js'\nimport {buildDebug} from './buildDebug.js'\nimport {VENDOR_DIR} from './constants.js'\nimport {createExternalFromImportMap} from './createExternalFromImportMap.js'\nimport {normalizeBasePath} from './normalizeBasePath.js'\nimport {sanityBuildEntries} from './vite/plugin-sanity-build-entries.js'\nimport {sanityFaviconsPlugin} from './vite/plugin-sanity-favicons.js'\nimport {sanityRuntimeRewritePlugin} from './vite/plugin-sanity-runtime-rewrite.js'\nimport {createVendorNamedExportsPlugin} from './vite/plugin-sanity-vendor-named-exports.js'\nimport {getDefaultFaviconsPath} from './writeFavicons.js'\n\ninterface ViteOptions {\n /**\n * Root path of the studio/sanity app\n */\n cwd: string\n\n entries: {\n relativeConfigLocation: string | null\n // `null` when a branded app declares no `entry` (sanity-io/workbench spec 002-workbench-extension-api, US5) — no app view.\n relativeEntry: string | null\n }\n\n /**\n * Returns the environment variables to be injected into the config.\n */\n getEnvironmentVariables(): Record<string, string>\n\n /**\n * Mode to run vite in - eg development or production\n */\n mode: 'development' | 'production'\n\n reactCompiler: CliConfig['reactCompiler']\n\n /**\n * Additional plugins when configured, eg. typegen\n */\n additionalPlugins?: Plugin[]\n\n /**\n * Auto-updates configuration (production builds only). When set, vendor\n * packages are emitted as hashed ESM chunks by this build and the import map\n * in `index.html` is derived from the build output.\n */\n autoUpdates?: AutoUpdatesBuildConfig\n\n /**\n * Base path (eg under where to serve the app - `/studio` or similar)\n * Will be normalized to ensure it starts and ends with a `/`\n */\n basePath?: string\n\n exposes?: WorkbenchExposes\n\n isApp?: boolean\n\n /**\n * Whether this is a workbench app (opted in via `unstable_defineApp`). Drives\n * the module-federation build.\n */\n isWorkbenchApp?: boolean\n\n /**\n * Whether or not to minify the output (only used in `mode: 'production'`)\n */\n minify?: boolean\n\n /**\n * Output directory (eg where to place the built files, if any)\n */\n outputDir?: string\n\n /**\n * Schema extraction configuration\n */\n schemaExtraction?: CliConfig['schemaExtraction']\n\n /**\n * HTTP development server configuration\n */\n server?: {host?: string; port?: number}\n\n /**\n * Whether or not to enable source maps\n */\n sourceMap?: boolean\n\n /**\n * The workbench app's bus identity, stamped into its modules as\n * `__SANITY_APP_ID__` for `@sanity/runtime`. Only read for workbench apps.\n */\n workbenchAppId?: string\n}\n\n/**\n * Get a configuration object for Vite based on the passed options\n *\n * @internal Only meant for consumption inside of Sanity modules, do not depend on this externally\n */\nexport async function getViteConfig(options: ViteOptions): Promise<InlineConfig> {\n const {\n additionalPlugins,\n autoUpdates,\n basePath: rawBasePath = '/',\n cwd,\n entries,\n exposes,\n isApp,\n isWorkbenchApp,\n minify,\n mode,\n outputDir,\n reactCompiler,\n schemaExtraction,\n server,\n // default to `true` when `mode=development`\n sourceMap = options.mode === 'development',\n workbenchAppId,\n } = options\n\n const basePath = normalizeBasePath(rawBasePath)\n\n const configPath = (await findProjectRoot(cwd)).path\n\n const customFaviconsPath = path.join(cwd, 'static')\n const defaultFaviconsPath = await getDefaultFaviconsPath()\n const staticPath = `${basePath}static`\n\n const envVars = options.getEnvironmentVariables()\n\n const sharedPlugins: PluginOption = [\n ...getReactPlugins(reactCompiler),\n ...(schemaExtraction?.enabled\n ? [\n sanitySchemaExtractionPlugin({\n additionalPatterns: schemaExtraction.watchPatterns,\n configPath,\n enforceRequiredFields: schemaExtraction.enforceRequiredFields,\n outputPath: schemaExtraction.path,\n telemetryLogger: getCliTelemetry(),\n workDir: cwd,\n workspaceName: schemaExtraction.workspace,\n }),\n ]\n : []),\n ]\n\n const viteConfig: InlineConfig = {\n base: basePath,\n build: {\n outDir: outputDir || path.resolve(cwd, 'dist'),\n sourcemap: sourceMap,\n },\n // Define a custom cache directory so that sanity's vite cache\n // does not conflict with any potential local vite projects\n cacheDir: `${SANITY_CACHE_DIR}/vite`,\n configFile: false,\n define: {\n __SANITY_BUILD_TIMESTAMP__: JSON.stringify(Date.now()),\n __SANITY_STAGING__: isStaging(),\n 'process.env.MODE': JSON.stringify(mode),\n 'process.env.PKG_BUILD_VERSION': JSON.stringify(process.env.PKG_BUILD_VERSION),\n /**\n * Yes, double negatives are confusing.\n * The default value of `SC_DISABLE_SPEEDY` is `process.env.NODE_ENV === 'production'`: https://github.com/styled-components/styled-components/blob/99c02f52d69e8e509c0bf012cadee7f8e819a6dd/packages/styled-components/src/constants.ts#L34\n * Which means that in production, use the much faster way of inserting CSS rules, based on the CSSStyleSheet API (https://developer.mozilla.org/en-US/docs/Web/API/CSSStyleSheet/insertRule)\n * while in dev mode, use the slower way of inserting CSS rules, which appends text nodes to the `<style>` tag: https://github.com/styled-components/styled-components/blob/99c02f52d69e8e509c0bf012cadee7f8e819a6dd/packages/styled-components/src/sheet/Tag.ts#L74-L76\n * There are historical reasons for this, primarily that browsers initially did not support editing CSS rules in the DevTools inspector if `CSSStyleSheet.insetRule` were used.\n * However, that's no longer the case (since Chrome 81 back in April 2020: https://developer.chrome.com/docs/css-ui/css-in-js), the latest version of FireFox also supports it,\n * and there is no longer any reason to use the much slower method in dev mode.\n */\n 'process.env.SC_DISABLE_SPEEDY': JSON.stringify('false'),\n ...envVars,\n },\n envPrefix: isApp ? 'SANITY_APP_' : 'SANITY_STUDIO_',\n logLevel: mode === 'production' ? 'silent' : 'info',\n mode,\n plugins: [\n // Federation builds skip the serve-only client plugins (favicons, runtime\n // rewrite) — they no-op at build. `sanityBuildEntries` is scoped to the\n // `client` environment so it emits the standalone SPA `index.html`\n // (bridge-free) when the workbench remote SPA is enabled, and no-ops in the\n // federation env / when no client env exists (see plugin-sanity-environment).\n ...(isWorkbenchApp\n ? [\n ...sharedPlugins,\n await workbenchVitePlugins({appId: workbenchAppId, cwd, entries, exposes, isApp}),\n {\n ...sanityBuildEntries({basePath, bridge: false, cwd, isApp}),\n applyToEnvironment: (env) => env.name === 'client',\n } satisfies Plugin,\n ]\n : [\n ...sharedPlugins,\n sanityFaviconsPlugin({\n customFaviconsPath,\n defaultFaviconsPath,\n staticUrlPath: staticPath,\n }),\n sanityRuntimeRewritePlugin(),\n sanityBuildEntries({autoUpdates, basePath, cwd, isApp}),\n ]),\n // Caller-provided plugins (e.g. typegen in dev) aren't client-specific,\n // so they apply to federation builds too.\n ...(additionalPlugins || []),\n ],\n resolve: {\n dedupe: ['react', 'react-dom', 'sanity', 'styled-components'],\n // Honor the studio's tsconfig `paths`, consistent with studioWorkerLoader.worker.ts.\n tsconfigPaths: true,\n },\n root: cwd,\n server: {\n host: server?.host,\n port: server?.port || 3333,\n // Apps drift to a free port (the reported URL embeds whichever port was\n // claimed), and workbench runs stack servers on adjacent ports — both\n // need the fallback. Studios fail fast on a busy port.\n strictPort: !isApp && !isWorkbenchApp,\n\n /**\n * Significantly speed up startup time,\n * and most importantly eliminates the `new dependencies optimized: foobar. optimized dependencies changed. reloading`\n * types of initial reload loops that otherwise happen as vite discovers deps that need to be optimized.\n * This option starts the traversal up front, and warms up the dep tree required to render the userland sanity.config.ts file,\n * and thus avoids frustrating reload loops.\n */\n warmup: {\n clientFiles: ['./.sanity/runtime/app.js'],\n },\n },\n }\n\n // Front-load the deps the federation `exposes` reach only via the host's\n // dynamic imports, which Vite's dep scanner (crawling from the HTML entry)\n // otherwise misses — see `workbenchOptimizeDeps`. Dev-server only; Vite\n // ignores `optimizeDeps` at build. Set before the userland `vite` hook so an\n // app can still extend the list.\n if (isWorkbenchApp && mode === 'development') {\n const runtimeDir = path.join(cwd, '.sanity', 'runtime')\n const appSources = [entries.relativeEntry, entries.relativeConfigLocation]\n .filter((relativePath): relativePath is string => relativePath !== null)\n .map((relativePath) => path.resolve(runtimeDir, relativePath))\n viteConfig.optimizeDeps = workbenchOptimizeDeps({appSources, cwd, exposes})\n }\n\n // Federation builds don't produce a client bundle — the federation\n // plugin configures its own environment and build entry point.\n if (mode === 'production' && !isWorkbenchApp) {\n if (autoUpdates) {\n viteConfig.plugins!.push(\n // Re-expose CommonJS named exports (react, react-dom) as real ESM exports\n // on the emitted vendor chunks; Rolldown only emits `export default` for a\n // CommonJS entry.\n createVendorNamedExportsPlugin(autoUpdates.vendor.namesByChunkName),\n // The import map and vendor specifiers are externals of the studio/app\n // bundle, resolved by the browser at runtime. They are handed to\n // `esmExternalRequirePlugin` rather than `rolldownOptions.external`: the\n // plugin both marks them external AND rewrites bundled CommonJS\n // `require()` calls of an external (e.g. react-dom requiring react) into\n // ESM imports, while `rolldownOptions.external` would short-circuit that\n // rewrite and leave a runtime `require` shim that throws in the browser.\n esmExternalRequirePlugin({\n external: createExternalFromImportMap({\n imports: {\n ...autoUpdates.imports,\n ...Object.fromEntries(\n Object.values(autoUpdates.vendor.specifiersByChunkName).map((specifier) => [\n specifier,\n '',\n ]),\n ),\n },\n }),\n }),\n )\n }\n\n const vendorChunkNames = autoUpdates\n ? new Set(Object.keys(autoUpdates.vendor.specifiersByChunkName))\n : null\n\n viteConfig.build = {\n ...viteConfig.build,\n\n assetsDir: 'static',\n emptyOutDir: false, // Rely on CLI to do this\n minify: minify ? 'oxc' : false,\n\n rolldownOptions: {\n input: {\n sanity: path.join(cwd, '.sanity', 'runtime', 'app.js'),\n ...autoUpdates?.vendor.entries,\n },\n onwarn: onRolldownWarn,\n ...(autoUpdates\n ? {\n // Expose Rolldown's native MagicString on `renderChunk`'s `meta` so\n // the vendor named-exports plugin can edit chunks without a JS\n // dependency.\n experimental: {nativeMagicString: true},\n output: {\n entryFileNames: (chunk) =>\n vendorChunkNames!.has(chunk.name)\n ? `${VENDOR_DIR}/[name]-[hash].mjs`\n : 'static/[name]-[hash].js',\n exports: 'named',\n },\n // App-style builds default to `preserveEntrySignatures: false`, which\n // treeshakes the exports off entry chunks. Vendor chunks are loaded by\n // the browser via the import map, so their exports must survive (e.g.\n // styled-components' native ESM exports). `exports-only` keeps exports\n // for entries that have them, while the export-less `sanity` app entry\n // still bundles as before.\n preserveEntrySignatures: 'exports-only',\n }\n : {}),\n },\n }\n }\n\n return viteConfig\n}\n\n/**\n * The React plugin(s) for the given `reactCompiler` configuration.\n *\n * With the (default) babel transform the compiler runs as a babel preset\n * next to a plain `viteReact()`. With the experimental oxc transform,\n * `viteReact`'s `compiler` option lets `oxc-transform-react` own the React\n * Compiler, TypeScript/JSX and Fast Refresh transforms in one pass. The\n * `transform` discriminator is stripped so neither compiler receives an\n * option it does not know.\n */\nfunction getReactPlugins(reactCompiler: CliConfig['reactCompiler']): PluginOption[] {\n const config: ReactCompilerConfig | undefined =\n reactCompiler === true ? {} : reactCompiler || undefined\n\n if (!config) {\n return [viteReact()]\n }\n\n if (config.transform === 'oxc') {\n const {transform, ...compilerOptions} = config\n return [viteReact({compiler: compilerOptions})]\n }\n\n const {transform, ...compilerOptions} = config\n return [viteReact(), babel({presets: [reactCompilerPreset(compilerOptions)]})]\n}\n\nfunction onRolldownWarn(warning: Rolldown.RolldownLog, warn: Rolldown.LoggingFunction) {\n if (suppressUnusedImport(warning)) {\n return\n }\n\n warn(warning)\n}\n\nfunction suppressUnusedImport(warning: Rolldown.RolldownLog & {ids?: string[]}): boolean {\n if (warning.code !== 'UNUSED_EXTERNAL_IMPORT') return false\n\n // Suppress:\n // ```\n // \"useDebugValue\" is imported from external module \"react\"…\n // ```\n if (warning.names?.includes('useDebugValue')) {\n warning.names = warning.names.filter((n) => n !== 'useDebugValue')\n if (warning.names.length === 0) return true\n }\n\n // If some library does something unexpected, we suppress since it isn't actionable\n if (warning.ids?.every((id) => id.includes('/node_modules/') || id.includes('\\\\node_modules\\\\')))\n return true\n\n return false\n}\n\n/**\n * Re-asserts the critical parts of the default config after a userland vite\n * config (`vite` in `sanity.cli.ts`) has been applied.\n *\n * Everything `getViteConfig` sets under `build.rolldownOptions` is load-bearing:\n * the `input` entries (the studio entry plus, for auto-updating studios/apps,\n * the vendor entries), `preserveEntrySignatures`, the `experimental` flags the\n * vendor plugins rely on, and the `output` chunk naming. A userland config that\n * returns a brand-new object for any of these would silently break the build\n * (e.g. vendor chunks never emitted while the bundle still treats them as\n * external), so the default `rolldownOptions` are deep-merged back over the\n * userland config: userland additions survive, replacements of critical\n * options are healed.\n *\n * @param config - User-modified configuration\n * @param defaultConfig - The configuration produced by `getViteConfig`, before the userland config was applied\n * @returns Merged configuration\n * @internal\n */\nexport async function finalizeViteConfig(\n config: InlineConfig,\n defaultConfig: InlineConfig,\n): Promise<InlineConfig> {\n if (typeof config.build?.rolldownOptions?.input !== 'object') {\n throw new TypeError(\n 'Vite config must contain `build.rolldownOptions.input`, and it must be an object',\n )\n }\n\n if (!config.root) {\n throw new Error(\n 'Vite config must contain `root` property, and must point to the Sanity root directory',\n )\n }\n\n return mergeConfig(config, {\n build: {\n rolldownOptions: defaultConfig.build?.rolldownOptions ?? {},\n },\n })\n}\n\n/**\n * Merge user-provided Vite configuration object or function\n *\n * @param defaultConfig - Default configuration object\n * @param userConfig - User-provided configuration object or function\n * @returns Merged configuration\n * @internal\n */\nexport async function extendViteConfigWithUserConfig(\n env: ConfigEnv,\n defaultConfig: InlineConfig,\n userConfig: UserViteConfig,\n): Promise<InlineConfig> {\n let config = defaultConfig\n\n if (typeof userConfig === 'function') {\n buildDebug('Extending vite config using user-specified function')\n config = await userConfig(config, env)\n } else if (typeof userConfig === 'object') {\n buildDebug('Merging vite config using user-specified object')\n config = mergeConfig(config, userConfig)\n }\n\n return config\n}\n"],"names":["path","babel","findProjectRoot","getCliTelemetry","isStaging","workbenchOptimizeDeps","workbenchVitePlugins","viteReact","reactCompilerPreset","esmExternalRequirePlugin","mergeConfig","SANITY_CACHE_DIR","sanitySchemaExtractionPlugin","buildDebug","VENDOR_DIR","createExternalFromImportMap","normalizeBasePath","sanityBuildEntries","sanityFaviconsPlugin","sanityRuntimeRewritePlugin","createVendorNamedExportsPlugin","getDefaultFaviconsPath","getViteConfig","options","additionalPlugins","autoUpdates","basePath","rawBasePath","cwd","entries","exposes","isApp","isWorkbenchApp","minify","mode","outputDir","reactCompiler","schemaExtraction","server","sourceMap","workbenchAppId","configPath","customFaviconsPath","join","defaultFaviconsPath","staticPath","envVars","getEnvironmentVariables","sharedPlugins","getReactPlugins","enabled","additionalPatterns","watchPatterns","enforceRequiredFields","outputPath","telemetryLogger","workDir","workspaceName","workspace","viteConfig","base","build","outDir","resolve","sourcemap","cacheDir","configFile","define","__SANITY_BUILD_TIMESTAMP__","JSON","stringify","Date","now","__SANITY_STAGING__","process","env","PKG_BUILD_VERSION","envPrefix","logLevel","plugins","appId","bridge","applyToEnvironment","name","staticUrlPath","dedupe","tsconfigPaths","root","host","port","strictPort","warmup","clientFiles","runtimeDir","appSources","relativeEntry","relativeConfigLocation","filter","relativePath","map","optimizeDeps","push","vendor","namesByChunkName","external","imports","Object","fromEntries","values","specifiersByChunkName","specifier","vendorChunkNames","Set","keys","assetsDir","emptyOutDir","rolldownOptions","input","sanity","onwarn","onRolldownWarn","experimental","nativeMagicString","output","entryFileNames","chunk","has","exports","preserveEntrySignatures","config","undefined","transform","compilerOptions","compiler","presets","warning","warn","suppressUnusedImport","code","names","includes","n","length","ids","every","id","finalizeViteConfig","defaultConfig","TypeError","Error","extendViteConfigWithUserConfig","userConfig"],"mappings":"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"}
@@ -4,12 +4,7 @@ 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
6
  const defaultRequester = createRequester({
7
- middleware: {
8
- httpErrors: false,
9
- promise: {
10
- onlyBody: false
11
- }
12
- }
7
+ httpErrors: false
13
8
  });
14
9
  /**
15
10
  * @internal
@@ -83,8 +78,8 @@ async function getRemoteResolvedVersion(url) {
83
78
  let response;
84
79
  try {
85
80
  response = await defaultRequester({
86
- maxRedirects: 0,
87
81
  method: 'HEAD',
82
+ redirect: 'manual',
88
83
  url
89
84
  });
90
85
  } catch (err) {
@@ -94,17 +89,17 @@ async function getRemoteResolvedVersion(url) {
94
89
  });
95
90
  }
96
91
  // 302 is expected, but lets also handle 2xx
97
- if (response.statusCode < 400) {
98
- const resolved = response.headers['x-resolved-version'];
92
+ if (response.status < 400) {
93
+ const resolved = response.headers.get('x-resolved-version');
99
94
  if (!resolved) {
100
95
  throw new Error(`Missing 'x-resolved-version' header on response from HEAD ${url}`);
101
96
  }
102
97
  return resolved;
103
98
  }
104
- if (response.statusCode === 404) {
99
+ if (response.status === 404) {
105
100
  return null;
106
101
  }
107
- throw new Error(`Unexpected HTTP response: ${response.statusCode} ${response.statusMessage}`);
102
+ throw new Error(`Unexpected HTTP response: ${response.status} ${response.statusText}`);
108
103
  }
109
104
 
110
105
  //# sourceMappingURL=compareDependencyVersions.js.map
@@ -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 middleware: {httpErrors: false, promise: {onlyBody: 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 maxRedirects: 0,\n method: 'HEAD',\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.statusCode < 400) {\n const resolved = response.headers['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.statusCode === 404) {\n return null\n }\n\n throw new Error(`Unexpected HTTP response: ${response.statusCode} ${response.statusMessage}`)\n}\n"],"names":["path","getLocalPackageVersion","readPackageJson","createRequester","coerce","eq","prerelease","parse","semverParse","getModuleUrl","defaultRequester","middleware","httpErrors","promise","onlyBody","compareDependencyVersions","packages","workDir","appId","manifest","join","skipSchemaValidation","dependencies","devDependencies","mismatched","unresolvedPrerelease","pkg","name","resolvedVersion","getRemoteResolvedVersion","version","push","Error","packageVersion","manifestVersion","installed","remote","url","response","maxRedirects","method","err","message","String","cause","statusCode","resolved","headers","statusMessage"],"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;QAACC,YAAY;QAAOC,SAAS;YAACC,UAAU;QAAK;IAAC;AAC5D;AAOA;;;;;;;;;;;;;;;;;;;;;CAqBC,GACD,OAAO,eAAeC,0BACpBC,QAA2C,EAC3CC,OAAe,EACf,EAACC,KAAK,EAAmC,GAAG,CAAC,CAAC;IAE9C,MAAMC,WAAW,MAAMjB,gBAAgBF,KAAKoB,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,yBAAyBpB,aAAaiB,KAAK;YAACR;QAAK;QAE/E,IAAIU,oBAAoB,MAAM;YAC5B,IAAItB,WAAWoB,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,MAAMhC,uBAAuByB,IAAIC,IAAI,EAAEV;QAE9D,MAAMiB,kBAAkBZ,YAAY,CAACI,IAAIC,IAAI,CAAC;QAE9C,MAAMQ,YAAY/B,OAAO6B,iBAAiBzB,YAAYyB,kBAAkB7B,OAAO8B;QAE/E,IAAI,CAACC,WAAW;YACd,MAAM,IAAIH,MAAM,CAAC,sCAAsC,EAAEN,IAAIC,IAAI,EAAE;QACrE;QAEA,IAAI,CAACtB,GAAGuB,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,MAAM5B,iBAAiB;YAChC6B,cAAc;YACdC,QAAQ;YACRH;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,UAAU,GAAG,KAAK;QAC7B,MAAMC,WAAWR,SAASS,OAAO,CAAC,qBAAqB;QACvD,IAAI,CAACD,UAAU;YACb,MAAM,IAAId,MAAM,CAAC,0DAA0D,EAAEK,KAAK;QACpF;QACA,OAAOS;IACT;IAEA,IAAIR,SAASO,UAAU,KAAK,KAAK;QAC/B,OAAO;IACT;IAEA,MAAM,IAAIb,MAAM,CAAC,0BAA0B,EAAEM,SAASO,UAAU,CAAC,CAAC,EAAEP,SAASU,aAAa,EAAE;AAC9F"}
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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sanity/cli-build",
3
- "version": "5.2.0",
3
+ "version": "5.3.0",
4
4
  "description": "Internal Sanity package for building studios and apps",
5
5
  "keywords": [
6
6
  "cli",
@@ -52,10 +52,9 @@
52
52
  "@sanity/schema": "^6.7.0",
53
53
  "@sanity/telemetry": "^1.1.0",
54
54
  "@sanity/types": "^6.7.0",
55
- "@vitejs/plugin-react": "^6.0.5",
55
+ "@vitejs/plugin-react": "^6.1.0",
56
56
  "chokidar": "^5.0.0",
57
57
  "cjs-module-lexer": "^2.2.0",
58
- "debug": "^4.4.3",
59
58
  "empathic": "^2.0.1",
60
59
  "lodash-es": "^4.18.1",
61
60
  "node-html-parser": "^7.1.0",
@@ -64,43 +63,47 @@
64
63
  "react": "^19.2.7",
65
64
  "react-dom": "^19.2.7",
66
65
  "semver": "^7.8.1",
67
- "vite": "^8.2.0",
66
+ "vite": "^8.2.1",
68
67
  "zod": "^4.4.3",
69
- "@sanity/cli-core": "^3.0.0",
70
- "@sanity/workbench-cli": "^2.0.0"
68
+ "@sanity/cli-core": "^3.2.0",
69
+ "@sanity/workbench-cli": "^2.0.2"
71
70
  },
72
71
  "devDependencies": {
73
72
  "@eslint/compat": "^2.1.0",
74
- "@sanity/pkg-utils": "^11.0.17",
73
+ "@sanity/pkg-utils": "^12.2.0",
75
74
  "@swc/cli": "^0.8.1",
76
75
  "@swc/core": "^1.15.43",
77
- "@types/debug": "^4.1.13",
78
76
  "@types/lodash-es": "^4.17.12",
79
77
  "@types/node": "^22.20.0",
80
78
  "@types/picomatch": "^4.0.3",
81
79
  "@types/react": "^19.2.17",
82
80
  "@types/react-dom": "^19.2.3",
83
81
  "@types/semver": "^7.7.1",
84
- "@vitest/coverage-istanbul": "^4.1.10",
82
+ "@vitest/coverage-istanbul": "^4.1.11",
85
83
  "babel-plugin-react-compiler": "^1.0.0",
86
84
  "eslint": "^10.7.0",
87
85
  "magic-string": "^0.30.21",
86
+ "oxc-transform-react": "^0.145.0",
88
87
  "publint": "^0.3.21",
89
88
  "sanity": "^6.7.0",
90
89
  "styled-components": "^6.4.3",
91
90
  "typescript": "^6.0.3",
92
- "vitest": "^4.1.10",
91
+ "vitest": "^4.1.11",
93
92
  "@repo/package.config": "0.0.1",
94
93
  "@repo/tsconfig": "3.70.0",
95
- "@sanity/cli-test": "10.0.0",
94
+ "@sanity/cli-test": "12.0.0",
96
95
  "@sanity/eslint-config-cli": "^1.1.3"
97
96
  },
98
97
  "peerDependencies": {
99
- "babel-plugin-react-compiler": "*"
98
+ "babel-plugin-react-compiler": "*",
99
+ "oxc-transform-react": "*"
100
100
  },
101
101
  "peerDependenciesMeta": {
102
102
  "babel-plugin-react-compiler": {
103
103
  "optional": true
104
+ },
105
+ "oxc-transform-react": {
106
+ "optional": true
104
107
  }
105
108
  },
106
109
  "engines": {