regime/scripts/resolve-workspaces.ts
2026-05-02 13:16:15 +02:00

51 lines
1.7 KiB
TypeScript

import { readFileSync, writeFileSync, existsSync, readdirSync } from "fs"
import { join } from "path"
import { execSync } from "child_process"
const pkg = JSON.parse(readFileSync("package.json", "utf8"))
const ws: string[] = pkg.workspaces?.packages || pkg.workspaces || []
if (!Array.isArray(ws)) process.exit(0)
const ext = ws.filter((p) => p.startsWith(".."))
if (ext.length === 0) process.exit(0)
// collect local workspace package names
const localNames = new Set<string>()
for (const pattern of ws.filter((p) => !p.startsWith(".."))) {
const base = pattern.replace(/\/\*$/, "")
if (!existsSync(base)) continue
for (const dir of readdirSync(base, { withFileTypes: true })) {
if (!dir.isDirectory()) continue
const p = join(base, dir.name, "package.json")
if (existsSync(p)) localNames.add(JSON.parse(readFileSync(p, "utf8")).name)
}
}
// remove external workspace entries
pkg.workspaces.packages = ws.filter((p) => !p.startsWith(".."))
writeFileSync("package.json", JSON.stringify(pkg, null, 2) + "\n")
// find all workspace:* deps that are not local — those are external
const files = execSync('find . -name package.json -not -path "*/node_modules/*"')
.toString()
.trim()
.split("\n")
const resolved: string[] = []
for (const file of files) {
const content = readFileSync(file, "utf8")
let changed = content
const re = /"([^"]+)": "workspace:\*"/g
let m: RegExpExecArray | null
while ((m = re.exec(content)) !== null) {
if (!localNames.has(m[1])) {
changed = changed.replace(m[0], `"${m[1]}": "*"`)
resolved.push(m[1])
}
}
if (changed !== content) writeFileSync(file, changed)
}
if (resolved.length) {
console.log("Resolved external workspace deps:", [...new Set(resolved)].join(", "))
}