diff --git a/src/commands/init.ts b/src/commands/init.ts index a436274..f5f0c25 100644 --- a/src/commands/init.ts +++ b/src/commands/init.ts @@ -8,7 +8,7 @@ import { DEFAULT_PRISMIC_HOST, env } from "../env"; import { openBrowser } from "../lib/browser"; import { CommandError, createCommand, type CommandConfig } from "../lib/command"; import { diffArrays } from "../lib/diff"; -import { installDependencies } from "../lib/packageJson"; +import { installDependencies, readPackageJson, removeDependencies } from "../lib/packageJson"; import { ForbiddenRequestError, UnauthorizedRequestError } from "../lib/request"; import { createConfig, @@ -146,6 +146,17 @@ export default createCommand(config, async ({ values }) => { try { await deleteLegacySliceMachineConfig(); } catch {} + // Slice Machine is replaced by the Type Builder and CLI, so its packages + // are no longer needed after migrating. + const { dependencies, devDependencies, peerDependencies } = await readPackageJson(); + const sliceMachinePackages = Object.keys({ + ...dependencies, + ...devDependencies, + ...peerDependencies, + }).filter((name) => name === "slice-machine-ui" || name.startsWith("@slicemachine/adapter-")); + if (sliceMachinePackages.length > 0) { + await removeDependencies(sliceMachinePackages); + } console.info("Migrated slicemachine.config.json to prismic.config.json"); } diff --git a/src/lib/packageJson.ts b/src/lib/packageJson.ts index acc0c37..9b71f11 100644 --- a/src/lib/packageJson.ts +++ b/src/lib/packageJson.ts @@ -47,6 +47,19 @@ export async function addDependencies(dependencies: Record): Pro await writeFile(packageJsonPath, newContents); } +export async function removeDependencies(names: string[]): Promise { + const packageJsonPath = await findPackageJson(); + const raw = await readFile(packageJsonPath, "utf8"); + const indent = detectIndent(raw).indent || "\t"; + const packageJson = JSON.parse(raw); + for (const section of ["dependencies", "devDependencies", "peerDependencies"]) { + if (!packageJson[section]) continue; + for (const name of names) delete packageJson[section][name]; + } + const newContents = JSON.stringify(packageJson, null, indent) + "\n"; + await writeFile(packageJsonPath, newContents); +} + export async function getNpmPackageVersion(name: string, tag = "latest"): Promise { const url = new URL(`${name}/${tag}`, "https://registry.npmjs.org/"); const { version } = await request(url, { diff --git a/test/init.test.ts b/test/init.test.ts index 78a4efb..f7943bb 100644 --- a/test/init.test.ts +++ b/test/init.test.ts @@ -148,6 +148,41 @@ it("migrates slicemachine.config.json", async ({ expect, project, prismic, repo await expect(access(new URL("slicemachine.config.json", project))).rejects.toThrow(); }); +it("uninstalls Slice Machine packages when migrating", async ({ + expect, + project, + prismic, + repo, +}) => { + await rm(new URL("prismic.config.json", project)); + await writeFile( + new URL("package.json", project), + JSON.stringify({ + dependencies: { next: "latest" }, + devDependencies: { + "slice-machine-ui": "^2.0.0", + // A non-matching adapter, to verify any @slicemachine/adapter-* is removed. + "@slicemachine/adapter-nuxt": "^0.3.0", + }, + }), + ); + await writeFile( + new URL("slicemachine.config.json", project), + JSON.stringify({ repositoryName: repo, libraries: ["./src/slices"] }), + ); + + const proc = prismic("init"); + const output = captureOutput(proc); + await expect.poll(output, { timeout: 15_000 }).toContain("Migrated slicemachine.config.json"); + proc.kill(); + + const packageJson = JSON.parse(await readFile(new URL("package.json", project), "utf-8")); + const allDependencies = { ...packageJson.dependencies, ...packageJson.devDependencies }; + expect(allDependencies).not.toHaveProperty("slice-machine-ui"); + expect(allDependencies).not.toHaveProperty("@slicemachine/adapter-nuxt"); + expect(allDependencies).toHaveProperty("next"); +}); + it("fails when Type Builder is not enabled", async ({ expect, project, prismic, repo }) => { await rm(new URL("prismic.config.json", project)); const { exitCode, stderr } = await prismic("init", ["--repo", repo], {