import { css, js, json, test, yaml } from '../utils'
let testFn = process.platform === 'linux' ? test : test.skip
testFn(
'@tailwindcss/oxide-wasm32-wasi can be loaded into a Node.js process',
{
fs: {
'package.json': json`
{
"dependencies": {
"@tailwindcss/oxide-wasm32-wasi": "workspace:^"
}
}
`,
'src/index.css': css`@import 'tailwindcss/utilities';`,
'src/index.js': js`
const className = "content-['src/index.js']"
module.exports = { className }
`,
'index.mjs': js`
import { Scanner } from '@tailwindcss/oxide-wasm32-wasi'
import { join, resolve } from 'node:path'
let scanner = new Scanner({
sources: [
{
base: join(process.cwd(), 'src'),
pattern: '**/*',
negated: false,
},
],
})
console.log(JSON.stringify(scanner.scan()))
process.exit()
`,
},
},
async ({ expect, exec }) => {
let output = await exec(`node index.mjs`)
expect(JSON.parse(output)).toMatchInlineSnapshot(`
[
"className",
"const",
"content-['src/index.js']",
"exports",
]
`)
},
)
testFn(
'`@tailwindcss/oxide` falls back to the wasm build when no native binding is available',
{
fs: {
'package.json': json`
{
"dependencies": {
"@tailwindcss/oxide": "workspace:^"
}
}
`,
'pnpm-workspace.yaml': yaml`
# Trick pnpm in only supporting an architecture that @tailwindcss/oxide
# doesn't support, and therefore should fallback to the wasm version.
supportedArchitectures:
os:
- openbsd
cpu:
- x64
`,
'src/index.js': js`
const className = "content-['src/index.js']"
module.exports = { className }
`,
'index.mjs': js`
import { createRequire } from 'node:module'
import { join } from 'node:path'
let require = createRequire(import.meta.url)
let { Scanner } = require('@tailwindcss/oxide')
let loaded = Object.keys(require.cache)
let scanner = new Scanner({
sources: [
{
base: join(process.cwd(), 'src'),
pattern: '**/*',
negated: false,
},
],
})
console.log(
JSON.stringify({
native: loaded.filter((file) => file.endsWith('.node')),
wasi: loaded.some((file) => file.endsWith('tailwindcss-oxide.wasi.cjs')),
candidates: scanner.scan(),
}),
)
process.exit()
`,
},
},
async ({ expect, exec }) => {
let output = await exec(`node index.mjs`, { env: { NODE_PATH: '' } })
let { native, wasi, candidates } = JSON.parse(output)
expect(native).toEqual([])
expect(wasi).toBe(true)
expect(candidates).toMatchInlineSnapshot(`
[
"className",
"const",
"content-['src/index.js']",
"exports",
]
`)
},
)
testFn(
'the wasm build loads even when preopening the filesystem root is denied',
{
fs: {
'package.json': json`
{
"dependencies": {
"@tailwindcss/oxide": "workspace:^"
}
}
`,
'pnpm-workspace.yaml': yaml`
# Trick pnpm in only supporting an architecture that @tailwindcss/oxide
# doesn't support, and therefore should fallback to the wasm version.
supportedArchitectures:
os:
- openbsd
cpu:
- x64
`,
'preload.cjs': js`
const wasi = require('node:wasi')
const RealWASI = wasi.WASI
wasi.WASI = class WASI extends RealWASI {
constructor(options) {
if (options?.preopens?.['/'] !== undefined) {
const error = new Error('UVWASI_EACCES, uvwasi_init')
error.code = 'UVWASI_EACCES'
error.syscall = 'uvwasi_init'
throw error
}
super(options)
}
}
`,
'src/index.js': js`
const className = "content-['src/index.js']"
module.exports = { className }
`,
'index.mjs': js`
import { createRequire } from 'node:module'
import { join } from 'node:path'
let require = createRequire(import.meta.url)
let { Scanner } = require('@tailwindcss/oxide')
let loaded = Object.keys(require.cache)
let scanner = new Scanner({
sources: [
{
base: join(process.cwd(), 'src'),
pattern: '**/*',
negated: false,
},
],
})
console.log(
JSON.stringify({
wasi: loaded.some((file) => file.endsWith('tailwindcss-oxide.wasi.cjs')),
candidates: scanner.scan(),
}),
)
process.exit()
`,
},
},
async ({ expect, exec }) => {
let output = await exec(`node --require ./preload.cjs index.mjs`, { env: { NODE_PATH: '' } })
let { wasi, candidates } = JSON.parse(output.trim().split('\n')[0])
expect(wasi).toBe(true)
expect(candidates).toMatchInlineSnapshot(`
[
"className",
"const",
"content-['src/index.js']",
"exports",
]
`)
},
)