resolve relative deps

This commit is contained in:
Dan Finch 2026-05-02 15:25:00 +02:00
parent c0df0a0409
commit 6d43e70205
3 changed files with 92 additions and 45 deletions

View file

@ -4,14 +4,21 @@ 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 hasWorkspaces = Array.isArray(ws)
const ext = ws.filter((p) => p.startsWith(".."))
if (ext.length === 0) process.exit(0)
// remove external workspace entries if present
if (hasWorkspaces) {
const ext = ws.filter((p) => p.startsWith(".."))
if (ext.length > 0) {
pkg.workspaces.packages = ws.filter((p) => !p.startsWith(".."))
writeFileSync("package.json", JSON.stringify(pkg, null, 2) + "\n")
}
}
// collect local workspace package names
const localNames = new Set<string>()
for (const pattern of ws.filter((p) => !p.startsWith(".."))) {
if (hasWorkspaces) {
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 })) {
@ -19,13 +26,10 @@ for (const pattern of ws.filter((p) => !p.startsWith(".."))) {
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
// find all package.json files
const files = execSync('find . -name package.json -not -path "*/node_modules/*"')
.toString()
.trim()
@ -35,17 +39,27 @@ const resolved: string[] = []
for (const file of files) {
const content = readFileSync(file, "utf8")
let changed = content
const re = /"([^"]+)": "workspace:\*"/g
// replace workspace:* deps that aren't local
const wsRe = /"([^"]+)": "workspace:\*"/g
let m: RegExpExecArray | null
while ((m = re.exec(content)) !== null) {
while ((m = wsRe.exec(content)) !== null) {
if (!localNames.has(m[1])) {
changed = changed.replace(m[0], `"${m[1]}": "*"`)
resolved.push(m[1])
}
}
// replace ../path deps
const pathRe = /"([^"]+)": "\.\.\/[^"]+"/g
while ((m = pathRe.exec(content)) !== null) {
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(", "))
console.log("Resolved external deps:", [...new Set(resolved)].join(", "))
}

View file

@ -2,6 +2,7 @@ import { defineConfig } from "oxlint"
export default defineConfig({
plugins: ["typescript", "unicorn", "oxc"],
ignorePatterns: ["**/*.gen.ts"],
categories: {
correctness: "error",
suspicious: "warn",
@ -10,38 +11,70 @@ export default defineConfig({
restriction: "error",
},
rules: {
"capitalized-comments": "off",
"default-case": "off",
"filename-case": "off",
"func-style": ["error", "declaration", { allowArrowFunctions: true }],
"id-length": "off",
"init-declarations": "off",
"max-params": "off",
"max-statements": "off",
"new-cap": "off",
"no-array-for-each": "off",
"no-async-await": "off",
"no-await-expression-member": "off",
"no-await-in-loop": "off",
"no-bitwise": "off",
"no-console": "off",
"no-dynamic-delete": "off",
"no-empty-file": "off",
"no-empty-function": "off",
"no-implicit-coercion": "off",
"no-magic-numbers": "off",
"no-nested-ternary": "off",
"unicorn/no-nested-ternary": "off",
"no-null": "off",
"no-optional-chaining": "off",
"no-plusplus": "off",
"no-rest-spread-properties": "off",
"no-shadow-restricted-names": "off",
"no-shadow": "off",
"no-ternary": "off",
"no-undefined": "off",
"no-underscore-dangle": "off",
"no-use-before-define": "off",
"unicorn/numeric-separators-style": "off",
"prefer-for-of": "off",
"prefer-template": "off",
"typescript/no-non-null-assertion": "off",
"typescript/no-empty-interface": "off",
"prefer-ternary": "off",
"require-module-specifiers": "off",
"sort-imports": "off",
"sort-keys": "off",
"switch-case-braces": "off",
"typescript/consistent-indexed-object-style": "off",
"typescript/consistent-type-definitions": ["error", "type"],
"typescript/explicit-function-return-type": "off",
"typescript/explicit-member-accessibility": "off",
"typescript/explicit-module-boundary-types": "off",
"no-use-before-define": "off",
"no-dynamic-delete": "off",
"id-length": "off",
"new-cap": "off",
"no-shadow": "off",
"no-ternary": "off",
"func-style": ["error", "declaration"],
"typescript/prefer-function-type": "off",
"typescript/consistent-indexed-object-style": "off",
"no-undefined": "off",
"filename-case": "off",
"no-magic-numbers": "off",
"max-statements": "off",
"no-plusplus": "off",
"no-array-for-each": "off",
"sort-imports": "off",
"no-optional-chaining": "off",
"default-case": "off",
"prefer-for-of": "off",
"switch-case-braces": "off",
"require-module-specifiers": "off",
"typescript/no-empty-interface": "off",
"typescript/no-empty-object-type": "off",
"typescript/no-namespace": "off",
"typescript/no-non-null-assertion": "off",
"typescript/prefer-function-type": "off",
},
ignorePatterns: ["**/*.gen.ts"],
overrides: [
{
files: ["*.test.ts"],
rules: {
"typescript/no-explicit-any": "off",
},
},
{
files: ["*.d.ts"],
rules: {
"typescript/consistent-function-scoping": "off",
"typescript/consistent-type-definitions": "off",
},
},
],
})

View file

@ -3,6 +3,6 @@
"@typescript/native-preview": "beta"
},
"scripts": {
"check": "tsgo --noEmit"
"check": "tsgo --noEmit && find . -mindepth 2 -name tsconfig.json -not -path '*/node_modules/*' -exec tsgo --noEmit -p {} \\;"
}
}