UNPKG

sanity

Version:

Sanity is a real-time content infrastructure with a scalable, hosted backend featuring a Graph Oriented Query Language (GROQ), asset pipelines and fast edge caches

331 lines (310 loc) • 14.4 kB
"use strict"; var path = require("node:path"), generateHelpUrl_esm = require("./generate-help-url.esm.js"), resolveFrom = require("resolve-from"), semver = require("semver"), shouldAutoUpdate = require("./shouldAutoUpdate.js"), execa = require("execa"), oneline = require("oneline"), _internal = require("./_internal.js"), preferredPM = require("preferred-pm"), which = require("which"); function _interopDefaultCompat(e) { return e && typeof e == "object" && "default" in e ? e : { default: e }; } var path__default = /* @__PURE__ */ _interopDefaultCompat(path), resolveFrom__default = /* @__PURE__ */ _interopDefaultCompat(resolveFrom), semver__default = /* @__PURE__ */ _interopDefaultCompat(semver), execa__default = /* @__PURE__ */ _interopDefaultCompat(execa), oneline__default = /* @__PURE__ */ _interopDefaultCompat(oneline), preferredPM__default = /* @__PURE__ */ _interopDefaultCompat(preferredPM), which__default = /* @__PURE__ */ _interopDefaultCompat(which), peerDependencies = { "styled-components": "^6.1.15" }; const PACKAGES = [{ name: "react", supported: ["^18 || ^19"], deprecatedBelow: null }, { name: "react-dom", supported: ["^18 || ^19"], deprecatedBelow: null }, { name: "styled-components", supported: ["^6"], deprecatedBelow: null }, { name: "@sanity/ui", supported: ["^2", "^3"], deprecatedBelow: null }]; async function checkStudioDependencyVersions(workDir) { const manifest = await shouldAutoUpdate.readPackageJson(path__default.default.join(workDir, "package.json")), dependencies = { ...manifest.dependencies, ...manifest.devDependencies }, packageInfo = PACKAGES.map(async (pkg) => { const dependency = dependencies[pkg.name]; if (!dependency) return !1; const manifestPath = resolveFrom__default.default.silent(workDir, path__default.default.join(pkg.name, "package.json")), installed = semver__default.default.coerce(manifestPath ? (await shouldAutoUpdate.readPackageManifest(manifestPath)).version : dependency.replace(/[\D.]/g, "")); if (!installed) return !1; const supported = pkg.supported.join(" || "), isUntested = !semver__default.default.satisfies(installed, supported) && semver__default.default.gtr(installed, supported), isUnsupported = !semver__default.default.satisfies(installed, supported) && !isUntested, isDeprecated = pkg.deprecatedBelow ? semver__default.default.ltr(installed, pkg.deprecatedBelow) : !1; return { ...pkg, installed, isUnsupported, isDeprecated, isUntested }; }), installedPackages = (await Promise.all(packageInfo)).filter((inp) => inp !== !1), unsupported = installedPackages.filter((pkg) => pkg.isUnsupported), deprecated = installedPackages.filter((pkg) => !pkg.isUnsupported && pkg.isDeprecated), untested = installedPackages.filter((pkg) => pkg.isUntested); deprecated.length > 0 && console.warn(` [WARN] The following package versions have been deprecated and should be upgraded: ${listPackages(deprecated)} Support for these will be removed in a future release! ${getUpgradeInstructions(deprecated)} `), untested.length > 0 && console.warn(` [WARN] The following package versions have not yet been marked as supported: ${listPackages(untested)} You _may_ encounter bugs while using these versions. ${getDowngradeInstructions(untested)} `), unsupported.length > 0 && (console.error(` [ERROR] The following package versions are no longer supported and needs to be upgraded: ${listPackages(unsupported)} ${getUpgradeInstructions(unsupported)} `), process.exit(1)); } function listPackages(pkgs) { return pkgs.map((pkg) => `${pkg.name} (installed: ${pkg.installed}, want: ${pkg.deprecatedBelow || pkg.supported.join(" || ")})`).join(` `); } function getUpgradeInstructions(pkgs) { const inst = pkgs.map((pkg) => { const [highestSupported] = pkg.supported.map((version) => (semver__default.default.coerce(version) || { version: "" }).version).sort(semver__default.default.rcompare); return `"${pkg.name}@${highestSupported}"`; }).join(" "); return `To upgrade, run either: npm install ${inst} or yarn add ${inst} or pnpm add ${inst} Read more at ${generateHelpUrl_esm.generateHelpUrl("upgrade-packages")}`; } function getDowngradeInstructions(pkgs) { const inst = pkgs.map((pkg) => { const [highestSupported] = pkg.supported.map((version) => (semver__default.default.coerce(version) || { version: "" }).version).sort(semver__default.default.rcompare); return `"${pkg.name}@${highestSupported}"`; }).join(" "); return `To downgrade, run either: yarn add ${inst} or npm install ${inst} or pnpm install ${inst}`; } const defaultStudioManifestProps = { name: "studio", version: "1.0.0" }; async function checkRequiredDependencies(context) { if (_internal.determineIsApp(context.cliConfig)) return { didInstall: !1, installedSanityVersion: "" }; const { workDir: studioPath, output } = context, [studioPackageManifest, installedStyledComponentsVersion, installedSanityVersion] = await Promise.all([await shouldAutoUpdate.readPackageManifest(path__default.default.join(studioPath, "package.json"), defaultStudioManifestProps), await shouldAutoUpdate.readModuleVersion(studioPath, "styled-components"), await shouldAutoUpdate.readModuleVersion(studioPath, "sanity")]), wantedStyledComponentsVersionRange = peerDependencies["styled-components"]; if (!installedSanityVersion) throw new Error("Failed to read the installed sanity version."); const declaredStyledComponentsVersion = studioPackageManifest.dependencies["styled-components"] || studioPackageManifest.devDependencies["styled-components"]; if (!declaredStyledComponentsVersion) { const [file, ...args] = process.argv; return await installDependencies({ "styled-components": wantedStyledComponentsVersionRange }, context), await execa__default.default(file, args, { cwd: studioPath, stdio: "inherit" }), { didInstall: !0, installedSanityVersion }; } const isStyledComponentsVersionRangeInCatalog = declaredStyledComponentsVersion.startsWith("catalog:"); let minDeclaredStyledComponentsVersion = null; try { minDeclaredStyledComponentsVersion = semver__default.default.minVersion(declaredStyledComponentsVersion); } catch { } if (!minDeclaredStyledComponentsVersion && !isStyledComponentsVersionRangeInCatalog) throw new Error(oneline__default.default` Declared dependency \`styled-components\` has an invalid version range: \`${declaredStyledComponentsVersion}\`. `); if (!isStyledComponentsVersionRangeInCatalog && isComparableRange(declaredStyledComponentsVersion) && !semver__default.default.satisfies(minDeclaredStyledComponentsVersion, wantedStyledComponentsVersionRange) && output.warn(oneline__default.default` Declared version of styled-components (${declaredStyledComponentsVersion}) is not compatible with the version required by sanity (${wantedStyledComponentsVersionRange}). This might cause problems! `), !installedStyledComponentsVersion) throw new Error(oneline__default.default` Declared dependency \`styled-components\` is not installed - run \`npm install\`, \`yarn install\` or \`pnpm install\` to install it before re-running this command. `); return semver__default.default.satisfies(installedStyledComponentsVersion, wantedStyledComponentsVersionRange) || output.warn(oneline__default.default` Installed version of styled-components (${installedStyledComponentsVersion}) is not compatible with the version required by sanity (${wantedStyledComponentsVersionRange}). This might cause problems! `), { didInstall: !1, installedSanityVersion }; } async function installDependencies(dependencies, context) { const { output, prompt, workDir, cliPackageManager } = context, packages = []; output.print("The Sanity studio needs to install missing dependencies:"); for (const [pkgName, version] of Object.entries(dependencies)) { const declaration = `${pkgName}@${version}`; output.print(`- ${declaration}`), packages.push(declaration); } if (!cliPackageManager) { output.error("ERROR: Could not determine package manager choice - run `npm install` or equivalent"); return; } const { getPackageManagerChoice: getPackageManagerChoice2, installNewPackages } = cliPackageManager, { mostOptimal, chosen: pkgManager } = await getPackageManagerChoice2(workDir, { prompt }); mostOptimal && pkgManager !== mostOptimal && output.warn(`WARN: This project appears to be installed with or using ${mostOptimal} - using a different package manager _may_ result in errors.`), await installNewPackages({ packages, packageManager: pkgManager }, context); } function isComparableRange(range) { return /^[\^~]?\d+(\.\d+)?(\.\d+)?$/.test(range); } const EXPERIMENTAL = ["bun"]; async function getPackageManagerChoice(workDir, options) { const rootDir = workDir || process.cwd(), preferred = (await preferredPM__default.default(rootDir))?.name; if (preferred && await hasCommand(preferred, rootDir)) return { chosen: preferred, mostOptimal: preferred }; const mostLikelyPM = await getMostLikelyInstalledPackageManager(rootDir); if (!(typeof options.interactive == "boolean" ? options.interactive : _internal.isInteractive)) return { chosen: mostLikelyPM || await getFallback(rootDir), mostOptimal: preferred }; if (!("prompt" in options)) throw new Error("Must pass `prompt` when in interactive mode"); const messageSuffix = preferred ? ` (preferred is ${preferred}, but is not installed)` : "", installed = await getAvailablePackageManagers(rootDir); return { chosen: await options.prompt.single({ type: "list", choices: installed.map((pm) => ({ value: pm, name: EXPERIMENTAL.includes(pm) ? `${pm} (experimental)` : pm })), default: preferred || mostLikelyPM, message: `Package manager to use for installing dependencies?${messageSuffix}` }), mostOptimal: preferred }; } async function getFallback(cwd) { return await hasNpmInstalled(cwd) ? "npm" : await hasYarnInstalled(cwd) ? "yarn" : await hasPnpmInstalled(cwd) ? "pnpm" : await hasBunInstalled(cwd) ? "bun" : "manual"; } async function getAvailablePackageManagers(cwd) { const [npm, yarn, pnpm, bun] = await Promise.all([hasNpmInstalled(cwd), hasYarnInstalled(cwd), hasPnpmInstalled(cwd), hasBunInstalled(cwd)]); return [npm && "npm", yarn && "yarn", pnpm && "pnpm", bun && "bun", "manual"].filter((pm) => pm !== !1); } function hasNpmInstalled(cwd) { return hasCommand("npm", cwd); } function hasYarnInstalled(cwd) { return hasCommand("yarn", cwd); } function hasPnpmInstalled(cwd) { return hasCommand("pnpm", cwd); } function hasBunInstalled(cwd) { return hasCommand("bun", cwd); } function getNpmRunPath(cwd) { let previous, cwdPath = path__default.default.resolve(cwd); const result = []; for (; previous !== cwdPath; ) result.push(path__default.default.join(cwdPath, "node_modules", ".bin")), previous = cwdPath, cwdPath = path__default.default.resolve(cwdPath, ".."); result.push(path__default.default.resolve(cwd, process.execPath, "..")); const pathEnv = process.env[getPathEnvVarKey()]; return [...result, pathEnv].join(path__default.default.delimiter); } function getPartialEnvWithNpmPath(cwd) { return { [getPathEnvVarKey()]: getNpmRunPath(cwd) }; } function getPathEnvVarKey() { return process.platform !== "win32" ? "PATH" : Object.keys(process.env).reverse().find((key) => key.toUpperCase() === "PATH") || "Path"; } function getCommandPath(cmd, cwd) { const options = { path: cwd ? getNpmRunPath(cwd) : void 0 }; return which__default.default(cmd, options).catch(() => null); } function hasCommand(cmd, cwd) { return getCommandPath(cmd, cwd).then((cmdPath) => cmdPath !== null); } async function getMostLikelyInstalledPackageManager(rootDir) { const installed = await getAvailablePackageManagers(rootDir), running = getRunningPackageManager(); return running && installed.includes(running) ? running : void 0; } function getRunningPackageManager() { const agent = process.env.npm_config_user_agent || ""; if (agent.includes("yarn")) return "yarn"; if (agent.includes("pnpm")) return "pnpm"; if (agent.includes("bun")) return "bun"; if (/^npm\/\d/.test(agent)) return "npm"; } async function upgradePackages(options, context) { const { packageManager, packages } = options, { output, workDir } = context, execOptions = { encoding: "utf8", env: getPartialEnvWithNpmPath(workDir), cwd: workDir, stdio: "inherit" }, upgradePackageArgs = packages.map((pkg) => pkg.join("@")); let result; if (packageManager === "npm") { const npmArgs = ["install", "--legacy-peer-deps", ...upgradePackageArgs]; output.print(`Running 'npm ${npmArgs.join(" ")}'`), result = await execa__default.default("npm", npmArgs, execOptions); } else if (packageManager === "yarn") { const yarnArgs = ["upgrade ", ...upgradePackageArgs]; output.print(`Running 'yarn ${yarnArgs.join(" ")}'`), result = await execa__default.default("yarn", yarnArgs, execOptions); } else if (packageManager === "pnpm") { const pnpmArgs = ["upgrade", ...upgradePackageArgs]; output.print(`Running 'pnpm ${pnpmArgs.join(" ")}'`), result = await execa__default.default("pnpm", pnpmArgs, execOptions); } else if (packageManager === "bun") { const bunArgs = ["update", ...upgradePackageArgs]; output.print(`Running 'bun ${bunArgs.join(" ")}'`), result = await execa__default.default("bun", bunArgs, execOptions); } else packageManager === "manual" && output.print(`Manual installation selected - run 'npm upgrade ${upgradePackageArgs.join(" ")}' or equivalent`); if (result?.exitCode || result?.failed) throw new Error("Package upgrade failed"); } exports.checkRequiredDependencies = checkRequiredDependencies; exports.checkStudioDependencyVersions = checkStudioDependencyVersions; exports.getPackageManagerChoice = getPackageManagerChoice; exports.upgradePackages = upgradePackages; //# sourceMappingURL=upgradePackages.js.map