From b4e61b48be8910e91e74d90f997039e024cc2b0c Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Mon, 13 Jul 2026 19:14:11 +0100 Subject: [PATCH] refactor(build): derive package entries from exports --- tsdown.config.ts | 261 ++++++----------------------------------------- 1 file changed, 30 insertions(+), 231 deletions(-) diff --git a/tsdown.config.ts b/tsdown.config.ts index 99fcc222bf0b..24e4fccfa3a3 100644 --- a/tsdown.config.ts +++ b/tsdown.config.ts @@ -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 { }; } -function buildGatewayProtocolDistEntries(): Record { - 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 { - 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 { - 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 { - 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 { - 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 { - 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 { - return buildPackageDistEntriesFromExports("normalization-core"); -} - -function buildRetryDistEntries(): Record { - return buildPackageDistEntriesFromExports("retry"); -} - -function buildMediaCoreDistEntries(): Record { - return buildPackageDistEntriesFromExports("media-core"); -} - function buildPackageDistEntriesFromExports(packageDir: string): Record { 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 a.localeCompare(b))); } -function buildAcpCoreDistEntries(): Record { - return buildPackageDistEntriesFromExports("acp-core"); -} - -function buildTerminalCoreDistEntries(): Record { - 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 { - return { - "provider-runtime-shared": "packages/web-content-core/src/provider-runtime-shared.ts", - }; -} - function buildSpeechCoreDistEntries(): Record { return { api: "packages/speech-core/api.ts", @@ -532,20 +411,6 @@ function buildLlmCoreDistEntries(): Record { }; } -function buildModelCatalogCoreDistEntries(): Record { - 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 { ...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 { 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,