mtcute/.config/vite-utils/package-json.js

173 lines
5.6 KiB
JavaScript
Raw Normal View History

2024-08-21 11:05:07 +03:00
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
}
2024-08-21 11:05:07 +03:00
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,
}
}