import type { ExtensionBuildSpec } from "./spec.ts"; /** Generated `package.json` for a built extension package. */ export interface GeneratedPackageJson { name: string; version: string; private: true; type: "module"; main: string; license?: string; description?: string; keywords?: string[]; peerDependencies?: Record; dependencies?: Record; pi: Partial>; } export function generatePackageJson( spec: ExtensionBuildSpec, version: string, /** Exact resolved versions for externals; falls back to the source range. */ resolvedExternals: Record = {}, ): GeneratedPackageJson { const source = spec.pkg; const extensions = ( source.pi?.extensions?.length ? source.pi.extensions : ["index.ts"] ).map((entry) => entry.replace(/\.[cm]?[jt]s$/u, ".ts")); const pi: GeneratedPackageJson["pi"] = { extensions }; for (const field of ["skills", "prompts", "themes"] as const) if (source.pi?.[field]) pi[field] = [...(source.pi[field] ?? [])]; const dependencies = Object.fromEntries( Object.keys(spec.externals) .sort() .map((dep) => [ dep, resolvedExternals[dep] ?? source.dependencies?.[dep] ?? "*", ]), ); const generated: GeneratedPackageJson = { name: source.name, version, private: true, type: "module", main: extensions[0] ?? "index.ts", pi, }; if (source.license) generated.license = source.license; if (source.description) generated.description = source.description; if (source.keywords) generated.keywords = [...source.keywords]; if (source.peerDependencies) generated.peerDependencies = { ...source.peerDependencies }; if (Object.keys(dependencies).length) generated.dependencies = dependencies; return generated; }