Tools live under tools/<role>/<domain> (checks, generate, release, ci, dev), every tool is a workspace named @open-pencil/<domain>-tools, a shared tools/tsconfig.json backs the new check:tools gate that fixed 55 latent type errors, test:tools runs through bun --filter, the placement check is its own checks/test-homes package, and every tool resolves the repository through resolveWorkspaceRoot. Bun, Node, and mdast types live in a tools-root workspace so they never reach the app program.
62 lines
1.7 KiB
TypeScript
62 lines
1.7 KiB
TypeScript
import { describe, expect, test } from 'bun:test'
|
|
|
|
import {
|
|
collectExportTargets,
|
|
concreteImportSpecifiers,
|
|
validateManifest
|
|
} from '#package-artifacts/manifest/exports'
|
|
import type { PackageManifest } from '#package-artifacts/manifest/types'
|
|
|
|
const validManifest: PackageManifest = {
|
|
name: '@open-pencil/example',
|
|
version: '1.0.0',
|
|
files: ['dist'],
|
|
exports: {
|
|
'.': {
|
|
types: './dist/index.d.ts',
|
|
bun: './dist/index.js',
|
|
import: './dist/index.js'
|
|
},
|
|
'./feature': { import: './dist/feature.js' },
|
|
'./pattern/*': { import: './dist/*.js' },
|
|
'./package.json': './package.json'
|
|
}
|
|
}
|
|
|
|
describe('export metadata', () => {
|
|
test('collects conditional targets with their fields', () => {
|
|
expect(collectExportTargets(validManifest.exports, ['exports'])).toContainEqual({
|
|
condition: 'bun',
|
|
field: 'exports["."].bun',
|
|
target: './dist/index.js'
|
|
})
|
|
})
|
|
|
|
test('derives only concrete public import specifiers', () => {
|
|
expect(concreteImportSpecifiers(validManifest)).toEqual([
|
|
'@open-pencil/example',
|
|
'@open-pencil/example/feature'
|
|
])
|
|
})
|
|
|
|
test('accepts pack-safe runtime targets', () => {
|
|
expect(validateManifest(validManifest)).toEqual([])
|
|
})
|
|
|
|
test('rejects source bun targets and runtime declarations', () => {
|
|
const diagnostics = validateManifest({
|
|
...validManifest,
|
|
exports: {
|
|
'.': {
|
|
bun: './src/index.ts',
|
|
import: './dist/index.d.ts'
|
|
}
|
|
}
|
|
})
|
|
expect(diagnostics.map(({ message }) => message)).toEqual([
|
|
'target is excluded by files (./src/index.ts)',
|
|
'runtime target is a declaration file (./dist/index.d.ts)'
|
|
])
|
|
})
|
|
})
|