openpencil/scripts/smoke-packages.ts
2026-05-24 12:15:29 +03:00

71 lines
2.5 KiB
TypeScript

import { mkdtempSync, rmSync } from 'node:fs'
import { tmpdir } from 'node:os'
import { basename, join } from 'node:path'
import { fileURLToPath } from 'node:url'
const rootDir = fileURLToPath(new URL('..', import.meta.url))
const packageDirs = ['packages/core', 'packages/vue', 'packages/mcp', 'packages/cli']
function run(command: string[], cwd = rootDir): string {
const proc = Bun.spawnSync(command, { cwd, stdout: 'pipe', stderr: 'pipe' })
const stdout = proc.stdout.toString()
const stderr = proc.stderr.toString()
if (!proc.success) {
console.error(`$ ${command.join(' ')}`)
if (stdout) console.error(stdout)
if (stderr) console.error(stderr)
process.exit(proc.exitCode || 1)
}
return stdout.trim()
}
function nodeEval(code: string, cwd: string): void {
run(['node', '--input-type=module', '--eval', code], cwd)
}
const tempDir = mkdtempSync(join(tmpdir(), 'open-pencil-package-smoke-'))
try {
run(['bun', 'run', 'build:packages'])
const tarballs: string[] = []
for (const packageDir of packageDirs) {
const output = run(
['bun', 'pm', 'pack', '--destination', tempDir, '--quiet'],
join(rootDir, packageDir)
)
const filename = output
.split('\n')
.map((line) => line.trim())
.findLast((line) => line.length > 0)
if (!filename) throw new Error(`No tarball produced for ${packageDir}`)
const tarball = filename.startsWith('/') ? filename : join(tempDir, filename)
tarballs.push(tarball)
const contents = run(['tar', '-tf', tarball])
const runtimeTs = contents
.split('\n')
.filter((entry) => /package\/src\/.*\.ts$/.test(entry) && !entry.endsWith('.d.ts'))
if (runtimeTs.length > 0) {
console.error(`${basename(tarball)} includes runtime TypeScript:\n${runtimeTs.join('\n')}`)
process.exit(1)
}
}
run(['npm', 'init', '-y'], tempDir)
run(['npm', 'install', '--ignore-scripts', '--no-audit', '--no-fund', ...tarballs], tempDir)
nodeEval("await import('@open-pencil/core')", tempDir)
nodeEval("await import('@open-pencil/core/scene-graph')", tempDir)
nodeEval("await import('@open-pencil/vue')", tempDir)
nodeEval("await import('@open-pencil/mcp')", tempDir)
run(['node', 'node_modules/.bin/openpencil', '--help'], tempDir)
run(['node', 'node_modules/.bin/openpencil-mcp', '--help'], tempDir)
run(['node', 'node_modules/.bin/openpencil-mcp-http', '--help'], tempDir)
console.log('Packed package smoke tests passed.')
} finally {
rmSync(tempDir, { recursive: true, force: true })
}