import { readFileSync } from 'node:fs' import { resolve } from 'node:path' import { fileURLToPath } from 'node:url' const rootPackageJson = JSON.parse(readFileSync(new URL('../../package.json', import.meta.url), 'utf-8')) const packagesDir = fileURLToPath(new URL('../../packages', import.meta.url)) const IS_JSR = process.env.JSR === '1' export function getPackageVersion(name) { const json = JSON.parse(readFileSync(resolve(packagesDir, name, 'package.json'), 'utf-8')) return json.version } export function processPackageJson(packageDir) { const packageJsonOrig = JSON.parse(readFileSync(resolve(packageDir, 'package.json'), 'utf-8')) const packageJson = structuredClone(packageJsonOrig) const entrypoints = {} // copy common fields from root for (const field of ['license', 'author', 'contributors', 'homepage', 'repository', 'bugs']) { if (rootPackageJson[field]) { packageJson[field] = rootPackageJson[field] } } const newScripts = {} if (packageJson.keepScripts) { for (const script of packageJson.keepScripts) { newScripts[script] = packageJson.scripts[script] } delete packageJson.keepScripts } packageJson.scripts = newScripts delete packageJson.devDependencies delete packageJson.private if (packageJson.distOnlyFields) { Object.assign(packageJson, packageJson.distOnlyFields) delete packageJson.distOnlyFields } if (packageJson.jsrOnlyFields) { if (IS_JSR) { Object.assign(packageJson, packageJson.jsrOnlyFields) } delete packageJson.jsrOnlyFields } function replaceWorkspaceDependencies(field) { if (!packageJson[field]) return const dependencies = packageJson[field] for (const name of Object.keys(dependencies)) { if (name.startsWith('@fuman/')) { delete dependencies[name] // fuman is bundled with vite for now continue } const value = dependencies[name] if (value.startsWith('workspace:')) { if (value !== 'workspace:^' && value !== 'workspace:*') { throw new Error( `Cannot replace workspace dependency ${name} with ${value} - only workspace:^ and * are supported`, ) } if (!name.startsWith('@mtcute/')) { throw new Error(`Cannot replace workspace dependency ${name} - only @mtcute/* is supported`) } // note: pnpm replaces workspace:* with the current version, unlike this script const depVersion = value === 'workspace:*' ? '*' : `^${getPackageVersion(name.slice(8))}` dependencies[name] = depVersion } } } replaceWorkspaceDependencies('dependencies') replaceWorkspaceDependencies('devDependencies') replaceWorkspaceDependencies('peerDependencies') replaceWorkspaceDependencies('optionalDependencies') delete packageJson.typedoc if (packageJson.browser) { function maybeFixPath(p, repl) { if (!p) return p if (p.startsWith('./src/')) { return repl + p.slice(6) } if (p.startsWith('./')) { return repl + p.slice(2) } return p } for (const key of Object.keys(packageJson.browser)) { if (!key.startsWith('./src/')) continue const path = key.slice(6) packageJson.browser[`./esm/${path}`] = maybeFixPath(packageJson.browser[key], './esm/') delete packageJson.browser[key] } } if (packageJson.exports) { let exports = packageJson.exports if (typeof exports === 'string') { exports = { '.': exports } } if (typeof exports !== 'object') { throw new TypeError('package.json exports must be an object') } const newExports = {} for (const [key, value] of Object.entries(exports)) { if (typeof value !== 'string') { throw new TypeError(`package.json exports value must be a string: ${key}`) } if (value.endsWith('.wasm')) { newExports[key] = value continue } let entrypointName = key.replace(/^\.(\/|$)/, '').replace(/\.js$/, '') if (entrypointName === '') entrypointName = 'index' entrypoints[entrypointName] = value newExports[key] = { import: { types: `./${entrypointName}.d.ts`, default: `./${entrypointName}.js`, }, require: { types: `./${entrypointName}.d.cts`, default: `./${entrypointName}.cjs`, }, } } packageJson.exports = newExports } if (typeof packageJson.bin === 'object') { const newBin = {} for (const [key, value] of Object.entries(packageJson.bin)) { if (typeof value !== 'string') { throw new TypeError(`package.json bin value must be a string: ${key}`) } let entrypointName = key.replace(/^\.(\/|$)/, '').replace(/\.js$/, '') if (entrypointName === '') entrypointName = 'index' entrypoints[entrypointName] = value newBin[key] = `./${entrypointName}.js` } packageJson.bin = newBin } return { packageJsonOrig, packageJson, entrypoints, } }