@ucdjs/release-scripts 0.1.0-beta.60 → 0.1.0-beta.61

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,3 +1,102 @@
1
1
  # @ucdjs/release-scripts
2
2
 
3
- This repository contains release and publish scripts for the UCDJS organization.
3
+ [![npm version][npm-version-src]][npm-version-href]
4
+ [![npm downloads][npm-downloads-src]][npm-downloads-href]
5
+
6
+ Monorepo release automation for pnpm workspaces. Handles version calculation, dependency graph resolution, changelog generation, and GitHub integration.
7
+
8
+ ## Installation
9
+
10
+ ```bash
11
+ npm install @ucdjs/release-scripts
12
+ ```
13
+
14
+ ## Usage
15
+
16
+ ```typescript
17
+ import { createReleaseScripts } from "@ucdjs/release-scripts";
18
+
19
+ const release = await createReleaseScripts({
20
+ repo: "owner/repo",
21
+ githubToken: process.env.GITHUB_TOKEN,
22
+ });
23
+
24
+ // Prepare a release (calculate versions, update package.json files, create PR)
25
+ const result = await release.prepare();
26
+
27
+ // Verify a release branch matches expected state
28
+ await release.verify();
29
+
30
+ // Publish packages to npm
31
+ await release.publish();
32
+ ```
33
+
34
+ ### Configuration
35
+
36
+ ```typescript
37
+ const release = await createReleaseScripts({
38
+ repo: "owner/repo",
39
+ githubToken: "...",
40
+ workspaceRoot: process.cwd(),
41
+ dryRun: false,
42
+ safeguards: true,
43
+ globalCommitMode: "dependencies",
44
+ packages: {
45
+ include: ["@scope/pkg-a", "@scope/pkg-b"],
46
+ exclude: ["@scope/internal"],
47
+ excludePrivate: true,
48
+ },
49
+ branch: {
50
+ release: "release/next",
51
+ default: "main",
52
+ },
53
+ npm: {
54
+ provenance: true,
55
+ access: "public",
56
+ },
57
+ changelog: {
58
+ enabled: true,
59
+ emojis: true,
60
+ },
61
+ });
62
+ ```
63
+
64
+ ### Package Discovery
65
+
66
+ ```typescript
67
+ // List all workspace packages
68
+ const packages = await release.packages.list();
69
+
70
+ // Get a specific package
71
+ const pkg = await release.packages.get("@scope/pkg-a");
72
+ ```
73
+
74
+ ### Workflows
75
+
76
+ #### `prepare()`
77
+
78
+ Calculates version bumps from conventional commits, updates `package.json` files, generates changelogs, and creates/updates a release pull request.
79
+
80
+ #### `verify()`
81
+
82
+ Validates that a release branch matches expected release artifacts. Compares expected vs actual versions and dependency ranges, then sets a GitHub commit status.
83
+
84
+ #### `publish()`
85
+
86
+ Publishes packages to npm in topological order with provenance support, creates git tags, and pushes them to the remote.
87
+
88
+ ## CLI Flags
89
+
90
+ When used in a script, the following flags are supported:
91
+
92
+ - `--dry` / `-d` - Dry-run mode, no changes are made
93
+ - `--verbose` / `-v` - Enable verbose logging
94
+
95
+ ## 📄 License
96
+
97
+ Published under [MIT License](./LICENSE).
98
+
99
+ [npm-version-src]: https://img.shields.io/npm/v/@ucdjs/release-scripts?style=flat&colorA=18181B&colorB=4169E1
100
+ [npm-version-href]: https://npmjs.com/package/@ucdjs/release-scripts
101
+ [npm-downloads-src]: https://img.shields.io/npm/dm/@ucdjs/release-scripts?style=flat&colorA=18181B&colorB=4169E1
102
+ [npm-downloads-href]: https://npmjs.com/package/@ucdjs/release-scripts
@@ -1,6 +1,5 @@
1
1
  import * as path from "node:path";
2
2
  import * as fs from "node:fs";
3
-
4
3
  //#region node_modules/.pnpm/eta@4.5.1/node_modules/eta/dist/index.mjs
5
4
  var EtaError = class extends Error {
6
5
  constructor(message) {
@@ -476,6 +475,5 @@ var Eta = class extends Eta$1 {
476
475
  readFile = readFile;
477
476
  resolvePath = resolvePath;
478
477
  };
479
-
480
478
  //#endregion
481
- export { Eta as t };
479
+ export { Eta as t };
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { t as Eta } from "./eta-DAZlmVBQ.mjs";
1
+ import { t as Eta } from "./eta-g9ausaEx.mjs";
2
2
  import process from "node:process";
3
3
  import readline from "node:readline";
4
4
  import { parseArgs } from "node:util";
@@ -10,7 +10,6 @@ import { getCommits, groupByType } from "commit-parser";
10
10
  import { dedent } from "@luxass/utils";
11
11
  import semver, { gt } from "semver";
12
12
  import prompts from "prompts";
13
-
14
13
  //#region src/shared/utils.ts
15
14
  const ucdjsReleaseOverridesPath = ".github/ucdjs-release.overrides.json";
16
15
  function parseCLIFlags() {
@@ -114,7 +113,6 @@ async function dryRun(bin, args, opts) {
114
113
  async function runIfNotDry(bin, args, opts) {
115
114
  return getIsDryRun() ? dryRun(bin, args, opts) : run(bin, args, opts);
116
115
  }
117
-
118
116
  //#endregion
119
117
  //#region src/shared/errors.ts
120
118
  function isRecord(value) {
@@ -219,16 +217,16 @@ function printReleaseError(error) {
219
217
  function exitWithError(message, hint, cause) {
220
218
  throw new ReleaseError(message, hint, cause);
221
219
  }
222
-
223
220
  //#endregion
224
221
  //#region src/operations/changelog-format.ts
222
+ const HASH_PREFIX_RE = /^#/;
225
223
  function formatCommitLine({ commit, owner, repo, authors }) {
226
224
  const commitUrl = `https://github.com/${owner}/${repo}/commit/${commit.hash}`;
227
225
  let line = `${commit.description}`;
228
226
  const references = commit.references ?? [];
229
227
  for (const ref of references) {
230
228
  if (!ref.value) continue;
231
- const number = Number.parseInt(ref.value.replace(/^#/, ""), 10);
229
+ const number = Number.parseInt(ref.value.replace(HASH_PREFIX_RE, ""), 10);
232
230
  if (Number.isNaN(number)) continue;
233
231
  if (ref.type === "issue") {
234
232
  line += ` ([Issue ${ref.value}](https://github.com/${owner}/${repo}/issues/${number}))`;
@@ -263,7 +261,6 @@ function buildTemplateGroups(options) {
263
261
  };
264
262
  });
265
263
  }
266
-
267
264
  //#endregion
268
265
  //#region src/core/github.ts
269
266
  function toGitHubError(operation, error) {
@@ -459,9 +456,10 @@ var GitHubClient = class {
459
456
  function createGitHubClient(options) {
460
457
  return new GitHubClient(options);
461
458
  }
459
+ const NON_WHITESPACE_RE = /\S/;
462
460
  function dedentString(str) {
463
461
  const lines = str.split("\n");
464
- const minIndent = lines.filter((line) => line.trim().length > 0).reduce((min, line) => Math.min(min, line.search(/\S/)), Infinity);
462
+ const minIndent = lines.filter((line) => line.trim().length > 0).reduce((min, line) => Math.min(min, line.search(NON_WHITESPACE_RE)), Infinity);
465
463
  return lines.map((line) => minIndent === Infinity ? line : line.slice(minIndent)).join("\n").trim();
466
464
  }
467
465
  function generatePullRequestBody(updates, body) {
@@ -475,7 +473,6 @@ function generatePullRequestBody(updates, body) {
475
473
  hasDirectChanges: u.hasDirectChanges
476
474
  })) });
477
475
  }
478
-
479
476
  //#endregion
480
477
  //#region src/options.ts
481
478
  const DEFAULT_PR_BODY_TEMPLATE = dedent`
@@ -586,7 +583,6 @@ function normalizeReleaseScriptsOptions(options) {
586
583
  }
587
584
  };
588
585
  }
589
-
590
586
  //#endregion
591
587
  //#region src/types.ts
592
588
  function ok(value) {
@@ -601,9 +597,10 @@ function err(error) {
601
597
  error
602
598
  };
603
599
  }
604
-
605
600
  //#endregion
606
601
  //#region src/core/git.ts
602
+ const CHECKOUT_BRANCH_RE = /Switched to (?:a new )?branch '(.+)'/;
603
+ const COMMIT_HASH_RE = /^[0-9a-f]{40}$/i;
607
604
  function toGitError(operation, error) {
608
605
  const formatted = formatUnknownError(error);
609
606
  return {
@@ -686,6 +683,30 @@ async function isWorkingDirectoryClean(workspaceRoot) {
686
683
  * @param {string} workspaceRoot - The root directory of the workspace
687
684
  * @returns {Promise<boolean>} Promise resolving to true if branch exists, false otherwise
688
685
  */
686
+ /**
687
+ * Check if a remote branch exists on origin
688
+ * @param {string} branch - The branch name to check
689
+ * @param {string} workspaceRoot - The root directory of the workspace
690
+ * @returns {Promise<Result<boolean, GitError>>} Promise resolving to true if remote branch exists
691
+ */
692
+ async function doesRemoteBranchExist(branch, workspaceRoot) {
693
+ try {
694
+ await run("git", [
695
+ "ls-remote",
696
+ "--exit-code",
697
+ "--heads",
698
+ "origin",
699
+ branch
700
+ ], { nodeOptions: {
701
+ cwd: workspaceRoot,
702
+ stdio: "pipe"
703
+ } });
704
+ return ok(true);
705
+ } catch (error) {
706
+ logger.verbose(`Remote branch "origin/${branch}" does not exist: ${formatUnknownError(error).message}`);
707
+ return ok(false);
708
+ }
709
+ }
689
710
  async function doesBranchExist(branch, workspaceRoot) {
690
711
  try {
691
712
  await run("git", [
@@ -751,7 +772,7 @@ async function checkoutBranch(branch, workspaceRoot) {
751
772
  cwd: workspaceRoot,
752
773
  stdio: "pipe"
753
774
  } })).stderr.trim();
754
- const match = output.match(/Switched to (?:a new )?branch '(.+)'/);
775
+ const match = output.match(CHECKOUT_BRANCH_RE);
755
776
  if (match && match[1] === branch) {
756
777
  logger.info(`Successfully switched to branch: ${farver.green(branch)}`);
757
778
  return ok(true);
@@ -985,10 +1006,9 @@ async function getGroupedFilesByCommitSha(workspaceRoot, from, to) {
985
1006
  } });
986
1007
  const lines = stdout.trim().split("\n").filter((line) => line.trim() !== "");
987
1008
  let currentSha = null;
988
- const HASH_REGEX = /^[0-9a-f]{40}$/i;
989
1009
  for (const line of lines) {
990
1010
  const trimmedLine = line.trim();
991
- if (HASH_REGEX.test(trimmedLine)) {
1011
+ if (COMMIT_HASH_RE.test(trimmedLine)) {
992
1012
  currentSha = trimmedLine;
993
1013
  commitsMap.set(currentSha, []);
994
1014
  continue;
@@ -1055,9 +1075,9 @@ async function createAndPushPackageTag(packageName, version, workspaceRoot) {
1055
1075
  if (!createResult.ok) return createResult;
1056
1076
  return pushTag(`${packageName}@${version}`, workspaceRoot);
1057
1077
  }
1058
-
1059
1078
  //#endregion
1060
1079
  //#region src/core/changelog.ts
1080
+ const CHANGELOG_VERSION_RE = /##\s+(?:<small>)?\[?([^\](\s<]+)/;
1061
1081
  const excludeAuthors = [
1062
1082
  /\[bot\]/i,
1063
1083
  /dependabot/i,
@@ -1125,7 +1145,7 @@ async function updateChangelog(options) {
1125
1145
  const insertAt = parsed.headerLineEnd + 1;
1126
1146
  const before = lines.slice(0, insertAt);
1127
1147
  const after = lines.slice(insertAt);
1128
- if (before.length > 0 && before[before.length - 1] !== "") before.push("");
1148
+ if (before.length > 0 && before.at(-1) !== "") before.push("");
1129
1149
  updatedContent = [
1130
1150
  ...before,
1131
1151
  newEntry,
@@ -1154,7 +1174,7 @@ async function resolveCommitAuthors(commits, githubClient) {
1154
1174
  });
1155
1175
  commitAuthors.set(commit.hash, authorsForCommit);
1156
1176
  }
1157
- const authors = Array.from(authorMap.values());
1177
+ const authors = [...authorMap.values()];
1158
1178
  await Promise.all(authors.map((info) => githubClient.resolveAuthorInfo(info)));
1159
1179
  return commitAuthors;
1160
1180
  }
@@ -1174,7 +1194,7 @@ function parseChangelog(content) {
1174
1194
  for (let i = headerLineEnd + 1; i < lines.length; i++) {
1175
1195
  const line = lines[i].trim();
1176
1196
  if (line.startsWith("## ")) {
1177
- const versionMatch = line.match(/##\s+(?:<small>)?\[?([^\](\s<]+)/);
1197
+ const versionMatch = line.match(CHANGELOG_VERSION_RE);
1178
1198
  if (versionMatch) {
1179
1199
  const version = versionMatch[1];
1180
1200
  const lineStart = i;
@@ -1199,7 +1219,6 @@ function parseChangelog(content) {
1199
1219
  headerLineEnd
1200
1220
  };
1201
1221
  }
1202
-
1203
1222
  //#endregion
1204
1223
  //#region src/operations/semver.ts
1205
1224
  function isValidSemver(version) {
@@ -1235,7 +1254,6 @@ function getNextPrereleaseVersion(currentVersion, mode, identifier) {
1235
1254
  if (!next) throw new Error(`Failed to compute prerelease version for ${currentVersion}`);
1236
1255
  return next;
1237
1256
  }
1238
-
1239
1257
  //#endregion
1240
1258
  //#region src/core/prompts.ts
1241
1259
  async function selectPackagePrompt(packages) {
@@ -1417,7 +1435,6 @@ async function confirmOverridePrompt(pkg, overrideVersion) {
1417
1435
  if (!response.choice) return null;
1418
1436
  return response.choice;
1419
1437
  }
1420
-
1421
1438
  //#endregion
1422
1439
  //#region src/core/workspace.ts
1423
1440
  function toWorkspaceError(operation, error) {
@@ -1501,7 +1518,7 @@ async function findWorkspacePackages(workspaceRoot, options) {
1501
1518
  };
1502
1519
  });
1503
1520
  const packages = await Promise.all(promises);
1504
- if (excludedPackages.size > 0) logger.info(`Excluded packages: ${farver.green(Array.from(excludedPackages).join(", "))}`);
1521
+ if (excludedPackages.size > 0) logger.info(`Excluded packages: ${farver.green([...excludedPackages].join(", "))}`);
1505
1522
  return packages.filter((pkg) => pkg !== null);
1506
1523
  } catch (err) {
1507
1524
  logger.error("Error discovering workspace packages:", err);
@@ -1517,7 +1534,6 @@ function shouldIncludePackage(pkg, options) {
1517
1534
  if (options.exclude?.includes(pkg.name)) return false;
1518
1535
  return true;
1519
1536
  }
1520
-
1521
1537
  //#endregion
1522
1538
  //#region src/operations/branch.ts
1523
1539
  async function prepareReleaseBranch(options) {
@@ -1538,9 +1554,13 @@ async function prepareReleaseBranch(options) {
1538
1554
  const checkedOut = await checkoutBranch(releaseBranch, workspaceRoot);
1539
1555
  if (!checkedOut.ok) return checkedOut;
1540
1556
  if (branchExists.value) {
1541
- const pulled = await pullLatestChanges(releaseBranch, workspaceRoot);
1542
- if (!pulled.ok) return pulled;
1543
- if (!pulled.value) logger.warn("Failed to pull latest changes, continuing anyway.");
1557
+ const remoteExists = await doesRemoteBranchExist(releaseBranch, workspaceRoot);
1558
+ if (!remoteExists.ok) return remoteExists;
1559
+ if (remoteExists.value) {
1560
+ const pulled = await pullLatestChanges(releaseBranch, workspaceRoot);
1561
+ if (!pulled.ok) return pulled;
1562
+ if (!pulled.value) logger.warn("Failed to pull latest changes, continuing anyway.");
1563
+ } else logger.info(`Remote branch "origin/${releaseBranch}" does not exist yet, skipping pull.`);
1544
1564
  }
1545
1565
  const rebased = await rebaseBranch(defaultBranch, workspaceRoot);
1546
1566
  if (!rebased.ok) return rebased;
@@ -1557,7 +1577,6 @@ async function syncReleaseChanges(options) {
1557
1577
  if (!pushed.ok) return pushed;
1558
1578
  return ok(true);
1559
1579
  }
1560
-
1561
1580
  //#endregion
1562
1581
  //#region src/versioning/commits.ts
1563
1582
  /**
@@ -1643,7 +1662,7 @@ function findCommitRange(packageCommits) {
1643
1662
  for (const commits of packageCommits.values()) {
1644
1663
  if (commits.length === 0) continue;
1645
1664
  const firstCommit = commits[0].shortHash;
1646
- const lastCommit = commits[commits.length - 1].shortHash;
1665
+ const lastCommit = commits.at(-1).shortHash;
1647
1666
  if (!newestCommit) newestCommit = firstCommit;
1648
1667
  oldestCommit = lastCommit;
1649
1668
  }
@@ -1712,7 +1731,6 @@ async function getGlobalCommitsPerPackage(workspaceRoot, packageCommits, allPack
1712
1731
  }
1713
1732
  return result;
1714
1733
  }
1715
-
1716
1734
  //#endregion
1717
1735
  //#region src/operations/version.ts
1718
1736
  function determineHighestBump(commits) {
@@ -1744,7 +1762,6 @@ function determineBumpType(commit) {
1744
1762
  if (commit.type === "fix" || commit.type === "perf") return "patch";
1745
1763
  return "none";
1746
1764
  }
1747
-
1748
1765
  //#endregion
1749
1766
  //#region src/versioning/package.ts
1750
1767
  /**
@@ -1874,7 +1891,6 @@ function createDependentUpdates(graph, workspacePackages, directUpdates, exclude
1874
1891
  }
1875
1892
  return allUpdates;
1876
1893
  }
1877
-
1878
1894
  //#endregion
1879
1895
  //#region src/versioning/version.ts
1880
1896
  const messageColorMap = {
@@ -2148,7 +2164,6 @@ function getDependencyUpdates(pkg, allUpdates) {
2148
2164
  if (updates.size === 0) logger.verbose(` - No dependency updates needed`);
2149
2165
  return updates;
2150
2166
  }
2151
-
2152
2167
  //#endregion
2153
2168
  //#region src/operations/calculate.ts
2154
2169
  async function calculateUpdates(options) {
@@ -2181,7 +2196,6 @@ function ensureHasPackages(packages) {
2181
2196
  });
2182
2197
  return ok(packages);
2183
2198
  }
2184
-
2185
2199
  //#endregion
2186
2200
  //#region src/operations/pr.ts
2187
2201
  async function syncPullRequest(options) {
@@ -2218,7 +2232,6 @@ async function syncPullRequest(options) {
2218
2232
  created: !doesExist
2219
2233
  });
2220
2234
  }
2221
-
2222
2235
  //#endregion
2223
2236
  //#region src/workflows/prepare.ts
2224
2237
  async function prepareWorkflow(options) {
@@ -2258,6 +2271,23 @@ async function prepareWorkflow(options) {
2258
2271
  logger.info("No existing version overrides file found. Continuing...");
2259
2272
  logger.verbose(`Reading overrides file failed: ${formatUnknownError(error).message}`);
2260
2273
  }
2274
+ if (Object.keys(existingOverrides).length > 0) {
2275
+ const packageNames = new Set(workspacePackages.map((p) => p.name));
2276
+ const staleEntries = [];
2277
+ for (const [pkgName, override] of Object.entries(existingOverrides)) {
2278
+ if (!packageNames.has(pkgName)) {
2279
+ staleEntries.push(pkgName);
2280
+ delete existingOverrides[pkgName];
2281
+ continue;
2282
+ }
2283
+ const pkg = workspacePackages.find((p) => p.name === pkgName);
2284
+ if (pkg && semver.valid(override.version) && semver.gte(pkg.version, override.version)) {
2285
+ staleEntries.push(pkgName);
2286
+ delete existingOverrides[pkgName];
2287
+ }
2288
+ }
2289
+ if (staleEntries.length > 0) logger.info(`Removed ${staleEntries.length} stale override(s): ${staleEntries.join(", ")}`);
2290
+ }
2261
2291
  const updatesResult = await calculateUpdates({
2262
2292
  workspacePackages,
2263
2293
  workspaceRoot: options.workspaceRoot,
@@ -2391,7 +2421,6 @@ async function prepareWorkflow(options) {
2391
2421
  created: prResult.value.created
2392
2422
  };
2393
2423
  }
2394
-
2395
2424
  //#endregion
2396
2425
  //#region src/core/npm.ts
2397
2426
  function toNPMError(operation, error, code) {
@@ -2504,7 +2533,7 @@ async function publishPackage(packageName, version, workspaceRoot, options) {
2504
2533
  } catch (error) {
2505
2534
  const code = classifyPublishErrorCode(error);
2506
2535
  if (code === "EPUBLISHCONFLICT" && attempt < maxAttempts) {
2507
- const delay = backoffMs[attempt - 1] ?? backoffMs[backoffMs.length - 1];
2536
+ const delay = backoffMs[attempt - 1] ?? backoffMs.at(-1);
2508
2537
  logger.warn(`Publish conflict for ${packageName}@${version} (attempt ${attempt}/${maxAttempts}). Retrying in ${Math.ceil(delay / 1e3)}s...`);
2509
2538
  await wait(delay);
2510
2539
  continue;
@@ -2513,7 +2542,6 @@ async function publishPackage(packageName, version, workspaceRoot, options) {
2513
2542
  }
2514
2543
  return err(toNPMError("publishPackage", /* @__PURE__ */ new Error(`Failed to publish ${packageName}@${version} after ${maxAttempts} attempts`), "EPUBLISHCONFLICT"));
2515
2544
  }
2516
-
2517
2545
  //#endregion
2518
2546
  //#region src/workflows/publish.ts
2519
2547
  async function getReleaseBodyFromChangelog(workspaceRoot, packageName, packagePath, version) {
@@ -2678,7 +2706,6 @@ async function publishWorkflow(options) {
2678
2706
  }
2679
2707
  logger.success("All packages published successfully!");
2680
2708
  }
2681
-
2682
2709
  //#endregion
2683
2710
  //#region src/workflows/verify.ts
2684
2711
  async function verifyWorkflow(options) {
@@ -2773,7 +2800,6 @@ async function verifyWorkflow(options) {
2773
2800
  logger.success("Verification successful. Commit status set to 'success'.");
2774
2801
  }
2775
2802
  }
2776
-
2777
2803
  //#endregion
2778
2804
  //#region src/index.ts
2779
2805
  function withErrorBoundary(fn) {
@@ -2831,6 +2857,5 @@ async function createReleaseScripts(options) {
2831
2857
  }
2832
2858
  };
2833
2859
  }
2834
-
2835
2860
  //#endregion
2836
- export { createReleaseScripts };
2861
+ export { createReleaseScripts };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ucdjs/release-scripts",
3
- "version": "0.1.0-beta.60",
3
+ "version": "0.1.0-beta.61",
4
4
  "description": "@ucdjs release scripts",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -26,23 +26,26 @@
26
26
  ],
27
27
  "dependencies": {
28
28
  "@luxass/utils": "2.7.3",
29
- "commit-parser": "1.3.0",
29
+ "commit-parser": "1.3.1",
30
30
  "farver": "1.0.0-beta.1",
31
31
  "prompts": "2.4.2",
32
32
  "semver": "7.7.4",
33
- "tinyexec": "1.0.2"
33
+ "tinyexec": "1.0.4"
34
34
  },
35
35
  "devDependencies": {
36
- "@luxass/eslint-config": "7.2.0",
36
+ "@luxass/eslint-config": "7.3.0",
37
37
  "@types/node": "22.18.12",
38
38
  "@types/prompts": "2.4.9",
39
39
  "@types/semver": "7.7.1",
40
- "eslint": "10.0.0",
40
+ "eslint": "10.0.3",
41
41
  "eta": "4.5.1",
42
- "tsdown": "0.20.3",
42
+ "tsdown": "0.21.2",
43
43
  "typescript": "5.9.3",
44
- "vitest": "4.0.18",
45
- "vitest-testdirs": "4.4.2"
44
+ "vitest": "4.1.0",
45
+ "vitest-testdirs": "4.4.3"
46
+ },
47
+ "inlinedDependencies": {
48
+ "eta": "4.5.1"
46
49
  },
47
50
  "scripts": {
48
51
  "build": "tsdown",