studiocms
Version:
Astro Native CMS for AstroDB. Built from the ground up by the Astro community.
90 lines (89 loc) • 3.76 kB
JavaScript
import { askToContinue, spinner } from "@withstudiocms/effect/clack";
import { Effect, genLogger } from "../../effect.js";
import { CliContext } from "../utils/context.js";
import { StudioCMSScopes } from "./index.js";
import { fetchPackageJson, parsePluginName } from "./npm-utils.js";
class ValidatePlugins extends Effect.Service()("ValidatePlugins", {
effect: genLogger("studiocms/cli/add/validatePlugins/ValidatePlugins.effect")(function* () {
const run = (names) => genLogger("studiocms/cli/add/validatePlugins/ValidatePlugins.effect.run")(function* () {
const { chalk } = yield* CliContext;
const spin = yield* spinner();
yield* spin.start("Resolving packages...");
const entries = [];
for (const plugin of names) {
const parsed = yield* parsePluginName(plugin);
if (!parsed)
throw new Error(`${chalk.bold(plugin)} does not appear to be a valid package name!`);
const { scope, name, tag } = parsed;
let pkgJson = {};
let pkgType;
if (scope && !StudioCMSScopes.includes(scope)) {
pkgType = "third-party";
} else {
const firstPartyPkgCheck = yield* fetchPackageJson(scope, name, tag);
if (firstPartyPkgCheck instanceof Error) {
if (firstPartyPkgCheck.message) {
yield* spin.message(chalk.yellow(firstPartyPkgCheck.message));
}
yield* spin.message(
chalk.yellow(`${chalk.bold(plugin)} is not an official StudioCMS package.`)
);
if (!(yield* askToContinue())) {
throw new Error(
`No problem! Find our official plugins at ${chalk.magenta("https://docs.studiocms.dev")}`
);
}
yield* spin.start("Resolving with third party packages...");
pkgType = "third-party";
} else {
pkgType = "first-party";
pkgJson = firstPartyPkgCheck;
}
}
if (pkgType === "third-party") {
const thirdPartyPkgCheck = yield* fetchPackageJson(scope, name, tag);
if (thirdPartyPkgCheck instanceof Error) {
if (thirdPartyPkgCheck.message) {
yield* spin.message(chalk.yellow(thirdPartyPkgCheck.message));
}
throw new Error(`Unable to fetch ${chalk.bold(plugin)}. Does the package exist?`);
}
pkgJson = thirdPartyPkgCheck;
}
const resolvedScope = pkgType === "first-party" ? "@studiocms" : scope;
const packageName = `${resolvedScope ? `${resolvedScope}/` : ""}${name}`;
const pluginName = packageName;
const dependencies = [[pkgJson.name, `^${pkgJson.version}`]];
if (pkgJson.peerDependencies) {
const meta = pkgJson.peerDependenciesMeta || {};
for (const peer in pkgJson.peerDependencies) {
const optional = meta[peer]?.optional || false;
const isStudioCMS = peer === "studiocms";
if (!optional && !isStudioCMS) {
dependencies.push([peer, pkgJson.peerDependencies[peer]]);
}
}
}
const keywords = Array.isArray(pkgJson.keywords) ? pkgJson.keywords : [];
if (!keywords.includes("studiocms-plugin")) {
throw new Error(
`${chalk.bold(plugin)} doesn't appear to be an StudioCMS Plugin. Find our official plugins at ${chalk.magenta("https://docs.studiocms.dev")}`
);
}
entries.push({
id: plugin,
packageName,
dependencies,
pluginName
});
}
yield* spin.stop("Packages Resolved.");
return entries;
});
return { run };
})
}) {
}
export {
ValidatePlugins
};