mirror of
https://github.com/zhw2590582/ArtPlayer.git
synced 2026-10-23 22:01:20 -08:00
test(BASE-05): capture published distribution and type consumers
This commit is contained in:
1 parent
2b7054d8a5
commit
c7a375e146
21 files changed
+5079
-28
No files matched your search
@@ -0,0 +1,67 @@
|
||||
import assert from 'node:assert/strict'
|
||||
import fs from 'node:fs'
|
||||
import path from 'node:path'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
import { hash, refactorDir } from './releases.mjs'
|
||||
|
||||
const root = path.resolve(refactorDir, '..')
|
||||
const filename = path.join(refactorDir, 'baselines/distribution.json')
|
||||
function files(dir) {
|
||||
if (!fs.existsSync(dir)) return []
|
||||
return fs.readdirSync(dir, { withFileTypes: true }).flatMap(entry => entry.isDirectory() ? files(path.join(dir, entry.name)) : [path.join(dir, entry.name)])
|
||||
}
|
||||
function targets(value, field) {
|
||||
if (typeof value === 'string') return [{ field, path: value }]
|
||||
if (value && typeof value === 'object') return Object.entries(value).flatMap(([key, child]) => targets(child, `${field}.${key}`))
|
||||
return []
|
||||
}
|
||||
export function captureDistribution() {
|
||||
const initial = JSON.parse(fs.readFileSync(path.join(refactorDir, 'package-inventory.json'), 'utf8'))
|
||||
return { schemaVersion: 1, task: 'BASE-05', capturedAt: new Date().toISOString(), sourceCommit: '2b7054d8',
|
||||
note: 'Workspace manifest and observed resource inventory. Existing dist files may be stale; presence and hashes are not proof of a fresh build or npm publication. Only core/chapter published tarballs are verified in releases.json and consumers.json.',
|
||||
packages: initial.packages.map(pkg => {
|
||||
const dir = path.join(root, 'packages', pkg.name)
|
||||
const manifestBytes = fs.readFileSync(path.join(dir, 'package.json'))
|
||||
const manifest = JSON.parse(manifestBytes)
|
||||
const resources = ['dist', 'types'].flatMap(name => files(path.join(dir, name))).map(file => ({ path: path.relative(dir, file).replaceAll('\\', '/'), bytes: fs.statSync(file).size, sha256: hash(fs.readFileSync(file)) })).sort((a, b) => a.path.localeCompare(b.path))
|
||||
const declaredTargets = ['main', 'module', 'legacy', 'types', 'typings', 'exports', 'typesVersions', 'browser', 'unpkg', 'jsdelivr'].flatMap(field => targets(manifest[field], field)).map(target => {
|
||||
const normalized = target.path.replace(/^\.\//, '')
|
||||
const regex = new RegExp(`^${normalized.split('*').map(part => part.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')).join('.*')}$`)
|
||||
return { ...target, observedMatches: resources.filter(resource => regex.test(resource.path)).map(resource => resource.path) }
|
||||
})
|
||||
const site = pkg.name === 'artplayer-vitepress'
|
||||
return { name: pkg.name, kind: site ? 'documentation-site' : 'npm-library', manifest, manifestSha256Lf: hash(manifestBytes.toString().replaceAll('\r\n', '\n')), declaredTargets, resources,
|
||||
sourceAssets: files(path.join(dir, 'src')).filter(file => !/\.[cm]?[jt]sx?$/.test(file)).map(file => path.relative(dir, file).replaceAll('\\', '/')).sort(),
|
||||
buildOutputs: site ? ['docs/document/** via vitepress outDir'] : [`dist/${pkg.name}.js`, `dist/${pkg.name}.legacy.js`, `dist/${pkg.name}.mjs`, `docs/compiled/${pkg.name}.{js,legacy.js,mjs} copied by root build`],
|
||||
distributionStatus: site ? 'Actual workflow builds a static site; no library entrypoints. Manifest lacks private:true; publication intent needs SITE/REL confirmation, not an automatic npm release.' : 'Workspace inventory; per-package published contract remains required unless listed in releases.json.',
|
||||
}
|
||||
}),
|
||||
}
|
||||
}
|
||||
export function validateDistribution(report) {
|
||||
const initial = JSON.parse(fs.readFileSync(path.join(refactorDir, 'package-inventory.json'), 'utf8'))
|
||||
assert.equal(report.schemaVersion, 1)
|
||||
assert.deepEqual(report.packages.map(pkg => pkg.name), initial.packages.map(pkg => pkg.name), 'Distribution package coverage changed')
|
||||
for (const pkg of report.packages) {
|
||||
assert.equal(pkg.manifest.name, pkg.name)
|
||||
if (pkg.kind === 'npm-library') assert(pkg.resources.length > 0 && pkg.declaredTargets.length > 0, `Missing library resources: ${pkg.name}`)
|
||||
for (const resource of pkg.resources) assert(!resource.path.startsWith('/') && !resource.path.split('/').includes('..') && /^[a-f0-9]{64}$/.test(resource.sha256), 'Invalid resource provenance')
|
||||
}
|
||||
assert.equal(report.packages.filter(pkg => pkg.kind === 'documentation-site').length, 1)
|
||||
const thumbnail = report.packages.find(pkg => pkg.name === 'artplayer-tool-thumbnail')
|
||||
assert(thumbnail.declaredTargets.some(target => target.path.endsWith('.esm.js') && !target.observedMatches.length), 'Missing thumbnail entrypoint discrepancy')
|
||||
}
|
||||
if (process.argv[1] && path.resolve(process.argv[1]) === fileURLToPath(import.meta.url)) {
|
||||
if (process.argv.includes('--capture')) {
|
||||
assert(!fs.existsSync(filename), 'Do not overwrite the historical distribution inventory')
|
||||
const report = captureDistribution()
|
||||
validateDistribution(report)
|
||||
fs.writeFileSync(filename, `${JSON.stringify(report, null, 2)}\n`)
|
||||
}
|
||||
else {
|
||||
assert(process.argv.slice(2).every(arg => arg === '--check'), 'Use --capture or --check')
|
||||
const report = JSON.parse(fs.readFileSync(filename, 'utf8'))
|
||||
validateDistribution(report)
|
||||
console.log(`Frozen distribution inventory: ${report.packages.length} packages; current build and npm contents are not revalidated by this command`)
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user