@d1g1tal/tsbuild 1.6.5 → 1.7.1

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/CHANGELOG.md CHANGED
@@ -1,3 +1,103 @@
1
+ ## [1.7.1](https://github.com/D1g1talEntr0py/tsbuild/compare/v1.7.0...v1.7.1) (2026-03-29)
2
+
3
+ ### Code Refactoring
4
+
5
+ * **bundler:** remove internal index files and improve declaration bundling (0299420b919a09fab5f3988124296e8105a21c7f)
6
+ - Updates package.json types and exports to point to type-script-project instead of index
7
+ - Removes src/index.ts and src/dts/index.ts files
8
+ - Updates test imports to reference declaration-bundler directly instead of via index
9
+ - Fixes declaration bundler to gracefully handle entry points without declaration files
10
+ - Updates declaration bundler to ensure the output directory exists before writing
11
+ - Refines declaration identifier conflict mapping to use Set for finalTypeExports
12
+ - Updates file-manager to skip processing and writing empty declaration files
13
+ - Removes internal Symbol.toStringTag from FileManager
14
+
15
+
16
+ ### Styles
17
+
18
+ * update editorconfig indent size to 2 (e56b2b6dc13e4b53ff064db8a8b950cc1c6b23ae)
19
+ - Changes indent_size from 1 to 2 in .editorconfig
20
+
21
+ ## [1.7.0](https://github.com/D1g1talEntr0py/tsbuild/compare/v1.6.5...v1.7.0) (2026-03-27)
22
+
23
+ ### Features
24
+
25
+ * **build:** add support for ES2025 ScriptTarget (2aecca9dc4ac67cd3e27021e34054a7c7552ebe9)
26
+ - Add `ES2025` targeting map for TS `ScriptTarget.ES2025` so newly produced esbuild configurations will honor it.
27
+
28
+
29
+ ### Bug Fixes
30
+
31
+ * **dts:** infer reference types for node protocols and correct module mapping (03c4ec5859b3741b7f30d590b38ea9c729128eea)
32
+ - Add logic in the `DeclarationBundler` to automatically infer `/// <reference types="node" />` when `node:` protocol imports are merged in, so the generated `.d.ts` file remains self-contained.
33
+ - Stop stripping inline `type` keywords from import statements in the `DeclarationProcessor`, preserving them for `.d.ts` output correctness.
34
+ - Remove unused `inlineTypePattern` import due to removing the stripping logic.
35
+ - Fix minor property initialization order formatting in `DeclarationBundler`.
36
+ - Add testing specific to these fixes in `declaration-bundler.test.ts` and `declaration-processor.test.ts`.
37
+
38
+ * **env:** support dynamic process.env extraction in config values (9469b5963d9ac5c1473bf500e96baa841b04b586)
39
+ - Expand `process.env` references dynamically in ESBuild `define` objects to support runtime-bound values instead of just static strings.
40
+
41
+ * **release:** manually update the workspace file since pnpm can't seem to get it right (8795a7497ab9cc26991001ef09145f8d92097841)
42
+
43
+ ### Code Refactoring
44
+
45
+ * **core:** simplify promise handling in TypeScript build configuration (e7b154ad9cf38347bf93cb3a48301753cead58e0)
46
+ - Remove intermediate `entryPointsPromise` variable and `.catch()` swallowing since rejection is natively handled when awaited later in the `build()` process.
47
+ - Improve the `tsbuildOptions` setup.
48
+
49
+ * **style:** remove explicit return types and clean up syntax (c306735aefb8ff4d4227f5bdaae21e7d0ed53f32)
50
+ - Remove redundant explicit return types from internal utility functions across several files (`constants`, `decorators`, `dts`, `file-manager`, `files`, `json`, `logger`, `paths`, etc.).
51
+ - Allow TypeScript to infer these return types automatically, reducing visual noise.
52
+ - Simplify closures to arrow functions or shortened arrow syntax where applicable.
53
+
54
+
55
+ ### Documentation
56
+
57
+ * **EADDRINUSE:** add issue draft for WSL2 network issue (5f5ea0d31f6df8e85a4e586c5f8018a56e5b2702)
58
+ - Add a detailed bug report draft describing the `EADDRINUSE` issue that occurs on every single activation attempt when running under WSL2 with `networkingMode=Mirrored`.
59
+ - Include a minimal reproduction case that demonstrates the underlying Node.js `net.createServer().listen()` race condition in WSL2 mirrored networking.
60
+ - Provide expected behavior and output logs for the VS Code extension failure.
61
+ - Suggest a direct bind and instance retention fix instead of the current close-and-reopen approach.
62
+
63
+ * **README:** update isolatedModules and TS strict requirements (c4a491791b8ad9d90c909ce9a2f8d03e1aeb0521)
64
+ - Update the minimum supported TypeScript badge to `>=5.6.3`.
65
+ - Clarify that `isolatedModules` is strictly required due to the reliance on esbuild for transpilation.
66
+ - Remove the `strict` option note for newer TS versions since it is enabled by default in TypeScript 6.0+.
67
+ - Add an "Advanced Features" section explicitly explaining *why* `isolatedModules` is necessary for esbuild.
68
+
69
+
70
+ ### Miscellaneous Chores
71
+
72
+ * **deps:** update package and lockfile dependencies (5a9f0623ffc63b42ddcdd7d2bc1882510f0a7d60)
73
+ - Update various devDependencies, including `typescript` to `^6.0.2` and related `@typescript-eslint` packages.
74
+ - Update `vitest` and coverage plugins to `^4.1.2`.
75
+ - Remove `@babel/plugin-proposal-decorators` and `@rolldown/plugin-babel` and replace Babel decorator handling in vitest config with a custom `esbuild` transformer.
76
+ - Add a `test:compat` script entry to test against 5 minor versions of TypeScript.
77
+ - Specify a peer dependency requirement for `typescript: >=5.6.3`.
78
+ - Modify `package.json` `types` field.
79
+ - Refresh and resolve `pnpm-lock.yaml` according to the new dependency state.
80
+
81
+ * **vscode:** set TS SDK path in settings (6e6622483d6648ba6cf283b362622665bd1dbede)
82
+ - Configure `.vscode/settings.json` to use the workspace `node_modules/typescript/lib` for the TypeScript language server.
83
+
84
+
85
+ ### Tests
86
+
87
+ * **compat:** introduce multi-version TypeScript testing script (3ad98b8cc914d6e7c37237713b11568e97ef1bbf)
88
+ - Add a new compatibility test script `test-ts-compat.ts` that iterates through minor TypeScript versions dynamically.
89
+ - Conditionally add support for testing `ES2024` and `ES2025` script targets only if the installed version of TS contains them.
90
+ - Implement a comprehensive type-guard/API compatibility test in `typescript-compatibility.test.ts` to guarantee runtime API availability.
91
+ - Update `tsconfig.json` for tests with required strict compatibility changes.
92
+
93
+
94
+ ### Continuous Integration
95
+
96
+ * **github:** add workflow for testing TypeScript compatibility (0c9bbbf8301ad66c4321fa9878169d66bbb1eda7)
97
+ - Create a new GitHub Actions workflow to run the test suite against multiple versions of TypeScript (5.6.3 to 6.0).
98
+ - Ensure backwards compatibility of the tools when run with older minimal supported TypeScript versions.
99
+ - Set up basic jobs utilizing `pnpm` and Node.js 24.
100
+
1
101
  ## [1.6.5](https://github.com/D1g1talEntr0py/tsbuild/compare/v1.6.4...v1.6.5) (2026-03-21)
2
102
 
3
103
  ### Code Refactoring
package/README.md CHANGED
@@ -6,7 +6,7 @@
6
6
  [![codecov](https://codecov.io/gh/D1g1talEntr0py/tsbuild/graph/badge.svg)](https://codecov.io/gh/D1g1talEntr0py/tsbuild)
7
7
  [![License: MIT](https://img.shields.io/github/license/D1g1talEntr0py/tsbuild)](https://github.com/D1g1talEntr0py/tsbuild/blob/main/LICENSE)
8
8
  [![Node.js](https://img.shields.io/node/v/@d1g1tal/tsbuild)](https://nodejs.org)
9
- [![TypeScript](https://img.shields.io/badge/TypeScript-5.9-blue?logo=typescript&logoColor=white)](https://www.typescriptlang.org/)
9
+ [![TypeScript](https://img.shields.io/badge/TypeScript->=5.6.3-blue?logo=typescript&logoColor=white)](https://www.typescriptlang.org/)
10
10
 
11
11
  A TypeScript build tool that combines three tools into one workflow: **TypeScript's type system** for correctness, **esbuild** for speed, and **SWC** for legacy decorator metadata (optional, not installed by default). Built for modern ESM-only projects on Node.js 22+.
12
12
 
@@ -125,8 +125,7 @@ By default, bare specifiers (e.g. `lodash-es`) are kept as external imports. Use
125
125
  "outDir": "./dist",
126
126
  "declaration": true,
127
127
  "incremental": true, // redundant — tsbuild enables this by default, but explicit is clear
128
- "isolatedDeclarations": true, // recommended: enables faster parallel declaration emit
129
- "isolatedModules": true,
128
+ "isolatedModules": true, // required flags constructs esbuild can't safely transpile
130
129
  "verbatimModuleSyntax": true,
131
130
  "strict": true,
132
131
  "target": "ESNext",
@@ -149,11 +148,10 @@ Set `incremental: false` to opt out of the `.tsbuildinfo` cache entirely. Every
149
148
  "compilerOptions": {
150
149
  "outDir": "./dist",
151
150
  "declaration": true,
152
- "incremental": false, // disables TypeScript's .tsbuildinfo cache and tsbuild's DTS cache
153
- "isolatedDeclarations": true,
154
- "isolatedModules": true,
151
+ "incremental": false, // disables TypeScript's .tsbuildinfo cache and tsbuild's DTS cache
152
+ "isolatedModules": true, // required — flags constructs esbuild can't safely transpile
155
153
  "verbatimModuleSyntax": true,
156
- "strict": true,
154
+ "strict": true, // Not needed with TypeScript 6 and above, since strict mode is enabled by default
157
155
  "target": "ESNext",
158
156
  "module": "ESNext",
159
157
  "moduleResolution": "Bundler", // recommended for library builds processed by a bundler
@@ -429,6 +427,24 @@ By default, bare specifiers (e.g., `lodash`) are treated as external when `platf
429
427
 
430
428
  ## Advanced Features
431
429
 
430
+ ### Isolated Modules
431
+
432
+ Because tsbuild uses esbuild for transpilation, and esbuild processes each file independently without a full type graph, you should set `isolatedModules: true` in your `tsconfig.json`:
433
+
434
+ ```jsonc
435
+ {
436
+ "compilerOptions": {
437
+ "isolatedModules": true
438
+ }
439
+ }
440
+ ```
441
+
442
+ This tells TypeScript to flag any construct that requires cross-file knowledge to transpile correctly — things like `const enum`, ambient module augmentation, or re-exporting a type without the `type` keyword. Without this, esbuild may encounter one of these patterns and silently emit incorrect code, since it has no way to identify the problem at transpile time.
443
+
444
+ With `isolatedModules: true`, TypeScript catches these issues during the type-check phase, before esbuild runs, so you get a clear error instead of a subtle runtime bug.
445
+
446
+ **`verbatimModuleSyntax` implies `isolatedModules`:** If you have `verbatimModuleSyntax: true` in your config, it already enforces all of `isolatedModules` and goes further by requiring `import type` for all type-only imports. If you're using `verbatimModuleSyntax`, adding `isolatedModules` is redundant but harmless.
447
+
432
448
  ### Decorator Metadata
433
449
 
434
450
  #### TC39 Standard Decorators (recommended)
@@ -22,81 +22,13 @@ import {
22
22
  dtsCacheFile,
23
23
  dtsCacheVersion,
24
24
  format,
25
- inlineTypePattern,
26
25
  newLine,
27
26
  processEnvExpansionPattern,
28
27
  sourceScriptExtensionExpression,
29
28
  toEsTarget,
30
29
  toJsxRenderingMode,
31
30
  typeMatcher
32
- } from "./7FPDHUPW.js";
33
-
34
- // src/errors.ts
35
- import { SyntaxKind } from "typescript";
36
- var BuildError = class extends Error {
37
- /**
38
- * Creates a new BuildError
39
- * @param message - Error message
40
- * @param code - Exit code (default: 1)
41
- */
42
- constructor(message, code = 1) {
43
- super(message);
44
- this.code = code;
45
- this.name = "BuildError";
46
- Error.captureStackTrace(this, this.constructor);
47
- }
48
- };
49
- var TypeCheckError = class extends BuildError {
50
- /**
51
- * Creates a new TypeCheckError
52
- * @param message - Error message
53
- * @param diagnostics - Optional TypeScript diagnostics output
54
- */
55
- constructor(message, diagnostics) {
56
- super(message, 1);
57
- this.diagnostics = diagnostics;
58
- this.name = "TypeCheckError";
59
- }
60
- };
61
- var BundleError = class extends BuildError {
62
- /**
63
- * Creates a new BundleError
64
- * @param message - Error message
65
- */
66
- constructor(message) {
67
- super(message, 2);
68
- this.name = "BundleError";
69
- }
70
- };
71
- var ConfigurationError = class extends BuildError {
72
- /**
73
- * Creates a new ConfigurationError
74
- * @param message - Error message
75
- */
76
- constructor(message) {
77
- super(message, 3);
78
- this.name = "ConfigurationError";
79
- }
80
- };
81
- var UnsupportedSyntaxError = class extends BundleError {
82
- /**
83
- * Creates an instance of UnsupportedSyntaxError.
84
- * @param node The node with unsupported syntax
85
- * @param message The message to display (default: 'Syntax not yet supported')
86
- */
87
- constructor(node, message = "Syntax not yet supported") {
88
- const syntaxKindName = SyntaxKind[node.kind] ?? `Unknown(${node.kind})`;
89
- const nodeText = node.getText ? node.getText().slice(0, 100) : "<no text>";
90
- super(`${message}: ${syntaxKindName} - "${nodeText}"`);
91
- this.name = "UnsupportedSyntaxError";
92
- }
93
- };
94
- var castError = (exception) => {
95
- if (exception instanceof Error) {
96
- return exception;
97
- }
98
- return new Error(typeof exception === "string" ? exception : "Unknown error");
99
- };
31
+ } from "./YC2FB45E.js";
100
32
 
101
33
  // src/files.ts
102
34
  import { dirname } from "node:path";
@@ -441,6 +373,73 @@ import MagicString2 from "magic-string";
441
373
  import { mkdir as mkdir2, writeFile as writeFile2 } from "node:fs/promises";
442
374
  import { basename, posix } from "node:path";
443
375
 
376
+ // src/errors.ts
377
+ import { SyntaxKind } from "typescript";
378
+ var BuildError = class extends Error {
379
+ /**
380
+ * Creates a new BuildError
381
+ * @param message - Error message
382
+ * @param code - Exit code (default: 1)
383
+ */
384
+ constructor(message, code = 1) {
385
+ super(message);
386
+ this.code = code;
387
+ this.name = "BuildError";
388
+ Error.captureStackTrace(this, this.constructor);
389
+ }
390
+ };
391
+ var TypeCheckError = class extends BuildError {
392
+ /**
393
+ * Creates a new TypeCheckError
394
+ * @param message - Error message
395
+ * @param diagnostics - Optional TypeScript diagnostics output
396
+ */
397
+ constructor(message, diagnostics) {
398
+ super(message, 1);
399
+ this.diagnostics = diagnostics;
400
+ this.name = "TypeCheckError";
401
+ }
402
+ };
403
+ var BundleError = class extends BuildError {
404
+ /**
405
+ * Creates a new BundleError
406
+ * @param message - Error message
407
+ */
408
+ constructor(message) {
409
+ super(message, 2);
410
+ this.name = "BundleError";
411
+ }
412
+ };
413
+ var ConfigurationError = class extends BuildError {
414
+ /**
415
+ * Creates a new ConfigurationError
416
+ * @param message - Error message
417
+ */
418
+ constructor(message) {
419
+ super(message, 3);
420
+ this.name = "ConfigurationError";
421
+ }
422
+ };
423
+ var UnsupportedSyntaxError = class extends BundleError {
424
+ /**
425
+ * Creates an instance of UnsupportedSyntaxError.
426
+ * @param node The node with unsupported syntax
427
+ * @param message The message to display (default: 'Syntax not yet supported')
428
+ */
429
+ constructor(node, message = "Syntax not yet supported") {
430
+ const syntaxKindName = SyntaxKind[node.kind] ?? `Unknown(${node.kind})`;
431
+ const nodeText = node.getText ? node.getText().slice(0, 100) : "<no text>";
432
+ super(`${message}: ${syntaxKindName} - "${nodeText}"`);
433
+ this.name = "UnsupportedSyntaxError";
434
+ }
435
+ };
436
+ var castError = (exception) => {
437
+ if (exception instanceof Error) {
438
+ return exception;
439
+ }
440
+ return new Error(typeof exception === "string" ? exception : "Unknown error");
441
+ };
442
+
444
443
  // src/dts/declaration-processor.ts
445
444
  import {
446
445
  canHaveModifiers,
@@ -614,29 +613,7 @@ var DeclarationProcessor = class _DeclarationProcessor {
614
613
  return length;
615
614
  }
616
615
  for (const node of sourceFile.statements) {
617
- if (isImportDeclaration(node)) {
618
- if (node.importClause?.phaseModifier === SyntaxKind2.TypeKeyword) {
619
- const importKeywordEnd = node.getStart() + "import".length;
620
- const typeMatch = code.slice(importKeywordEnd, node.getEnd()).match(typeMatcher);
621
- if (typeMatch?.index !== void 0) {
622
- const typeKeywordStart = importKeywordEnd + typeMatch.index;
623
- const typeKeywordEnd = typeKeywordStart + "type".length;
624
- code.remove(typeKeywordStart, typeKeywordEnd + getTrailingWhitespaceLength(typeKeywordEnd, node.getEnd()));
625
- }
626
- } else {
627
- inlineTypePattern.lastIndex = 0;
628
- let match;
629
- const replacements = [];
630
- while ((match = inlineTypePattern.exec(code.slice(node.getStart(), node.getEnd()))) !== null) {
631
- const typeKeywordStart = node.getStart() + match.index + match[1].length;
632
- const typeKeywordEnd = typeKeywordStart + "type".length;
633
- replacements.push({ start: typeKeywordStart, end: typeKeywordEnd + getTrailingWhitespaceLength(typeKeywordEnd, node.getEnd()) });
634
- }
635
- for (let i = replacements.length - 1; i >= 0; i--) {
636
- code.remove(replacements[i].start, replacements[i].end);
637
- }
638
- }
639
- } else if (isExportDeclaration(node)) {
616
+ if (isExportDeclaration(node)) {
640
617
  if (node.exportClause && isNamedExports(node.exportClause) && node.exportClause.elements.length === 0 && !node.moduleSpecifier) {
641
618
  code.remove(getStart(node), getEnd(node));
642
619
  } else if (node.isTypeOnly) {
@@ -1227,8 +1204,7 @@ var DeclarationBundler = class {
1227
1204
  forEachChild2(sourceFile, visitQualified);
1228
1205
  }
1229
1206
  const finalValueExports = [...new Set(valueExports.map(exportsMapper))];
1230
- const valueExportsSet = new Set(finalValueExports);
1231
- const finalTypeExports = [...new Set(typeExports.map(exportsMapper).filter((t) => !valueExportsSet.has(t)))];
1207
+ const finalTypeExports = [...new Set(typeExports.map(exportsMapper).filter((t) => !new Set(finalValueExports).has(t)))];
1232
1208
  return { code: magic.toString(), externalImports, typeExports: finalTypeExports, valueExports: finalValueExports };
1233
1209
  }
1234
1210
  /**
@@ -1263,9 +1239,8 @@ var DeclarationBundler = class {
1263
1239
  }
1264
1240
  for (const [name, sourcesSet] of declarationSources) {
1265
1241
  if (sourcesSet.size > 1) {
1266
- const sources = Array.from(sourcesSet);
1267
1242
  let suffix = 1;
1268
- for (const modulePath of sources.slice(1)) {
1243
+ for (const modulePath of Array.from(sourcesSet).slice(1)) {
1269
1244
  let candidate = `${name}$${suffix}`;
1270
1245
  while (declarationSources.has(candidate)) {
1271
1246
  candidate = `${name}$${++suffix}`;
@@ -1295,9 +1270,15 @@ var DeclarationBundler = class {
1295
1270
  codeBlocks.push(strippedCode.trim());
1296
1271
  }
1297
1272
  }
1298
- const uniqueTypeReferences = [...new Set(allTypeReferences)];
1273
+ const typeReferencesSet = new Set(allTypeReferences);
1299
1274
  const uniqueFileReferences = [...new Set(allFileReferences)];
1300
1275
  const mergedExternalImports = mergeImports(allExternalImports);
1276
+ for (const imp of mergedExternalImports) {
1277
+ if (imp.includes('"node:') || imp.includes("'node:")) {
1278
+ typeReferencesSet.add("node");
1279
+ }
1280
+ }
1281
+ const uniqueTypeReferences = [...typeReferencesSet];
1301
1282
  const finalValueExports = [...new Set(allValueExports)];
1302
1283
  const finalValueExportsSet = new Set(finalValueExports);
1303
1284
  const finalTypeExports = [...new Set(allTypeExports.filter((typeExport) => !finalValueExportsSet.has(typeExport)))];
@@ -1330,6 +1311,9 @@ var DeclarationBundler = class {
1330
1311
  */
1331
1312
  bundle(entryPoint) {
1332
1313
  const dtsEntryPoint = this.resolveEntryPoint(entryPoint, this.options.compilerOptions);
1314
+ if (dtsEntryPoint === void 0) {
1315
+ return "";
1316
+ }
1333
1317
  const { modules, bundledSpecifiers } = this.buildModuleGraph(dtsEntryPoint);
1334
1318
  const { code } = this.combineModules(this.sortModules(modules, dtsEntryPoint), bundledSpecifiers);
1335
1319
  return DeclarationProcessor.postProcess(createSourceFile(dtsEntryPoint, code, ScriptTarget.Latest, true));
@@ -1342,31 +1326,38 @@ var DeclarationBundler = class {
1342
1326
  */
1343
1327
  resolveEntryPoint(entryPoint, compilerOptions) {
1344
1328
  const dtsEntryPoint = sys.resolvePath(entryPoint.endsWith(FileExtension.DTS) ? entryPoint : this.sourceToDeclarationPath(entryPoint));
1345
- if (!this.declarationFiles.has(dtsEntryPoint)) {
1346
- const availableFiles = Array.from(this.declarationFiles.keys());
1347
- const entryPointFilename = basename(entryPoint);
1348
- const similarFiles = availableFiles.filter((filePath) => filePath.includes(entryPointFilename));
1349
- throw new BundleError(
1350
- `Entry point declaration file not found: ${dtsEntryPoint || "unknown"}
1329
+ if (this.declarationFiles.has(dtsEntryPoint)) {
1330
+ return dtsEntryPoint;
1331
+ }
1332
+ if (!entryPoint.endsWith(FileExtension.DTS)) {
1333
+ return void 0;
1334
+ }
1335
+ const availableFiles = Array.from(this.declarationFiles.keys());
1336
+ const entryPointFilename = basename(entryPoint);
1337
+ const similarFiles = availableFiles.filter((filePath) => filePath.includes(entryPointFilename));
1338
+ throw new BundleError(
1339
+ `Entry point declaration file not found: ${dtsEntryPoint || "unknown"}
1351
1340
  Original entry: ${entryPoint}
1352
1341
  Compiler options: outDir=${compilerOptions.outDir || "dist"}, rootDir=${compilerOptions.rootDir || "not set"}
1353
1342
  Similar files found:
1354
1343
  ${similarFiles.map((f) => ` - ${f}`).join("\n")}
1355
1344
  Total available files: ${availableFiles.length}`
1356
- );
1357
- }
1358
- return dtsEntryPoint;
1345
+ );
1359
1346
  }
1360
1347
  };
1361
1348
  async function bundleDeclarations(options) {
1362
- await mkdir2(options.compilerOptions.outDir, defaultDirOptions);
1349
+ if (!await Files.exists(options.compilerOptions.outDir)) {
1350
+ await mkdir2(options.compilerOptions.outDir, defaultDirOptions);
1351
+ }
1363
1352
  const dtsBundler = new DeclarationBundler(options);
1364
- const bundleTasks = Object.entries(options.entryPoints).map(async ([entryName, entryPoint]) => {
1365
- const outPath = Paths.join(options.compilerOptions.outDir, `${entryName}.d.ts`);
1353
+ const bundleTasks = [];
1354
+ for (const [entryName, entryPoint] of Object.entries(options.entryPoints)) {
1366
1355
  const content = dtsBundler.bundle(entryPoint);
1367
- await writeFile2(outPath, content, Encoding.utf8);
1368
- return { path: Paths.relative(options.currentDirectory, outPath), size: content.length };
1369
- });
1356
+ if (content.length > 0) {
1357
+ const outPath = Paths.join(options.compilerOptions.outDir, `${entryName}.d.ts`);
1358
+ bundleTasks.push(writeFile2(outPath, content, Encoding.utf8).then(() => ({ path: Paths.relative(options.currentDirectory, outPath), size: content.length })));
1359
+ }
1360
+ }
1370
1361
  const results = await Promise.all(bundleTasks);
1371
1362
  dtsBundler.clearExternalFiles();
1372
1363
  return results;
@@ -1802,9 +1793,11 @@ var FileManager = class {
1802
1793
  }
1803
1794
  const writeTasks = [];
1804
1795
  for (const [filePath, { code }] of this.declarationFiles) {
1805
- writeTasks.push(this.writeFile(projectDirectory, filePath, code));
1796
+ if (code.length > 0) {
1797
+ writeTasks.push(this.writeFile(projectDirectory, filePath, code));
1798
+ }
1806
1799
  }
1807
- return Promise.all(writeTasks);
1800
+ return (await Promise.all(writeTasks)).filter((result) => result !== void 0);
1808
1801
  }
1809
1802
  /**
1810
1803
  * Resolves entry points for declaration bundling.
@@ -1886,14 +1879,16 @@ var FileManager = class {
1886
1879
  */
1887
1880
  processEmittedFiles() {
1888
1881
  for (const { path, text } of this.pendingFiles) {
1889
- this.declarationFiles.set(path, DeclarationProcessor.preProcess(createSourceFile2(path, text, ScriptTarget2.Latest, true)));
1882
+ const result = DeclarationProcessor.preProcess(createSourceFile2(path, text, ScriptTarget2.Latest, true));
1883
+ if (result.code.length > 0) {
1884
+ this.declarationFiles.set(path, result);
1885
+ }
1890
1886
  }
1891
1887
  this.pendingFiles.length = 0;
1892
1888
  }
1893
1889
  /**
1894
1890
  * Custom inspection method for better type representation.
1895
1891
  * @returns The string 'FileManager'
1896
- * @internal
1897
1892
  */
1898
1893
  get [Symbol.toStringTag]() {
1899
1894
  return "FileManager";
@@ -2100,6 +2095,7 @@ import { performance as performance2 } from "node:perf_hooks";
2100
2095
  import { sys as sys2, createIncrementalProgram, formatDiagnostics, formatDiagnosticsWithColorAndContext, parseJsonConfigFileContent, readConfigFile, findConfigFile } from "typescript";
2101
2096
  var globCharacters = /[*?\\[\]!].*$/;
2102
2097
  var domPredicate = (lib) => lib.toUpperCase() === "DOM";
2098
+ var tsLogo = TextFormat.bgBlue(TextFormat.bold(TextFormat.whiteBright(" TS ")));
2103
2099
  var diagnosticsHost = { getNewLine: () => sys2.newLine, getCurrentDirectory: sys2.getCurrentDirectory, getCanonicalFileName: (fileName) => fileName };
2104
2100
  var _triggerRebuild_dec, _processDeclarations_dec, _transpile_dec, _typeCheck_dec, _build_dec, _TypeScriptProject_decorators, _init3;
2105
2101
  _TypeScriptProject_decorators = [closeOnExit], _build_dec = [measure("Build")], _typeCheck_dec = [measure("Type-checking")], _transpile_dec = [measure("Transpile", true)], _processDeclarations_dec = [measure("Bundle Declarations", true)], _triggerRebuild_dec = [debounce(100)];
@@ -2128,10 +2124,7 @@ var _TypeScriptProject = class _TypeScriptProject {
2128
2124
  }
2129
2125
  this.fileManager = new FileManager(buildCache);
2130
2126
  this.builderProgram = createIncrementalProgram({ rootNames, options: this.configuration.compilerOptions, projectReferences, configFileParsingDiagnostics });
2131
- const entryPointsPromise = this.getEntryPoints(entryPoints);
2132
- entryPointsPromise.catch(() => {
2133
- });
2134
- this.buildConfiguration = { entryPoints: entryPointsPromise, target: toEsTarget(target), outDir, ...tsbuildOptions };
2127
+ this.buildConfiguration = { entryPoints: this.getEntryPoints(entryPoints), target: toEsTarget(target), outDir, ...tsbuildOptions };
2135
2128
  }
2136
2129
  /**
2137
2130
  * Cleans the output directory
@@ -2141,8 +2134,7 @@ var _TypeScriptProject = class _TypeScriptProject {
2141
2134
  return Files.empty(this.buildConfiguration.outDir);
2142
2135
  }
2143
2136
  async build() {
2144
- const tsLogo = TextFormat.bgBlue(TextFormat.bold(TextFormat.whiteBright(" TS ")));
2145
- Logger.header(`${tsLogo} tsbuild v${"1.6.5"}${this.configuration.compilerOptions.incremental && this.configuration.buildCache?.isValid() ? " [incremental]" : ""}`);
2137
+ Logger.header(`${tsLogo} tsbuild v${"1.7.1"}${this.configuration.compilerOptions.incremental && this.configuration.buildCache?.isValid() ? " [incremental]" : ""}`);
2146
2138
  try {
2147
2139
  const processes = [];
2148
2140
  const filesWereEmitted = await this.typeCheck();
@@ -2201,7 +2193,7 @@ var _TypeScriptProject = class _TypeScriptProject {
2201
2193
  }
2202
2194
  if (this.configuration.compilerOptions.emitDecoratorMetadata) {
2203
2195
  try {
2204
- const { swcDecoratorMetadataPlugin } = await import("./GQLOAEUW.js");
2196
+ const { swcDecoratorMetadataPlugin } = await import("./GNBUFD72.js");
2205
2197
  plugins.push(swcDecoratorMetadataPlugin);
2206
2198
  } catch {
2207
2199
  throw new ConfigurationError("emitDecoratorMetadata is enabled but @swc/core is not installed. Install it with: pnpm add -D @swc/core");
@@ -2533,10 +2525,10 @@ var _TypeScriptProject = class _TypeScriptProject {
2533
2525
  * @returns Elapsed time in milliseconds
2534
2526
  */
2535
2527
  static elapsed(markName) {
2536
- const endMark = performance2.mark(`${markName}:end`);
2537
- const ms = ~~(endMark.startTime - performance2.getEntriesByName(markName, "mark")[0].startTime);
2528
+ const { name, startTime } = performance2.mark(`${markName}:end`);
2529
+ const ms = ~~(startTime - performance2.getEntriesByName(markName, "mark")[0].startTime);
2538
2530
  performance2.clearMarks(markName);
2539
- performance2.clearMarks(endMark.name);
2531
+ performance2.clearMarks(name);
2540
2532
  return ms;
2541
2533
  }
2542
2534
  };
@@ -3,7 +3,7 @@ import {
3
3
  Json,
4
4
  Paths,
5
5
  typeScriptExtensionExpression
6
- } from "./7FPDHUPW.js";
6
+ } from "./YC2FB45E.js";
7
7
 
8
8
  // src/plugins/decorator-metadata.ts
9
9
  import { dirname } from "node:path";
@@ -81,6 +81,7 @@ var scriptTargetToEsTarget = {
81
81
  [ScriptTarget.ES2022]: "ES2022",
82
82
  [ScriptTarget.ES2023]: "ES2023",
83
83
  [ScriptTarget.ES2024]: "ES2024",
84
+ [ScriptTarget.ES2025]: "ES2025",
84
85
  [ScriptTarget.ESNext]: "ESNext",
85
86
  [ScriptTarget.JSON]: "ESNext"
86
87
  };
@@ -119,7 +120,6 @@ var typeMatcher = /\btype\b/;
119
120
  var sourceScriptExtensionExpression = /(?<!\.d)\.[jt]sx?$/;
120
121
  var typeScriptExtensionExpression = /(\.tsx?)$/;
121
122
  var processEnvExpansionPattern = /\$\{process\.env\.([^}]+)\}/g;
122
- var inlineTypePattern = /([{,]\s+)type\s+/g;
123
123
 
124
124
  // src/paths.ts
125
125
  import { lstat } from "node:fs/promises";
@@ -279,7 +279,6 @@ export {
279
279
  sourceScriptExtensionExpression,
280
280
  typeScriptExtensionExpression,
281
281
  processEnvExpansionPattern,
282
- inlineTypePattern,
283
282
  Paths,
284
283
  Json
285
284
  };
package/dist/tsbuild.js CHANGED
@@ -2,8 +2,8 @@
2
2
  import {
3
3
  BuildError,
4
4
  TypeScriptProject
5
- } from "./SFYLP6W7.js";
6
- import "./7FPDHUPW.js";
5
+ } from "./DT4U2QPA.js";
6
+ import "./YC2FB45E.js";
7
7
 
8
8
  // src/tsbuild.ts
9
9
  import { sys } from "typescript";
@@ -30,7 +30,7 @@ if (help) {
30
30
  process.exit(0);
31
31
  }
32
32
  if (version) {
33
- console.log("1.6.5");
33
+ console.log("1.7.1");
34
34
  process.exit(0);
35
35
  }
36
36
  var typeScriptOptions = {
@@ -1,7 +1,9 @@
1
- import { Plugin, TsconfigRaw } from "esbuild";
2
- import { FileSystemEvent, WatchrOptions } from "@d1g1tal/watchr";
3
- import { CompilerOptions, Diagnostic, ProjectReference, ScriptTarget } from "typescript";
4
- import { PerformanceEntry, PerformanceMeasureOptions } from "node:perf_hooks";
1
+ /// <reference types="node" />
2
+
3
+ import type { Plugin, TsconfigRaw } from "esbuild";
4
+ import type { FileSystemEvent, WatchrOptions } from "@d1g1tal/watchr";
5
+ import type { CompilerOptions, Diagnostic, ProjectReference, ScriptTarget } from "typescript";
6
+ import type { PerformanceEntry, PerformanceMeasureOptions } from "node:perf_hooks";
5
7
 
6
8
  declare global {
7
9
  interface ImportMeta {
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  TypeScriptProject
3
- } from "./SFYLP6W7.js";
4
- import "./7FPDHUPW.js";
3
+ } from "./DT4U2QPA.js";
4
+ import "./YC2FB45E.js";
5
5
  export {
6
6
  TypeScriptProject
7
7
  };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@d1g1tal/tsbuild",
3
3
  "author": "D1g1talEntr0py",
4
- "version": "1.6.5",
4
+ "version": "1.7.1",
5
5
  "license": "MIT",
6
6
  "description": "A fast, ESM-only TypeScript build tool combining the TypeScript API for type checking and declaration generation, esbuild for bundling, and SWC for decorator metadata.",
7
7
  "homepage": "https://github.com/D1g1talEntr0py/tsbuild#readme",
@@ -26,10 +26,11 @@
26
26
  "access": "public"
27
27
  },
28
28
  "type": "module",
29
+ "types": "./dist/type-script-project.d.ts",
29
30
  "exports": {
30
31
  ".": {
31
- "types": "./dist/index.d.ts",
32
- "import": "./dist/index.js"
32
+ "types": "./dist/type-script-project.d.ts",
33
+ "import": "./dist/type-script-project.js"
33
34
  }
34
35
  },
35
36
  "files": [
@@ -43,26 +44,27 @@
43
44
  "tsbuild": "./dist/tsbuild.js"
44
45
  },
45
46
  "dependencies": {
46
- "@d1g1tal/watchr": "^1.0.4",
47
+ "@d1g1tal/watchr": "^1.0.5",
47
48
  "esbuild": "^0.27.4",
48
49
  "magic-string": "^0.30.21"
49
50
  },
50
51
  "devDependencies": {
51
- "@babel/plugin-proposal-decorators": "^7.29.0",
52
52
  "@eslint/js": "^10.0.1",
53
- "@rolldown/plugin-babel": "^0.2.2",
54
53
  "@types/node": "^25.5.0",
55
- "@typescript-eslint/eslint-plugin": "^8.57.1",
56
- "@typescript-eslint/parser": "^8.57.1",
57
- "@vitest/coverage-v8": "^4.1.0",
54
+ "@typescript-eslint/eslint-plugin": "^8.57.2",
55
+ "@typescript-eslint/parser": "^8.57.2",
56
+ "@vitest/coverage-v8": "^4.1.2",
58
57
  "eslint": "^10.1.0",
59
- "eslint-plugin-jsdoc": "^62.8.0",
58
+ "eslint-plugin-jsdoc": "^62.8.1",
60
59
  "fs-monkey": "^1.1.0",
61
- "memfs": "^4.56.11",
60
+ "memfs": "^4.57.1",
62
61
  "tsx": "^4.21.0",
63
- "typescript": "^5.9.3",
64
- "typescript-eslint": "^8.57.1",
65
- "vitest": "^4.1.0"
62
+ "typescript": "^6.0.2",
63
+ "typescript-eslint": "^8.57.2",
64
+ "vitest": "^4.1.2"
65
+ },
66
+ "peerDependencies": {
67
+ "typescript": ">=5.6.3"
66
68
  },
67
69
  "keywords": [
68
70
  "typescript",
@@ -83,6 +85,7 @@
83
85
  "lint": "eslint ./src",
84
86
  "test": "vitest run",
85
87
  "test:coverage": "vitest run --coverage",
86
- "test:watch": "vitest"
88
+ "test:watch": "vitest",
89
+ "test:compat": "tsx tests/scripts/test-ts-compat.ts --versions 5"
87
90
  }
88
91
  }