@d1g1tal/tsbuild 1.6.0 → 1.6.2

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 ADDED
@@ -0,0 +1,624 @@
1
+ ## [1.6.2](https://github.com/D1g1talEntr0py/tsbuild/compare/v1.6.1...v1.6.2) (2026-03-18)
2
+
3
+ ### Bug Fixes
4
+
5
+ * **compiler:** rewrite relative specifiers to include .js extension (39bc1a19d6d79cebb298e7717435591099f47c11)
6
+ - Add relativeSpecifierPattern to detect bare relative imports
7
+ - Implement rewriteRelativeSpecifiers to append .js for ESM Node resolution
8
+ - Apply rewriteRelativeSpecifiers before writing files in FileManager
9
+ - Update fileMapper in output plugin to rewrite JS contents
10
+
11
+
12
+ ### Miscellaneous Chores
13
+
14
+ * **workspace:** update workspace configurations and metadata (af85d4d72aa726a9f1d2b5ef60dc2e3beae8318c)
15
+ - Remove FORCE_JAVASCRIPT_ACTIONS_TO_NODE24 from github actions CI
16
+ - Add compiler, type-checking, and library keywords to package.json
17
+ - Format babel preset plugins array in vitest.config.ts
18
+ - Disable typecheck in vitest configuration explicitly
19
+
20
+ ## [1.6.1](https://github.com/D1g1talEntr0py/tsbuild/compare/v1.6.0...v1.6.1) (2026-03-18)
21
+
22
+ ### Bug Fixes
23
+
24
+ * **test:** workaround vitest 4.1 decorator regression (e018d99561fad324f4f8c73bf34fd6b4fcd881e5)
25
+ - add @rolldown/plugin-babel and @babel/plugin-proposal-decorators to devDependencies
26
+ - update vitest.config.ts to transform decorators using babel
27
+ - introduce tests/tsconfig.json for test environment typing
28
+ - bump typescript-eslint and @types/node dependencies
29
+ - sync pnpm-lock.yaml with updated dependencies
30
+
31
+
32
+ ### Miscellaneous Chores
33
+
34
+ * **pkg:** update package manager and project scripts (57a0ff3aa552d49aa56745bd0179ee245fd70ac7)
35
+ - bump pnpm packageManager field to 10.32.1
36
+ - include CHANGELOG.md in the list of published files
37
+ - remove deprecated prepare script
38
+ - add test:watch convenience script for vitest
39
+
40
+ * **style:** add editorconfig (55d07cb8090f6874e7f16a5c7943309e6ade8f64)
41
+ - establish consistent coding styles across the workspace
42
+ - configure standard indents, charsets, and newline rules
43
+
44
+
45
+ ### Continuous Integration
46
+
47
+ * force actions to use Node.js 24 (9eaac47d702c40ce9d8aeb7b7e6d990ccfa3b51d)
48
+ * updated actions to latest versions (a5a7b0f36420cad83192fca489c5ff9bc376b9d7)
49
+ * upgrade github actions runner versions (b9ed4f72294dee56713155623b016fc4951c8931)
50
+ - bump actions/checkout to v6
51
+ - bump pnpm/action-setup to v5
52
+ - bump actions/setup-node to v6
53
+ - enforce using latest npm globally in publish workflow
54
+
55
+ ## [1.6.0](https://github.com/D1g1talEntr0py/tsbuild/compare/v1.5.0...v1.6.0) (2026-03-12)
56
+
57
+ ### Features
58
+
59
+ * **logger:** add ANSI-safe header width and styled build banner (6dd2e72306dcc29998b2a1900c51e044d5cd0b9a)
60
+ - Fix header box width calculation by stripping ANSI escape codes before measuring message length
61
+ - Add TextFormat import to TypeScriptProject for use in the build header
62
+ - Prefix build header message with a styled blue TS logo
63
+ - Rename logPerformance label from 'Process Declarations' to 'Bundle Declarations'
64
+ - Update logger subSteps test to cover filtering behaviour and new PerformanceSubStep shape
65
+ - Add test case asserting nothing is logged when all steps are below the threshold
66
+
67
+
68
+ ### Bug Fixes
69
+
70
+ * **incremental:** prevent false change detection on .tsbuildinfo writes (8cb4d9631336d1a2a4401da0b1bcdacdc873bb6a)
71
+ - Remove forced declarationDir: undefined override from compiler option overrides
72
+ - Remove corresponding type entry from CompilerOptionOverrides
73
+ - Move hasEmittedFiles tracking inside the non-buildinfo branch of fileWriter so only real output files (not .tsbuildinfo) set the flag
74
+ - Return true from the hasChanged check when declaration:false is set, ensuring esbuild always runs when declarations are disabled
75
+ - Add test verifying that writing only .tsbuildinfo does not set the emitted flag
76
+ - Update existing incremental no-changes test to properly simulate a prior build with cached declarations
77
+ - Update test asserting esbuild is always invoked for declaration:false projects
78
+ - Remove outdated declarationDir override test
79
+ - Remove outdated test asserting esbuild was skipped for declaration:false incremental builds
80
+ - Add incremental: false to basic build integration tests to keep them hermetic
81
+
82
+
83
+ ### Performance Improvements
84
+
85
+ * **logger:** filter sub-steps below 5ms to reduce build output noise (fe37d375ca8f3ee79f3c1602cc0240f0d6aefd94)
86
+ - Add ms field to PerformanceSubStep type to carry the raw numeric duration
87
+ - Update addPerformanceStep to accept a number and derive the formatted string internally
88
+ - Update TypeScriptProject.elapsed() to return a number instead of a pre-formatted string
89
+ - Update all call sites to pass numeric millisecond values
90
+ - Filter out sub-steps with ms < 5 before logging; return early if nothing remains
91
+ - Update tests to reflect the new numeric API and updated PerformanceSubStep shape
92
+
93
+
94
+ ### Documentation
95
+
96
+ * update runtime requirements, watchr link, and exports docs (5fe88a82785f56743f82e68622e9986924444b10)
97
+ - Bump minimum Node.js requirement from 20.16.0 to 22+ in README and copilot instructions
98
+ - Bump minimum pnpm requirement from 9+ to 10+ in copilot instructions
99
+ - Update watchr link in README to point to the correct fork repository
100
+ - Update exports condition list to include node and module conditions
101
+ - Remove stale Performance Notes and Testing Gaps sections from copilot instructions
102
+
103
+
104
+ ### Miscellaneous Chores
105
+
106
+ * **deps:** update dependencies (3b4a3acacd4306e9110b1d1858ce2e43326c8c31)
107
+
108
+ ### Build System
109
+
110
+ * **deps:** bump esbuild, vitest, and related packages (4f10321b7772e0ea6c94faa86d38f3156d3a0f7b)
111
+ - Upgrade esbuild from 0.27.3 to 0.27.4
112
+ - Upgrade vitest and @vitest/* packages from 4.0.18 to 4.1.0
113
+ - Upgrade @vitest/coverage-v8 from 4.0.18 to 4.1.0
114
+ - Upgrade eslint-plugin-jsdoc from 62.7.1 to 62.8.0
115
+ - Add convert-source-map 2.0.0 as new transitive dependency
116
+ - Upgrade ast-v8-to-istanbul from 0.3.12 to 1.0.0
117
+ - Upgrade es-module-lexer from 1.7.0 to 2.0.0
118
+ - Upgrade std-env from 3.10.0 to 4.0.0
119
+ - Upgrade tinyrainbow from 3.0.3 to 3.1.0
120
+ - Update pnpm-lock.yaml to reflect all dependency changes
121
+ - Remove prepublishOnly script from package.json
122
+
123
+ ## [1.5.0](https://github.com/D1g1talEntr0py/tsbuild/compare/v1.4.1...v1.5.0) (2026-03-08)
124
+
125
+ ### Features
126
+
127
+ * **compiler:** always inject 'node' into compiler types (04f1e680dc9a8a76458fd82831f007463588fa6b)
128
+ - Merges 'node' into the resolved types array when building the TypeScript incremental program, using a Set to deduplicate
129
+ - User-specified types from tsconfig and tool options are preserved and merged, so 'node' is always present without overwriting other entries
130
+
131
+ * **compiler:** force declarationDir to undefined in overrides (f1fd8efb22658cedf75f296567fc96af618731c8)
132
+ - Adds declarationDir: undefined to CompilerOptionOverrides type and constant so .d.ts output always goes to outDir, making declaration files reliably discoverable by the bundler regardless of user tsconfig settings
133
+ - Updates the constants test to assert declarationDir is undefined in the overrides object
134
+
135
+
136
+ ### Documentation
137
+
138
+ * update minimum node.js version to 22+ (39e4a319afe4718b052ee2170583e9a928c2dc8a)
139
+ - Updates the README description to reflect that the tool targets Node.js 22+ instead of the previously stated 20.16.0+
140
+
141
+
142
+ ### Miscellaneous Chores
143
+
144
+ * **ci:** update the noode version for the README.md badge and packageManager pnpm version (89467c98966ea232fc015df8c6e5fbcaeb327b55)
145
+ * **docs:** moved quick start section after installation and fixed some spelling errors (ea23a1a3e2a576c73caaa79514db3306576cd1fd)
146
+ * **docs:** update the incremental builds section (9a971879a09a48ffb91177a34a3b9daaa8046f38)
147
+
148
+ ### Tests
149
+
150
+ * **compiler:** add tests for declarationDir and types overrides (a5ba00a8ed1190ff531e1dbb0af4db8880bbb18f)
151
+ - Adds a test asserting declarationDir is overridden to undefined even when set in tsconfig
152
+ - Adds a test asserting types defaults to include 'node' when not specified in tsconfig
153
+ - Adds a test asserting user-specified types are merged with the 'node' default
154
+ - Adds a test asserting 'node' is not duplicated when the user already includes it
155
+ - Adds a @types/node stub in the memfs test environment to prevent TS2688 errors during test runs where node_modules is unavailable
156
+ - Fixes mock type casts to use 'as unknown as Diagnostic' for stricter TypeScript compatibility
157
+ - Changes private transpile() call in a test to use bracket access to avoid visibility errors
158
+
159
+ ## [1.4.1](https://github.com/D1g1talEntr0py/tsbuild/compare/v1.4.0...v1.4.1) (2026-03-08)
160
+
161
+ ### Bug Fixes
162
+
163
+ * **ci:** drop node 20 and fix publish git checks (3ff1b239fcc1f7d2d0814bc59d3a61632671e043)
164
+ - Removes Node.js 20 from the CI test matrix, keeping only 22 and 24 as actively tested versions
165
+ - Adds --no-git-checks to the publish command to prevent pnpm from blocking the release due to git state checks in the semantic-release automation context
166
+
167
+ ## [1.4.0](https://github.com/D1g1talEntr0py/tsbuild/compare/v1.3.2...v1.4.0) (2026-03-08)
168
+
169
+ ### Features
170
+
171
+ * **cache:** add isValid() to BuildCache interface (2987352e2391ccf62c032e68ee668468cd18ddf0)
172
+ - Adds isValid() method to IncrementalBuildCache returning !this.invalidated
173
+ - Adds isValid(): boolean to the BuildCache interface with JSDoc
174
+ - Adds missing JSDoc comments to other BuildCache interface methods
175
+ - Fixes incremental build header label to only show when cache is actually valid
176
+
177
+
178
+ ### Documentation
179
+
180
+ * expand Quick Start section in README (c31223b8296100af4899fcdec468580b5fe72a4f)
181
+ - Adds minimal config example showing no tsbuild section is needed
182
+ - Adds noExternal usage example for bundling a specific package
183
+ - Adds preferred incremental tsconfig setup with annotated options
184
+ - Adds preferred non-incremental tsconfig setup for CI environments
185
+ - Clarifies entry point inference and external dependency defaults
186
+
187
+
188
+ ### Build System
189
+
190
+ * update package metadata, deps, and release config (f203cf1611b337509e1f8c30d3b3ff9aebd28f1e)
191
+ - Reorganizes package.json field order, grouping author/license/homepage/repository/bugs/maintainers/engines/publishConfig near the top
192
+ - Adds maintainers field with name and email
193
+ - Adds README.md and LICENSE to published files list
194
+ - Moves keywords field to end of package.json
195
+ - Updates release commands in .releaserc.json to use pnpm with lint and build steps before pack
196
+ - Switches publishCmd to pnpm publish --provenance
197
+ - Reorders tsconfig.json compiler options for clarity, groups isolated/verbatim options, moves lib after noUncheckedIndexedAccess, removes moduleDetection: force
198
+ - Bumps @types/node, eslint, and memfs dev dependencies to latest minor versions
199
+ - Updates pnpm-lock.yaml to reflect all dependency version changes
200
+
201
+ ## [1.3.2](https://github.com/D1g1talEntr0py/tsbuild/compare/v1.3.1...v1.3.2) (2026-03-01)
202
+
203
+ ### Bug Fixes
204
+
205
+ * updated the entry point inferrence handling message to be more helpful (eeddaaab6faf553098cbf0e85ecd9f0c05d22718)
206
+
207
+ ### Tests
208
+
209
+ * remove test coverage (6f2ba17ce701d2b37232ab0f8fb64f4891557bee)
210
+
211
+ ## [1.3.1](https://github.com/D1g1talEntr0py/tsbuild/compare/v1.3.0...v1.3.1) (2026-03-01)
212
+
213
+ ### Bug Fixes
214
+
215
+ * **entry-points:** Resolves conditional exports (65a5d4835ba51e906422982ad1e4d1ba83eeae94)
216
+
217
+ ### Documentation
218
+
219
+ * updated readme to include tsdown in the tool comparison section (ad3f38a38d05314aabbcc10bba1e55856b50086d)
220
+
221
+ ### Miscellaneous Chores
222
+
223
+ * **repo:** Updates ignore and README badges (9bdd6ce61a2f97b92ede9f118df7b20aaabb0074)
224
+
225
+ ## [1.3.0](https://github.com/D1g1talEntr0py/tsbuild/compare/v1.2.5...v1.3.0) (2026-02-28)
226
+
227
+ ### Features
228
+
229
+ * **logger:** add sub-step tree logging to performance output (2a775ca35d4b3524d2862f6e3b5e15040c2efb55)
230
+ Introduces timed sub-step display beneath each build step in the
231
+ performance log, making it easy to see where time is spent within a
232
+ single decorated method.
233
+
234
+ - Adds PerformanceSubStep type and exports it from the public types index
235
+ - Extends PerformanceEntryDetail to carry an optional steps array
236
+ - Adds Logger.subSteps() with tree-style ├─/└─ formatting and aligned columns
237
+ - Adds module-level pendingSteps buffer to the performance decorator
238
+ - Exports addPerformanceStep() so callers can register sub-steps during a decorated call
239
+ - Flushes pending steps into the measurement detail inside the measure decorator
240
+ - Calls Logger.subSteps() from the observer when steps are present
241
+ - Adds unit tests for Logger.subSteps() alignment and single-item edge case
242
+ - Adds unit test verifying sub-step attachment and observer rendering
243
+ - Updates Logger mock in all affected test files to include subSteps
244
+
245
+ * **type-script-project:** add per-phase timing to type-check step (acaf8a0c432bb9d340f2441a59577153c7d67ade)
246
+ Instruments the three distinct phases of a type-check cycle with
247
+ sub-step performance marks so the log shows exactly where build
248
+ time is being spent.
249
+
250
+ - Imports addPerformanceStep and the perf_hooks performance API
251
+ - Wraps emit, diagnostics collection, and finalize with performance marks
252
+ - Adds a private static elapsed() helper to compute and format duration from a named mark
253
+ - Updates finalize() call-site to drop the now-unnecessary await
254
+
255
+
256
+ ### Performance Improvements
257
+
258
+ * **file-manager:** defer emit work and make cache saves async (afe576b5969c7088ccfd77a22e6cd0b6555e1974)
259
+ Reduces time spent inside TypeScript's synchronous emit() call by
260
+ deferring declaration pre-processing and .tsbuildinfo I/O to a
261
+ separate step after emit() returns. Cache persistence becomes a
262
+ fire-and-forget promise, unblocking the current build's parallel
263
+ phases.
264
+
265
+ - Buffers raw declaration text and .tsbuildinfo content in fileWriter instead of processing synchronously
266
+ - Introduces processEmittedFiles() to run AST creation and pre-processing after emit
267
+ - Changes finalize() from async to sync; starts a background save promise
268
+ - Adds flush() to await any in-flight background I/O when needed
269
+ - Updates initialize() and close() to handle pending save state correctly
270
+ - Removes the unused synchronous sys import from typescript
271
+ - Updates JSDoc to reflect the deferred processing model
272
+ - Removes await from all finalize() call-sites in tests
273
+ - Adds explicit finalize() calls in tests that inspect declaration files directly
274
+ - Adds await flush() in tests that read cache state from a second instance
275
+
276
+ ## [1.2.5](https://github.com/D1g1talEntr0py/tsbuild/compare/v1.2.4...v1.2.5) (2026-02-28)
277
+
278
+ ### Bug Fixes
279
+
280
+ * **decorator-metadata:** make @swc/core a true optional dep (69d35717e6f941cf9591097629b51858d3d282f0)
281
+ The static import of @swc/core was removed in an earlier commit that
282
+ made it an optional peer dependency, but the plugin still used a
283
+ static import at the top of the file, causing the now-working
284
+ type-checker to surface a TS2307 resolution error.
285
+
286
+ Converts the import to a dynamic import inside the onLoad callback so
287
+ it is only resolved when the plugin is actually used. Adds a minimal
288
+ ambient module declaration so TypeScript can resolve the shape of the
289
+ dynamic import without requiring @swc/core to be installed.
290
+
291
+ Changed files:
292
+ - src/@types/swc.d.ts
293
+ - src/plugins/decorator-metadata.ts
294
+
295
+ * **type-check:** include semantic diagnostics in type-check (2a3400a73aef2a6b6ac6c3e29ad56369c666ea6a)
296
+ Previously, only emit-phase diagnostics were checked, causing all
297
+ semantic errors (e.g. TS2307, TS2322) to be silently ignored.
298
+
299
+ Fixes this by explicitly calling getSemanticDiagnostics() and merging
300
+ the result with emit diagnostics before checking for errors.
301
+
302
+ Changed files:
303
+ - src/type-script-project.ts
304
+ - tests/type-script-project.test.ts
305
+
306
+ ## [1.2.4](https://github.com/D1g1talEntr0py/tsbuild/compare/v1.2.3...v1.2.4) (2026-02-28)
307
+
308
+ ### Code Refactoring
309
+
310
+ * **deps:** remove @swc/core optional dependency (6eeff9af10e8e0ca469699cccd580127c5160df5)
311
+ - Removes @swc/core and @swc/types as optional dependencies from package.json
312
+ - Updates pnpm-lock.yaml to drop all @swc/* package entries and snapshots
313
+ - Bumps pnpm packageManager version to 10.30.3
314
+ - Rewrites README introduction to clarify the tool's purpose and tone
315
+ - Adds TC39 standard decorators as a first-class supported feature with no extra dependencies
316
+ - Splits legacy decorator metadata into its own feature bullet, noting @swc/core must be installed manually
317
+ - Replaces the three-phase build description with a clearer two-phase explanation
318
+ - Adds a Quick Start section showing the minimal tsconfig.json setup and how to run a build
319
+ - Simplifies installation instructions by removing the --no-optional flag example
320
+ - Adds an explicit note that @swc/core will never be installed automatically
321
+ - Expands the Configuration section with an explanation of how tsconfig.json compilerOptions are honoured automatically
322
+ - Adds a comment to the entryPoints example clarifying that entry points can be inferred from package.json
323
+ - Adds a CLI usage note clarifying global vs local install invocation
324
+ - Adds a dedicated Incremental Builds section documenting both caches, the .tsbuild/ directory, and the --force and --clearCache flags
325
+ - Rewrites the Decorator Metadata section to lead with TC39 standard decorators and move legacy decorator metadata to a secondary subsection
326
+ - Clarifies that the build fails with a helpful message if @swc/core is missing when emitDecoratorMetadata is set
327
+ - Corrects the parallel processing performance note to accurately describe declaration bundling and transpilation running in parallel after type checking
328
+ - Fixes the circular dependency warning description to say tsbuild continues rather than just emitting a warning
329
+ - Updates the Limitations section to remove the Experimental label and improve the plugins limitation description
330
+ - Updates the comparison table to split decorator support into TC39 and legacy rows
331
+ - Changes the license from ISC to MIT
332
+ - Removes the closing disclaimer recommending tsup for production use
333
+
334
+ ## [1.2.3](https://github.com/D1g1talEntr0py/tsbuild/compare/v1.2.2...v1.2.3) (2026-02-25)
335
+
336
+ ### Bug Fixes
337
+
338
+ * **deps:** update minimatch (958d33ffed3a53997b260afe6e2dc40b9553681a)
339
+
340
+ ## [1.2.2](https://github.com/D1g1talEntr0py/tsbuild/compare/v1.2.1...v1.2.2) (2026-02-25)
341
+
342
+ ### Bug Fixes
343
+
344
+ * **build:** log configuration errors before exiting (7a2497ae68be5924f19c61aab3936d0f0805453a)
345
+ ConfigurationError was being thrown but never logged, leaving the user
346
+ with no visible feedback about what went wrong during the build.
347
+
348
+ - Handles ConfigurationError separately from other BuildError subclasses
349
+ in the build error handler
350
+ - Logs the error message via the logger before setting the exit code
351
+ - Clarifies the comment for TypeCheckError and BundleError, which are
352
+ already logged at the point they are thrown
353
+
354
+ * **entry-points:** use file stem instead of package name for root export (f641c1f0f6e20d79ac9566297b204458d4c37699)
355
+ Previously, the root export ('.') used the unscoped package name as the
356
+ entry point key, which could conflict with bin entries and was
357
+ unpredictable when the source file name differed from the package name.
358
+
359
+ - Adds a `stemOf` helper to extract the filename stem from a path
360
+ - Uses the file stem of the resolved source path as the entry key for
361
+ the root export ('.') and for string exports
362
+ - Non-root subpath exports continue to use the subpath-derived name
363
+ - Fixes a bug where bin entries with different names were silently
364
+ dropped because they collided with the package-name-based export key
365
+
366
+
367
+ ### Tests
368
+
369
+ * **entry-points:** update tests to reflect file-stem entry naming (38c296d1441ecfb435e6b7fd69493ab936be11fc)
370
+ Follows up on the change that uses file stems instead of package names
371
+ for root export entry point keys.
372
+
373
+ - Updates all test expectations that previously expected the unscoped
374
+ package name (e.g., 'my-pkg') as the root entry key to now expect the
375
+ file stem (e.g., 'index')
376
+ - Renames a test to better describe the new behaviour of combining
377
+ exports and bin when their names differ
378
+ - Adds a new test that mirrors the real-world tsbuild package layout,
379
+ where exports '.' resolves to index.ts and bin resolves to tsbuild.ts,
380
+ verifying both are included as separate entries
381
+ - Adds a missing `name` field to a test fixture that requires it
382
+ - Updates a test description to reflect that file stem is used for root
383
+ exports while subpath names are used for other exports
384
+
385
+ ## [1.2.1](https://github.com/D1g1talEntr0py/tsbuild/compare/v1.2.0...v1.2.1) (2026-02-25)
386
+
387
+ ### Bug Fixes
388
+
389
+ * **paths:** return false for non-existent paths in type checks (393856cfff44dedffa1e63b3f5fa5a9b3863d023)
390
+ - Handle ENOENT in isDirectory and isFile instead of throwing
391
+ - Re-throw any unexpected errors to preserve error visibility
392
+ - Update JSDoc to document non-existence behavior
393
+ - Add unit tests covering existing directory, existing file, and non-existent path cases for both methods
394
+ - Mock node:fs and node:fs/promises with memfs for isolated in-memory testing
395
+
396
+ * **type-script-project:** validate entry points exist and suppress unhandled rejection (758be0311f505f9f0417036912a35a186dfa96fc)
397
+ - Throw a ConfigurationError when an entry point path does not exist as a file or directory
398
+ - Suppress the unhandled rejection warning on the entry points promise since the rejection is handled when awaited in build()
399
+ - Inline a single-use variable in dependency path parsing for clarity
400
+ - Remove stale commented-out entry points from tsconfig.json
401
+ - Add a test asserting that a missing entry point causes exit code 3 during build
402
+
403
+ ## [1.2.0](https://github.com/D1g1talEntr0py/tsbuild/compare/v1.1.3...v1.2.0) (2026-02-24)
404
+
405
+ ### Features
406
+
407
+ * **entry-points:** add unscoped name support and drop .mjs mapping (d11c55e994b6ca780b52e67ad7c8c6dda26c8a9b)
408
+ - Removes .mjs and .d.mts from the output-to-source extension map since the project is ESM-only and only emits .js
409
+ - Adds an unscope() helper to strip npm scope prefixes (e.g. @scope/pkg → pkg) so scoped package names produce clean entry point keys
410
+ - Applies unscoping when deriving entry point names from the root export (.) and when using package.json name as a fallback key
411
+ - Enables tsconfig.json to rely on auto-inferred entry points by commenting out the explicit entryPoints config, exercising the zero-config path
412
+
413
+
414
+ ### Code Refactoring
415
+
416
+ * **type-script-project:** remove unused packageJson field (96c5659ac9e9617feea3454414880b8ebb23f466)
417
+ - Drops the cached packageJson instance field that was read but never used outside of the dependency resolution method
418
+ - Simplifies the class by eliminating unnecessary state that was populated as a side-effect of reading dependencies
419
+
420
+
421
+ ### Documentation
422
+
423
+ * update README with new features and revised benchmarks (2f3141830cca6d7dc3d2ecea5efae87a6cdd56a6)
424
+ - Documents the zero-config entry point auto-inference feature including resolution order and constraints
425
+ - Documents circular dependency detection behavior in the declaration bundler
426
+ - Adds the zero-config entry point feature to the feature highlights list
427
+ - Updates build time benchmarks to reflect current measured performance
428
+
429
+
430
+ ### Miscellaneous Chores
431
+
432
+ * consolidate agent guidelines into copilot-instructions (0830c1c47b583fac5ce3d472f52694cc073b1f33)
433
+ - Removes the standalone AGENTS.md file to reduce documentation fragmentation
434
+ - Inlines the core principles, coding rules, testing rules, and workflow rules directly into .github/copilot-instructions.md
435
+ - Condenses verbose guidelines into concise bullet points while preserving all essential constraints
436
+ - Ensures Copilot and other agents read a single authoritative source of truth
437
+
438
+ * **release:** make all commit types visible in changelog (f884bcf888927bb9c273aa52962de1cd742b91c3)
439
+ - Removes the hidden:true flag from docs, style, chore, test, build, and ci commit types in .releaserc.json
440
+ - All commit types will now appear in generated changelogs regardless of semantic-release conventions
441
+
442
+
443
+ ### Tests
444
+
445
+ * **entry-points:** update tests for .mjs removal and scoped names (1eba92d4ed914182bf0445684ec415c17b4dba7b)
446
+ - Removes test cases for .mjs and .d.mts extension mappings that no longer exist in the source
447
+ - Updates the module field fallback test to use .js instead of .mjs
448
+ - Corrects the expectation for .mjs exports to be undefined (unmappable) rather than resolving
449
+ - Adds a new test covering scoped package name stripping across exports, bin, and the root export key
450
+
451
+ ## [1.1.3](https://github.com/D1g1talEntr0py/tsbuild/compare/v1.1.2...v1.1.3) (2026-02-24)
452
+
453
+ ### Bug Fixes
454
+
455
+ * **dts:** improve circular dependency detection with full cycle path (b5bbb2bf6028eca05cdf13d6d7eb24058917a0f6)
456
+ - Tracks the current visit stack so the exact cycle can be reconstructed
457
+ - Reports the full chain of modules involved in the cycle instead of just the entry point
458
+ - Properly cleans up visiting state and stack when a module is not found
459
+ - Updates the test assertion to verify the full cycle path is reported
460
+
461
+ ## [1.1.2](https://github.com/D1g1talEntr0py/tsbuild/compare/v1.1.1...v1.1.2) (2026-02-24)
462
+
463
+ ### Bug Fixes
464
+
465
+ * **bundler:** flatten qualified names from bundled namespace imports (883c4a4e47df1d2de7e91e549e37cae0c09753e8)
466
+ - Adds tracking of namespace aliases created from bundled `import * as Alias` statements
467
+ - When a bundled module is inlined, its namespace import is stripped, so all `Alias.X` qualified references must be rewritten to plain `X` to avoid broken output
468
+ - Fixes identifier re-insertion bug where the rename visitor was walking import/export declarations that had already been removed via magic.remove(), causing overwrite() to reinsert removed text and produce corrupted output like `};Json$1JsonPrimitive$1`
469
+ - Restricts the rename visitor to declaration statements only, skipping import/export declarations
470
+ - Imports two new TypeScript AST helpers needed for the above fixes
471
+
472
+ ## [1.1.1](https://github.com/D1g1talEntr0py/tsbuild/compare/v1.1.0...v1.1.1) (2026-02-24)
473
+
474
+ ### Bug Fixes
475
+
476
+ * **dts:** correct scoped package name in DTS output (9c40f48a896d5dab7d05c130eb624d288d0f6967)
477
+ Two bugs caused scoped npm package imports (e.g. `@d1g1tal/watchr`) to be
478
+ emitted as unscoped names (`watchr`) in the bundled declaration output.
479
+
480
+ - Race condition in `IncrementalBuildCache`: `loadCache()` starts reading
481
+ the cache file asynchronously in the constructor, but `invalidate()` is
482
+ called afterward; the I/O read could complete before `rmSync` deleted the
483
+ file, so stale cache data was returned by `restore()` even after
484
+ `--clearCache`; fixed by adding an `invalidated` flag that makes
485
+ `restore()` bail out immediately when set
486
+ - Ambiguous path matching in `sourceToDeclarationPath`: when both a stale
487
+ cache entry (`dist/src/@types/index.d.ts` from an old build) and the
488
+ correct current entry (`dist/@types/index.d.ts`) exist in
489
+ `declarationFiles`, the stale one (inserted earlier from `restore()`) was
490
+ returned first; fixed by selecting the match with the shortest relative
491
+ path since TypeScript strips `rootDir` from output paths
492
+ - Add test for the `invalidated` flag race-condition fix in
493
+ `tests/build-cache.test.ts`
494
+ - Add test for shortest-path preference in
495
+ `tests/declaration-bundler.test.ts`
496
+
497
+ ## [1.1.0](https://github.com/D1g1talEntr0py/tsbuild/compare/v1.0.3...v1.1.0) (2026-02-24)
498
+
499
+ ### Features
500
+
501
+ * **entry-points:** infer entry points from package.json when none configured (a3c73da481e4e59416e2f6e4483e932c525d0968)
502
+ - add src/entry-points.ts with inferEntryPoints() that reverse-maps output paths
503
+ from exports, bin, main, and module fields back to source files
504
+ - add PackageJson type covering exports, bin, main, module, dependencies,
505
+ and peerDependencies fields
506
+ - integrate inferEntryPoints into TypeScriptProject.readConfiguration() so
507
+ projects with no explicit entryPoints config auto-infer from package.json
508
+ - update schema.json markdownDescription for entryPoints to document the
509
+ auto-inference behaviour
510
+ - replace ProjectDependencies with PackageJson in getProjectDependencyPaths()
511
+ and cache the parsed package.json on the instance for reuse
512
+ - add tests/entry-points.test.ts covering all inference paths
513
+
514
+
515
+ ### Bug Fixes
516
+
517
+ * **dts:** fix modifier removal eating next token's leading character (7a0f90321ca00879557ec55e2464b72d97bfe528)
518
+ - replace hard-coded '+ 1' offset in fixModifiers with a call to the
519
+ existing getTrailingWhitespaceLength() helper so that only actual
520
+ whitespace after the modifier keyword is consumed, not the first
521
+ character of the following token
522
+ - add tests covering export modifier at end of line, export default, and
523
+ export with multiple trailing spaces
524
+
525
+ * **dts:** separate external declarations, fix rename collisions, warn on circular deps (5daeb0a227b502a6fda29f24d756dfc1f1fb7df6)
526
+ - introduce externalDeclarationFiles Map separate from declarationFiles so
527
+ externally-resolved node_modules .d.ts files never pollute the project map
528
+ - update moduleResolutionHost.fileExists and readFile to check both maps
529
+ - store disk-loaded external declarations in externalDeclarationFiles instead
530
+ of declarationFiles to prevent memory accumulation across entry points
531
+ - add clearExternalFiles() method and call it after all bundling completes to
532
+ free memory used by externally-resolved declarations
533
+ - expand buildDependencyGraph and topological-sort visit() to look up cached
534
+ declarations in both maps
535
+ - fix rename collision detection: iterate with an incrementing suffix and
536
+ skip candidates already present in declarationSources instead of always
537
+ using sequential indices
538
+ - emit a Logger.warn() message when a circular dependency is detected rather
539
+ than silently returning
540
+ - replace TODO comment on posix.normalize with an accurate explanation
541
+ - add tests for circular dependency warning, rename collision avoidance,
542
+ and external-file cleanup path
543
+
544
+ * **errors:** make UnsupportedSyntaxError extend BundleError with exit code 2 (ee239c97a05b0f2fb58e911ab83cd90519ffd3b8)
545
+ - change UnsupportedSyntaxError base class from Error to BundleError so
546
+ it carries exit code 2 and participates in the standard error hierarchy
547
+ - set this.name to 'UnsupportedSyntaxError' for correct identification
548
+ after instanceof checks across prototype chains
549
+ - update JSDoc to clarify it is thrown during DTS processing
550
+ - add test asserting instanceof BundleError, instanceof BuildError,
551
+ exit code 2, and correct name
552
+
553
+ ## [1.0.3](https://github.com/D1g1talEntr0py/tsbuild/compare/v1.0.2...v1.0.3) (2026-02-24)
554
+
555
+ ### Bug Fixes
556
+
557
+ * **build:** fix --force flag, new-file watch handling, and minor correctness issues (c005d19c406aafd44c54836f4ca38026f72a2ba5)
558
+ - Fixes the `--force` flag being silently ignored when incremental
559
+ TypeScript reports no changed files; reorders the condition so `force`
560
+ independently bypasses the `filesWereEmitted` gate
561
+ - Fixes newly added source files being silently dropped during a watch
562
+ rebuild by adding a `FileEvent.add` handler that appends the path to
563
+ `rootNames` when not already present
564
+ - Passes `configFileParsingDiagnostics` when recreating the incremental
565
+ program so config-level errors are surfaced rather than swallowed
566
+ - Removes a stale `compilerOptionOverrides` spread that was clobbering
567
+ user-provided compiler options
568
+ - Caches the package.json dependency read as a lazy promise to avoid
569
+ repeated file reads across multiple calls
570
+ - Adds tests covering the --force bypass and the new-file rootNames
571
+ insertion, including a guard against duplicate entries
572
+
573
+ * **dts:** fix identifier rename whitespace bug and optimise directory lookups (1321f065be435d37cfd524e2bd11908e4c57c5db)
574
+ - Fixes a bug where renaming conflicting exported identifiers consumed
575
+ leading trivia (whitespace), turning `type Options` into `typeOptions$1`;
576
+ replaces `node.pos` with `node.getStart()` which excludes trivia
577
+ - Removes an erroneous `isModuleBlock` recursion in identifier collection
578
+ that could cause duplicate or mis-scoped renames, and drops its import
579
+ - Replaces the O(n) linear scan on every `directoryExists` call with an
580
+ O(1) pre-computed `Set` of all ancestor directory paths, built once
581
+ after declaration files are loaded
582
+ - Removes the fragile on-demand lazy loading of external declaration files
583
+ from within the import-resolution loop
584
+ - Replaces the manual collect-sort-apply transformation pattern in
585
+ `postProcess` with direct `MagicString` edits during the AST walk,
586
+ removing the `CodeTransformation` type and its reverse-order comparator
587
+ - Adds a regression test for the whitespace-preservation fix
588
+
589
+
590
+ ### Code Refactoring
591
+
592
+ * clean up dead code and simplify type constraints (3ccfd81f146b968ed1e4af46971927261a9eea36)
593
+ - Relaxes overly strict self-referential generic constraints on
594
+ `TypedFunction` and `OptionalReturn` to use a simpler upper bound,
595
+ eliminating circular constraint errors
596
+ - Removes unused recursive JSON utility types (`JsonArray`, `JsonObject`,
597
+ `JsonValue`) that were never consumed outside the type file
598
+ - Removes the `NodeType` string-literal constant and its export, which
599
+ was dead code left over from an earlier ESTree-based AST walking approach
600
+ - Removes its corresponding test coverage
601
+ - Updates the debounce module to drop the now-unnecessary `TypedFunction`
602
+ import and inlines a more precise constraint directly on the method
603
+
604
+ ## [1.0.2](https://github.com/D1g1talEntr0py/tsbuild/compare/v1.0.1...v1.0.2) (2026-02-24)
605
+
606
+ ### Bug Fixes
607
+
608
+ * **ci:** attach npm package tarball to github release (b0c0c49a868eabf7da9d86608c8d53f6056cb201)
609
+
610
+ ## [1.0.1](https://github.com/D1g1talEntr0py/tsbuild/compare/v1.0.0...v1.0.1) (2026-02-24)
611
+
612
+ ### Bug Fixes
613
+
614
+ * **ci:** add registry-url to setup-node for trusted publisher OIDC (420d5200bf0685b57d2713fe59bebae49981fdfe)
615
+ * **ci:** use exec plugin for npm publish to support trusted publishers (89efe130d17d417962a3b27735990629343ee11c)
616
+
617
+ # Changelog
618
+
619
+ ## 1.0.0 (2026-02-16)
620
+
621
+
622
+ ### Features
623
+
624
+ * initial release ([8a49106](https://github.com/D1g1talEntr0py/tsbuild/commit/8a49106dcc03c911b1670ed07e86c29717007a26))
@@ -1391,9 +1391,18 @@ async function bundleDeclarations(options) {
1391
1391
  // src/plugins/output.ts
1392
1392
  import { extname } from "node:path";
1393
1393
  var FileMode = { READ_WRITE: 438, READ_WRITE_EXECUTE: 493 };
1394
+ var relativeSpecifierPattern = /(from\s+['"])(\.\.?\/[^'"]*?)(['"])/g;
1395
+ function rewriteRelativeSpecifiers(code) {
1396
+ return code.replace(relativeSpecifierPattern, (_, before, path, after) => {
1397
+ if (/\.[a-z]+$/i.test(path)) return before + path + after;
1398
+ return `${before}${path}.js${after}`;
1399
+ });
1400
+ }
1394
1401
  async function fileMapper({ path, contents }) {
1395
- const mode = extname(path) === FileExtension.JS && contents[0] === 35 && contents[1] === 33 ? FileMode.READ_WRITE_EXECUTE : FileMode.READ_WRITE;
1396
- return Files.write(path, contents, { mode });
1402
+ const isJs = extname(path) === FileExtension.JS;
1403
+ const mode = isJs && contents[0] === 35 && contents[1] === 33 ? FileMode.READ_WRITE_EXECUTE : FileMode.READ_WRITE;
1404
+ const finalContents = isJs ? new TextEncoder().encode(rewriteRelativeSpecifiers(new TextDecoder().decode(contents))) : contents;
1405
+ return Files.write(path, finalContents, { mode });
1397
1406
  }
1398
1407
  var outputPlugin = () => {
1399
1408
  return {
@@ -1822,8 +1831,9 @@ var FileManager = class {
1822
1831
  * @returns Metadata of the written file
1823
1832
  */
1824
1833
  async writeFile(projectDirectory, filePath, content) {
1825
- await Files.write(filePath, content);
1826
- return { path: Paths.relative(projectDirectory, filePath), size: content.length };
1834
+ const rewritten = rewriteRelativeSpecifiers(content);
1835
+ await Files.write(filePath, rewritten);
1836
+ return { path: Paths.relative(projectDirectory, filePath), size: rewritten.length };
1827
1837
  }
1828
1838
  /**
1829
1839
  * Function that intercepts file writes during TypeScript emit.
@@ -2105,7 +2115,7 @@ var _TypeScriptProject = class _TypeScriptProject {
2105
2115
  }
2106
2116
  async build() {
2107
2117
  const tsLogo = TextFormat.bgBlue(TextFormat.bold(TextFormat.whiteBright(" TS ")));
2108
- Logger.header(`${tsLogo} tsbuild v${"1.6.0"}${this.configuration.compilerOptions.incremental && this.configuration.buildCache?.isValid() ? " [incremental]" : ""}`);
2118
+ Logger.header(`${tsLogo} tsbuild v${"1.6.2"}${this.configuration.compilerOptions.incremental && this.configuration.buildCache?.isValid() ? " [incremental]" : ""}`);
2109
2119
  try {
2110
2120
  const processes = [];
2111
2121
  const filesWereEmitted = await this.typeCheck();
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  TypeScriptProject
3
- } from "./Q7VGDC7X.js";
3
+ } from "./ET53LOOP.js";
4
4
  import "./7FPDHUPW.js";
5
5
  export {
6
6
  TypeScriptProject
package/dist/tsbuild.js CHANGED
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  BuildError,
4
4
  TypeScriptProject
5
- } from "./Q7VGDC7X.js";
5
+ } from "./ET53LOOP.js";
6
6
  import "./7FPDHUPW.js";
7
7
 
8
8
  // src/tsbuild.ts
@@ -30,7 +30,7 @@ if (help) {
30
30
  process.exit(0);
31
31
  }
32
32
  if (version) {
33
- console.log("1.6.0");
33
+ console.log("1.6.2");
34
34
  process.exit(0);
35
35
  }
36
36
  var typeScriptOptions = {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@d1g1tal/tsbuild",
3
3
  "author": "D1g1talEntr0py",
4
- "version": "1.6.0",
4
+ "version": "1.6.2",
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",
@@ -36,6 +36,7 @@
36
36
  "./dist",
37
37
  "./schema.json",
38
38
  "README.md",
39
+ "CHANGELOG.md",
39
40
  "LICENSE"
40
41
  ],
41
42
  "bin": {
@@ -47,10 +48,12 @@
47
48
  "magic-string": "^0.30.21"
48
49
  },
49
50
  "devDependencies": {
51
+ "@babel/plugin-proposal-decorators": "^7.29.0",
50
52
  "@eslint/js": "^10.0.1",
51
- "@types/node": "^25.4.0",
52
- "@typescript-eslint/eslint-plugin": "^8.57.0",
53
- "@typescript-eslint/parser": "^8.57.0",
53
+ "@rolldown/plugin-babel": "^0.2.2",
54
+ "@types/node": "^25.5.0",
55
+ "@typescript-eslint/eslint-plugin": "^8.57.1",
56
+ "@typescript-eslint/parser": "^8.57.1",
54
57
  "@vitest/coverage-v8": "^4.1.0",
55
58
  "eslint": "^10.0.3",
56
59
  "eslint-plugin-jsdoc": "^62.8.0",
@@ -58,13 +61,16 @@
58
61
  "memfs": "^4.56.11",
59
62
  "tsx": "^4.21.0",
60
63
  "typescript": "^5.9.3",
61
- "typescript-eslint": "^8.57.0",
64
+ "typescript-eslint": "^8.57.1",
62
65
  "vitest": "^4.1.0"
63
66
  },
64
67
  "keywords": [
65
68
  "typescript",
66
69
  "build",
67
70
  "bundler",
71
+ "compiler",
72
+ "type-checking",
73
+ "library",
68
74
  "esbuild",
69
75
  "declarations",
70
76
  "dts",
@@ -76,6 +82,7 @@
76
82
  "type-check": "tsx ./src/tsbuild.ts --noEmit",
77
83
  "lint": "eslint ./src",
78
84
  "test": "vitest run",
79
- "test:coverage": "vitest run --coverage"
85
+ "test:coverage": "vitest run --coverage",
86
+ "test:watch": "vitest"
80
87
  }
81
88
  }