refactor(build): derive package entries from exports

This commit is contained in:
Peter Steinberger
2026-07-13 19:14:11 +01:00
parent 2eaf7ed9f0
commit b4e61b48be
+30 -231
View File
@@ -137,21 +137,22 @@ function buildInputOptions(options: InputOptionsArg): InputOptionsReturn {
function nodeBuildConfig(config: UserConfig): UserConfig {
return {
...config,
dts: TSDOWN_DECLARATIONS,
env,
outExtensions: () => ({ js: ".js", dts: ".d.ts" }),
fixedExtension: false,
platform: "node",
sourcemap: OUTPUT_SOURCE_MAPS,
inputOptions: buildInputOptions,
};
}
function nodeWorkspacePackageBuildConfig(config: UserConfig): UserConfig {
function nodeWorkspacePackageBuildConfig(packageDir: string, config: UserConfig = {}): UserConfig {
return {
...config,
dts: TSDOWN_DECLARATIONS,
entry: config.entry ?? buildPackageDistEntriesFromExports(packageDir),
env,
format: "esm",
platform: "node",
outDir: config.outDir ?? tsdownPackageOutputRoot(packageDir),
sourcemap: OUTPUT_SOURCE_MAPS,
inputOptions: buildInputOptions,
};
@@ -364,95 +365,6 @@ function buildAgentCoreDistEntries(): Record<string, string> {
};
}
function buildGatewayProtocolDistEntries(): Record<string, string> {
return {
// Package exports resolve from packages/gateway-protocol/dist, while the
// root build still emits dist/gateway/protocol/index for Docker harnesses.
index: "packages/gateway-protocol/src/index.ts",
"client-info": "packages/gateway-protocol/src/client-info.ts",
"connect-error-details": "packages/gateway-protocol/src/connect-error-details.ts",
"frame-guards": "packages/gateway-protocol/src/frame-guards.ts",
schema: "packages/gateway-protocol/src/schema.ts",
"startup-unavailable": "packages/gateway-protocol/src/startup-unavailable.ts",
version: "packages/gateway-protocol/src/version.ts",
};
}
function buildGatewayClientDistEntries(): Record<string, string> {
return {
// Keep package entrypoints explicit so package.json exports and root build
// config cannot drift when client internals are split again.
index: "packages/gateway-client/src/index.ts",
browser: "packages/gateway-client/src/browser.ts",
readiness: "packages/gateway-client/src/readiness.ts",
timeouts: "packages/gateway-client/src/timeouts.ts",
};
}
function buildNetPolicyDistEntries(): Record<string, string> {
return {
// These subpaths are imported by root runtime code and exported by the
// package. Keep the build list adjacent to package.json exports.
index: "packages/net-policy/src/index.ts",
ip: "packages/net-policy/src/ip.ts",
ipv4: "packages/net-policy/src/ipv4.ts",
"redact-sensitive-url": "packages/net-policy/src/redact-sensitive-url.ts",
"url-protocol": "packages/net-policy/src/url-protocol.ts",
"url-userinfo": "packages/net-policy/src/url-userinfo.ts",
};
}
function buildMediaGenerationCoreDistEntries(): Record<string, string> {
return {
index: "packages/media-generation-core/src/index.ts",
"capability-model-ref": "packages/media-generation-core/src/capability-model-ref.ts",
catalog: "packages/media-generation-core/src/catalog.ts",
"model-ref": "packages/media-generation-core/src/model-ref.ts",
normalization: "packages/media-generation-core/src/normalization.ts",
};
}
function buildMediaUnderstandingCoreDistEntries(): Record<string, string> {
return {
"active-model": "packages/media-understanding-common/src/active-model.ts",
defaults: "packages/media-understanding-common/src/defaults.ts",
errors: "packages/media-understanding-common/src/errors.ts",
format: "packages/media-understanding-common/src/format.ts",
"openai-compatible-video": "packages/media-understanding-common/src/openai-compatible-video.ts",
"output-extract": "packages/media-understanding-common/src/output-extract.ts",
"provider-id": "packages/media-understanding-common/src/provider-id.ts",
"provider-supports": "packages/media-understanding-common/src/provider-supports.ts",
types: "packages/media-understanding-common/src/types.ts",
video: "packages/media-understanding-common/src/video.ts",
};
}
function buildMarkdownCoreDistEntries(): Record<string, string> {
return {
index: "packages/markdown-core/src/index.ts",
"code-spans": "packages/markdown-core/src/code-spans.ts",
fences: "packages/markdown-core/src/fences.ts",
frontmatter: "packages/markdown-core/src/frontmatter.ts",
ir: "packages/markdown-core/src/ir.ts",
render: "packages/markdown-core/src/render.ts",
"render-aware-chunking": "packages/markdown-core/src/render-aware-chunking.ts",
tables: "packages/markdown-core/src/tables.ts",
types: "packages/markdown-core/src/types.ts",
};
}
function buildNormalizationCoreDistEntries(): Record<string, string> {
return buildPackageDistEntriesFromExports("normalization-core");
}
function buildRetryDistEntries(): Record<string, string> {
return buildPackageDistEntriesFromExports("retry");
}
function buildMediaCoreDistEntries(): Record<string, string> {
return buildPackageDistEntriesFromExports("media-core");
}
function buildPackageDistEntriesFromExports(packageDir: string): Record<string, string> {
const packageJsonPath = path.join("packages", packageDir, "package.json");
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf8")) as {
@@ -480,39 +392,6 @@ function buildPackageDistEntriesFromExports(packageDir: string): Record<string,
return Object.fromEntries(Object.entries(entries).toSorted(([a], [b]) => a.localeCompare(b)));
}
function buildAcpCoreDistEntries(): Record<string, string> {
return buildPackageDistEntriesFromExports("acp-core");
}
function buildTerminalCoreDistEntries(): Record<string, string> {
return {
index: "packages/terminal-core/src/index.ts",
ansi: "packages/terminal-core/src/ansi.ts",
"decorative-emoji": "packages/terminal-core/src/decorative-emoji.ts",
"health-style": "packages/terminal-core/src/health-style.ts",
links: "packages/terminal-core/src/links.ts",
note: "packages/terminal-core/src/note.ts",
"osc-progress": "packages/terminal-core/src/osc-progress.ts",
palette: "packages/terminal-core/src/palette.ts",
"progress-line": "packages/terminal-core/src/progress-line.ts",
"prompt-select-styled": "packages/terminal-core/src/prompt-select-styled.ts",
"prompt-select-styled-params": "packages/terminal-core/src/prompt-select-styled-params.ts",
"prompt-style": "packages/terminal-core/src/prompt-style.ts",
restore: "packages/terminal-core/src/restore.ts",
"safe-text": "packages/terminal-core/src/safe-text.ts",
"stream-writer": "packages/terminal-core/src/stream-writer.ts",
table: "packages/terminal-core/src/table.ts",
"terminal-link": "packages/terminal-core/src/terminal-link.ts",
theme: "packages/terminal-core/src/theme.ts",
};
}
function buildWebContentCoreDistEntries(): Record<string, string> {
return {
"provider-runtime-shared": "packages/web-content-core/src/provider-runtime-shared.ts",
};
}
function buildSpeechCoreDistEntries(): Record<string, string> {
return {
api: "packages/speech-core/api.ts",
@@ -532,20 +411,6 @@ function buildLlmCoreDistEntries(): Record<string, string> {
};
}
function buildModelCatalogCoreDistEntries(): Record<string, string> {
return {
index: "packages/model-catalog-core/src/index.ts",
"configured-model-refs": "packages/model-catalog-core/src/configured-model-refs.ts",
"model-catalog-normalize": "packages/model-catalog-core/src/model-catalog-normalize.ts",
"model-catalog-refs": "packages/model-catalog-core/src/model-catalog-refs.ts",
"model-catalog-types": "packages/model-catalog-core/src/model-catalog-types.ts",
"provider-id": "packages/model-catalog-core/src/provider-id.ts",
"provider-model-id-normalization":
"packages/model-catalog-core/src/provider-model-id-normalization.ts",
"provider-model-id-normalize": "packages/model-catalog-core/src/provider-model-id-normalize.ts",
};
}
function shouldExternalizeAgentCoreDependency(id: string): boolean {
return (
id === "@openclaw/ai" ||
@@ -605,28 +470,30 @@ function buildUnifiedDistEntries(): Record<string, string> {
...coreDistEntries,
...dockerE2eHarnessEntries,
...Object.fromEntries(
Object.entries(buildNormalizationCoreDistEntries()).map(([entry, source]) => [
`normalization-core/${entry}`,
Object.entries(buildPackageDistEntriesFromExports("normalization-core")).map(
([entry, source]) => [`normalization-core/${entry}`, source],
),
),
...Object.fromEntries(
Object.entries(buildPackageDistEntriesFromExports("retry")).map(([entry, source]) => [
`retry/${entry}`,
source,
]),
),
...Object.fromEntries(
Object.entries(buildRetryDistEntries()).map(([entry, source]) => [`retry/${entry}`, source]),
),
...Object.fromEntries(
Object.entries(buildMediaCoreDistEntries()).map(([entry, source]) => [
Object.entries(buildPackageDistEntriesFromExports("media-core")).map(([entry, source]) => [
`media-core/${entry}`,
source,
]),
),
...Object.fromEntries(
Object.entries(buildAcpCoreDistEntries()).map(([entry, source]) => [
Object.entries(buildPackageDistEntriesFromExports("acp-core")).map(([entry, source]) => [
`acp-core/${entry}`,
source,
]),
),
...Object.fromEntries(
Object.entries(buildTerminalCoreDistEntries()).map(([entry, source]) => [
Object.entries(buildPackageDistEntriesFromExports("terminal-core")).map(([entry, source]) => [
`terminal-core/${entry}`,
source,
]),
@@ -655,130 +522,62 @@ function buildUnifiedDistEntries(): Record<string, string> {
const configs = [
nodeBuildConfig({
clean: true,
dts: TSDOWN_DECLARATIONS,
entry: buildAgentCoreDistEntries(),
outDir: tsdownPackageOutputRoot("agent-core"),
deps: {
neverBundle: shouldExternalizeAgentCoreDependency,
},
}),
nodeWorkspacePackageBuildConfig({
clean: true,
dts: TSDOWN_DECLARATIONS,
entry: buildGatewayProtocolDistEntries(),
outDir: tsdownPackageOutputRoot("gateway-protocol"),
nodeWorkspacePackageBuildConfig("gateway-protocol", {
deps: {
neverBundle: shouldExternalizeGatewayProtocolDependency,
},
}),
nodeWorkspacePackageBuildConfig({
clean: true,
dts: TSDOWN_DECLARATIONS,
entry: buildGatewayClientDistEntries(),
outDir: tsdownPackageOutputRoot("gateway-client"),
nodeWorkspacePackageBuildConfig("gateway-client", {
deps: {
neverBundle: shouldExternalizeGatewayClientDependency,
},
}),
nodeWorkspacePackageBuildConfig({
clean: true,
dts: TSDOWN_DECLARATIONS,
entry: buildNetPolicyDistEntries(),
outDir: tsdownPackageOutputRoot("net-policy"),
nodeWorkspacePackageBuildConfig("net-policy", {
deps: {
neverBundle: shouldExternalizeNetPolicyDependency,
},
}),
nodeWorkspacePackageBuildConfig({
clean: true,
dts: TSDOWN_DECLARATIONS,
entry: buildMediaGenerationCoreDistEntries(),
outDir: tsdownPackageOutputRoot("media-generation-core"),
}),
nodeWorkspacePackageBuildConfig({
clean: true,
dts: TSDOWN_DECLARATIONS,
entry: buildMediaUnderstandingCoreDistEntries(),
outDir: tsdownPackageOutputRoot("media-understanding-common"),
}),
nodeWorkspacePackageBuildConfig({
clean: true,
dts: TSDOWN_DECLARATIONS,
entry: buildMarkdownCoreDistEntries(),
outDir: tsdownPackageOutputRoot("markdown-core"),
nodeWorkspacePackageBuildConfig("media-generation-core"),
nodeWorkspacePackageBuildConfig("media-understanding-common"),
nodeWorkspacePackageBuildConfig("markdown-core", {
deps: {
neverBundle: shouldExternalizeMarkdownCoreDependency,
},
}),
nodeWorkspacePackageBuildConfig({
clean: true,
dts: TSDOWN_DECLARATIONS,
entry: buildNormalizationCoreDistEntries(),
outDir: tsdownPackageOutputRoot("normalization-core"),
}),
nodeWorkspacePackageBuildConfig({
clean: true,
dts: TSDOWN_DECLARATIONS,
entry: buildRetryDistEntries(),
outDir: tsdownPackageOutputRoot("retry"),
}),
nodeWorkspacePackageBuildConfig({
clean: true,
dts: TSDOWN_DECLARATIONS,
entry: buildMediaCoreDistEntries(),
outDir: tsdownPackageOutputRoot("media-core"),
}),
nodeWorkspacePackageBuildConfig({
clean: true,
dts: TSDOWN_DECLARATIONS,
entry: buildAcpCoreDistEntries(),
outDir: tsdownPackageOutputRoot("acp-core"),
}),
nodeWorkspacePackageBuildConfig({
clean: true,
dts: TSDOWN_DECLARATIONS,
entry: buildTerminalCoreDistEntries(),
outDir: tsdownPackageOutputRoot("terminal-core"),
nodeWorkspacePackageBuildConfig("normalization-core"),
nodeWorkspacePackageBuildConfig("retry"),
nodeWorkspacePackageBuildConfig("media-core"),
nodeWorkspacePackageBuildConfig("acp-core"),
nodeWorkspacePackageBuildConfig("terminal-core", {
deps: {
neverBundle: shouldExternalizeTerminalCoreDependency,
},
}),
nodeWorkspacePackageBuildConfig({
clean: true,
dts: TSDOWN_DECLARATIONS,
entry: buildWebContentCoreDistEntries(),
nodeWorkspacePackageBuildConfig("web-content-core", {
outDir: "packages/web-content-core/dist",
}),
nodeWorkspacePackageBuildConfig({
clean: true,
dts: TSDOWN_DECLARATIONS,
nodeWorkspacePackageBuildConfig("speech-core", {
entry: buildSpeechCoreDistEntries(),
outDir: tsdownPackageOutputRoot("speech-core"),
deps: {
neverBundle: shouldExternalizeSpeechCoreDependency,
},
}),
nodeWorkspacePackageBuildConfig({
clean: true,
dts: TSDOWN_DECLARATIONS,
nodeWorkspacePackageBuildConfig("llm-core", {
entry: buildLlmCoreDistEntries(),
outDir: tsdownPackageOutputRoot("llm-core"),
deps: {
neverBundle: shouldExternalizeLlmCoreDependency,
},
}),
nodeWorkspacePackageBuildConfig({
clean: true,
dts: TSDOWN_DECLARATIONS,
entry: buildModelCatalogCoreDistEntries(),
outDir: tsdownPackageOutputRoot("model-catalog-core"),
}),
nodeWorkspacePackageBuildConfig("model-catalog-core"),
nodeBuildConfig({
// Build core entrypoints, plugin-sdk subpaths, bundled plugin entrypoints,
// and bundled hooks in one graph so runtime singletons are emitted once.
clean: true,
dts: TSDOWN_DECLARATIONS,
entry: buildUnifiedDistEntries(),
deps: {
alwaysBundle: shouldAlwaysBundleDependency,