UNPKG

studiocms

Version:

Astro Native CMS for AstroDB. Built from the ground up by the Astro community.

105 lines (89 loc) 3.88 kB
import { askToContinue, spinner } from '@withstudiocms/effect/clack'; import { Effect, genLogger } from '../../effect.js'; import { CliContext } from '../utils/context.js'; import { type PluginInfo, StudioCMSScopes } from './index.js'; import { fetchPackageJson, parsePluginName } from './npm-utils.js'; export class ValidatePlugins extends Effect.Service<ValidatePlugins>()('ValidatePlugins', { effect: genLogger('studiocms/cli/add/validatePlugins/ValidatePlugins.effect')(function* () { const run = (names: string[]) => genLogger('studiocms/cli/add/validatePlugins/ValidatePlugins.effect.run')(function* () { const { chalk } = yield* CliContext; const spin = yield* spinner(); yield* spin.start('Resolving packages...'); const entries: PluginInfo[] = []; 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; // biome-ignore lint/suspicious/noExplicitAny: this is a valid use case for explicit any let pkgJson: any = {}; let pkgType: 'first-party' | 'third-party'; 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'; // biome-ignore lint/suspicious/noExplicitAny: this is a valid use case for explicit any pkgJson = firstPartyPkgCheck as any; } } 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?`); } // biome-ignore lint/suspicious/noExplicitAny: this is a valid use case for explicit any pkgJson = thirdPartyPkgCheck as any; } const resolvedScope = pkgType === 'first-party' ? '@studiocms' : scope; const packageName = `${resolvedScope ? `${resolvedScope}/` : ''}${name}`; const pluginName = packageName; const dependencies: PluginInfo['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 }; }), }) {}