Files
webnet/eslint.config.test.js
T
codingetandCodex 2cabbf50f1
CI / format (pull_request) Successful in 1m58s
CI / lint (pull_request) Successful in 2m0s
CI / install (pull_request) Successful in 5m26s
CI / typetest (pull_request) Successful in 1m27s
CI / node-tests (pull_request) Successful in 1m48s
CI / typecheck (pull_request) Successful in 1m49s
CI / browser-tests (pull_request) Successful in 3m10s
test: tighten package-boundary checks
Co-Authored-By: gpt-5.6-sol <noreply@openai.com>
2026-07-26 15:50:36 +00:00

82 lines
3.0 KiB
JavaScript

import assert from "node:assert/strict"
import path from "node:path"
import { test } from "node:test"
import { ESLint } from "eslint"
const eslint = new ESLint()
async function messages(
source,
filePath = "packages/sftp/src/package-boundary-check.ts",
instance = eslint,
) {
const [result] = await instance.lintText(source, { filePath })
return result.messages.map(({ message, ruleId }) => ({ message, ruleId }))
}
test("rejects cross-package internal imports", async () => {
for (const specifier of [
"@webnet/ssh/_internals",
"@webnet/ssh/_internals.js",
"@webnet/transport/loopback/_internals",
"@webnet/transport/loopback/_internals.js",
]) {
const result = await messages(`import { Reader } from "${specifier}"; void Reader`)
assert.ok(result.some(({ ruleId }) => ruleId === "no-restricted-imports"))
}
})
test("rejects dynamic cross-package internal imports", async () => {
const result = await messages('await import("@webnet/ssh/_internals.js")')
assert.ok(result.some(({ ruleId }) => ruleId === "no-restricted-syntax"))
})
test("rejects relative cross-package source escapes", async () => {
for (const [source, filePath] of [
['import { Reader } from "../../ssh/src/cursor.js"; void Reader'],
[
'await import("../../../ssh/src/cursor.js")',
"packages/sftp/src/server/package-boundary-check.ts",
],
['export { Reader } from "../../ssh/src/cursor.js"'],
['import { Reader } from "../../ssh/./src/cursor.js"; void Reader'],
['await import("../.././ssh/src/cursor.js")'],
['export { Reader } from "../../ssh/other/../src/cursor.js"'],
['import "../../ssh/dist/index.js"'],
]) {
const result = await messages(source, filePath)
assert.ok(
result.some(
({ message, ruleId }) =>
ruleId === "package-boundary/no-relative-source-escapes" &&
message.includes("Relative cross-package"),
),
)
}
})
test("rejects relative source escapes when invoked from a package directory", async () => {
const packageEslint = new ESLint({ cwd: path.resolve("packages/sftp") })
const result = await messages(
'import { Reader } from "../../ssh/src/cursor.js"; void Reader',
"src/package-boundary-check.ts",
packageEslint,
)
assert.ok(result.some(({ ruleId }) => ruleId === "package-boundary/no-relative-source-escapes"))
})
test("rejects wildcard and cross-package re-exports", async () => {
const wildcard = await messages('export * from "./local.js"')
assert.ok(wildcard.some(({ message }) => message.includes("Wildcard exports")))
const crossPackage = await messages('export { VFSError } from "@webnet/vfs"')
assert.ok(crossPackage.some(({ message }) => message.includes("Cross-package re-exports")))
})
test("allows public imports and explicit package-local exports", async () => {
const result = await messages(
'import { SSHClientConnection } from "@webnet/ssh"; import { Reader } from "./sftp/cursor.js"; export { SSHClientConnection, Reader }',
)
assert.deepEqual(result, [])
})