import { readFile } from 'node:fs/promises' import { join, resolve } from 'node:path' export async function readJson(path) { return JSON.parse(await readFile(path, 'utf8')) } export function npmPackFilename(packageName, packageVersion) { return `${packageName.replace(/^@/, '').replace(/\//g, '-')}-${packageVersion}.tgz` } export function ecosystemPackageSpecs(wrapperManifest) { return [ { id: 'core', kind: 'core', packageDir: 'packages/core', publicSource: true, corePackage: wrapperManifest.corePackage }, ...(wrapperManifest.renderers || []).map(renderer => ({ id: `renderer-${renderer.id}`, kind: 'renderer', packageDir: renderer.packageDir, renderer, publicSource: renderer.publicSource !== false })), ...(wrapperManifest.presets || []).map(preset => ({ id: `preset-${preset.id}`, kind: 'preset', packageDir: preset.packageDir, preset, publicSource: preset.publicSource !== false })), ...(wrapperManifest.compatibilityPackages || []).map(compatibilityPackage => ({ id: compatibilityPackage.id, kind: 'compatibility', packageDir: compatibilityPackage.packageDir, compatibilityPackage, publicSource: compatibilityPackage.publicSource === true, releaseArtifact: compatibilityPackage.releaseArtifact ?? { includeTarball: true } })), ...wrapperManifest.wrappers.map(wrapper => ({ id: wrapper.id, kind: 'standard-wrapper', packageDir: wrapper.packageDir, wrapper, publicSource: true })) ] } export async function loadEcosystemPackageEntry(sourceRoot, spec) { const absoluteDir = resolve(sourceRoot, spec.packageDir) const packageJson = await readJson(join(absoluteDir, 'package.json')) return { ...spec, absoluteDir, packageJson, packageName: packageJson.name, version: packageJson.version, tarballName: npmPackFilename(packageJson.name, packageJson.version), releaseArtifact: spec.releaseArtifact ?? { includeTarball: true } } } export async function loadEcosystemReleaseContext(sourceRoot) { const rootPackage = await readJson(join(sourceRoot, 'package.json')) const wrapperManifest = await readJson(join(sourceRoot, 'ecosystem', 'wrappers.json')) const specs = ecosystemPackageSpecs(wrapperManifest) const entries = await Promise.all(specs.map(spec => loadEcosystemPackageEntry(sourceRoot, spec))) return { rootPackage, wrapperManifest, specs, entries } } export function collectExportEntrypoints(value, paths = new Set()) { if (!value) { return paths } if (typeof value === 'string') { paths.add(value) return paths } if (Array.isArray(value)) { for (const item of value) { collectExportEntrypoints(item, paths) } return paths } if (typeof value === 'object') { for (const item of Object.values(value)) { collectExportEntrypoints(item, paths) } } return paths } export function collectPackageEntrypoints(packageJson) { const entrypoints = new Set() for (const field of ['main', 'module', 'browser', 'types', 'svelte']) { if (typeof packageJson[field] === 'string') { entrypoints.add(packageJson[field]) } } for (const item of collectExportEntrypoints(packageJson.exports)) { entrypoints.add(item) } for (const item of Object.values(packageJson.bin || {})) { if (typeof item === 'string') { entrypoints.add(item) } } return [...entrypoints].filter(entrypoint => !entrypoint.startsWith('/') && !entrypoint.includes(':') && !entrypoint.includes('*') && !entrypoint.startsWith('#') && entrypoint !== './' && entrypoint !== '.' ) } export function ecosystemPackageManifestEntry(entry) { return { id: entry.id, kind: entry.kind, packageName: entry.packageName, version: entry.version, packageDir: entry.packageDir, tarball: entry.tarballName, publicSource: entry.publicSource, releaseArtifact: entry.releaseArtifact, targetPackage: entry.compatibilityPackage?.targetPackage ?? null, github: entry.wrapper?.github ?? entry.renderer?.github ?? entry.preset?.github ?? null, gitee: entry.wrapper?.gitee ?? entry.renderer?.gitee ?? entry.preset?.gitee ?? null, sourceRepository: entry.corePackage?.sourceRepository ?? null } }