Files
deepseek-harness/scripts/release/installed-product-isolation.ts
T
Turtle 9b4aacb41a refactor(util): collect hardcoded official plugin lists in dsh-official-bundles
Move @deepseek-ai/dsh-official-bundles from packages/boot to packages/util
and move the plugin manager's protected plugin list and the Web plugin
page's hidden, ordered, and experimental bundle lists into it, so editing
any of these lists no longer touches app-boot or either plugin manager
package.
2026-10-23 12:12:38 +08:00

74 lines
3.4 KiB
TypeScript

/** Experimental-package isolation for the installed default product's dependency graph. */
import { existsSync, readFileSync, realpathSync } from 'node:fs'
import { createRequire } from 'node:module'
import { join } from 'node:path'
import { hasExperimentalPackageReference } from '../experimental-package-policy.ts'
import { OPTIONAL_BUNDLES } from '../../packages/util/official-bundles/src/bundles.ts'
interface InstalledManifest {
name: string
dependencies?: Record<string, string>
optionalDependencies?: Record<string, string>
peerDependencies?: Record<string, string>
peerDependenciesMeta?: Record<string, { optional?: boolean }>
}
/**
* Reject experimental dependencies reachable from one installed product entry.
* Other packages installed beside the entry and development dependencies do not join its graph.
* @param directory - installed entry package directory.
* @returns number of distinct installed packages visited.
*/
export function verifyInstalledProductIsolation(directory: string, optionalBundles: readonly string[] = OPTIONAL_BUNDLES): number {
const visited = new Set<string>()
const queue = [{ directory, chain: [] as string[] }]
for (const item of queue) {
const canonical = realpathSync(item.directory)
if (visited.has(canonical)) continue
visited.add(canonical)
const manifest = JSON.parse(readFileSync(join(canonical, 'package.json'), 'utf8')) as InstalledManifest
const chain = [...item.chain, manifest.name]
rejectExperimental(manifest.name, chain)
// The bundles the entry package ships switched off are installed beside the product, not required by it.
const offered = item.chain.length === 0 ? new Set(optionalBundles) : new Set<string>()
for (const section of ['dependencies', 'optionalDependencies', 'peerDependencies'] as const) {
for (const [name, range] of Object.entries(manifest[section] ?? {})) {
if (section === 'dependencies' && offered.has(name)) {
if (installedPackage(canonical, name) === undefined) throw new Error(`optional bundle is missing: ${[...chain, name].join(' -> ')}`)
continue
}
rejectExperimental(name, [...chain, name])
if (range.startsWith('npm:')) {
rejectExperimental(range.slice(4), [...chain, `${name} (${range})`])
}
const dependency = installedPackage(canonical, name)
if (dependency === undefined) {
if (section === 'optionalDependencies'
|| Object.hasOwn(manifest.optionalDependencies ?? {}, name)
|| section === 'peerDependencies' && manifest.peerDependenciesMeta?.[name]?.optional === true) continue
throw new Error(`default product dependency is missing: ${[...chain, name].join(' -> ')}`)
}
queue.push({ directory: dependency, chain })
}
}
}
return visited.size
}
function rejectExperimental(name: string, chain: readonly string[]): void {
if (hasExperimentalPackageReference(name)) {
throw new Error(`default product includes an experimental package: ${chain.join(' -> ')}`)
}
}
/** Resolve a dependency directory through the installed package's ancestor node_modules. */
function installedPackage(from: string, name: string): string | undefined {
const resolver = createRequire(join(from, 'package.json'))
for (const directory of resolver.resolve.paths(name) ?? []) {
const candidate = join(directory, name)
if (existsSync(join(candidate, 'package.json'))) return candidate
}
return undefined
}