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
208 lines (187 loc) • 9.79 kB
JavaScript
;
var generateHelpUrl = require("@sanity/generate-help-url"), fs = require("fs"), path = require("path"), resolveFrom = require("resolve-from"), semver = require("semver"), execa = require("execa"), fs$1 = require("fs/promises"), oneline = require("oneline"), perf_hooks = require("perf_hooks");
function _interopDefaultCompat(e) {
return e && typeof e == "object" && "default" in e ? e : { default: e };
}
var fs__default = /* @__PURE__ */ _interopDefaultCompat(fs), 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);
const PACKAGES = [
{ name: "react", supported: ["^18"], deprecatedBelow: null },
{ name: "react-dom", supported: ["^18"], deprecatedBelow: null }
];
function checkStudioDependencyVersions(workDir) {
const manifest = readPackageJson$1(path__default.default.join(workDir, "package.json")), dependencies = { ...manifest.dependencies, ...manifest.devDependencies }, installedPackages = PACKAGES.map((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 ? readPackageJson$1(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
};
}).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.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}`;
}
function readPackageJson$1(filePath) {
try {
return JSON.parse(fs__default.default.readFileSync(filePath, "utf8"));
} catch (err) {
throw new Error(`Failed to read "${filePath}": ${err.message}`);
}
}
var peerDependencies = {
react: "^18",
"react-dom": "^18",
"styled-components": "^5.2 || ^6"
};
const defaultStudioManifestProps = {
name: "studio",
version: "1.0.0"
};
async function checkRequiredDependencies(context) {
const { workDir: studioPath, output } = context, [studioPackageManifest, installedStyledComponentsVersion] = await Promise.all([
await readPackageManifest(path__default.default.join(studioPath, "package.json"), defaultStudioManifestProps),
await readModuleVersion(studioPath, "styled-components")
]), wantedStyledComponentsVersionRange = peerDependencies["styled-components"], declaredStyledComponentsVersion = studioPackageManifest.dependencies["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 };
}
let minDeclaredStyledComponentsVersion = null;
try {
minDeclaredStyledComponentsVersion = semver__default.default.minVersion(declaredStyledComponentsVersion);
} catch {
}
if (!minDeclaredStyledComponentsVersion)
throw new Error(oneline__default.default`
Declared dependency \`styled-components\` has an invalid version range:
\`${declaredStyledComponentsVersion}\`.
`);
if (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 };
}
async function readModuleVersion(studioPath, moduleName) {
const manifestPath = resolveFrom__default.default.silent(studioPath, path__default.default.join(moduleName, "package.json"));
return manifestPath ? (await readPackageManifest(manifestPath)).version : null;
}
async function readPackageManifest(packageJsonPath, defaults = {}) {
let manifest;
try {
manifest = { ...defaults, ...await readPackageJson(packageJsonPath) };
} catch (err) {
throw new Error(`Failed to read "${packageJsonPath}": ${err.message}`);
}
if (!isPackageManifest(manifest))
throw new Error(`Failed to read "${packageJsonPath}": Invalid package manifest`);
const { name, version, dependencies = {}, devDependencies = {} } = manifest;
return { name, version, dependencies, devDependencies };
}
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, installNewPackages } = cliPackageManager, { mostOptimal, chosen: pkgManager } = await getPackageManagerChoice(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 isPackageManifest(item) {
return typeof item == "object" && item !== null && "name" in item && "version" in item;
}
function isComparableRange(range) {
return /^[\^~]?\d+(\.\d+)?(\.\d+)?$/.test(range);
}
function readPackageJson(filePath) {
return fs$1.readFile(filePath, "utf8").then((res) => JSON.parse(res));
}
function getTimer() {
const timings = {}, startTimes = {};
function start(name) {
if (typeof startTimes[name] < "u")
throw new Error(`Timer "${name}" already started, cannot overwrite`);
startTimes[name] = perf_hooks.performance.now();
}
function end(name) {
if (typeof startTimes[name] > "u")
throw new Error(`Timer "${name}" never started, cannot end`);
return timings[name] = perf_hooks.performance.now() - startTimes[name], timings[name];
}
return { start, end, getTimings: () => timings };
}
exports.checkRequiredDependencies = checkRequiredDependencies;
exports.checkStudioDependencyVersions = checkStudioDependencyVersions;
exports.getTimer = getTimer;
//# sourceMappingURL=timing.js.map