Files
orca/build-plugins/plain-node-entry-guard.test.ts
T

125 lines
4.5 KiB
TypeScript

import type { NormalizedOutputOptions, OutputBundle, OutputChunk } from 'rollup'
import { describe, expect, it } from 'vitest'
import { createPlainNodeEntryGuardPlugin } from './plain-node-entry-guard'
function entryChunk(name: string, code: string, imports: string[] = []): OutputChunk {
return {
type: 'chunk',
name,
fileName: `${name}.js`,
code,
isEntry: true,
imports,
dynamicImports: []
} as unknown as OutputChunk
}
describe('plain Node entry guard', () => {
it('rejects electron imports reachable from the managed WSL watcher host', () => {
const plugin = createPlainNodeEntryGuardPlugin()
const hook = plugin.writeBundle
const chunk = entryChunk('wsl-watcher-host', 'require("electron")')
const bundle = { [chunk.fileName]: chunk } as OutputBundle
expect(() => {
if (typeof hook === 'function') {
hook.call(
{
meta: { watchMode: false, rollupVersion: 'test', viteVersion: 'test' }
} as never,
{ dir: 'out/main' } as NormalizedOutputOptions,
bundle
)
}
}).toThrow(/wsl-watcher-host.*requires electron/)
})
it('rejects shared chunks that are not copied into the managed runtime', () => {
const host = entryChunk('wsl-watcher-host', 'require("node:fs")', ['chunks/shared.js'])
const shared = entryChunk('shared', 'module.exports = {}')
shared.isEntry = false
shared.fileName = 'chunks/shared.js'
expect(() => runGuard([host, shared])).toThrow(/reaches shared chunk "chunks\/shared\.js"/)
})
it('rejects bare dependencies that are absent from the managed runtime', () => {
const host = entryChunk('wsl-watcher-host', 'require("external-package")')
expect(() => runGuard([host])).toThrow(/loads unavailable dependency "external-package"/)
})
it('allows only Node built-ins and the staged native watcher binding', () => {
const host = entryChunk(
'wsl-watcher-host',
'require("node:fs"); require("path"); require("./watcher.node"); require.main === module'
)
expect(() => runGuard([host])).not.toThrow()
})
it('rejects a bare native watcher loader that Node would resolve as a package', () => {
const host = entryChunk('wsl-watcher-host', 'require("watcher.node")')
expect(() => runGuard([host])).toThrow(/loads unavailable dependency "watcher\.node"/)
})
it('rejects Rollup assets that are absent from the staged dependency set', () => {
const host = entryChunk('wsl-watcher-host', 'require("node:fs")')
host.referencedFiles = ['assets/runtime-data.bin']
expect(() => runGuard([host])).toThrow(/references unstaged asset/)
})
it('rejects implicit chunks that would not be copied beside host.js', () => {
const host = entryChunk('wsl-watcher-host', 'require("node:fs")')
host.implicitlyLoadedBefore = ['chunks/implicit.js']
const implicit = entryChunk('implicit', 'module.exports = {}')
implicit.isEntry = false
implicit.fileName = 'chunks/implicit.js'
expect(() => runGuard([host, implicit])).toThrow(/reaches shared chunk "chunks\/implicit\.js"/)
})
it.each([
'require.resolve("external-package")',
'module.require("external-package")',
'import(loaderTarget)',
'createRequire(import.meta.url)'
])('rejects indirect or dynamic loaders: %s', (code) => {
const host = entryChunk('wsl-watcher-host', code)
expect(() => runGuard([host])).toThrow(
/dependencies cannot be proven|loads unavailable dependency/
)
})
it.each([
'const load = require; load("external-package")',
'const load = module.require; load("external-package")',
'const load = require.resolve; load("external-package")',
'const { require: load } = module; load("external-package")',
'module["req" + "uire"]("external-package")',
'const property = "require"; module[property]("external-package")',
'require["res" + "olve"]("external-package")'
])('rejects aliased CommonJS loaders: %s', (code) => {
const host = entryChunk('wsl-watcher-host', code)
expect(() => runGuard([host])).toThrow(/dependencies cannot be proven/)
})
})
function runGuard(chunks: OutputChunk[]): void {
const hook = createPlainNodeEntryGuardPlugin().writeBundle
const bundle = Object.fromEntries(chunks.map((chunk) => [chunk.fileName, chunk])) as OutputBundle
if (typeof hook === 'function') {
hook.call(
{
meta: { watchMode: false, rollupVersion: 'test', viteVersion: 'test' }
} as never,
{ dir: 'out/main' } as NormalizedOutputOptions,
bundle
)
}
}