import { existsSync, mkdirSync, readFileSync, rmSync } from 'node:fs'; import { cp } from 'node:fs/promises'; import path from 'node:path'; import { fileURLToPath } from 'node:url'; const rootDir = path.resolve( path.dirname(fileURLToPath(import.meta.url)), '..', ); const rootNodeModules = path.join(rootDir, 'node_modules'); const standaloneNodeModules = path.join( rootDir, 'apps/next/.next/standalone/node_modules', ); const seedPackages = [ '@payloadcms/db-postgres', '@payloadcms/graphql', '@payloadcms/next', '@payloadcms/richtext-lexical', '@payloadcms/ui', 'payload', ]; const packageJsonPathFor = (packageName, startDir) => { let current = startDir; while (true) { const candidate = path.join( current, 'node_modules', packageName, 'package.json', ); if (existsSync(candidate)) { return candidate; } const parent = path.dirname(current); if (parent === current) { return null; } current = parent; } }; const targetDirFor = (packageName) => path.join(standaloneNodeModules, ...packageName.split('/')); const copyPackage = async (packageName, startDir, seen) => { if (seen.has(packageName)) { return; } seen.add(packageName); const packageJsonPath = packageJsonPathFor(packageName, startDir); if (!packageJsonPath) { throw new Error(`Unable to resolve runtime package "${packageName}"`); } const packageDir = path.dirname(packageJsonPath); const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf8')); const targetDir = targetDirFor(packageName); rmSync(targetDir, { force: true, recursive: true }); mkdirSync(path.dirname(targetDir), { recursive: true }); await cp(packageDir, targetDir, { dereference: false, errorOnExist: false, force: true, recursive: true, }); const dependencies = { ...packageJson.dependencies, }; const optionalDependencies = { ...packageJson.optionalDependencies, }; for (const dependencyName of [ ...Object.keys(dependencies).sort(), ...Object.keys(optionalDependencies).sort(), ]) { if (dependencyName.startsWith('@types/')) { continue; } try { await copyPackage(dependencyName, packageDir, seen); } catch (error) { if (dependencyName in optionalDependencies) { continue; } throw error; } } }; mkdirSync(standaloneNodeModules, { recursive: true }); const seen = new Set(); for (const packageName of seedPackages) { await copyPackage(packageName, rootDir, seen); } console.log( `Copied ${seen.size} Payload runtime packages into Next standalone output.`, );