import { promises } from 'fs'
import { bold, cyan, red } from './picocolors'
import path from 'path'
import { hasNecessaryDependencies } from './has-necessary-dependencies'
import type { NecessaryDependencies } from './has-necessary-dependencies'
import { fileExists, FileType } from './file-exists'
import * as Log from '../build/output/log'
import { getPkgManager } from './helpers/get-pkg-manager'
async function missingDependencyError(dir: string) {
const packageManager = getPkgManager(dir)
throw new Error(
bold(
red(
"It looks like you're trying to use Partytown with next/script but do not have the required package(s) installed."
)
) +
'\n\n' +
bold(`Please install Partytown by running:`) +
'\n\n' +
`\t${bold(
cyan(
(packageManager === 'yarn'
? 'yarn add --dev'
: packageManager === 'pnpm'
? 'pnpm install --save-dev'
: 'npm install --save-dev') + ' @builder.io/partytown'
)
)}` +
'\n\n' +
bold(
`If you are not trying to use Partytown, please disable the experimental ${cyan(
'"nextScriptWorkers"'
)} flag in next.config.js.`
) +
'\n'
)
}
async function copyPartytownStaticFiles(
deps: NecessaryDependencies,
staticDir: string
) {
const partytownLibDir = path.join(staticDir, '~partytown')
const hasPartytownLibDir = await fileExists(
partytownLibDir,
FileType.Directory
)
if (hasPartytownLibDir) {
await promises.rm(partytownLibDir, { recursive: true, force: true })
}
const { copyLibFiles } = await Promise.resolve(
require(path.join(deps.resolved.get('@builder.io/partytown')!, '../utils'))
)
await copyLibFiles(partytownLibDir)
}
export async function verifyPartytownSetup(
dir: string,
targetDir: string
): Promise<void> {
const partytownDeps: NecessaryDependencies = hasNecessaryDependencies(dir, [
{
file: '@builder.io/partytown',
pkg: '@builder.io/partytown',
exportsRestrict: false,
},
])
if (partytownDeps.missing?.length > 0) {
await missingDependencyError(dir)
} else {
try {
await copyPartytownStaticFiles(partytownDeps, targetDir)
} catch (err) {
Log.warn(
`Partytown library files could not be copied to the static directory. Please ensure that ${bold(
cyan('@builder.io/partytown')
)} is installed as a dependency.`
)
}
}
}