diff --git a/src/actions/init.ts b/src/actions/init.ts index b536bb88..6431bef7 100644 --- a/src/actions/init.ts +++ b/src/actions/init.ts @@ -7,6 +7,7 @@ import {TypedFlags} from 'meow' import {getPackage} from '../npm/package' import {defaultSourceJs, defaultSourceTs} from '../configs/default-source' import {incompatiblePluginPackage} from '../constants' +import {forcedPackageVersions} from '../configs/forced-package-versions' export const initFlags = { ...sharedFlags, @@ -68,8 +69,14 @@ export type InitFlags = TypedFlags const defaultDependencies = [incompatiblePluginPackage] -const defaultDevDependencies = {react: '^17.0.0 || ^18.0.0', sanity: '^3.0.0-dev-preview.15'} -const defaultPeerDependencies = {react: '^17.0.0 || ^18.0.0', sanity: 'dev-preview'} +const defaultDevDependencies = { + react: forcedPackageVersions.react, + sanity: forcedPackageVersions.sanity, +} +const defaultPeerDependencies = { + react: forcedPackageVersions.react, + sanity: forcedPackageVersions.sanity, +} export interface InitOptions { basePath: string diff --git a/src/actions/verify-package.ts b/src/actions/verify-package.ts index 82b4706a..cfd7f906 100644 --- a/src/actions/verify-package.ts +++ b/src/actions/verify-package.ts @@ -18,9 +18,10 @@ import { validateParcelDependency, validatePluginSanityJson, validateRollupConfig, - validateSanityDependencies, + validateDeprecatedDependencies, validateScripts, validateTsConfig, + validateSanityDependencies, } from './verify/validations' import {PackageJson, TsConfig} from './verify/types' import chalk from 'chalk' @@ -49,6 +50,7 @@ export async function verifyPackage({basePath, flags}: {basePath: string; flags: await validation('babelConfig', async () => validateBabelConfig({basePath})) await validation('dependencies', async () => validateSanityDependencies(packageJson)) + await validation('dependencies', async () => validateDeprecatedDependencies(packageJson)) await validation('eslintImports', async () => validateImports({basePath})) if (errors.length) { diff --git a/src/actions/verify-studio.ts b/src/actions/verify-studio.ts index ba599665..46c5f9bb 100644 --- a/src/actions/verify-studio.ts +++ b/src/actions/verify-studio.ts @@ -12,7 +12,7 @@ import { VerifyPackageConfig, } from './verify/verify-common' import {PackageJson, TsConfig} from './verify/types' -import {validateSanityDependencies, validateStudioConfig} from './verify/validations' +import {validateDeprecatedDependencies, validateStudioConfig} from './verify/validations' export async function verifyStudio({basePath, flags}: {basePath: string; flags: VerifyFlags}) { let errors: string[] = [] @@ -25,7 +25,7 @@ export async function verifyStudio({basePath, flags}: {basePath: string; flags: const tsConfig = await readJson5File({basePath, filename: 'tsconfig.json'}) await validation('studioConfig', async () => validateStudioConfig({basePath})) - await validation('dependencies', async () => validateSanityDependencies(packageJson)) + await validation('dependencies', async () => validateDeprecatedDependencies(packageJson)) await validation('eslintImports', async () => validateImports({basePath})) if (errors.length) { diff --git a/src/actions/verify/validations.ts b/src/actions/verify/validations.ts index 939801cf..a27dea55 100644 --- a/src/actions/verify/validations.ts +++ b/src/actions/verify/validations.ts @@ -4,7 +4,7 @@ import validateNpmPackageName from 'validate-npm-package-name' // @ts-expect-error missing types import findBabelConfig from 'find-babel-config' import {incompatiblePluginPackage, urls} from '../../constants' -import {mergedPackages} from '../../configs/merged-packages' +import {deprecatedDevDeps, mergedPackages} from '../../configs/banned-packages' import path from 'path' import {fileExists, readFileContent, readJson5File} from '../../util/files' import chalk from 'chalk' @@ -192,6 +192,25 @@ export function validateSanityDependencies(packageJson: PackageJson): string[] { return [] } +export function validateDeprecatedDependencies(packageJson: PackageJson): string[] { + const {dependencies, devDependencies, peerDependencies} = packageJson + const allDependencies = {...dependencies, ...devDependencies, ...peerDependencies} + + const illegalDeps = Object.keys(allDependencies).filter((dep) => deprecatedDevDeps.includes(dep)) + const deps = new Set(illegalDeps) + const unique = [...deps.values()] + if (unique.length) { + return [ + outdent` + package.json contains deprecated dependencies that should be removed: + - ${unique.join('\n- ')} + `.trimStart(), + ] + } + + return [] +} + export async function validateRollupConfig({basePath}: {basePath: string}) { const configpath = path.normalize(path.join(basePath, 'rollup.config.js')) diff --git a/src/configs/merged-packages.ts b/src/configs/banned-packages.ts similarity index 89% rename from src/configs/merged-packages.ts rename to src/configs/banned-packages.ts index 1f4ffb1d..010cbe7a 100644 --- a/src/configs/merged-packages.ts +++ b/src/configs/banned-packages.ts @@ -17,3 +17,5 @@ export const mergedPackages = [ '@sanity/structure', '@sanity/studio-hints', ].sort() + +export const deprecatedDevDeps = ['tsdx', 'sanipack'] diff --git a/src/configs/forced-package-versions.ts b/src/configs/forced-package-versions.ts new file mode 100644 index 00000000..04a4cf6e --- /dev/null +++ b/src/configs/forced-package-versions.ts @@ -0,0 +1,12 @@ +export const forcedPackageVersions = { + react: '^18.0.0', + '@types/react': '^18.0.0', + 'react-dom': '^18.0.0', + '@types/react-dom': '^18.0.0', + sanity: 'dev-preview || 3.0.0-dev-preview.22', + 'sanity-ui': '^1.0.0-beta.31', + + //TODO delete both of these when we ditch parcel + parcel: '~2.6.0', + typescript: '~4.7.0', +} as const diff --git a/src/dependencies/import-linter.ts b/src/dependencies/import-linter.ts index 0e8ac2ee..d08895e1 100644 --- a/src/dependencies/import-linter.ts +++ b/src/dependencies/import-linter.ts @@ -1,5 +1,5 @@ import log from '../util/log' -import {mergedPackages} from '../configs/merged-packages' +import {mergedPackages} from '../configs/banned-packages' import {urls} from '../constants' import {ESLint} from 'eslint' import path from 'path' diff --git a/src/npm/package.ts b/src/npm/package.ts index d62422fa..2dabdd54 100644 --- a/src/npm/package.ts +++ b/src/npm/package.ts @@ -13,6 +13,7 @@ import {cliName} from '../constants' import {InjectOptions, PackageData} from '../actions/inject' import {expectedScripts} from '../actions/verify/validations' import {PackageJson} from '../actions/verify/types' +import {forcedPackageVersions} from '../configs/forced-package-versions' const readFile = util.promisify(fs.readFile) @@ -223,13 +224,16 @@ export async function writePackageJson(data: PackageData, options: InjectOptions } log.debug('Resolving latest versions for %s', newDevDependencies.join(', ')) - const dependencies = {...(prev.dependencies || {}), ...(addDeps || {})} - const devDependencies = { + const dependencies = forceDependencyVersions({...(prev.dependencies || {}), ...(addDeps || {})}) + const devDependencies = forceDependencyVersions({ ...(addDevDeps || {}), ...(prev.devDependencies || {}), ...(await resolveLatestVersions(newDevDependencies)), - } - const peerDependencies = {...(prev.peerDependencies || {}), ...(addPeers || {})} + }) + const peerDependencies = forceDependencyVersions({ + ...(prev.peerDependencies || {}), + ...(addPeers || {}), + }) const alwaysOnTop = { name: pluginName, @@ -365,3 +369,15 @@ export function sortKeys>(unordered: T): T { return obj }, {} as T) } + +function forceDependencyVersions(deps: Record): Record { + const entries = Object.entries(forcedPackageVersions).map((entry) => { + const [pkg] = entry + const forceVersion = forcedPackageVersions[pkg as keyof typeof forcedPackageVersions] + if (forceVersion) { + return [pkg, forceVersion] + } + return entry + }) + return Object.fromEntries(entries) +}