diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index c71f05f4e..05118d7b2 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -121,7 +121,7 @@ jobs:
- name: Install dependencies
run: npm ci
- name: E2E test affected projects
- run: npx nx affected -t e2e-test --parallel=1
+ run: npx nx affected -t e2e-test --verbose --parallel=1
build:
runs-on: ubuntu-latest
diff --git a/README.md b/README.md
index e899bfa18..7265970cf 100644
--- a/README.md
+++ b/README.md
@@ -1,89 +1,126 @@
-
Code PushUp CLI
-
-Comprehensive tech quality monitoring
-
-Quantify tech debt — Track incremental improvements — Monitor regressions
+# @code-pushup/models
----
+[](https://www.npmjs.com/package/@code-pushup/models)
+[](https://npmtrends.com/@code-pushup/models)
+[](https://www.npmjs.com/package/@code-pushup/models?activeTab=dependencies)
-[](https://github.com/code-pushup/cli/releases/latest)
-[](https://github.com/code-pushup/cli/releases)
-
-[](https://opensource.org/licenses/MIT)
-[](https://github.com/code-pushup/cli/pulse/monthly)
-[](https://github.com/code-pushup/cli/actions/workflows/ci.yml?query=branch%3Amain)
-[](https://codecov.io/gh/code-pushup/cli)
+**Model definitions and validators** for the [Code PushUp CLI](../cli/README.md).
----
+For a full list of models defined by this package, see the auto-generated [Code PushUp models reference](./docs/models-reference.md).
-
-
-
-
-
-
-
+## Setup
----
+If you've already installed another `@code-pushup/*` package, then you may have already installed `@code-pushup/models` indirectly.
-### 🔌 Code quality tools are like phone chargers. Everyone has a different plug.
+If not, you can always install it separately:
-_Common problems with keeping track of technical quality:_
+```sh
+npm install --save-dev @code-pushup/models
+```
-- When **tech debt is invisible**, it's difficult to plan much-needed maintenance efforts 🔧
-- Individual tools measure different metrics, inability to combine them leads to
- a **lack of comprehensive overview** 🧑🦯
-- Open-source tools typically used for failing checks in CI, which **can't measure incremental improvements** due to arbitrary pass/fail thresholds 🤖
-- Off-the-shelf solutions tend to be opinionated and **hard to customize**, so may not fit your specific needs 🧱
+```sh
+yarn add --dev @code-pushup/models
+```
-_We want to change that!_
+```sh
+pnpm add --save-dev @code-pushup/models
+```
----
+## Usage
-## 🔎🔬 Code quality integrations for any tool 📉🔍
+### Importing Everything (Traditional)
-| [🚀 Get started](./packages/cli/README.md#getting-started)️ | [🤖 CI automation](https://github.com/marketplace/actions/code-pushup) |
-| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
-|
|
|
-| - Run **[📦 `@code-pushup/cli`](./packages/cli#readme)** to collect **reports**.
- [Get started](./packages/cli/README.md#getting-started) quickly with our [**official plugins**](#-officially-supported-plugins)! ⏱️
| - Easy **CI** setup with **[🤖 `code-pushup/github-action`](https://github.com/marketplace/actions/code-pushup)**.
- Import logic from **[📦 `@code-pushup/core`](./packages/core#readme)** to craft **custom tools**.
|
+Import the type definitions if using TypeScript:
-| 📈 [Portal](https://code-pushup.dev#portal)️ | 🔌 [Custom plugins](./packages/cli/docs/custom-plugins.md) |
-| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
-|
|
|
-| - **[Portal](https://code-pushup.dev#portal)** 🌐 **visualizes reports** in a slick UI.
- Track **historical data** from uploads. ⬆️
| - All the [data models](./packages/models/docs/models-reference.md) you need are provided in **[📦 `@code-pushup/models`](./packages/models/README.md)**.
- Find tons of useful utilities in **[📦 `@code-pushup/utils`](./packages/utils/README.md)**.
|
+- in `code-pushup.config.ts`:
----
+ ```ts
+ import type { CoreConfig } from '@code-pushup/models';
-### 🔌 Officially supported plugins
+ export default {
+ // ... this is type-checked ...
+ } satisfies CoreConfig;
+ ```
-| Icon | Name | Description |
-| :------------------------------------------------------------: | :-------------------------------------------------- | :--------------------------------------------------------------------------------- |
-|
| [ESLint](./packages/plugin-eslint#readme) | Static analysis using **ESLint** rules. |
-|
| [Code Coverage](./packages/plugin-coverage#readme) | Collects code **coverage** from your tests. |
-|
| [JS Packages](./packages/plugin-js-packages#readme) | Checks 3rd party packages for known **vulnerabilities** and **outdated** versions. |
-|
| [Lighthouse](./packages/plugin-lighthouse#readme) | Measures web performance and best practices with **Lighthouse**. |
-|
| [JSDocs](./packages/plugin-jsdocs#readme) | Analyzes how much source code is **documented** using JSDocs comments. |
-|
| [TypeScript](./packages/plugin-typescript#readme) | Checks for **TypeScript** errors using strict compiler flags. |
+- in custom plugin:
----
+ ```ts
+ import type { PluginConfig } from '@code-pushup/models';
-## 📝 How it works
+ export default function myCustomPlugin(): PluginConfig {
+ return {
+ // ... this is type-checked ...
+ };
+ }
+ ```
-1. **[Configure](./packages/cli/README.md#getting-started)**
- Pick from a set of supported packages or include your own ideas. 🧩
+ ```ts
+ import type { AuditOutput } from '@code-pushup/models';
-2. **[Integrate](https://github.com/marketplace/actions/code-pushup)**
- Use our integration guide and packages to set up CI integration in minutes. ⏱️
+ async function myCustomPluginRunner() {
+ const audits: AuditOutput[] = await collectAudits();
-3. **[Observe](https://code-pushup.dev#portal)**
- Guard regressions and track improvements with every code change. 🔍
+ await writeFile(RUNNER_OUTPUT_FILE, JSON.stringify(audits));
+ }
+ ```
-4. **Relax!**
- Watch improvements, share reports 📈
+### Importing Specific Modules (Recommended)
----
+For better tree-shaking and smaller bundle sizes, import only what you need from specific modules:
-## 💖 Want to support us?
+```ts
+// Import only audit-related models
+import { auditSchema } from '@code-pushup/models/audit';
+import type { AuditOutput } from '@code-pushup/models/audit-output';
+// Import only configuration models
+import type { CoreConfig } from '@code-pushup/models/core-config';
+import { persistConfigSchema } from '@code-pushup/models/persist-config';
+// Import only plugin-related models
+import type { PluginConfig } from '@code-pushup/models/plugin-config';
+// Import only report-related models
+import type { Report } from '@code-pushup/models/report';
+import { reportsDiffSchema } from '@code-pushup/models/reports-diff';
+```
-- Read how to contribute to the codebase. See: [CONTRIBUTING.md](./CONTRIBUTING.md) 🤝
-
+### Available Entry Points
+
+The following modules are available as individual entry points:
+
+| Module | Import Path | Description |
+| --------------- | ------------------------------------- | ----------------------------- |
+| Audit | `@code-pushup/models/audit` | Audit definitions and schemas |
+| Audit Output | `@code-pushup/models/audit-output` | Audit output models |
+| Cache Config | `@code-pushup/models/cache-config` | Cache configuration models |
+| Category Config | `@code-pushup/models/category-config` | Category configuration models |
+| Commit | `@code-pushup/models/commit` | Commit-related models |
+| Configuration | `@code-pushup/models/configuration` | General configuration models |
+| Core Config | `@code-pushup/models/core-config` | Core configuration models |
+| Group | `@code-pushup/models/group` | Group-related models |
+| Issue | `@code-pushup/models/issue` | Issue definitions and schemas |
+| Persist Config | `@code-pushup/models/persist-config` | Persist configuration models |
+| Plugin Config | `@code-pushup/models/plugin-config` | Plugin configuration models |
+| Report | `@code-pushup/models/report` | Report models |
+| Reports Diff | `@code-pushup/models/reports-diff` | Report diff models |
+| Runner Config | `@code-pushup/models/runner-config` | Runner configuration models |
+| Source | `@code-pushup/models/source` | Source location models |
+| Table | `@code-pushup/models/table` | Table formatting models |
+| Tree | `@code-pushup/models/tree` | Tree structure models |
+| Upload Config | `@code-pushup/models/upload-config` | Upload configuration models |
+
+### Runtime Validation
+
+If you need runtime validation, use the underlying Zod schemas:
+
+```ts
+// Import from specific modules (recommended)
+import { coreConfigSchema } from '@code-pushup/models/core-config';
+import { auditOutputSchema } from '@code-pushup/models/audit-output';
+
+// Or import from main entry point
+import { coreConfigSchema } from '@code-pushup/models';
+
+const json = JSON.parse(readFileSync('code-pushup.config.json'));
+const config = coreConfigSchema.parse(json); // throws ZodError if invalid
+```
+
+> **💡 Pro tip**: Using specific module imports (e.g., `@code-pushup/models/audit`) instead of the main entry point can significantly reduce your bundle size and avoid side effects by only including the code you actually use.
diff --git a/eslint.config.js b/eslint.config.js
index c25afb9dc..ee0a43d85 100644
--- a/eslint.config.js
+++ b/eslint.config.js
@@ -26,6 +26,7 @@ export default tseslint.config(
enforceBuildableLibDependency: true,
allow: [
String.raw`^.*/eslint(\.base)?\.config\.[cm]?js$`,
+ String.raw`^.*/tsdown\.base\.[cm]?js$`,
String.raw`^.*/code-pushup\.(config|preset)(\.m?[jt]s)?$`,
'^[./]+/tools/.*$',
],
@@ -110,6 +111,14 @@ export default tseslint.config(
{
files: ['**/*.json'],
languageOptions: { parser: jsoncParser },
+ rules: {
+ '@nx/dependency-checks': [
+ 'error',
+ {
+ ignoredDependencies: ['tsdown'],
+ },
+ ],
+ },
},
{
files: ['**/*.ts', '**/*.js'],
@@ -138,6 +147,7 @@ export default tseslint.config(
ignores: [
'**/*.mock.*',
'**/code-pushup.config.ts',
+ '**/tsdown.config.ts',
'**/mocks/fixtures/**',
'**/__snapshots__/**',
'**/dist',
diff --git a/examples/plugins/package.json b/examples/plugins/package.json
new file mode 100644
index 000000000..78dc892f9
--- /dev/null
+++ b/examples/plugins/package.json
@@ -0,0 +1,95 @@
+{
+ "name": "examples-plugins",
+ "version": "0.0.1",
+ "type": "module",
+ "main": "./src/index.cjs",
+ "module": "./src/index.mjs",
+ "types": "./src/index.d.cts",
+ "exports": {
+ ".": {
+ "import": "./src/index.mjs",
+ "require": "./src/index.cjs",
+ "types": "./src/index.d.mts"
+ },
+ "./file-size/src/file-size.plugin": {
+ "import": "./src/file-size/src/file-size.plugin.mjs",
+ "require": "./src/file-size/src/file-size.plugin.cjs",
+ "types": "./src/file-size/src/file-size.plugin.d.mts"
+ },
+ "./lighthouse/mock/fixtures/lhr": {
+ "import": "./src/lighthouse/mock/fixtures/lhr.mjs",
+ "require": "./src/lighthouse/mock/fixtures/lhr.cjs",
+ "types": "./src/lighthouse/mock/fixtures/lhr.d.mts"
+ },
+ "./lighthouse/src": {
+ "import": "./src/lighthouse/src/index.mjs",
+ "require": "./src/lighthouse/src/index.cjs",
+ "types": "./src/lighthouse/src/index.d.mts"
+ },
+ "./lighthouse/src/constants": {
+ "import": "./src/lighthouse/src/constants.mjs",
+ "require": "./src/lighthouse/src/constants.cjs",
+ "types": "./src/lighthouse/src/constants.d.mts"
+ },
+ "./lighthouse/src/lighthouse.plugin": {
+ "import": "./src/lighthouse/src/lighthouse.plugin.mjs",
+ "require": "./src/lighthouse/src/lighthouse.plugin.cjs",
+ "types": "./src/lighthouse/src/lighthouse.plugin.d.mts"
+ },
+ "./lighthouse/src/types": {
+ "import": "./src/lighthouse/src/types.mjs",
+ "require": "./src/lighthouse/src/types.cjs",
+ "types": "./src/lighthouse/src/types.d.mts"
+ },
+ "./lighthouse/src/utils": {
+ "import": "./src/lighthouse/src/utils.mjs",
+ "require": "./src/lighthouse/src/utils.cjs",
+ "types": "./src/lighthouse/src/utils.d.mts"
+ },
+ "./package-json/src": {
+ "import": "./src/package-json/src/index.mjs",
+ "require": "./src/package-json/src/index.cjs",
+ "types": "./src/package-json/src/index.d.mts"
+ },
+ "./package-json/src/constants": {
+ "import": "./src/package-json/src/constants.mjs",
+ "require": "./src/package-json/src/constants.cjs",
+ "types": "./src/package-json/src/constants.d.mts"
+ },
+ "./package-json/src/integration/dependencies.audit": {
+ "import": "./src/package-json/src/integration/dependencies.audit.mjs",
+ "require": "./src/package-json/src/integration/dependencies.audit.cjs",
+ "types": "./src/package-json/src/integration/dependencies.audit.d.mts"
+ },
+ "./package-json/src/integration/license.audit": {
+ "import": "./src/package-json/src/integration/license.audit.mjs",
+ "require": "./src/package-json/src/integration/license.audit.cjs",
+ "types": "./src/package-json/src/integration/license.audit.d.mts"
+ },
+ "./package-json/src/integration/type.audit": {
+ "import": "./src/package-json/src/integration/type.audit.mjs",
+ "require": "./src/package-json/src/integration/type.audit.cjs",
+ "types": "./src/package-json/src/integration/type.audit.d.mts"
+ },
+ "./package-json/src/integration/types": {
+ "import": "./src/package-json/src/integration/types.mjs",
+ "require": "./src/package-json/src/integration/types.cjs",
+ "types": "./src/package-json/src/integration/types.d.mts"
+ },
+ "./package-json/src/integration/utils": {
+ "import": "./src/package-json/src/integration/utils.mjs",
+ "require": "./src/package-json/src/integration/utils.cjs",
+ "types": "./src/package-json/src/integration/utils.d.mts"
+ },
+ "./package-json/src/package-json.plugin": {
+ "import": "./src/package-json/src/package-json.plugin.mjs",
+ "require": "./src/package-json/src/package-json.plugin.cjs",
+ "types": "./src/package-json/src/package-json.plugin.d.mts"
+ },
+ "./package-json/src/scoring": {
+ "import": "./src/package-json/src/scoring.mjs",
+ "require": "./src/package-json/src/scoring.cjs",
+ "types": "./src/package-json/src/scoring.d.mts"
+ }
+ }
+}
diff --git a/examples/plugins/tsdown.config.ts b/examples/plugins/tsdown.config.ts
new file mode 100644
index 000000000..d0a57d026
--- /dev/null
+++ b/examples/plugins/tsdown.config.ts
@@ -0,0 +1,10 @@
+import { defineConfig } from 'tsdown';
+import { baseConfig, getExternalDependencies } from '../../tsdown.base';
+
+const __dirname = import.meta.dirname;
+
+export default defineConfig(async () => ({
+ ...baseConfig({ projectRoot: __dirname }),
+ external: await getExternalDependencies(__dirname),
+ copy: [],
+}));
diff --git a/nx.json b/nx.json
index 7b41eba43..cb9eb5e83 100644
--- a/nx.json
+++ b/nx.json
@@ -26,6 +26,7 @@
"!{projectRoot}/tsconfig.@(test|tools).json",
"!{workspaceRoot}/**/(*.)coverage/**/*"
],
+ "tsdownConfigs": ["{projectRoot}/tsdown.config.ts"],
"test-vitest-inputs": [
"os",
{
@@ -78,14 +79,14 @@
"--max-warnings=0",
"--no-warn-ignored",
"--error-on-unmatched-pattern=false",
- "--format=./tools/eslint-formatter-multi/dist/src/index.js"
+ "--format=./tools/eslint-formatter-multi/dist/src/index.mjs"
],
"env": {
"ESLINT_FORMATTER_CONFIG": "{\"outputDir\":\"{projectRoot}/.eslint\"}"
}
}
},
- "build": {
+ "build-old": {
"dependsOn": ["^build"],
"inputs": ["production", "^production"],
"cache": true,
@@ -98,6 +99,19 @@
"assets": ["{projectRoot}/*.md"]
}
},
+ "build": {
+ "dependsOn": ["^build"],
+ "inputs": ["production", "^production", "tsdownConfigs"],
+ "cache": true,
+ "executor": "nx:run-commands",
+ "options": {
+ "commands": [
+ "node_modules/.bin/tsdown --config {projectRoot}/tsdown.config.ts"
+ ],
+ "outputPath": "{projectRoot}/dist"
+ },
+ "outputs": ["{projectRoot}/dist"]
+ },
"unit-test": {
"cache": true,
"inputs": ["default", "test-vitest-inputs"],
@@ -361,6 +375,10 @@
"filterByTags": ["publishable"]
}
}
+ },
+ {
+ "plugin": "./tools/src/ts-down.plugin.mjs",
+ "exclude": ["nx-plugin"]
}
],
"nxCloudId": "65d4d862d2adb16a45a4bc7c"
diff --git a/package-lock.json b/package-lock.json
index b8d79a01d..921f5d339 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -104,6 +104,7 @@
"react-dom": "18.3.1",
"ts-patch": "^3.3.0",
"tsconfig-paths": "^4.2.0",
+ "tsdown": "^0.15.1",
"tsx": "^4.19.0",
"type-fest": "^4.26.1",
"typescript": "5.7.3",
@@ -290,14 +291,14 @@
}
},
"node_modules/@babel/generator": {
- "version": "7.28.3",
- "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.3.tgz",
- "integrity": "sha512-3lSpxGgvnmZznmBkCRnVREPUFJv2wrv9iAoFDvADJc0ypmdOxdUtcLeBgBJ6zE0PMeTKnxeQzyk0xTBq4Ep7zw==",
+ "version": "7.28.5",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.5.tgz",
+ "integrity": "sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@babel/parser": "^7.28.3",
- "@babel/types": "^7.28.2",
+ "@babel/parser": "^7.28.5",
+ "@babel/types": "^7.28.5",
"@jridgewell/gen-mapping": "^0.3.12",
"@jridgewell/trace-mapping": "^0.3.28",
"jsesc": "^3.0.2"
@@ -639,9 +640,9 @@
}
},
"node_modules/@babel/helper-validator-identifier": {
- "version": "7.27.1",
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz",
- "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==",
+ "version": "7.28.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz",
+ "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==",
"dev": true,
"license": "MIT",
"engines": {
@@ -687,13 +688,13 @@
}
},
"node_modules/@babel/parser": {
- "version": "7.28.3",
- "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.3.tgz",
- "integrity": "sha512-7+Ey1mAgYqFAx2h0RuoxcQT5+MlG3GTV0TQrgr7/ZliKsm/MNDxVVutlWaziMq7wJNAz8MTqz55XLpWvva6StA==",
+ "version": "7.28.5",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.5.tgz",
+ "integrity": "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@babel/types": "^7.28.2"
+ "@babel/types": "^7.28.5"
},
"bin": {
"parser": "bin/babel-parser.js"
@@ -2271,14 +2272,14 @@
}
},
"node_modules/@babel/types": {
- "version": "7.28.2",
- "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.2.tgz",
- "integrity": "sha512-ruv7Ae4J5dUYULmeXw1gmb7rYRz57OWCPM57pHojnLq/3Z1CK2lNSLTCVjxVk1F/TZHwOZZrOWi0ur95BbLxNQ==",
+ "version": "7.28.5",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.5.tgz",
+ "integrity": "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-string-parser": "^7.27.1",
- "@babel/helper-validator-identifier": "^7.27.1"
+ "@babel/helper-validator-identifier": "^7.28.5"
},
"engines": {
"node": ">=6.9.0"
@@ -4356,10 +4357,11 @@
}
},
"node_modules/@jridgewell/sourcemap-codec": {
- "version": "1.5.0",
- "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz",
- "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==",
- "dev": true
+ "version": "1.5.5",
+ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",
+ "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==",
+ "dev": true,
+ "license": "MIT"
},
"node_modules/@jridgewell/trace-mapping": {
"version": "0.3.30",
@@ -6733,6 +6735,16 @@
"@octokit/openapi-types": "^20.0.0"
}
},
+ "node_modules/@oxc-project/types": {
+ "version": "0.95.0",
+ "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.95.0.tgz",
+ "integrity": "sha512-vACy7vhpMPhjEJhULNxrdR0D943TkA/MigMpJCHmBHvMXxRStRi/dPtTlfQ3uDwWSzRpT8z+7ImjZVf8JWBocQ==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/Boshen"
+ }
+ },
"node_modules/@paulirish/trace_engine": {
"version": "0.0.32",
"resolved": "https://registry.npmjs.org/@paulirish/trace_engine/-/trace_engine-0.0.32.tgz",
@@ -6898,6 +6910,315 @@
"tslib": "2.8.1"
}
},
+ "node_modules/@quansync/fs": {
+ "version": "0.1.5",
+ "resolved": "https://registry.npmjs.org/@quansync/fs/-/fs-0.1.5.tgz",
+ "integrity": "sha512-lNS9hL2aS2NZgNW7BBj+6EBl4rOf8l+tQ0eRY6JWCI8jI2kc53gSoqbjojU0OnAWhzoXiOjFyGsHcDGePB3lhA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "quansync": "^0.2.11"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sxzz"
+ }
+ },
+ "node_modules/@rolldown/binding-android-arm64": {
+ "version": "1.0.0-beta.45",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.0-beta.45.tgz",
+ "integrity": "sha512-bfgKYhFiXJALeA/riil908+2vlyWGdwa7Ju5S+JgWZYdR4jtiPOGdM6WLfso1dojCh+4ZWeiTwPeV9IKQEX+4g==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/binding-darwin-arm64": {
+ "version": "1.0.0-beta.45",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.0-beta.45.tgz",
+ "integrity": "sha512-xjCv4CRVsSnnIxTuyH1RDJl5OEQ1c9JYOwfDAHddjJDxCw46ZX9q80+xq7Eok7KC4bRSZudMJllkvOKv0T9SeA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/binding-darwin-x64": {
+ "version": "1.0.0-beta.45",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.0-beta.45.tgz",
+ "integrity": "sha512-ddcO9TD3D/CLUa/l8GO8LHzBOaZqWg5ClMy3jICoxwCuoz47h9dtqPsIeTiB6yR501LQTeDsjA4lIFd7u3Ljfw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/binding-freebsd-x64": {
+ "version": "1.0.0-beta.45",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.0-beta.45.tgz",
+ "integrity": "sha512-MBTWdrzW9w+UMYDUvnEuh0pQvLENkl2Sis15fHTfHVW7ClbGuez+RWopZudIDEGkpZXdeI4CkRXk+vdIIebrmg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/binding-linux-arm-gnueabihf": {
+ "version": "1.0.0-beta.45",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.0-beta.45.tgz",
+ "integrity": "sha512-4YgoCFiki1HR6oSg+GxxfzfnVCesQxLF1LEnw9uXS/MpBmuog0EOO2rYfy69rWP4tFZL9IWp6KEfGZLrZ7aUog==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/binding-linux-arm64-gnu": {
+ "version": "1.0.0-beta.45",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.0-beta.45.tgz",
+ "integrity": "sha512-LE1gjAwQRrbCOorJJ7LFr10s5vqYf5a00V5Ea9wXcT2+56n5YosJkcp8eQ12FxRBv2YX8dsdQJb+ZTtYJwb6XQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/binding-linux-arm64-musl": {
+ "version": "1.0.0-beta.45",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.0-beta.45.tgz",
+ "integrity": "sha512-tdy8ThO/fPp40B81v0YK3QC+KODOmzJzSUOO37DinQxzlTJ026gqUSOM8tzlVixRbQJltgVDCTYF8HNPRErQTA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/binding-linux-x64-gnu": {
+ "version": "1.0.0-beta.45",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.0-beta.45.tgz",
+ "integrity": "sha512-lS082ROBWdmOyVY/0YB3JmsiClaWoxvC+dA8/rbhyB9VLkvVEaihLEOr4CYmrMse151C4+S6hCw6oa1iewox7g==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/binding-linux-x64-musl": {
+ "version": "1.0.0-beta.45",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.0-beta.45.tgz",
+ "integrity": "sha512-Hi73aYY0cBkr1/SvNQqH8Cd+rSV6S9RB5izCv0ySBcRnd/Wfn5plguUoGYwBnhHgFbh6cPw9m2dUVBR6BG1gxA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/binding-openharmony-arm64": {
+ "version": "1.0.0-beta.45",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.0-beta.45.tgz",
+ "integrity": "sha512-fljEqbO7RHHogNDxYtTzr+GNjlfOx21RUyGmF+NrkebZ8emYYiIqzPxsaMZuRx0rgZmVmliOzEp86/CQFDKhJQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openharmony"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/binding-wasm32-wasi": {
+ "version": "1.0.0-beta.45",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.0-beta.45.tgz",
+ "integrity": "sha512-ZJDB7lkuZE9XUnWQSYrBObZxczut+8FZ5pdanm8nNS1DAo8zsrPuvGwn+U3fwU98WaiFsNrA4XHngesCGr8tEQ==",
+ "cpu": [
+ "wasm32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "@napi-rs/wasm-runtime": "^1.0.7"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/@rolldown/binding-wasm32-wasi/node_modules/@emnapi/core": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.7.0.tgz",
+ "integrity": "sha512-pJdKGq/1iquWYtv1RRSljZklxHCOCAJFJrImO5ZLKPJVJlVUcs8yFwNQlqS0Lo8xT1VAXXTCZocF9n26FWEKsw==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "@emnapi/wasi-threads": "1.1.0",
+ "tslib": "^2.4.0"
+ }
+ },
+ "node_modules/@rolldown/binding-wasm32-wasi/node_modules/@emnapi/runtime": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.7.0.tgz",
+ "integrity": "sha512-oAYoQnCYaQZKVS53Fq23ceWMRxq5EhQsE0x0RdQ55jT7wagMu5k+fS39v1fiSLrtrLQlXwVINenqhLMtTrV/1Q==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "tslib": "^2.4.0"
+ }
+ },
+ "node_modules/@rolldown/binding-wasm32-wasi/node_modules/@emnapi/wasi-threads": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.1.0.tgz",
+ "integrity": "sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "tslib": "^2.4.0"
+ }
+ },
+ "node_modules/@rolldown/binding-wasm32-wasi/node_modules/@napi-rs/wasm-runtime": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.0.7.tgz",
+ "integrity": "sha512-SeDnOO0Tk7Okiq6DbXmmBODgOAb9dp9gjlphokTUxmt8U3liIP1ZsozBahH69j/RJv+Rfs6IwUKHTgQYJ/HBAw==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "@emnapi/core": "^1.5.0",
+ "@emnapi/runtime": "^1.5.0",
+ "@tybys/wasm-util": "^0.10.1"
+ }
+ },
+ "node_modules/@rolldown/binding-wasm32-wasi/node_modules/@tybys/wasm-util": {
+ "version": "0.10.1",
+ "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.1.tgz",
+ "integrity": "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "tslib": "^2.4.0"
+ }
+ },
+ "node_modules/@rolldown/binding-win32-arm64-msvc": {
+ "version": "1.0.0-beta.45",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.0-beta.45.tgz",
+ "integrity": "sha512-zyzAjItHPUmxg6Z8SyRhLdXlJn3/D9KL5b9mObUrBHhWS/GwRH4665xCiFqeuktAhhWutqfc+rOV2LjK4VYQGQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/binding-win32-ia32-msvc": {
+ "version": "1.0.0-beta.45",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-ia32-msvc/-/binding-win32-ia32-msvc-1.0.0-beta.45.tgz",
+ "integrity": "sha512-wODcGzlfxqS6D7BR0srkJk3drPwXYLu7jPHN27ce2c4PUnVVmJnp9mJzUQGT4LpmHmmVdMZ+P6hKvyTGBzc1CA==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/binding-win32-x64-msvc": {
+ "version": "1.0.0-beta.45",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.0-beta.45.tgz",
+ "integrity": "sha512-wiU40G1nQo9rtfvF9jLbl79lUgjfaD/LTyUEw2Wg/gdF5OhjzpKMVugZQngO+RNdwYaNj+Fs+kWBWfp4VXPMHA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
"node_modules/@rolldown/pluginutils": {
"version": "1.0.0-beta.32",
"resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.32.tgz",
@@ -11646,6 +11967,30 @@
"node": "*"
}
},
+ "node_modules/ast-kit": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/ast-kit/-/ast-kit-2.2.0.tgz",
+ "integrity": "sha512-m1Q/RaVOnTp9JxPX+F+Zn7IcLYMzM8kZofDImfsKZd8MbR+ikdOzTeztStWqfrqIxZnYWryyI9ePm3NGjnZgGw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/parser": "^7.28.5",
+ "pathe": "^2.0.3"
+ },
+ "engines": {
+ "node": ">=20.19.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sxzz"
+ }
+ },
+ "node_modules/ast-kit/node_modules/pathe": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz",
+ "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/ast-types": {
"version": "0.13.4",
"resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.13.4.tgz",
@@ -12343,6 +12688,16 @@
"node": ">=6"
}
},
+ "node_modules/birpc": {
+ "version": "2.8.0",
+ "resolved": "https://registry.npmjs.org/birpc/-/birpc-2.8.0.tgz",
+ "integrity": "sha512-Bz2a4qD/5GRhiHSwj30c/8kC8QGj12nNDwz3D4ErQ4Xhy35dsSDvF+RA/tWpjyU0pdGtSDiEk6B5fBGE1qNVhw==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ }
+ },
"node_modules/bl": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
@@ -12827,6 +13182,22 @@
"node": "*"
}
},
+ "node_modules/chokidar": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz",
+ "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "readdirp": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 14.16.0"
+ },
+ "funding": {
+ "url": "https://paulmillr.com/funding/"
+ }
+ },
"node_modules/chrome-launcher": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/chrome-launcher/-/chrome-launcher-1.1.2.tgz",
@@ -14781,6 +15152,13 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/defu": {
+ "version": "6.1.4",
+ "resolved": "https://registry.npmjs.org/defu/-/defu-6.1.4.tgz",
+ "integrity": "sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/degenerator": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/degenerator/-/degenerator-5.0.1.tgz",
@@ -14895,6 +15273,16 @@
"resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1312386.tgz",
"integrity": "sha512-DPnhUXvmvKT2dFA/j7B+riVLUt9Q6RKJlcppojL5CoRywJJKLDYnRlw0gTFKfgDPHP5E04UoB71SxoJlVZy8FA=="
},
+ "node_modules/diff": {
+ "version": "8.0.2",
+ "resolved": "https://registry.npmjs.org/diff/-/diff-8.0.2.tgz",
+ "integrity": "sha512-sSuxWU5j5SR9QQji/o2qMvqRNYRDOcBTgsJ/DeCf4iSN4gW+gNMXM7wFIP+fdXZxoNiAnHUTGjCr+TSWXdRDKg==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.3.1"
+ }
+ },
"node_modules/diff-sequences": {
"version": "29.6.3",
"resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz",
@@ -15024,6 +15412,27 @@
"url": "https://dotenvx.com"
}
},
+ "node_modules/dts-resolver": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/dts-resolver/-/dts-resolver-2.1.3.tgz",
+ "integrity": "sha512-bihc7jPC90VrosXNzK0LTE2cuLP6jr0Ro8jk+kMugHReJVLIpHz/xadeq3MhuwyO4TD4OA3L1Q8pBBFRc08Tsw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=20.19.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sxzz"
+ },
+ "peerDependencies": {
+ "oxc-resolver": ">=11.0.0"
+ },
+ "peerDependenciesMeta": {
+ "oxc-resolver": {
+ "optional": true
+ }
+ }
+ },
"node_modules/dunder-proto": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.0.tgz",
@@ -15150,6 +15559,16 @@
"node": ">= 4"
}
},
+ "node_modules/empathic": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/empathic/-/empathic-2.0.0.tgz",
+ "integrity": "sha512-i6UzDscO/XfAcNYD75CfICkmfLedpyPDdozrLMmQc5ORaQcdMoc21OnlEylMIqI7U8eniKrPMxxtj8k0vhmJhA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=14"
+ }
+ },
"node_modules/encodeurl": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz",
@@ -17936,10 +18355,11 @@
}
},
"node_modules/get-tsconfig": {
- "version": "4.8.1",
- "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.8.1.tgz",
- "integrity": "sha512-k9PN+cFBmaLWtVz29SkUoqU5O0slLuHJXt/2P+tMVFT+phsSGXGkp9t3rQIqdz0e+06EHNGs3oM6ZX1s2zHxRg==",
+ "version": "4.13.0",
+ "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.13.0.tgz",
+ "integrity": "sha512-1VKTZJCwBrvbd+Wn3AOgQP/2Av+TfTCOlE4AcRJE72W1ksZXbAx8PPBR9RzgTeSPzlPMHrbANMH3LbltH73wxQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"resolve-pkg-maps": "^1.0.0"
},
@@ -18420,6 +18840,13 @@
"node": ">=0.10.0"
}
},
+ "node_modules/hookable": {
+ "version": "5.5.3",
+ "resolved": "https://registry.npmjs.org/hookable/-/hookable-5.5.3.tgz",
+ "integrity": "sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/hosted-git-info": {
"version": "7.0.2",
"resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-7.0.2.tgz",
@@ -23063,12 +23490,13 @@
}
},
"node_modules/magic-string": {
- "version": "0.30.11",
- "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.11.tgz",
- "integrity": "sha512-+Wri9p0QHMy+545hKww7YAu5NyzF8iomPL/RQazugQ9+Ez4Ic3mERMd8ZTX5rfK944j+560ZJi8iAwgak1Ac7A==",
+ "version": "0.30.21",
+ "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz",
+ "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "@jridgewell/sourcemap-codec": "^1.5.0"
+ "@jridgewell/sourcemap-codec": "^1.5.5"
}
},
"node_modules/magicast": {
@@ -26115,6 +26543,23 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/quansync": {
+ "version": "0.2.11",
+ "resolved": "https://registry.npmjs.org/quansync/-/quansync-0.2.11.tgz",
+ "integrity": "sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://github.com/sponsors/antfu"
+ },
+ {
+ "type": "individual",
+ "url": "https://github.com/sponsors/sxzz"
+ }
+ ],
+ "license": "MIT"
+ },
"node_modules/query-registry": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/query-registry/-/query-registry-3.0.1.tgz",
@@ -26449,6 +26894,20 @@
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
"dev": true
},
+ "node_modules/readdirp": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz",
+ "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 14.18.0"
+ },
+ "funding": {
+ "type": "individual",
+ "url": "https://paulmillr.com/funding/"
+ }
+ },
"node_modules/real-require": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/real-require/-/real-require-0.2.0.tgz",
@@ -26783,6 +27242,116 @@
"node": ">=10.0.0"
}
},
+ "node_modules/rolldown": {
+ "version": "1.0.0-beta.45",
+ "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.0-beta.45.tgz",
+ "integrity": "sha512-iMmuD72XXLf26Tqrv1cryNYLX6NNPLhZ3AmNkSf8+xda0H+yijjGJ+wVT9UdBUHOpKzq9RjKtQKRCWoEKQQBZQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@oxc-project/types": "=0.95.0",
+ "@rolldown/pluginutils": "1.0.0-beta.45"
+ },
+ "bin": {
+ "rolldown": "bin/cli.mjs"
+ },
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ },
+ "optionalDependencies": {
+ "@rolldown/binding-android-arm64": "1.0.0-beta.45",
+ "@rolldown/binding-darwin-arm64": "1.0.0-beta.45",
+ "@rolldown/binding-darwin-x64": "1.0.0-beta.45",
+ "@rolldown/binding-freebsd-x64": "1.0.0-beta.45",
+ "@rolldown/binding-linux-arm-gnueabihf": "1.0.0-beta.45",
+ "@rolldown/binding-linux-arm64-gnu": "1.0.0-beta.45",
+ "@rolldown/binding-linux-arm64-musl": "1.0.0-beta.45",
+ "@rolldown/binding-linux-x64-gnu": "1.0.0-beta.45",
+ "@rolldown/binding-linux-x64-musl": "1.0.0-beta.45",
+ "@rolldown/binding-openharmony-arm64": "1.0.0-beta.45",
+ "@rolldown/binding-wasm32-wasi": "1.0.0-beta.45",
+ "@rolldown/binding-win32-arm64-msvc": "1.0.0-beta.45",
+ "@rolldown/binding-win32-ia32-msvc": "1.0.0-beta.45",
+ "@rolldown/binding-win32-x64-msvc": "1.0.0-beta.45"
+ }
+ },
+ "node_modules/rolldown-plugin-dts": {
+ "version": "0.17.4",
+ "resolved": "https://registry.npmjs.org/rolldown-plugin-dts/-/rolldown-plugin-dts-0.17.4.tgz",
+ "integrity": "sha512-eWno7CR/Da2jA+5mTHxeMx78p4AmoUocEKDQT8XKwhq9Oroyf67ZfBOE82d4EvDjktiQTePpKdIKc69pND88Og==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/generator": "^7.28.5",
+ "@babel/parser": "^7.28.5",
+ "@babel/types": "^7.28.5",
+ "ast-kit": "^2.2.0",
+ "birpc": "^2.7.0",
+ "debug": "^4.4.3",
+ "dts-resolver": "^2.1.2",
+ "get-tsconfig": "^4.13.0",
+ "magic-string": "^0.30.21"
+ },
+ "engines": {
+ "node": ">=20.18.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sxzz"
+ },
+ "peerDependencies": {
+ "@ts-macro/tsc": "^0.3.6",
+ "@typescript/native-preview": ">=7.0.0-dev.20250601.1",
+ "rolldown": "^1.0.0-beta.44",
+ "typescript": "^5.0.0",
+ "vue-tsc": "~3.1.0"
+ },
+ "peerDependenciesMeta": {
+ "@ts-macro/tsc": {
+ "optional": true
+ },
+ "@typescript/native-preview": {
+ "optional": true
+ },
+ "typescript": {
+ "optional": true
+ },
+ "vue-tsc": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/rolldown-plugin-dts/node_modules/debug": {
+ "version": "4.4.3",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
+ "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/rolldown-plugin-dts/node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/rolldown/node_modules/@rolldown/pluginutils": {
+ "version": "1.0.0-beta.45",
+ "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.45.tgz",
+ "integrity": "sha512-Le9ulGCrD8ggInzWw/k2J8QcbPz7eGIOWqfJ2L+1R0Opm7n6J37s2hiDWlh6LJN0Lk9L5sUzMvRHKW7UxBZsQA==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/rollup": {
"version": "4.48.0",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.48.0.tgz",
@@ -28819,13 +29388,13 @@
"dev": true
},
"node_modules/tinyglobby": {
- "version": "0.2.14",
- "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.14.tgz",
- "integrity": "sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==",
+ "version": "0.2.15",
+ "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz",
+ "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==",
"license": "MIT",
"dependencies": {
- "fdir": "^6.4.4",
- "picomatch": "^4.0.2"
+ "fdir": "^6.5.0",
+ "picomatch": "^4.0.3"
},
"engines": {
"node": ">=12.0.0"
@@ -29236,6 +29805,124 @@
"node": ">=4"
}
},
+ "node_modules/tsdown": {
+ "version": "0.15.12",
+ "resolved": "https://registry.npmjs.org/tsdown/-/tsdown-0.15.12.tgz",
+ "integrity": "sha512-c8VLlQm8/lFrOAg5VMVeN4NAbejZyVQkzd+ErjuaQgJFI/9MhR9ivr0H/CM7UlOF1+ELlF6YaI7sU/4itgGQ8w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansis": "^4.2.0",
+ "cac": "^6.7.14",
+ "chokidar": "^4.0.3",
+ "debug": "^4.4.3",
+ "diff": "^8.0.2",
+ "empathic": "^2.0.0",
+ "hookable": "^5.5.3",
+ "rolldown": "1.0.0-beta.45",
+ "rolldown-plugin-dts": "^0.17.2",
+ "semver": "^7.7.3",
+ "tinyexec": "^1.0.1",
+ "tinyglobby": "^0.2.15",
+ "tree-kill": "^1.2.2",
+ "unconfig": "^7.3.3"
+ },
+ "bin": {
+ "tsdown": "dist/run.mjs"
+ },
+ "engines": {
+ "node": ">=20.19.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sxzz"
+ },
+ "peerDependencies": {
+ "@arethetypeswrong/core": "^0.18.1",
+ "publint": "^0.3.0",
+ "typescript": "^5.0.0",
+ "unplugin-lightningcss": "^0.4.0",
+ "unplugin-unused": "^0.5.0",
+ "unrun": "^0.2.1"
+ },
+ "peerDependenciesMeta": {
+ "@arethetypeswrong/core": {
+ "optional": true
+ },
+ "publint": {
+ "optional": true
+ },
+ "typescript": {
+ "optional": true
+ },
+ "unplugin-lightningcss": {
+ "optional": true
+ },
+ "unplugin-unused": {
+ "optional": true
+ },
+ "unrun": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/tsdown/node_modules/ansis": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/ansis/-/ansis-4.2.0.tgz",
+ "integrity": "sha512-HqZ5rWlFjGiV0tDm3UxxgNRqsOTniqoKZu0pIAfh7TZQMGuZK+hH0drySty0si0QXj1ieop4+SkSfPZBPPkHig==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": ">=14"
+ }
+ },
+ "node_modules/tsdown/node_modules/debug": {
+ "version": "4.4.3",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
+ "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/tsdown/node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/tsdown/node_modules/semver": {
+ "version": "7.7.3",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz",
+ "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/tsdown/node_modules/tinyexec": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.0.2.tgz",
+ "integrity": "sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ }
+ },
"node_modules/tslib": {
"version": "2.8.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
@@ -29657,6 +30344,47 @@
"through": "^2.3.8"
}
},
+ "node_modules/unconfig": {
+ "version": "7.4.0",
+ "resolved": "https://registry.npmjs.org/unconfig/-/unconfig-7.4.0.tgz",
+ "integrity": "sha512-KM0SrvIvwQXJnbiSzur1Y+5jHSLVPhS31H5qzgjDQxGqS3PWrH6X7TxYX/JTuTlItarHkZ9ePK9t01Q6wu1c4Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@quansync/fs": "^0.1.5",
+ "defu": "^6.1.4",
+ "jiti": "^2.6.1",
+ "quansync": "^0.2.11",
+ "unconfig-core": "7.4.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ }
+ },
+ "node_modules/unconfig-core": {
+ "version": "7.4.0",
+ "resolved": "https://registry.npmjs.org/unconfig-core/-/unconfig-core-7.4.0.tgz",
+ "integrity": "sha512-3ew7rvES5x2LCZ/QRKV3nQQpq7eFYuszQuvZrhTHxDPKc34QFjRXI17XGiZI+WQTVIXKYeBti4v3LS39NWmhmg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@quansync/fs": "^0.1.5",
+ "quansync": "^0.2.11"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ }
+ },
+ "node_modules/unconfig/node_modules/jiti": {
+ "version": "2.6.1",
+ "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.6.1.tgz",
+ "integrity": "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "jiti": "lib/jiti-cli.mjs"
+ }
+ },
"node_modules/undici": {
"version": "6.21.3",
"resolved": "https://registry.npmjs.org/undici/-/undici-6.21.3.tgz",
diff --git a/package.json b/package.json
index a5fec600c..661420015 100644
--- a/package.json
+++ b/package.json
@@ -114,6 +114,7 @@
"react-dom": "18.3.1",
"ts-patch": "^3.3.0",
"tsconfig-paths": "^4.2.0",
+ "tsdown": "^0.15.1",
"tsx": "^4.19.0",
"type-fest": "^4.26.1",
"typescript": "5.7.3",
@@ -164,5 +165,35 @@
"commitizen": {
"path": "@commitlint/cz-commitlint"
}
+ },
+ "main": "./packages/plugin-typescript/dist/src/index.cjs",
+ "module": "./packages/plugin-typescript/dist/src/index.mjs",
+ "types": "./packages/plugin-typescript/dist/src/index.d.cts",
+ "exports": {
+ "./lib/extend/jest-extended.matcher": {
+ "import": "./testing/test-setup/dist/src/lib/extend/jest-extended.matcher.mjs",
+ "require": "./testing/test-setup/dist/src/lib/extend/jest-extended.matcher.cjs"
+ },
+ "./lib/extend/markdown-table.matcher": {
+ "import": "./testing/test-setup/dist/src/lib/extend/markdown-table.matcher.mjs",
+ "require": "./testing/test-setup/dist/src/lib/extend/markdown-table.matcher.cjs"
+ },
+ "./lib/extend/path.matcher": {
+ "import": "./testing/test-setup/dist/src/lib/extend/path.matcher.mjs",
+ "require": "./testing/test-setup/dist/src/lib/extend/path.matcher.cjs"
+ },
+ "./lib/extend/ui-logger.matcher": {
+ "import": "./testing/test-setup/dist/src/lib/extend/ui-logger.matcher.mjs",
+ "require": "./testing/test-setup/dist/src/lib/extend/ui-logger.matcher.cjs"
+ },
+ "./lib/extend/ui-logger.matcher.utils": {
+ "import": "./testing/test-setup/dist/src/lib/extend/ui-logger.matcher.utils.mjs",
+ "require": "./testing/test-setup/dist/src/lib/extend/ui-logger.matcher.utils.cjs"
+ },
+ "./lib/reset.mocks": {
+ "import": "./testing/test-setup/dist/src/lib/reset.mocks.mjs",
+ "require": "./testing/test-setup/dist/src/lib/reset.mocks.cjs"
+ },
+ "./package.json": "./package.json"
}
}
diff --git a/packages/ci/eslint.config.js b/packages/ci/eslint.config.js
index 13888c2a8..3270b7608 100644
--- a/packages/ci/eslint.config.js
+++ b/packages/ci/eslint.config.js
@@ -17,7 +17,12 @@ export default tseslint.config(
rules: {
'@nx/dependency-checks': [
'error',
- { ignoredDependencies: ['type-fest'] }, // only for internal typings
+ {
+ ignoredDependencies: [
+ 'type-fest', // only for internal typings
+ 'tsdown',
+ ],
+ },
],
},
},
diff --git a/packages/ci/tsdown.config.ts b/packages/ci/tsdown.config.ts
new file mode 100644
index 000000000..d8c536f13
--- /dev/null
+++ b/packages/ci/tsdown.config.ts
@@ -0,0 +1,9 @@
+import { defineConfig } from 'tsdown';
+import { baseConfig, getExternalDependencies } from '../../tsdown.base';
+
+const __dirname = import.meta.dirname;
+
+export default defineConfig(async () => ({
+ ...baseConfig({ projectRoot: __dirname }),
+ external: await getExternalDependencies(__dirname),
+}));
diff --git a/packages/cli/src/index.ts b/packages/cli/src/index.ts
index e55c1b364..8bd934cd5 100755
--- a/packages/cli/src/index.ts
+++ b/packages/cli/src/index.ts
@@ -6,8 +6,11 @@ import { cli } from './lib/cli.js';
import './lib/polyfills.js';
// bootstrap Yargs, parse arguments and execute command
-await cli(hideBin(process.argv)).argv;
+// eslint-disable-next-line unicorn/prefer-top-level-await
+(async () => {
+ await cli(hideBin(process.argv)).argv;
-// we need to explicitly exit with successful code otherwise we risk hanging process in certain situations
-// eslint-disable-next-line n/no-process-exit
-process.exit(0);
+ // we need to explicitly exit with successful code otherwise we risk hanging process in certain situations
+ // eslint-disable-next-line n/no-process-exit
+ process.exit(0);
+})();
diff --git a/packages/cli/tsdown.config.ts b/packages/cli/tsdown.config.ts
new file mode 100644
index 000000000..d8c536f13
--- /dev/null
+++ b/packages/cli/tsdown.config.ts
@@ -0,0 +1,9 @@
+import { defineConfig } from 'tsdown';
+import { baseConfig, getExternalDependencies } from '../../tsdown.base';
+
+const __dirname = import.meta.dirname;
+
+export default defineConfig(async () => ({
+ ...baseConfig({ projectRoot: __dirname }),
+ external: await getExternalDependencies(__dirname),
+}));
diff --git a/packages/core/tsdown.config.ts b/packages/core/tsdown.config.ts
new file mode 100644
index 000000000..d8c536f13
--- /dev/null
+++ b/packages/core/tsdown.config.ts
@@ -0,0 +1,9 @@
+import { defineConfig } from 'tsdown';
+import { baseConfig, getExternalDependencies } from '../../tsdown.base';
+
+const __dirname = import.meta.dirname;
+
+export default defineConfig(async () => ({
+ ...baseConfig({ projectRoot: __dirname }),
+ external: await getExternalDependencies(__dirname),
+}));
diff --git a/packages/create-cli/eslint.config.js b/packages/create-cli/eslint.config.js
index 22fda2e40..14410a0d8 100644
--- a/packages/create-cli/eslint.config.js
+++ b/packages/create-cli/eslint.config.js
@@ -17,7 +17,12 @@ export default tseslint.config(
rules: {
'@nx/dependency-checks': [
'error',
- { ignoredDependencies: ['@code-pushup/nx-plugin'] }, // nx-plugin is run via CLI
+ {
+ ignoredDependencies: [
+ '@code-pushup/nx-plugin', // nx-plugin is run via CLI
+ 'tsdown',
+ ],
+ },
],
},
},
diff --git a/packages/create-cli/src/index.ts b/packages/create-cli/src/index.ts
index 221a00a2a..ecbb0e510 100755
--- a/packages/create-cli/src/index.ts
+++ b/packages/create-cli/src/index.ts
@@ -1,4 +1,7 @@
#! /usr/bin/env node
import { initCodePushup } from './lib/init.js';
-await initCodePushup();
+// eslint-disable-next-line unicorn/prefer-top-level-await
+(async () => {
+ await initCodePushup();
+})();
diff --git a/packages/create-cli/tsdown.config.ts b/packages/create-cli/tsdown.config.ts
new file mode 100644
index 000000000..d8c536f13
--- /dev/null
+++ b/packages/create-cli/tsdown.config.ts
@@ -0,0 +1,9 @@
+import { defineConfig } from 'tsdown';
+import { baseConfig, getExternalDependencies } from '../../tsdown.base';
+
+const __dirname = import.meta.dirname;
+
+export default defineConfig(async () => ({
+ ...baseConfig({ projectRoot: __dirname }),
+ external: await getExternalDependencies(__dirname),
+}));
diff --git a/packages/models/transformers/tsdown.config.ts b/packages/models/transformers/tsdown.config.ts
new file mode 100644
index 000000000..6d3a52b4f
--- /dev/null
+++ b/packages/models/transformers/tsdown.config.ts
@@ -0,0 +1,10 @@
+import { defineConfig } from 'tsdown';
+import { baseConfig, getExternalDependencies } from '../../../tsdown.base';
+
+const __dirname = import.meta.dirname;
+
+export default defineConfig(async () => ({
+ ...baseConfig({ projectRoot: __dirname }),
+ external: await getExternalDependencies(__dirname),
+ copy: [],
+}));
diff --git a/packages/models/tsconfig.lib.json b/packages/models/tsconfig.lib.json
index 2c92983e0..60df65b5d 100644
--- a/packages/models/tsconfig.lib.json
+++ b/packages/models/tsconfig.lib.json
@@ -16,6 +16,7 @@
"vitest.unit.config.ts",
"vitest.int.config.ts",
"code-pushup.config.ts",
+ "tsdown.config.ts",
"zod2md.config.ts",
"src/**/*.test.ts",
"src/**/*.mock.ts",
diff --git a/packages/models/tsdown.config.ts b/packages/models/tsdown.config.ts
new file mode 100644
index 000000000..003de7e15
--- /dev/null
+++ b/packages/models/tsdown.config.ts
@@ -0,0 +1,19 @@
+import { defineConfig } from 'tsdown';
+import { baseConfig, getExternalDependencies } from '../../tsdown.base';
+
+const __dirname = import.meta.dirname;
+
+export default defineConfig(async () => ({
+ ...baseConfig({ projectRoot: __dirname }),
+ external: await getExternalDependencies(__dirname),
+ copy: [
+ {
+ from: `${__dirname}/package.json`,
+ to: `${__dirname}/dist/package.json`,
+ },
+ {
+ from: `${__dirname}/README.md`,
+ to: `${__dirname}/dist/README.md`,
+ },
+ ],
+}));
diff --git a/packages/nx-plugin/tsdown.config.ts b/packages/nx-plugin/tsdown.config.ts
new file mode 100644
index 000000000..87ee494fd
--- /dev/null
+++ b/packages/nx-plugin/tsdown.config.ts
@@ -0,0 +1,75 @@
+import { copyFile, readFile, writeFile } from 'node:fs/promises';
+import { join } from 'node:path';
+import { defineConfig } from 'tsdown';
+import { baseConfig, getExternalDependencies } from '../../tsdown.base';
+
+const __dirname = import.meta.dirname;
+
+export default defineConfig(async () => {
+ const base = baseConfig({ projectRoot: __dirname });
+
+ // Remove generators.json and executors.json from copy array
+ // We'll handle them in onSuccess to update the .cjs references
+ const copyWithoutJsonFiles = ((base as any).copy || []).filter(
+ (item: any) =>
+ !item.to.endsWith('/generators.json') &&
+ !item.to.endsWith('/executors.json'),
+ );
+
+ return {
+ ...base,
+ format: ['cjs'], // NX supports only commonjs
+ external: await getExternalDependencies(__dirname),
+ copy: copyWithoutJsonFiles,
+ async onSuccess() {
+ // Call base onSuccess first
+ const baseOnSuccess = (base as any).onSuccess;
+ if (typeof baseOnSuccess === 'function') {
+ await baseOnSuccess();
+ }
+
+ // Copy and update generators.json
+ const generatorsJsonPath = join(__dirname, 'dist', 'generators.json');
+ await copyFile(join(__dirname, 'generators.json'), generatorsJsonPath);
+
+ const generatorsJson = JSON.parse(
+ await readFile(generatorsJsonPath, 'utf8'),
+ );
+
+ for (const generator of Object.values(generatorsJson.generators)) {
+ const gen = generator as { factory: string };
+ if (gen.factory && !gen.factory.endsWith('.cjs')) {
+ gen.factory = gen.factory.replace(/\.js$/, '') + '.cjs';
+ }
+ }
+
+ await writeFile(
+ generatorsJsonPath,
+ JSON.stringify(generatorsJson, null, 2) + '\n',
+ 'utf8',
+ );
+
+ // Copy and update executors.json
+ const executorsJsonPath = join(__dirname, 'dist', 'executors.json');
+ await copyFile(join(__dirname, 'executors.json'), executorsJsonPath);
+
+ const executorsJson = JSON.parse(
+ await readFile(executorsJsonPath, 'utf8'),
+ );
+
+ for (const executor of Object.values(executorsJson.executors)) {
+ const exec = executor as { implementation: string };
+ if (exec.implementation && !exec.implementation.endsWith('.cjs')) {
+ exec.implementation =
+ exec.implementation.replace(/\.js$/, '') + '.cjs';
+ }
+ }
+
+ await writeFile(
+ executorsJsonPath,
+ JSON.stringify(executorsJson, null, 2) + '\n',
+ 'utf8',
+ );
+ },
+ };
+});
diff --git a/packages/plugin-coverage/src/bin.ts b/packages/plugin-coverage/src/bin.ts
index fc625dd73..b05f672f0 100644
--- a/packages/plugin-coverage/src/bin.ts
+++ b/packages/plugin-coverage/src/bin.ts
@@ -4,4 +4,7 @@ import { executeRunner } from './lib/runner/index.js';
const { runnerConfigPath, runnerOutputPath } = Parser(process.argv);
-await executeRunner({ runnerConfigPath, runnerOutputPath });
+// eslint-disable-next-line unicorn/prefer-top-level-await
+(async () => {
+ await executeRunner({ runnerConfigPath, runnerOutputPath });
+})();
diff --git a/packages/plugin-coverage/src/lib/coverage-plugin.ts b/packages/plugin-coverage/src/lib/coverage-plugin.ts
index 93a94b4c6..2b8e235fe 100644
--- a/packages/plugin-coverage/src/lib/coverage-plugin.ts
+++ b/packages/plugin-coverage/src/lib/coverage-plugin.ts
@@ -63,7 +63,7 @@ export async function coveragePlugin(
const runnerScriptPath = path.join(
fileURLToPath(path.dirname(import.meta.url)),
'..',
- 'bin.js',
+ 'bin.mjs',
);
const packageJson = createRequire(import.meta.url)(
diff --git a/packages/plugin-coverage/tsdown.config.ts b/packages/plugin-coverage/tsdown.config.ts
new file mode 100644
index 000000000..d8c536f13
--- /dev/null
+++ b/packages/plugin-coverage/tsdown.config.ts
@@ -0,0 +1,9 @@
+import { defineConfig } from 'tsdown';
+import { baseConfig, getExternalDependencies } from '../../tsdown.base';
+
+const __dirname = import.meta.dirname;
+
+export default defineConfig(async () => ({
+ ...baseConfig({ projectRoot: __dirname }),
+ external: await getExternalDependencies(__dirname),
+}));
diff --git a/packages/plugin-eslint/tsdown.config.ts b/packages/plugin-eslint/tsdown.config.ts
new file mode 100644
index 000000000..d8c536f13
--- /dev/null
+++ b/packages/plugin-eslint/tsdown.config.ts
@@ -0,0 +1,9 @@
+import { defineConfig } from 'tsdown';
+import { baseConfig, getExternalDependencies } from '../../tsdown.base';
+
+const __dirname = import.meta.dirname;
+
+export default defineConfig(async () => ({
+ ...baseConfig({ projectRoot: __dirname }),
+ external: await getExternalDependencies(__dirname),
+}));
diff --git a/packages/plugin-js-packages/src/bin.ts b/packages/plugin-js-packages/src/bin.ts
index fc625dd73..b05f672f0 100644
--- a/packages/plugin-js-packages/src/bin.ts
+++ b/packages/plugin-js-packages/src/bin.ts
@@ -4,4 +4,7 @@ import { executeRunner } from './lib/runner/index.js';
const { runnerConfigPath, runnerOutputPath } = Parser(process.argv);
-await executeRunner({ runnerConfigPath, runnerOutputPath });
+// eslint-disable-next-line unicorn/prefer-top-level-await
+(async () => {
+ await executeRunner({ runnerConfigPath, runnerOutputPath });
+})();
diff --git a/packages/plugin-js-packages/src/lib/js-packages-plugin.ts b/packages/plugin-js-packages/src/lib/js-packages-plugin.ts
index 8fe2491cd..c851446a4 100644
--- a/packages/plugin-js-packages/src/lib/js-packages-plugin.ts
+++ b/packages/plugin-js-packages/src/lib/js-packages-plugin.ts
@@ -45,7 +45,7 @@ export async function jsPackagesPlugin(
const runnerScriptPath = path.join(
fileURLToPath(path.dirname(import.meta.url)),
'..',
- 'bin.js',
+ 'bin.mjs',
);
const packageJson = createRequire(import.meta.url)(
diff --git a/packages/plugin-js-packages/tsdown.config.ts b/packages/plugin-js-packages/tsdown.config.ts
new file mode 100644
index 000000000..d8c536f13
--- /dev/null
+++ b/packages/plugin-js-packages/tsdown.config.ts
@@ -0,0 +1,9 @@
+import { defineConfig } from 'tsdown';
+import { baseConfig, getExternalDependencies } from '../../tsdown.base';
+
+const __dirname = import.meta.dirname;
+
+export default defineConfig(async () => ({
+ ...baseConfig({ projectRoot: __dirname }),
+ external: await getExternalDependencies(__dirname),
+}));
diff --git a/packages/plugin-jsdocs/tsdown.config.ts b/packages/plugin-jsdocs/tsdown.config.ts
new file mode 100644
index 000000000..d8c536f13
--- /dev/null
+++ b/packages/plugin-jsdocs/tsdown.config.ts
@@ -0,0 +1,9 @@
+import { defineConfig } from 'tsdown';
+import { baseConfig, getExternalDependencies } from '../../tsdown.base';
+
+const __dirname = import.meta.dirname;
+
+export default defineConfig(async () => ({
+ ...baseConfig({ projectRoot: __dirname }),
+ external: await getExternalDependencies(__dirname),
+}));
diff --git a/packages/plugin-lighthouse/src/lib/runner/constants.ts b/packages/plugin-lighthouse/src/lib/runner/constants.ts
index e57a7ef55..9af6e6ea2 100644
--- a/packages/plugin-lighthouse/src/lib/runner/constants.ts
+++ b/packages/plugin-lighthouse/src/lib/runner/constants.ts
@@ -11,12 +11,12 @@ import { DEFAULT_CHROME_FLAGS, LIGHTHOUSE_OUTPUT_PATH } from '../constants.js';
const { audits, categories } = defaultConfig;
-// internal intermediate variable to derive the relevant audits
+export const PLUGIN_SLUG = 'lighthouse';
+
const allRawLighthouseAudits = await Promise.all(
(audits ?? []).map(loadLighthouseAudit),
);
-export const PLUGIN_SLUG = 'lighthouse';
export const LIGHTHOUSE_NAVIGATION_AUDITS: Audit[] = allRawLighthouseAudits
// This plugin only supports the "navigation" mode of Lighthouse in the current implementation
// If we don't exclude other audits we throw in the plugin output validation as some of the provided audits are not included in `lighthouse-report.json`
@@ -35,6 +35,7 @@ export const LIGHTHOUSE_NAVIGATION_AUDITS: Audit[] = allRawLighthouseAudits
const navigationAuditSlugs = new Set(
LIGHTHOUSE_NAVIGATION_AUDITS.map(({ slug }) => slug),
);
+
export const LIGHTHOUSE_GROUPS: Group[] = Object.entries(categories ?? {}).map(
([id, category]) => ({
slug: id,
diff --git a/packages/plugin-lighthouse/tsdown.config.ts b/packages/plugin-lighthouse/tsdown.config.ts
new file mode 100644
index 000000000..e172e8fb6
--- /dev/null
+++ b/packages/plugin-lighthouse/tsdown.config.ts
@@ -0,0 +1,11 @@
+import { defineConfig } from 'tsdown';
+import { baseConfig, getExternalDependencies } from '../../tsdown.base';
+
+const __dirname = import.meta.dirname;
+
+export default defineConfig(async () => ({
+ ...baseConfig({ projectRoot: __dirname }),
+ // Override format to ESM only - this package uses top-level await in constants.ts
+ format: ['esm'],
+ external: await getExternalDependencies(__dirname),
+}));
diff --git a/packages/plugin-typescript/tsdown.config.ts b/packages/plugin-typescript/tsdown.config.ts
new file mode 100644
index 000000000..d8c536f13
--- /dev/null
+++ b/packages/plugin-typescript/tsdown.config.ts
@@ -0,0 +1,9 @@
+import { defineConfig } from 'tsdown';
+import { baseConfig, getExternalDependencies } from '../../tsdown.base';
+
+const __dirname = import.meta.dirname;
+
+export default defineConfig(async () => ({
+ ...baseConfig({ projectRoot: __dirname }),
+ external: await getExternalDependencies(__dirname),
+}));
diff --git a/packages/utils/eslint.config.js b/packages/utils/eslint.config.js
index 1ad01224a..0b1a1d6bf 100644
--- a/packages/utils/eslint.config.js
+++ b/packages/utils/eslint.config.js
@@ -17,7 +17,12 @@ export default tseslint.config(
rules: {
'@nx/dependency-checks': [
'error',
- { ignoredDependencies: ['esbuild'] }, // esbuild is a peer dependency of bundle-require
+ {
+ ignoredDependencies: [
+ 'esbuild', // esbuild is a peer dependency of bundle-require
+ 'tsdown',
+ ],
+ },
],
},
},
diff --git a/packages/utils/tsdown.config.ts b/packages/utils/tsdown.config.ts
new file mode 100644
index 000000000..f7cae589e
--- /dev/null
+++ b/packages/utils/tsdown.config.ts
@@ -0,0 +1,12 @@
+import { type ExportsOptions, defineConfig } from 'tsdown';
+import { baseConfig, getExternalDependencies } from '../../tsdown.base';
+
+const __dirname = import.meta.dirname;
+
+export default defineConfig(async () => ({
+ ...baseConfig({ projectRoot: __dirname }),
+ external: await getExternalDependencies(__dirname),
+ exports: {
+ all: true,
+ },
+}));
diff --git a/testing/test-nx-utils/tsdown.config.ts b/testing/test-nx-utils/tsdown.config.ts
new file mode 100644
index 000000000..bc504b43b
--- /dev/null
+++ b/testing/test-nx-utils/tsdown.config.ts
@@ -0,0 +1,16 @@
+import { defineConfig } from 'tsdown';
+import { baseConfig, getExternalDependencies } from '../../tsdown.base';
+
+const __dirname = import.meta.dirname;
+
+export default defineConfig(async () => ({
+ ...baseConfig({ projectRoot: __dirname }),
+ external: [
+ ...(await getExternalDependencies(__dirname)),
+ '@nx/devkit',
+ '@nx/js',
+ 'nx',
+ '@code-pushup/utils',
+ ],
+ copy: [],
+}));
diff --git a/testing/test-setup-config/package.json b/testing/test-setup-config/package.json
new file mode 100644
index 000000000..0e2d4d5fa
--- /dev/null
+++ b/testing/test-setup-config/package.json
@@ -0,0 +1,4 @@
+{
+ "name": "@code-pushup/test-setup-config",
+ "type": "module"
+}
diff --git a/testing/test-setup-config/tsdown.config.ts b/testing/test-setup-config/tsdown.config.ts
new file mode 100644
index 000000000..42f80b7bc
--- /dev/null
+++ b/testing/test-setup-config/tsdown.config.ts
@@ -0,0 +1,10 @@
+import { defineConfig } from 'tsdown';
+import { baseConfig, getExternalDependencies } from '../../tsdown.base';
+
+const __dirname = import.meta.dirname;
+
+export default defineConfig(async () => ({
+ ...baseConfig({ projectRoot: __dirname }),
+ external: [...(await getExternalDependencies(__dirname)), 'fsevents'],
+ copy: [],
+}));
diff --git a/testing/test-setup/tsdown.config.ts b/testing/test-setup/tsdown.config.ts
new file mode 100644
index 000000000..d0a57d026
--- /dev/null
+++ b/testing/test-setup/tsdown.config.ts
@@ -0,0 +1,10 @@
+import { defineConfig } from 'tsdown';
+import { baseConfig, getExternalDependencies } from '../../tsdown.base';
+
+const __dirname = import.meta.dirname;
+
+export default defineConfig(async () => ({
+ ...baseConfig({ projectRoot: __dirname }),
+ external: await getExternalDependencies(__dirname),
+ copy: [],
+}));
diff --git a/testing/test-utils/eslint.config.js b/testing/test-utils/eslint.config.js
index 2656b27cb..5b0e8e2f3 100644
--- a/testing/test-utils/eslint.config.js
+++ b/testing/test-utils/eslint.config.js
@@ -1,12 +1,33 @@
import tseslint from 'typescript-eslint';
import baseConfig from '../../eslint.config.js';
-export default tseslint.config(...baseConfig, {
- files: ['**/*.ts'],
- languageOptions: {
- parserOptions: {
- projectService: true,
- tsconfigRootDir: import.meta.dirname,
+export default tseslint.config(
+ ...baseConfig,
+ {
+ files: ['**/*.ts'],
+ languageOptions: {
+ parserOptions: {
+ projectService: true,
+ tsconfigRootDir: import.meta.dirname,
+ },
},
},
-});
+ {
+ files: ['**/*.json'],
+ rules: {
+ '@nx/dependency-checks': [
+ 'error',
+ {
+ ignoredDependencies: [
+ '@code-pushup/models',
+ 'simple-git',
+ 'vitest',
+ '@nx/devkit',
+ 'ansis',
+ 'tsdown',
+ ],
+ },
+ ],
+ },
+ },
+);
diff --git a/testing/test-utils/tsdown.config.ts b/testing/test-utils/tsdown.config.ts
new file mode 100644
index 000000000..d0a57d026
--- /dev/null
+++ b/testing/test-utils/tsdown.config.ts
@@ -0,0 +1,10 @@
+import { defineConfig } from 'tsdown';
+import { baseConfig, getExternalDependencies } from '../../tsdown.base';
+
+const __dirname = import.meta.dirname;
+
+export default defineConfig(async () => ({
+ ...baseConfig({ projectRoot: __dirname }),
+ external: await getExternalDependencies(__dirname),
+ copy: [],
+}));
diff --git a/tools/eslint-formatter-multi/eslint.config.js b/tools/eslint-formatter-multi/eslint.config.js
index 29bda515b..ac29358ba 100644
--- a/tools/eslint-formatter-multi/eslint.config.js
+++ b/tools/eslint-formatter-multi/eslint.config.js
@@ -15,7 +15,12 @@ export default tseslint.config(
{
files: ['**/*.json'],
rules: {
- '@nx/dependency-checks': ['error'],
+ '@nx/dependency-checks': [
+ 'error',
+ {
+ ignoredDependencies: ['tsdown'],
+ },
+ ],
},
},
);
diff --git a/tools/eslint-formatter-multi/package.json b/tools/eslint-formatter-multi/package.json
index 6aaddcec0..bd480bf82 100644
--- a/tools/eslint-formatter-multi/package.json
+++ b/tools/eslint-formatter-multi/package.json
@@ -32,8 +32,7 @@
"access": "public"
},
"dependencies": {
- "ansis": "^3.3.0",
- "tslib": "^2.8.1"
+ "ansis": "^3.3.0"
},
"peerDependencies": {
"eslint": "^8.0.0 || ^9.0.0"
diff --git a/tools/eslint-formatter-multi/tsdown.config.ts b/tools/eslint-formatter-multi/tsdown.config.ts
new file mode 100644
index 000000000..ae6f25d2e
--- /dev/null
+++ b/tools/eslint-formatter-multi/tsdown.config.ts
@@ -0,0 +1,19 @@
+import { defineConfig } from 'tsdown';
+import { baseConfig, getExternalDependencies } from '../../tsdown.base';
+
+const __dirname = import.meta.dirname;
+
+export default defineConfig(async () => {
+ const base = baseConfig({ projectRoot: __dirname });
+
+ // Filter out README.md from copy to avoid unlink errors
+ const copy = (base.copy || []).filter(
+ (item: any) => !item.to?.endsWith('/README.md'),
+ );
+
+ return {
+ ...base,
+ external: await getExternalDependencies(__dirname),
+ copy,
+ };
+});
diff --git a/tools/src/ts-down.plugin.mjs b/tools/src/ts-down.plugin.mjs
new file mode 100644
index 000000000..8e4f53667
--- /dev/null
+++ b/tools/src/ts-down.plugin.mjs
@@ -0,0 +1,86 @@
+import { existsSync } from 'node:fs';
+import { dirname, join } from 'node:path';
+
+const TSDOWN_CONFIG_GLOB = '**/tsdown.config.{ts,js,mjs}';
+
+/**
+ * Nx plugin to integrate TSDown into the build process.
+ *
+ * @example
+ * ```json
+ * {
+ * "plugins": ["./tools/src/ts-down.plugin.mjs"]
+ * }
+ * ```
+ * This will automatically add a build target to any project containing a `tsdown.config.ts`, `tsdown.config.js`, or `tsdown.config.mjs` file.
+ */
+const createNodesV2 = [
+ TSDOWN_CONFIG_GLOB,
+ async (configFiles, options, context) => {
+ return await Promise.all(
+ configFiles.map(async configFile => {
+ const projectRoot = dirname(configFile);
+ const normalizedProjectRoot = projectRoot === '.' ? '' : projectRoot;
+
+ // Check if this is a valid project (has package.json or project.json)
+ const hasPackageJson = existsSync(
+ join(context.workspaceRoot, projectRoot, 'package.json'),
+ );
+ const hasProjectJson = existsSync(
+ join(context.workspaceRoot, projectRoot, 'project.json'),
+ );
+
+ if (!hasPackageJson && !hasProjectJson) {
+ return [configFile, { projects: {} }];
+ }
+
+ const targetName = options?.targetName ?? 'tsd-build';
+
+ const targets = {
+ [targetName]: createTsdownBuildTarget(configFile, projectRoot),
+ };
+
+ const result = {
+ projects: {
+ [normalizedProjectRoot]: {
+ targets,
+ },
+ },
+ };
+
+ return [configFile, result];
+ }),
+ );
+ },
+];
+
+function createTsdownBuildTarget(configFile, projectRoot) {
+ return {
+ executor: 'nx:run-commands',
+ options: {
+ command: `node_modules/.bin/tsdown --config ${configFile}`,
+ cwd: '{workspaceRoot}',
+ },
+ cache: true,
+ inputs: [
+ 'production',
+ '^production',
+ {
+ externalDependencies: ['tsdown'],
+ },
+ ],
+ outputs: ['{projectRoot}/dist'],
+ metadata: {
+ description: 'Build the project using TSDown',
+ technologies: ['tsdown'],
+ },
+ };
+}
+
+// Default export for nx.json plugins
+const plugin = {
+ name: '@code-pushup/tsdown-plugin',
+ createNodesV2,
+};
+
+export default plugin;
diff --git a/tsdown.base.ts b/tsdown.base.ts
new file mode 100644
index 000000000..46ed71acb
--- /dev/null
+++ b/tsdown.base.ts
@@ -0,0 +1,213 @@
+import { readFileSync } from 'node:fs';
+import { readFile, writeFile } from 'node:fs/promises';
+import { join } from 'node:path';
+import { type UserConfig, defineConfig } from 'tsdown';
+
+export function baseConfig(options: { projectRoot: string }): UserConfig {
+ const { projectRoot } = options;
+
+ // Read package.json to get additional files to copy
+ const packageJsonPath = join(projectRoot, 'package.json');
+ let additionalCopyFiles: Array<{ from: string; to: string }> = [];
+
+ try {
+ const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf8'));
+
+ if (packageJson.files && Array.isArray(packageJson.files)) {
+ additionalCopyFiles = packageJson.files
+ .filter((file: string) => {
+ // Skip negation patterns (starting with !)
+ if (file.startsWith('!')) return false;
+ // Skip 'src' as it's already handled by the build output
+ if (file === 'src') return false;
+ // Include files that start with ./ or are specific files
+ return file.startsWith('./') || !file.includes('/');
+ })
+ .map((file: string) => ({
+ from: join(projectRoot, file),
+ to: join(projectRoot, 'dist', file),
+ }));
+ }
+ } catch (error) {
+ // If package.json doesn't exist or can't be read, continue without additional files
+ }
+
+ return defineConfig({
+ entry: `${projectRoot}/src/**/!(*.test|*.mock).ts`,
+ tsconfig: `${projectRoot}/tsconfig.lib.json`,
+ outDir: `${projectRoot}/dist/src`,
+ unbundle: true,
+ format: ['esm', 'cjs'],
+ fixedExtension: true,
+ dts: true,
+ hash: false,
+ external: [],
+ exports: true,
+ copy: [
+ {
+ from: `${projectRoot}/package.json`,
+ to: `${projectRoot}/dist/package.json`,
+ },
+ {
+ from: `${projectRoot}/README.md`,
+ to: `${projectRoot}/dist/README.md`,
+ },
+ ...additionalCopyFiles,
+ ],
+ async onSuccess() {
+ const distPackageJsonPath = join(projectRoot, 'dist', 'package.json');
+
+ try {
+ const packageJson = JSON.parse(
+ await readFile(distPackageJsonPath, 'utf8'),
+ );
+
+ // Remove fields not needed in published package
+ delete packageJson.devDependencies;
+ delete packageJson.scripts;
+ delete packageJson.nx;
+
+ // Update files field to include built output
+ if (packageJson.files) {
+ packageJson.files = packageJson.files.map((file: string) =>
+ file === 'src' ? 'src' : file,
+ );
+ }
+
+ // Detect if this is a CJS-only build by checking if .mjs files exist
+ const { existsSync } = await import('node:fs');
+ const indexMjsPath = join(projectRoot, 'dist', 'src', 'index.mjs');
+ const isCjsOnly = !existsSync(indexMjsPath);
+
+ // Adjust paths for the dist directory
+ if (packageJson.main) {
+ packageJson.main = packageJson.main.replace(/^dist\//, '');
+ if (isCjsOnly) {
+ packageJson.main = packageJson.main.replace(/\.js$/, '.cjs');
+ }
+ }
+ if (packageJson.module) {
+ packageJson.module = packageJson.module.replace(/^dist\//, '');
+ }
+ if (packageJson.types) {
+ packageJson.types = packageJson.types.replace(/^dist\//, '');
+ }
+ if (packageJson.typings) {
+ packageJson.typings = packageJson.typings.replace(/^dist\//, '');
+ if (isCjsOnly) {
+ packageJson.typings = packageJson.typings.replace(
+ /\.d\.ts$/,
+ '.d.cts',
+ );
+ }
+ }
+
+ // Update bin field to use correct extension for built files
+ if (packageJson.bin) {
+ if (typeof packageJson.bin === 'string') {
+ // Single bin entry
+ packageJson.bin = packageJson.bin
+ .replace(/^dist\//, '')
+ .replace(/\.js$/, '.mjs');
+ } else {
+ // Multiple bin entries
+ packageJson.bin = Object.fromEntries(
+ Object.entries(packageJson.bin).map(([name, path]) => [
+ name,
+ (path as string)
+ .replace(/^dist\//, '')
+ .replace(/\.js$/, '.mjs'),
+ ]),
+ );
+ }
+ }
+
+ // Generate exports field based on format
+ if (isCjsOnly) {
+ // CJS-only exports
+ packageJson.exports = {
+ '.': {
+ require: './src/index.cjs',
+ types: './src/index.d.cts',
+ },
+ './*': {
+ require: './src/*/index.cjs',
+ types: './src/*/index.d.cts',
+ },
+ './*/': {
+ require: './src/*/index.cjs',
+ types: './src/*/index.d.cts',
+ },
+ './*.js': {
+ require: './src/*.cjs',
+ types: './src/*.d.cts',
+ },
+ };
+ } else {
+ // Dual ESM/CJS exports
+ packageJson.exports = {
+ '.': {
+ import: './src/index.mjs',
+ require: './src/index.cjs',
+ types: './src/index.d.mts',
+ },
+ './*': {
+ import: './src/*/index.mjs',
+ require: './src/*/index.cjs',
+ types: './src/*/index.d.mts',
+ },
+ './*/': {
+ import: './src/*/index.mjs',
+ require: './src/*/index.cjs',
+ types: './src/*/index.d.mts',
+ },
+ './*.js': {
+ import: './src/*.mjs',
+ require: './src/*.cjs',
+ types: './src/*.d.mts',
+ },
+ };
+ }
+
+ await writeFile(
+ distPackageJsonPath,
+ JSON.stringify(packageJson, null, 2),
+ 'utf8',
+ );
+ } catch (error) {
+ // If package.json doesn't exist in dist (e.g., copy was overridden), skip modification
+ if ((error as NodeJS.ErrnoException).code !== 'ENOENT') {
+ throw error;
+ }
+ }
+ },
+ });
+}
+
+export function getProjectNameFromActiveTask(): string {
+ const projectName = process.env['NX_TASK_TARGET_PROJECT'];
+
+ if (!projectName || typeof projectName !== 'string') {
+ throw new Error('NX_TASK_TARGET_PROJECT is not set');
+ }
+
+ return projectName;
+}
+
+export async function getExternalDependencies(cwd: string): Promise {
+ try {
+ const packageJson = JSON.parse(
+ await readFile(join(cwd, 'package.json'), 'utf8'),
+ );
+
+ return [
+ ...Object.keys(packageJson.dependencies || {}),
+ ...Object.keys(packageJson.devDependencies || {}),
+ ...Object.keys(packageJson.optionalDependencies || {}),
+ ...Object.keys(packageJson.peerDependencies || {}),
+ ];
+ } catch {
+ // No package.json or unable to read it - return empty array
+ return [];
+ }
+}