Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package esbuild for openSUSE:Factory checked 
in at 2026-06-25 10:54:52
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/esbuild (Old)
 and      /work/SRC/openSUSE:Factory/.esbuild.new.2088 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "esbuild"

Thu Jun 25 10:54:52 2026 rev:23 rq:1361499 version:0.28.1

Changes:
--------
--- /work/SRC/openSUSE:Factory/esbuild/esbuild.changes  2026-05-06 
19:20:20.267117670 +0200
+++ /work/SRC/openSUSE:Factory/.esbuild.new.2088/esbuild.changes        
2026-06-25 10:58:03.339134317 +0200
@@ -1,0 +2,13 @@
+Wed Jun 24 00:52:00 UTC 2026 - Avindra Goolcharan <[email protected]>
+
+- update to 0.28.1:
+  * Disallow \ in local development server HTTP requests (GHSA-g7r4-m6w7-qqqr)
+  * Add integrity checks to the Deno API (GHSA-gv7w-rqvm-qjhr)
+  * Avoid inlining using and await using declarations (#4482)
+  * Fix module evaluation when an error is thrown (#4461, #4467)
+  * Fix some edge cases around the new operator (#4477)
+  * Fix renaming of nested var declarations (#4471)
+  * Emit var instead of const for certain TypeScript-only
+    constructs for ES5 (#4448)
+
+-------------------------------------------------------------------

Old:
----
  esbuild-0.28.0.tar.gz

New:
----
  esbuild-0.28.1.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ esbuild.spec ++++++
--- /var/tmp/diff_new_pack.Pj1ajV/_old  2026-06-25 10:58:04.003157234 +0200
+++ /var/tmp/diff_new_pack.Pj1ajV/_new  2026-06-25 10:58:04.007157371 +0200
@@ -24,7 +24,7 @@
 %global tag   v%{version}
 %global extractdir0 esbuild-%{version}
 Name:           esbuild
-Version:        0.28.0
+Version:        0.28.1
 Release:        0
 Summary:        A JavaScript bundler written for speed
 License:        MIT

++++++ _scmsync.obsinfo ++++++
--- /var/tmp/diff_new_pack.Pj1ajV/_old  2026-06-25 10:58:04.047158752 +0200
+++ /var/tmp/diff_new_pack.Pj1ajV/_new  2026-06-25 10:58:04.051158890 +0200
@@ -1,6 +1,6 @@
-mtime: 1778012606
-commit: a0f16d8475ab2ec3b2fff39de99b8a6d01bdf1f2a27a2cd87eabd66f52e2403c
+mtime: 1782262589
+commit: 51a1a680156f4a49bd060beecd6b847f6d6faf132cb90b87c3bbcd979d2c5696
 url: https://src.opensuse.org/javascript/esbuild
-revision: a0f16d8475ab2ec3b2fff39de99b8a6d01bdf1f2a27a2cd87eabd66f52e2403c
+revision: 51a1a680156f4a49bd060beecd6b847f6d6faf132cb90b87c3bbcd979d2c5696
 projectscmsync: https://src.opensuse.org/javascript/_ObsPrj.git
 

++++++ build.specials.obscpio ++++++

++++++ build.specials.obscpio ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/.gitignore new/.gitignore
--- old/.gitignore      1970-01-01 01:00:00.000000000 +0100
+++ new/.gitignore      2026-06-24 02:56:29.000000000 +0200
@@ -0,0 +1 @@
+.osc

++++++ esbuild-0.28.0.tar.gz -> esbuild-0.28.1.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/esbuild-0.28.0/CHANGELOG.md 
new/esbuild-0.28.1/CHANGELOG.md
--- old/esbuild-0.28.0/CHANGELOG.md     2026-04-02 22:23:56.000000000 +0200
+++ new/esbuild-0.28.1/CHANGELOG.md     2026-06-12 00:26:09.000000000 +0200
@@ -1,5 +1,80 @@
 # Changelog
 
+## 0.28.1
+
+* Disallow `\\` in local development server HTTP requests 
([GHSA-g7r4-m6w7-qqqr](https://github.com/evanw/esbuild/security/advisories/GHSA-g7r4-m6w7-qqqr))
+
+    This release fixes a security issue where HTTP requests to esbuild's local 
development server could traverse outside of the serve directory on Windows 
using a `\\` backslash character. It happened due to the use of Go's 
`path.Clean()` function, which only handles Unix-style `/` characters. HTTP 
requests with paths containing `\\` are no longer allowed.
+
+    Thanks to [@dellalibera](https://github.com/dellalibera) for reporting 
this issue.
+
+* Add integrity checks to the Deno API 
([GHSA-gv7w-rqvm-qjhr](https://github.com/evanw/esbuild/security/advisories/GHSA-gv7w-rqvm-qjhr))
+
+    The previous release of esbuild added integrity checks to esbuild's npm 
install script. This release also adds integrity checks to esbuild's Deno 
install script. Now esbuild's Deno API will also fail with an error if the 
downloaded esbuild binary contains something other than the expected content.
+
+    Note that esbuild's Deno API installs from `registry.npmjs.org` by 
default, but allows the `NPM_CONFIG_REGISTRY` environment variable to override 
this with a custom package registry. This change means that the esbuild 
executable served by `NPM_CONFIG_REGISTRY` must now match the expected content.
+
+    Thanks to [@sondt99](https://github.com/sondt99) for reporting this issue.
+
+* Avoid inlining `using` and `await using` declarations 
([#4482](https://github.com/evanw/esbuild/issues/4482))
+
+    Previously esbuild's minifier sometimes incorrectly inlined `using` and 
`await using` declarations into subsequent uses of that declaration, which then 
fails to dispose of the resource correctly. This bug happened because inlining 
was done for `let` and `const` declarations by avoiding doing it for `var` 
declarations, which no longer worked when more declaration types were added. 
Here's an example:
+
+    ```js
+    // Original code
+    {
+      using x = new Resource()
+      x.activate()
+    }
+
+    // Old output (with --minify)
+    new Resource().activate();
+
+    // New output (with --minify)
+    {using e=new Resource;e.activate()}
+    ```
+
+* Fix module evaluation when an error is thrown 
([#4461](https://github.com/evanw/esbuild/issues/4461), 
[#4467](https://github.com/evanw/esbuild/pull/4467))
+
+    If an error is thrown during module evaluation, esbuild previously didn't 
preserve the state of the module for subsequent module references. This was 
observable if `import()` or `require()` is used to import a module multiple 
times. The thrown error is supposed to be thrown by every call to `import()` or 
`require()`, not just the first. With this release, esbuild will now throw the 
same error every time you call `import()` or `require()` on a module that 
throws during its evaluation.
+
+* Fix some edge cases around the `new` operator 
([#4477](https://github.com/evanw/esbuild/issues/4477))
+
+    Previously esbuild incorrectly printed certain edge cases involving 
complex expressions inside the target of a `new` expression (specifically an 
optional chain and/or a tagged template literal). The generated code for the 
`new` target was not correctly wrapped with parentheses, and either contained a 
syntax error or had different semantics. These edge cases have been fixed so 
that they now correctly wrap the `new` target in parentheses. Here is an 
example of some affected code:
+
+    ```js
+    // Original code
+    new (foo()`bar`)()
+    new (foo()?.bar)()
+
+    // Old output
+    new foo()`bar`();
+    new (foo())?.bar();
+
+    // New output
+    new (foo())`bar`();
+    new (foo()?.bar)();
+    ```
+
+* Fix renaming of nested `var` declarations 
([#4471](https://github.com/evanw/esbuild/issues/4471))
+
+    This release fixes a bug where `var` declarations in nested scopes that 
are hoisted up to module scope were not correctly being renamed during 
bundling. That could previously lead to name collisions when minification was 
disabled, which could potentially cause a behavior change. The bug has been 
fixed so that these hoisted declarations are now considered to be module-level 
symbols during the name collision avoidance pass.
+
+* Emit `var` instead of `const` for certain TypeScript-only constructs for ES5 
([#4448](https://github.com/evanw/esbuild/issues/4448))
+
+    While esbuild doesn't generally support converting `const` to `var` for 
ES5 due to nested scoping rules (which is currently a build-time error), 
esbuild previously incorrectly converted TypeScript-only `import` assignment 
constructs into a `const` declaration even when targeting ES5. With this 
release, esbuild will now use `var` for this case instead:
+
+    ```js
+    // Original code
+    import x = require('y')
+
+    // Old output (with --target=es5)
+    const x = require("y");
+
+    // New output (with --target=es5)
+    var x = require("y");
+    ```
+
 ## 0.28.0
 
 * Add support for `with { type: 'text' }` imports 
([#4435](https://github.com/evanw/esbuild/issues/4435))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/esbuild-0.28.0/cmd/esbuild/version.go 
new/esbuild-0.28.1/cmd/esbuild/version.go
--- old/esbuild-0.28.0/cmd/esbuild/version.go   2026-04-02 22:23:56.000000000 
+0200
+++ new/esbuild-0.28.1/cmd/esbuild/version.go   2026-06-12 00:26:09.000000000 
+0200
@@ -1,3 +1,3 @@
 package main
 
-const esbuildVersion = "0.28.0"
+const esbuildVersion = "0.28.1"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/esbuild-0.28.0/go.version 
new/esbuild-0.28.1/go.version
--- old/esbuild-0.28.0/go.version       2026-04-02 22:23:56.000000000 +0200
+++ new/esbuild-0.28.1/go.version       2026-06-12 00:26:09.000000000 +0200
@@ -1 +1 @@
-1.26.1
+1.26.4
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/esbuild-0.28.0/internal/bundler_tests/bundler_default_test.go 
new/esbuild-0.28.1/internal/bundler_tests/bundler_default_test.go
--- old/esbuild-0.28.0/internal/bundler_tests/bundler_default_test.go   
2026-04-02 22:23:56.000000000 +0200
+++ new/esbuild-0.28.1/internal/bundler_tests/bundler_default_test.go   
2026-06-12 00:26:09.000000000 +0200
@@ -2746,6 +2746,32 @@
        })
 }
 
+func TestRenameNestedVar(t *testing.T) {
+       default_suite.expectBundled(t, bundled{
+               files: map[string]string{
+                       "/entry.js": `
+                               import { foo } from './foo'
+                               var topLevel = 0
+                               { var nested = 1 }
+                               function fn() { var inner = 2 }
+                               foo(topLevel, nested, fn)
+                       `,
+                       "/foo.js": `
+                               export function foo(a, b) {}
+                               var topLevel = 0
+                               { var nested = 1 }
+                               function fn() { var inner = 2 }
+                               foo(topLevel, nested, fn)
+                       `,
+               },
+               entryPaths: []string{"/entry.js"},
+               options: config.Options{
+                       Mode:          config.ModeBundle,
+                       AbsOutputFile: "/out.js",
+               },
+       })
+}
+
 func TestRenamePrivateIdentifiersNoBundle(t *testing.T) {
        default_suite.expectBundled(t, bundled{
                files: map[string]string{
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/esbuild-0.28.0/internal/bundler_tests/bundler_lower_test.go 
new/esbuild-0.28.1/internal/bundler_tests/bundler_lower_test.go
--- old/esbuild-0.28.0/internal/bundler_tests/bundler_lower_test.go     
2026-04-02 22:23:56.000000000 +0200
+++ new/esbuild-0.28.1/internal/bundler_tests/bundler_lower_test.go     
2026-06-12 00:26:09.000000000 +0200
@@ -86,7 +86,7 @@
                                        13: a[123n] **= b,
                                        14: a[this] **= b,
 
-                                       // These should need capturing (have 
object identitiy)
+                                       // These should need capturing (have 
object identity)
                                        15: a[/x/] **= b,
                                        16: a[{}] **= b,
                                        17: a[[]] **= b,
@@ -3163,3 +3163,23 @@
                },
        })
 }
+
+// https://github.com/evanw/esbuild/issues/4448
+func TestLowerConstIssue4448(t *testing.T) {
+       lower_suite.expectBundled(t, bundled{
+               files: map[string]string{
+                       "/entry.ts": `
+                               import x = require('fs')
+                               console.log(import.meta.foo(x))
+                       `,
+               },
+               entryPaths: []string{"/entry.ts"},
+               options: config.Options{
+                       Mode:                  config.ModePassThrough,
+                       UnsupportedJSFeatures: compat.ConstAndLet | 
compat.ImportMeta,
+                       AbsOutputFile:         "/out.js",
+               },
+               expectedScanLog: `entry.ts: WARNING: "import.meta" is not 
available in the configured target environment and will be empty
+`,
+       })
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/esbuild-0.28.0/internal/bundler_tests/bundler_ts_test.go 
new/esbuild-0.28.1/internal/bundler_tests/bundler_ts_test.go
--- old/esbuild-0.28.0/internal/bundler_tests/bundler_ts_test.go        
2026-04-02 22:23:56.000000000 +0200
+++ new/esbuild-0.28.1/internal/bundler_tests/bundler_ts_test.go        
2026-06-12 00:26:09.000000000 +0200
@@ -1065,7 +1065,7 @@
                        `,
                        "/all_computed.ts": `
                                @x?.[_ + 'y']()
-                               @new y?.[_ + 'x']()
+                               @new y()?.[_ + 'x']()
                                export default class Foo {
                                        @x @y [mUndef()]
                                        @x @y [mDef()] = 1
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/esbuild-0.28.0/internal/bundler_tests/snapshots/snapshots_default.txt 
new/esbuild-0.28.1/internal/bundler_tests/snapshots/snapshots_default.txt
--- old/esbuild-0.28.0/internal/bundler_tests/snapshots/snapshots_default.txt   
2026-04-02 22:23:56.000000000 +0200
+++ new/esbuild-0.28.1/internal/bundler_tests/snapshots/snapshots_default.txt   
2026-06-12 00:26:09.000000000 +0200
@@ -5201,7 +5201,7 @@
 
================================================================================
 TestMinifiedBundleCommonJS
 ---------- /out.js ----------
-var t=e(r=>{r.foo=function(){return 123}});var 
n=e((l,c)=>{c.exports={test:!0}});var{foo:f}=t();console.log(f(),n());
+var t=e(r=>{r.foo=function(){return 123}});var 
n=e((q,f)=>{f.exports={test:!0}});var{foo:i}=t();console.log(i(),n());
 
 
================================================================================
 TestMinifiedBundleES6
@@ -5286,7 +5286,7 @@
 var o=123;console.log(o,"no identifier in this file should be named W, X, Y, 
or Z");
 
 ---------- /out/require.js ----------
-var i=r((t,e)=>{e.exports=123});var s=i();console.log(s,"no identifier in this 
file should be named A, B, C, or D");
+var i=s((d,e)=>{e.exports=123});var l=i();console.log(l,"no identifier in this 
file should be named A, B, C, or D");
 
 
================================================================================
 TestMinifyNestedLabelsNoBundle
@@ -5898,6 +5898,33 @@
 }
 
 
================================================================================
+TestRenameNestedVar
+---------- /out.js ----------
+// foo.js
+function foo(a, b) {
+}
+var topLevel = 0;
+{
+  nested = 1;
+}
+var nested;
+function fn() {
+  var inner = 2;
+}
+foo(topLevel, nested, fn);
+
+// entry.js
+var topLevel2 = 0;
+{
+  nested2 = 1;
+}
+var nested2;
+function fn2() {
+  var inner = 2;
+}
+foo(topLevel2, nested2, fn2);
+
+================================================================================
 TestRenamePrivateIdentifiersNoBundle
 ---------- /out.js ----------
 class Foo {
@@ -6444,10 +6471,10 @@
 };
 new Foo(foo(objFoo));
 if (nested) {
-  let bar = function(x = this) {
+  let bar2 = function(x = this) {
     console.log(this);
   };
-  bar2 = bar;
+  bar = bar2;
   const objBar = {
     foo(x = this) {
       console.log(this);
@@ -6463,9 +6490,9 @@
       console.log(this);
     }
   }
-  new Bar(bar(objBar));
+  new Bar(bar2(objBar));
 }
-var bar2;
+var bar;
 
 
================================================================================
 TestThisOutsideFunction
@@ -7061,9 +7088,9 @@
 ---------- /out/nested.js ----------
 // nested.js
 if (true) {
-  let l = function() {
+  let l2 = function() {
   };
-  l2 = l;
+  l = l2;
   for (; 0; ) ;
   for ({ c, x: [d] } = {}; 0; ) ;
   for (e of []) ;
@@ -7084,7 +7111,7 @@
 var i;
 var j;
 var k;
-var l2;
+var l;
 
 ---------- /out/let.js ----------
 // let.js
@@ -7152,9 +7179,9 @@
 
 ---------- /out/nested.js ----------
 if (true) {
-  let l = function() {
+  let l2 = function() {
   };
-  var l2 = l;
+  var l = l2;
   var a;
   for (var b; 0; ) ;
   for (var { c, x: [d] } = {}; 0; ) ;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/esbuild-0.28.0/internal/bundler_tests/snapshots/snapshots_importstar.txt 
new/esbuild-0.28.1/internal/bundler_tests/snapshots/snapshots_importstar.txt
--- 
old/esbuild-0.28.0/internal/bundler_tests/snapshots/snapshots_importstar.txt    
    2026-04-02 22:23:56.000000000 +0200
+++ 
new/esbuild-0.28.1/internal/bundler_tests/snapshots/snapshots_importstar.txt    
    2026-06-12 00:26:09.000000000 +0200
@@ -125,7 +125,7 @@
 TestExportSelfCommonJSMinified
 ---------- /out.js ----------
 // entry.js
-var r = s((f, e) => {
+var r = c((g, e) => {
   e.exports = { foo: 123 };
   console.log(r());
 });
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/esbuild-0.28.0/internal/bundler_tests/snapshots/snapshots_lower.txt 
new/esbuild-0.28.1/internal/bundler_tests/snapshots/snapshots_lower.txt
--- old/esbuild-0.28.0/internal/bundler_tests/snapshots/snapshots_lower.txt     
2026-04-02 22:23:56.000000000 +0200
+++ new/esbuild-0.28.1/internal/bundler_tests/snapshots/snapshots_lower.txt     
2026-06-12 00:26:09.000000000 +0200
@@ -2012,6 +2012,13 @@
 console.log(loose_default, strict_default);
 
 
================================================================================
+TestLowerConstIssue4448
+---------- /out.js ----------
+var import_meta = {};
+var x = require("fs");
+console.log(import_meta.foo(x));
+
+================================================================================
 TestLowerExponentiationOperatorNoBundle
 ---------- /out.js ----------
 var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
@@ -2034,7 +2041,7 @@
   12: a[void 0] = __pow(a[void 0], b),
   13: a[/* @__PURE__ */ BigInt("123")] = __pow(a[/* @__PURE__ */ 
BigInt("123")], b),
   14: a[this] = __pow(a[this], b),
-  // These should need capturing (have object identitiy)
+  // These should need capturing (have object identity)
   15: a[_f = /x/] = __pow(a[_f], b),
   16: a[_g = {}] = __pow(a[_g], b),
   17: a[_h = []] = __pow(a[_h], b),
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/esbuild-0.28.0/internal/bundler_tests/snapshots/snapshots_ts.txt 
new/esbuild-0.28.1/internal/bundler_tests/snapshots/snapshots_ts.txt
--- old/esbuild-0.28.0/internal/bundler_tests/snapshots/snapshots_ts.txt        
2026-04-02 22:23:56.000000000 +0200
+++ new/esbuild-0.28.1/internal/bundler_tests/snapshots/snapshots_ts.txt        
2026-06-12 00:26:09.000000000 +0200
@@ -872,7 +872,7 @@
 ], Foo2, _a, 2);
 Foo2 = __decorateClass([
   x?.[_ + "y"](),
-  new y?.[_ + "x"]()
+  new y()?.[_ + "x"]()
 ], Foo2);
 
 // a.ts
@@ -1606,7 +1606,7 @@
 
================================================================================
 TestTSMinifiedBundleCommonJS
 ---------- /out.js ----------
-var t=e(r=>{r.foo=function(){return 123}});var 
n=e((l,c)=>{c.exports={test:!0}});var{foo:f}=t();console.log(f(),n());
+var t=e(r=>{r.foo=function(){return 123}});var 
n=e((q,f)=>{f.exports={test:!0}});var{foo:i}=t();console.log(i(),n());
 
 
================================================================================
 TestTSMinifiedBundleES6
@@ -2080,10 +2080,10 @@
 };
 new Foo(foo(objFoo));
 if (nested) {
-  let bar = function(x = this) {
+  let bar2 = function(x = this) {
     console.log(this);
   };
-  bar2 = bar;
+  bar = bar2;
   const objBar = {
     foo(x = this) {
       console.log(this);
@@ -2103,9 +2103,9 @@
       console.log(this);
     }
   }
-  new Bar(bar(objBar));
+  new Bar(bar2(objBar));
 }
-var bar2;
+var bar;
 
 
================================================================================
 TestThisInsideFunctionTSNoBundle
@@ -2229,10 +2229,10 @@
 };
 new Foo(foo(objFoo));
 if (nested) {
-  let bar = function(x = this) {
+  let bar2 = function(x = this) {
     console.log(this);
   };
-  bar2 = bar;
+  bar = bar2;
   const objBar = {
     foo(x = this) {
       console.log(this);
@@ -2248,6 +2248,6 @@
       console.log(this);
     }
   }
-  new Bar(bar(objBar));
+  new Bar(bar2(objBar));
 }
-var bar2;
+var bar;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/esbuild-0.28.0/internal/js_lexer/js_lexer.go 
new/esbuild-0.28.1/internal/js_lexer/js_lexer.go
--- old/esbuild-0.28.0/internal/js_lexer/js_lexer.go    2026-04-02 
22:23:56.000000000 +0200
+++ new/esbuild-0.28.1/internal/js_lexer/js_lexer.go    2026-06-12 
00:26:09.000000000 +0200
@@ -1713,7 +1713,7 @@
        //   // This is an error (equivalent to "var foo;" except for this rule)
        //   \u0076\u0061\u0072 foo;
        //
-       //   // This is an fine (equivalent to "foo.var;")
+       //   // This is a fine (equivalent to "foo.var;")
        //   foo.\u0076\u0061\u0072;
        //
        if Keywords[text] != 0 {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/esbuild-0.28.0/internal/js_parser/js_parser.go 
new/esbuild-0.28.1/internal/js_parser/js_parser.go
--- old/esbuild-0.28.0/internal/js_parser/js_parser.go  2026-04-02 
22:23:56.000000000 +0200
+++ new/esbuild-0.28.1/internal/js_parser/js_parser.go  2026-06-12 
00:26:09.000000000 +0200
@@ -1148,6 +1148,11 @@
 }
 
 func (p *parser) selectLocalKind(kind js_ast.LocalKind) js_ast.LocalKind {
+       // Use "var" instead of "let" and "const" if they aren't supported
+       if (kind == js_ast.LocalLet || kind == js_ast.LocalConst) && 
p.options.unsupportedJSFeatures.Has(compat.ConstAndLet) {
+               return js_ast.LocalVar
+       }
+
        // Use "var" instead of "let" and "const" if the variable declaration 
may
        // need to be separated from the initializer. This allows us to safely 
move
        // this declaration into a nested scope.
@@ -1518,7 +1523,6 @@
        // Overwrite this name in the declaring scope
        p.currentScope.Members[name] = js_ast.ScopeMember{Ref: ref, Loc: loc}
        return ref
-
 }
 
 // This type is just so we can use Go's native sort function
@@ -3488,6 +3492,7 @@
        exprFlagForLoopInit
        exprFlagForAwaitLoopInit
        exprFlagAfterQuestionAndBeforeColon
+       exprFlagIsNewTarget
 )
 
 func (p *parser) parsePrefix(level js_ast.L, errors *deferredErrors, flags 
exprFlag) js_ast.Expr {
@@ -3819,7 +3824,7 @@
                        return js_ast.Expr{Loc: loc, Data: 
&js_ast.ENewTarget{Range: r}}
                }
 
-               target := p.parseExprWithFlags(js_ast.LMember, flags)
+               target := p.parseExprWithFlags(js_ast.LMember, 
flags|exprFlagIsNewTarget)
                args := []js_ast.Expr{}
                var closeParenLoc logger.Loc
                var isMultiLine bool
@@ -4320,6 +4325,11 @@
                        optionalChain = oldOptionalChain
 
                case js_lexer.TQuestionDot:
+                       if (flags & exprFlagIsNewTarget) != 0 {
+                               p.log.AddError(&p.tracker, p.lexer.Range(), 
"Cannot use an unparenthesized optional chain inside the target of \"new\"")
+                               flags &= ^exprFlagIsNewTarget // Don't report 
this error more than once in this spot
+                       }
+
                        p.lexer.Next()
                        optionalStart := js_ast.OptionalChainStart
 
@@ -9180,7 +9190,7 @@
                                // should have visited all the uses of "let" 
and "const" declarations
                                // by now since they are scoped to this block 
which we just finished
                                // visiting.
-                               if prevS, ok := 
result[len(result)-1].Data.(*js_ast.SLocal); ok && prevS.Kind != 
js_ast.LocalVar {
+                               if prevS, ok := 
result[len(result)-1].Data.(*js_ast.SLocal); ok && (prevS.Kind == 
js_ast.LocalLet || prevS.Kind == js_ast.LocalConst) {
                                        last := prevS.Decls[len(prevS.Decls)-1]
 
                                        // The binding must be an identifier 
that is only used once.
@@ -10008,9 +10018,18 @@
 }
 
 func (p *parser) recordDeclaredSymbol(ref ast.Ref) {
+       isTopLevel := p.currentScope == p.moduleScope
+
+       // Check whether this symbol was hoisted out of a nested scope into the 
module scope
+       if !isTopLevel {
+               if symbol := p.symbols[ref.InnerIndex]; symbol.Kind.IsHoisted() 
&& p.moduleScope.Members[symbol.OriginalName].Ref == ref {
+                       isTopLevel = true
+               }
+       }
+
        p.declaredSymbols = append(p.declaredSymbols, js_ast.DeclaredSymbol{
                Ref:        ref,
-               IsTopLevel: p.currentScope == p.moduleScope,
+               IsTopLevel: isTopLevel,
        })
 }
 
@@ -18217,7 +18236,7 @@
        whyESMImportStatement
 )
 
-// Say why this the current file is being considered an ES module
+// Say why the current file is being considered an ES module
 func (p *parser) whyESModule() (whyESM, []logger.MsgData) {
        because := "This file is considered to be an ECMAScript module because"
        switch {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/esbuild-0.28.0/internal/js_parser/js_parser_test.go 
new/esbuild-0.28.1/internal/js_parser/js_parser_test.go
--- old/esbuild-0.28.0/internal/js_parser/js_parser_test.go     2026-04-02 
22:23:56.000000000 +0200
+++ new/esbuild-0.28.1/internal/js_parser/js_parser_test.go     2026-06-12 
00:26:09.000000000 +0200
@@ -2686,6 +2686,13 @@
        expectPrinted(t, "tag`${x}\\unicode`", "tag`${x}\\unicode`;\n")
        expectPrinted(t, "tag`\\u{10FFFFF}`", "tag`\\u{10FFFFF}`;\n")
 
+       expectPrinted(t, "new foo`bar`()", "new foo`bar`();\n")
+       expectPrinted(t, "new (foo`bar`)()", "new foo`bar`();\n")
+       expectPrinted(t, "(new foo)`bar`()", "new foo()`bar`();\n")
+       expectPrinted(t, "new foo()`bar`()", "new foo()`bar`();\n")
+       expectPrinted(t, "(new foo())`bar`()", "new foo()`bar`();\n")
+       expectPrinted(t, "new (foo()`bar`)()", "new (foo())`bar`();\n")
+
        expectPrinted(t, "tag``", "tag``;\n")
        expectPrinted(t, "(a?.b)``", "(a?.b)``;\n")
        expectPrinted(t, "(a?.(b))``", "(a?.(b))``;\n")
@@ -5258,6 +5265,8 @@
        check("var x = 1; return x", "var x = 1;\nreturn x;")
        check("let x = 1; return x", "return 1;")
        check("const x = 1; return x", "return 1;")
+       check("using x = 1; return x", "using x = 1;\nreturn x;")
+       check("return async () => { await using x = 1; return x }", "return 
async () => {\n  await using x = 1;\n  return x;\n};")
 
        check("let x = 1; if (false) x++; return x", "return 1;")
        check("let x = 1; if (true) x++; return x", "let x = 1;\nreturn x++, 
x;")
@@ -6121,6 +6130,7 @@
        expectPrinted(t, "(a?.b)[c]", "(a?.b)[c];\n")
        expectPrinted(t, "a?.b(c)", "a?.b(c);\n")
        expectPrinted(t, "(a?.b)(c)", "(a?.b)(c);\n")
+       expectPrinted(t, "new (a?.b)", "new (a?.b)();\n")
 
        expectPrinted(t, "a?.[b][c]", "a?.[b][c];\n")
        expectPrinted(t, "(a?.[b])[c]", "(a?.[b])[c];\n")
@@ -6130,6 +6140,7 @@
        expectPrinted(t, "(a?.[b]).c", "(a?.[b]).c;\n")
        expectPrinted(t, "a?.[b](c)", "a?.[b](c);\n")
        expectPrinted(t, "(a?.[b])(c)", "(a?.[b])(c);\n")
+       expectPrinted(t, "new (a?.[b])", "new (a?.[b])();\n")
 
        expectPrinted(t, "a?.(b)(c)", "a?.(b)(c);\n")
        expectPrinted(t, "(a?.(b))(c)", "(a?.(b))(c);\n")
@@ -6139,6 +6150,22 @@
        expectPrinted(t, "(a?.(b)).c", "(a?.(b)).c;\n")
        expectPrinted(t, "a?.(b)[c]", "a?.(b)[c];\n")
        expectPrinted(t, "(a?.(b))[c]", "(a?.(b))[c];\n")
+       expectPrinted(t, "new (a?.(b))", "new (a?.(b))();\n")
+
+       expectPrinted(t, "new a()?.b", "new a()?.b;\n")
+       expectPrinted(t, "new a()?.[b]", "new a()?.[b];\n")
+       expectPrinted(t, "new a()?.(b)", "new a()?.(b);\n")
+       expectPrinted(t, "new a.b()?.c", "new a.b()?.c;\n")
+       expectPrinted(t, "new a.b()?.[c]", "new a.b()?.[c];\n")
+       expectPrinted(t, "new a.b()?.(c)", "new a.b()?.(c);\n")
+
+       err := "<stdin>: ERROR: Cannot use an unparenthesized optional chain 
inside the target of \"new\"\n"
+       expectParseError(t, "new a?.b", err)
+       expectParseError(t, "new a?.[b]", err)
+       expectParseError(t, "new a?.(b)", err)
+       expectParseError(t, "new a.b?.c", err)
+       expectParseError(t, "new a.b?.[c]", err)
+       expectParseError(t, "new a.b?.(c)", err)
 }
 
 func TestPrivateIdentifiers(t *testing.T) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/esbuild-0.28.0/internal/js_parser/ts_parser_test.go 
new/esbuild-0.28.1/internal/js_parser/ts_parser_test.go
--- old/esbuild-0.28.0/internal/js_parser/ts_parser_test.go     2026-04-02 
22:23:56.000000000 +0200
+++ new/esbuild-0.28.1/internal/js_parser/ts_parser_test.go     2026-06-12 
00:26:09.000000000 +0200
@@ -2876,6 +2876,8 @@
 `
        expectParseErrorTS(t, "import x = require('y'); x = require('z')", 
errorText)
        expectParseErrorTS(t, "import x = y.z; x = z.y", errorText)
+
+       expectPrintedWithUnsupportedFeaturesTS(t, compat.ConstAndLet, "import x 
= require('y')", "var x = require(\"y\");\n")
 }
 
 func TestTSImportEqualsInNamespace(t *testing.T) {
@@ -2904,6 +2906,13 @@
        expectParseErrorTS(t, "namespace ns { export import foo from 'bar' }", 
"<stdin>: ERROR: Expected \"=\" but found \"from\"\n")
        expectParseErrorTS(t, "namespace ns { { import foo = bar } }", 
"<stdin>: ERROR: Unexpected \"foo\"\n")
        expectParseErrorTS(t, "namespace ns { { export import foo = bar } }", 
"<stdin>: ERROR: Unexpected \"export\"\n")
+
+       expectPrintedWithUnsupportedFeaturesTS(t, compat.ConstAndLet, 
"namespace ns { import x = require('y'); x }", `var ns;
+((ns) => {
+  var x = require("y");
+  x;
+})(ns || (ns = {}));
+`)
 }
 
 func TestTSTypeOnlyImport(t *testing.T) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/esbuild-0.28.0/internal/js_printer/js_printer.go 
new/esbuild-0.28.1/internal/js_printer/js_printer.go
--- old/esbuild-0.28.0/internal/js_printer/js_printer.go        2026-04-02 
22:23:56.000000000 +0200
+++ new/esbuild-0.28.1/internal/js_printer/js_printer.go        2026-06-12 
00:26:09.000000000 +0200
@@ -1399,7 +1399,7 @@
 func (p *printer) printRequireOrImportExpr(importRecordIndex uint32, level 
js_ast.L, flags printExprFlags, closeParenLoc logger.Loc, phase 
ast.ImportPhase) {
        record := &p.importRecords[importRecordIndex]
 
-       if level >= js_ast.LNew || (flags&forbidCall) != 0 {
+       if level >= js_ast.LNew || (flags&isNewTarget) != 0 {
                p.print("(")
                defer p.print(")")
                level = js_ast.LLowest
@@ -1759,7 +1759,7 @@
 
 // Constant folding is already implemented once in the parser. A smaller form
 // of constant folding (just for numbers) is implemented here to clean up 
cross-
-// module numeric constants and bitwise operations. This is not an general-
+// module numeric constants and bitwise operations. This is not a general-
 // purpose/optimal approach and never will be. For example, we can't affect
 // tree shaking at this stage because it has already happened.
 func (p *printer) lateConstantFoldUnaryOrBinaryOrIfExpr(expr js_ast.Expr) 
js_ast.Expr {
@@ -1989,7 +1989,7 @@
 type printExprFlags uint16
 
 const (
-       forbidCall printExprFlags = 1 << iota
+       isNewTarget printExprFlags = 1 << iota
        forbidIn
        hasNonOptionalChainParent
        exprResultIsUnused
@@ -2253,7 +2253,7 @@
                p.addSourceMapping(expr.Loc)
                p.print("new")
                p.printSpace()
-               p.printExpr(e.Target, js_ast.LNew, forbidCall)
+               p.printExpr(e.Target, js_ast.LNew, isNewTarget)
 
                // Omit the "()" when minifying, but only when safe to do so
                isMultiLine := !p.options.MinifyWhitespace && ((e.IsMultiLine 
&& len(e.Args) > 0) ||
@@ -2373,7 +2373,7 @@
                        }
                }
 
-               wrap := level >= js_ast.LNew || (flags&forbidCall) != 0
+               wrap := level >= js_ast.LNew || (flags&isNewTarget) != 0
                var targetFlags printExprFlags
                if e.OptionalChain == js_ast.OptionalChainNone {
                        targetFlags = hasNonOptionalChainParent
@@ -2456,7 +2456,7 @@
        case *js_ast.ERequireResolveString:
                recordLoc := p.importRecords[e.ImportRecordIndex].Range.Loc
                isMultiLine := p.willPrintExprCommentsAtLoc(recordLoc) || 
p.willPrintExprCommentsAtLoc(e.CloseParenLoc)
-               wrap := level >= js_ast.LNew || (flags&forbidCall) != 0
+               wrap := level >= js_ast.LNew || (flags&isNewTarget) != 0
                if wrap {
                        p.print("(")
                }
@@ -2495,7 +2495,7 @@
                        (p.willPrintExprCommentsAtLoc(e.Expr.Loc) ||
                                (printImportAssertOrWith && 
p.willPrintExprCommentsAtLoc(e.OptionsOrNil.Loc)) ||
                                p.willPrintExprCommentsAtLoc(e.CloseParenLoc))
-               wrap := level >= js_ast.LNew || (flags&forbidCall) != 0
+               wrap := level >= js_ast.LNew || (flags&isNewTarget) != 0
                if wrap {
                        p.print("(")
                }
@@ -2558,13 +2558,13 @@
                                break
                        }
                } else {
-                       if (flags & hasNonOptionalChainParent) != 0 {
+                       if (flags & (isNewTarget | hasNonOptionalChainParent)) 
!= 0 {
                                wrap = true
                                p.print("(")
                        }
-                       flags &= ^hasNonOptionalChainParent
+                       flags &= ^(isNewTarget | hasNonOptionalChainParent)
                }
-               p.printExpr(e.Target, js_ast.LPostfix, 
(flags&(forbidCall|hasNonOptionalChainParent))|isPropertyAccessTarget)
+               p.printExpr(e.Target, js_ast.LPostfix, 
(flags&(isNewTarget|hasNonOptionalChainParent))|isPropertyAccessTarget)
                if p.canPrintIdentifier(e.Name) {
                        if e.OptionalChain != js_ast.OptionalChainStart && 
p.needSpaceBeforeDot == len(p.js) {
                                // "1.toString" is a syntax error, so print "1 
.toString" instead
@@ -2614,13 +2614,13 @@
                                }
                        }
                } else {
-                       if (flags & hasNonOptionalChainParent) != 0 {
+                       if (flags & (isNewTarget | hasNonOptionalChainParent)) 
!= 0 {
                                p.print("(")
                                defer p.print(")")
                        }
-                       flags &= ^hasNonOptionalChainParent
+                       flags &= ^(isNewTarget | hasNonOptionalChainParent)
                }
-               p.printExpr(e.Target, js_ast.LPostfix, 
(flags&(forbidCall|hasNonOptionalChainParent))|isPropertyAccessTarget)
+               p.printExpr(e.Target, js_ast.LPostfix, 
(flags&(isNewTarget|hasNonOptionalChainParent))|isPropertyAccessTarget)
                if e.OptionalChain == js_ast.OptionalChainStart {
                        p.print("?.")
                }
@@ -3022,7 +3022,7 @@
                                p.printExpr(e.TagOrNil, js_ast.LLowest, 
isCallTargetOrTemplateTag)
                                p.print(")")
                        } else {
-                               p.printExpr(e.TagOrNil, js_ast.LPostfix, 
isCallTargetOrTemplateTag)
+                               p.printExpr(e.TagOrNil, js_ast.LPostfix, 
isCallTargetOrTemplateTag|(flags&isNewTarget))
                        }
                } else {
                        p.addSourceMapping(expr.Loc)
@@ -3081,7 +3081,7 @@
                        break
                }
 
-               wrap := level >= js_ast.LNew || (flags&forbidCall) != 0
+               wrap := level >= js_ast.LNew || (flags&isNewTarget) != 0
                hasPureComment := !p.options.MinifyWhitespace
 
                if hasPureComment && level >= js_ast.LPostfix {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/esbuild-0.28.0/internal/linker/linker.go 
new/esbuild-0.28.1/internal/linker/linker.go
--- old/esbuild-0.28.0/internal/linker/linker.go        2026-04-02 
22:23:56.000000000 +0200
+++ new/esbuild-0.28.1/internal/linker/linker.go        2026-06-12 
00:26:09.000000000 +0200
@@ -2431,9 +2431,9 @@
        // However, that generation is special-cased for various reasons and is
        // done later on. Still, we're going to need to ensure that this file
        // both depends on the "__commonJS" symbol and declares the 
"require_foo"
-       // symbol. Instead of special-casing this during the reachablity 
analysis
+       // symbol. Instead of special-casing this during the reachability 
analysis
        // below, we just append a dummy part to the end of the file with these
-       // dependencies and let the general-purpose reachablity analysis take 
care
+       // dependencies and let the general-purpose reachability analysis take 
care
        // of it.
        case graph.WrapCJS:
                runtimeRepr := 
c.graph.Files[runtime.SourceIndex].InputFile.Repr.(*graph.JSRepr)
@@ -5330,12 +5330,12 @@
        reservedNames := renamer.ComputeReservedNames(moduleScopes, 
c.graph.Symbols)
 
        // Node contains code that scans CommonJS modules in an attempt to 
statically
-       // detect the  set of export names that a module will use. However, it 
doesn't
+       // detect the set of export names that a module will use. However, it 
doesn't
        // do any scope analysis so it can be fooled by local variables with 
the same
        // name as the CommonJS module-scope variables "exports" and "module". 
Avoid
        // using these names in this case even if there is not a risk of a name
        // collision because there is still a risk of node incorrectly detecting
-       // something in a nested scope as an top-level export. Here's a case 
where
+       // something in a nested scope as a top-level export. Here's a case 
where
        // this happened: https://github.com/evanw/esbuild/issues/3544
        if c.options.OutputFormat == config.FormatCommonJS && 
c.options.Platform == config.PlatformNode {
                reservedNames["exports"] = 1
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/esbuild-0.28.0/internal/runtime/runtime.go 
new/esbuild-0.28.1/internal/runtime/runtime.go
--- old/esbuild-0.28.0/internal/runtime/runtime.go      2026-04-02 
22:23:56.000000000 +0200
+++ new/esbuild-0.28.1/internal/runtime/runtime.go      2026-06-12 
00:26:09.000000000 +0200
@@ -170,18 +170,40 @@
                // This is for lazily-initialized ESM code. This has two 
implementations, a
                // compact one for minified code and a verbose one that 
generates friendly
                // names in V8's profiler and in stack traces.
-               export var __esm = (fn, res) => function __init() {
-                       return fn && (res = (0, 
fn[__getOwnPropNames(fn)[0]])(fn = 0)), res
+               export var __esm = (fn, res, err) => function __init() {
+                       if (err) throw err[0]
+                       try {
+                               return fn && (res = (0, 
fn[__getOwnPropNames(fn)[0]])(fn = 0)), res
+                       } catch (e) {
+                               throw err = [e], e
+                       }
+               }
+               export var __esmMin = (fn, res, err) => () => {
+                       if (err) throw err[0]
+                       try {
+                               return fn && (res = fn(fn = 0)), res
+                       } catch (e) {
+                               throw err = [e], e
+                       }
                }
-               export var __esmMin = (fn, res) => () => (fn && (res = fn(fn = 
0)), res)
 
                // Wraps a CommonJS closure and returns a require() function. 
This has two
                // implementations, a compact one for minified code and a 
verbose one that
                // generates friendly names in V8's profiler and in stack 
traces.
                export var __commonJS = (cb, mod) => function __require() {
-                       return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = 
{exports: {}}).exports, mod), mod.exports
+                       try {
+                               return mod || (0, 
cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports
+                       } catch (e) {
+                               throw mod = 0, e
+                       }
+               }
+               export var __commonJSMin = (cb, mod) => () => {
+                       try {
+                               return mod || cb((mod = { exports: {} 
}).exports, mod), mod.exports
+                       } catch (e) {
+                               throw mod = 0, e
+                       }
                }
-               export var __commonJSMin = (cb, mod) => () => (mod || cb((mod = 
{exports: {}}).exports, mod), mod.exports)
 
                // Used to implement ESM exports both for "require()" and 
"import * as"
                export var __export = (target, all) => {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/esbuild-0.28.0/lib/deno/mod.ts 
new/esbuild-0.28.1/lib/deno/mod.ts
--- old/esbuild-0.28.0/lib/deno/mod.ts  2026-04-02 22:23:56.000000000 +0200
+++ new/esbuild-0.28.1/lib/deno/mod.ts  2026-06-12 00:26:09.000000000 +0200
@@ -4,6 +4,7 @@
 import * as denoflate from "https://deno.land/x/[email protected]/mod.ts";
 
 declare const ESBUILD_VERSION: string
+declare const ESBUILD_BINARY_HASHES: Record<string, string>
 
 export let version = ESBUILD_VERSION
 
@@ -59,6 +60,15 @@
   initializeWasCalled = true
 }
 
+async function binaryIntegrityCheck(pkg: string, subpath: string, bytes: 
Uint8Array): Promise<void> {
+  const hashBuffer = await crypto.subtle.digest('SHA-256', bytes as 
Uint8Array<ArrayBuffer>)
+  const hash = Array.from(new Uint8Array(hashBuffer)).map(b => 
b.toString(16).padStart(2, '0')).join('')
+  const key = `${pkg}/${subpath}`
+  const expected = ESBUILD_BINARY_HASHES[key]
+  if (!expected) throw new Error(`Missing hash for "${key}"`)
+  if (hash !== expected) throw new Error(`"${hash.slice(0, 8)}..." doesn't 
match "${expected.slice(0, 8)}..." for "${pkg}"`)
+}
+
 async function installFromNPM(name: string, subpath: string): Promise<string> {
   const { finalPath, finalDir } = getCachePath(name)
   try {
@@ -71,6 +81,7 @@
   const url = `${npmRegistry}/${name}/-/${name.replace("@esbuild/", 
"")}-${version}.tgz`
   const buffer = await fetch(url).then(r => r.arrayBuffer())
   const executable = extractFileFromTarGzip(new Uint8Array(buffer), subpath)
+  await binaryIntegrityCheck(name, subpath, executable)
 
   await Deno.mkdir(finalDir, {
     recursive: true,
@@ -130,7 +141,7 @@
     let name = str(offset, 100)
     let size = parseInt(str(offset + 124, 12), 8)
     offset += 512
-    if (!isNaN(size)) {
+    if (!isNaN(size) && size >= 0) {
       if (name === file) return buffer.subarray(offset, offset + size)
       offset += (size + 511) & ~511
     }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/esbuild-0.28.0/lib/npm/node-install.ts 
new/esbuild-0.28.1/lib/npm/node-install.ts
--- old/esbuild-0.28.0/lib/npm/node-install.ts  2026-04-02 22:23:56.000000000 
+0200
+++ new/esbuild-0.28.1/lib/npm/node-install.ts  2026-06-12 00:26:09.000000000 
+0200
@@ -94,7 +94,7 @@
     let name = str(offset, 100)
     let size = parseInt(str(offset + 124, 12), 8)
     offset += 512
-    if (!isNaN(size)) {
+    if (!isNaN(size) && size >= 0) {
       if (name === subpath) return buffer.subarray(offset, offset + size)
       offset += (size + 511) & ~511
     }
@@ -230,7 +230,7 @@
   const key = `${pkg}/${subpath}`
   const expected = packageJSON['esbuild.binaryHashes'][key]
   if (!expected) throw new Error(`Missing hash for "${key}"`)
-  if (hash !== expected) throw new Error(`"${hash.slice(0, 8)}..." doesn't 
match "${expected.slice(0, 8)}..."`)
+  if (hash !== expected) throw new Error(`"${hash.slice(0, 8)}..." doesn't 
match "${expected.slice(0, 8)}..." for "${pkg}"`)
 }
 
 async function downloadDirectlyFromNPM(pkg: string, subpath: string, binPath: 
string): Promise<void> {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/esbuild-0.28.0/npm/@esbuild/aix-ppc64/package.json 
new/esbuild-0.28.1/npm/@esbuild/aix-ppc64/package.json
--- old/esbuild-0.28.0/npm/@esbuild/aix-ppc64/package.json      2026-04-02 
22:23:56.000000000 +0200
+++ new/esbuild-0.28.1/npm/@esbuild/aix-ppc64/package.json      2026-06-12 
00:26:09.000000000 +0200
@@ -1,6 +1,6 @@
 {
   "name": "@esbuild/aix-ppc64",
-  "version": "0.28.0",
+  "version": "0.28.1",
   "description": "The IBM AIX PowerPC 64-bit binary for esbuild, a JavaScript 
bundler.",
   "repository": {
     "type": "git",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/esbuild-0.28.0/npm/@esbuild/android-arm/package.json 
new/esbuild-0.28.1/npm/@esbuild/android-arm/package.json
--- old/esbuild-0.28.0/npm/@esbuild/android-arm/package.json    2026-04-02 
22:23:56.000000000 +0200
+++ new/esbuild-0.28.1/npm/@esbuild/android-arm/package.json    2026-06-12 
00:26:09.000000000 +0200
@@ -1,6 +1,6 @@
 {
   "name": "@esbuild/android-arm",
-  "version": "0.28.0",
+  "version": "0.28.1",
   "description": "A WebAssembly shim for esbuild on Android ARM.",
   "repository": {
     "type": "git",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/esbuild-0.28.0/npm/@esbuild/android-arm64/package.json 
new/esbuild-0.28.1/npm/@esbuild/android-arm64/package.json
--- old/esbuild-0.28.0/npm/@esbuild/android-arm64/package.json  2026-04-02 
22:23:56.000000000 +0200
+++ new/esbuild-0.28.1/npm/@esbuild/android-arm64/package.json  2026-06-12 
00:26:09.000000000 +0200
@@ -1,6 +1,6 @@
 {
   "name": "@esbuild/android-arm64",
-  "version": "0.28.0",
+  "version": "0.28.1",
   "description": "The Android ARM 64-bit binary for esbuild, a JavaScript 
bundler.",
   "repository": {
     "type": "git",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/esbuild-0.28.0/npm/@esbuild/android-x64/package.json 
new/esbuild-0.28.1/npm/@esbuild/android-x64/package.json
--- old/esbuild-0.28.0/npm/@esbuild/android-x64/package.json    2026-04-02 
22:23:56.000000000 +0200
+++ new/esbuild-0.28.1/npm/@esbuild/android-x64/package.json    2026-06-12 
00:26:09.000000000 +0200
@@ -1,6 +1,6 @@
 {
   "name": "@esbuild/android-x64",
-  "version": "0.28.0",
+  "version": "0.28.1",
   "description": "A WebAssembly shim for esbuild on Android x64.",
   "repository": {
     "type": "git",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/esbuild-0.28.0/npm/@esbuild/darwin-arm64/package.json 
new/esbuild-0.28.1/npm/@esbuild/darwin-arm64/package.json
--- old/esbuild-0.28.0/npm/@esbuild/darwin-arm64/package.json   2026-04-02 
22:23:56.000000000 +0200
+++ new/esbuild-0.28.1/npm/@esbuild/darwin-arm64/package.json   2026-06-12 
00:26:09.000000000 +0200
@@ -1,6 +1,6 @@
 {
   "name": "@esbuild/darwin-arm64",
-  "version": "0.28.0",
+  "version": "0.28.1",
   "description": "The macOS ARM 64-bit binary for esbuild, a JavaScript 
bundler.",
   "repository": {
     "type": "git",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/esbuild-0.28.0/npm/@esbuild/darwin-x64/package.json 
new/esbuild-0.28.1/npm/@esbuild/darwin-x64/package.json
--- old/esbuild-0.28.0/npm/@esbuild/darwin-x64/package.json     2026-04-02 
22:23:56.000000000 +0200
+++ new/esbuild-0.28.1/npm/@esbuild/darwin-x64/package.json     2026-06-12 
00:26:09.000000000 +0200
@@ -1,6 +1,6 @@
 {
   "name": "@esbuild/darwin-x64",
-  "version": "0.28.0",
+  "version": "0.28.1",
   "description": "The macOS 64-bit binary for esbuild, a JavaScript bundler.",
   "repository": {
     "type": "git",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/esbuild-0.28.0/npm/@esbuild/freebsd-arm64/package.json 
new/esbuild-0.28.1/npm/@esbuild/freebsd-arm64/package.json
--- old/esbuild-0.28.0/npm/@esbuild/freebsd-arm64/package.json  2026-04-02 
22:23:56.000000000 +0200
+++ new/esbuild-0.28.1/npm/@esbuild/freebsd-arm64/package.json  2026-06-12 
00:26:09.000000000 +0200
@@ -1,6 +1,6 @@
 {
   "name": "@esbuild/freebsd-arm64",
-  "version": "0.28.0",
+  "version": "0.28.1",
   "description": "The FreeBSD ARM 64-bit binary for esbuild, a JavaScript 
bundler.",
   "repository": {
     "type": "git",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/esbuild-0.28.0/npm/@esbuild/freebsd-x64/package.json 
new/esbuild-0.28.1/npm/@esbuild/freebsd-x64/package.json
--- old/esbuild-0.28.0/npm/@esbuild/freebsd-x64/package.json    2026-04-02 
22:23:56.000000000 +0200
+++ new/esbuild-0.28.1/npm/@esbuild/freebsd-x64/package.json    2026-06-12 
00:26:09.000000000 +0200
@@ -1,6 +1,6 @@
 {
   "name": "@esbuild/freebsd-x64",
-  "version": "0.28.0",
+  "version": "0.28.1",
   "description": "The FreeBSD 64-bit binary for esbuild, a JavaScript 
bundler.",
   "repository": {
     "type": "git",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/esbuild-0.28.0/npm/@esbuild/linux-arm/package.json 
new/esbuild-0.28.1/npm/@esbuild/linux-arm/package.json
--- old/esbuild-0.28.0/npm/@esbuild/linux-arm/package.json      2026-04-02 
22:23:56.000000000 +0200
+++ new/esbuild-0.28.1/npm/@esbuild/linux-arm/package.json      2026-06-12 
00:26:09.000000000 +0200
@@ -1,6 +1,6 @@
 {
   "name": "@esbuild/linux-arm",
-  "version": "0.28.0",
+  "version": "0.28.1",
   "description": "The Linux ARM binary for esbuild, a JavaScript bundler.",
   "repository": {
     "type": "git",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/esbuild-0.28.0/npm/@esbuild/linux-arm64/package.json 
new/esbuild-0.28.1/npm/@esbuild/linux-arm64/package.json
--- old/esbuild-0.28.0/npm/@esbuild/linux-arm64/package.json    2026-04-02 
22:23:56.000000000 +0200
+++ new/esbuild-0.28.1/npm/@esbuild/linux-arm64/package.json    2026-06-12 
00:26:09.000000000 +0200
@@ -1,6 +1,6 @@
 {
   "name": "@esbuild/linux-arm64",
-  "version": "0.28.0",
+  "version": "0.28.1",
   "description": "The Linux ARM 64-bit binary for esbuild, a JavaScript 
bundler.",
   "repository": {
     "type": "git",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/esbuild-0.28.0/npm/@esbuild/linux-ia32/package.json 
new/esbuild-0.28.1/npm/@esbuild/linux-ia32/package.json
--- old/esbuild-0.28.0/npm/@esbuild/linux-ia32/package.json     2026-04-02 
22:23:56.000000000 +0200
+++ new/esbuild-0.28.1/npm/@esbuild/linux-ia32/package.json     2026-06-12 
00:26:09.000000000 +0200
@@ -1,6 +1,6 @@
 {
   "name": "@esbuild/linux-ia32",
-  "version": "0.28.0",
+  "version": "0.28.1",
   "description": "The Linux 32-bit binary for esbuild, a JavaScript bundler.",
   "repository": {
     "type": "git",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/esbuild-0.28.0/npm/@esbuild/linux-loong64/package.json 
new/esbuild-0.28.1/npm/@esbuild/linux-loong64/package.json
--- old/esbuild-0.28.0/npm/@esbuild/linux-loong64/package.json  2026-04-02 
22:23:56.000000000 +0200
+++ new/esbuild-0.28.1/npm/@esbuild/linux-loong64/package.json  2026-06-12 
00:26:09.000000000 +0200
@@ -1,6 +1,6 @@
 {
   "name": "@esbuild/linux-loong64",
-  "version": "0.28.0",
+  "version": "0.28.1",
   "description": "The Linux LoongArch 64-bit binary for esbuild, a JavaScript 
bundler.",
   "repository": {
     "type": "git",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/esbuild-0.28.0/npm/@esbuild/linux-mips64el/package.json 
new/esbuild-0.28.1/npm/@esbuild/linux-mips64el/package.json
--- old/esbuild-0.28.0/npm/@esbuild/linux-mips64el/package.json 2026-04-02 
22:23:56.000000000 +0200
+++ new/esbuild-0.28.1/npm/@esbuild/linux-mips64el/package.json 2026-06-12 
00:26:09.000000000 +0200
@@ -1,6 +1,6 @@
 {
   "name": "@esbuild/linux-mips64el",
-  "version": "0.28.0",
+  "version": "0.28.1",
   "description": "The Linux MIPS 64-bit Little Endian binary for esbuild, a 
JavaScript bundler.",
   "repository": {
     "type": "git",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/esbuild-0.28.0/npm/@esbuild/linux-ppc64/package.json 
new/esbuild-0.28.1/npm/@esbuild/linux-ppc64/package.json
--- old/esbuild-0.28.0/npm/@esbuild/linux-ppc64/package.json    2026-04-02 
22:23:56.000000000 +0200
+++ new/esbuild-0.28.1/npm/@esbuild/linux-ppc64/package.json    2026-06-12 
00:26:09.000000000 +0200
@@ -1,6 +1,6 @@
 {
   "name": "@esbuild/linux-ppc64",
-  "version": "0.28.0",
+  "version": "0.28.1",
   "description": "The Linux PowerPC 64-bit Little Endian binary for esbuild, a 
JavaScript bundler.",
   "repository": {
     "type": "git",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/esbuild-0.28.0/npm/@esbuild/linux-riscv64/package.json 
new/esbuild-0.28.1/npm/@esbuild/linux-riscv64/package.json
--- old/esbuild-0.28.0/npm/@esbuild/linux-riscv64/package.json  2026-04-02 
22:23:56.000000000 +0200
+++ new/esbuild-0.28.1/npm/@esbuild/linux-riscv64/package.json  2026-06-12 
00:26:09.000000000 +0200
@@ -1,6 +1,6 @@
 {
   "name": "@esbuild/linux-riscv64",
-  "version": "0.28.0",
+  "version": "0.28.1",
   "description": "The Linux RISC-V 64-bit binary for esbuild, a JavaScript 
bundler.",
   "repository": {
     "type": "git",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/esbuild-0.28.0/npm/@esbuild/linux-s390x/package.json 
new/esbuild-0.28.1/npm/@esbuild/linux-s390x/package.json
--- old/esbuild-0.28.0/npm/@esbuild/linux-s390x/package.json    2026-04-02 
22:23:56.000000000 +0200
+++ new/esbuild-0.28.1/npm/@esbuild/linux-s390x/package.json    2026-06-12 
00:26:09.000000000 +0200
@@ -1,6 +1,6 @@
 {
   "name": "@esbuild/linux-s390x",
-  "version": "0.28.0",
+  "version": "0.28.1",
   "description": "The Linux IBM Z 64-bit Big Endian binary for esbuild, a 
JavaScript bundler.",
   "repository": {
     "type": "git",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/esbuild-0.28.0/npm/@esbuild/linux-x64/package.json 
new/esbuild-0.28.1/npm/@esbuild/linux-x64/package.json
--- old/esbuild-0.28.0/npm/@esbuild/linux-x64/package.json      2026-04-02 
22:23:56.000000000 +0200
+++ new/esbuild-0.28.1/npm/@esbuild/linux-x64/package.json      2026-06-12 
00:26:09.000000000 +0200
@@ -1,6 +1,6 @@
 {
   "name": "@esbuild/linux-x64",
-  "version": "0.28.0",
+  "version": "0.28.1",
   "description": "The Linux 64-bit binary for esbuild, a JavaScript bundler.",
   "repository": {
     "type": "git",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/esbuild-0.28.0/npm/@esbuild/netbsd-arm64/package.json 
new/esbuild-0.28.1/npm/@esbuild/netbsd-arm64/package.json
--- old/esbuild-0.28.0/npm/@esbuild/netbsd-arm64/package.json   2026-04-02 
22:23:56.000000000 +0200
+++ new/esbuild-0.28.1/npm/@esbuild/netbsd-arm64/package.json   2026-06-12 
00:26:09.000000000 +0200
@@ -1,6 +1,6 @@
 {
   "name": "@esbuild/netbsd-arm64",
-  "version": "0.28.0",
+  "version": "0.28.1",
   "description": "The NetBSD ARM 64-bit binary for esbuild, a JavaScript 
bundler.",
   "repository": {
     "type": "git",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/esbuild-0.28.0/npm/@esbuild/netbsd-x64/package.json 
new/esbuild-0.28.1/npm/@esbuild/netbsd-x64/package.json
--- old/esbuild-0.28.0/npm/@esbuild/netbsd-x64/package.json     2026-04-02 
22:23:56.000000000 +0200
+++ new/esbuild-0.28.1/npm/@esbuild/netbsd-x64/package.json     2026-06-12 
00:26:09.000000000 +0200
@@ -1,6 +1,6 @@
 {
   "name": "@esbuild/netbsd-x64",
-  "version": "0.28.0",
+  "version": "0.28.1",
   "description": "The NetBSD AMD64 binary for esbuild, a JavaScript bundler.",
   "repository": {
     "type": "git",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/esbuild-0.28.0/npm/@esbuild/openbsd-arm64/package.json 
new/esbuild-0.28.1/npm/@esbuild/openbsd-arm64/package.json
--- old/esbuild-0.28.0/npm/@esbuild/openbsd-arm64/package.json  2026-04-02 
22:23:56.000000000 +0200
+++ new/esbuild-0.28.1/npm/@esbuild/openbsd-arm64/package.json  2026-06-12 
00:26:09.000000000 +0200
@@ -1,6 +1,6 @@
 {
   "name": "@esbuild/openbsd-arm64",
-  "version": "0.28.0",
+  "version": "0.28.1",
   "description": "The OpenBSD ARM 64-bit binary for esbuild, a JavaScript 
bundler.",
   "repository": {
     "type": "git",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/esbuild-0.28.0/npm/@esbuild/openbsd-x64/package.json 
new/esbuild-0.28.1/npm/@esbuild/openbsd-x64/package.json
--- old/esbuild-0.28.0/npm/@esbuild/openbsd-x64/package.json    2026-04-02 
22:23:56.000000000 +0200
+++ new/esbuild-0.28.1/npm/@esbuild/openbsd-x64/package.json    2026-06-12 
00:26:09.000000000 +0200
@@ -1,6 +1,6 @@
 {
   "name": "@esbuild/openbsd-x64",
-  "version": "0.28.0",
+  "version": "0.28.1",
   "description": "The OpenBSD 64-bit binary for esbuild, a JavaScript 
bundler.",
   "repository": {
     "type": "git",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/esbuild-0.28.0/npm/@esbuild/openharmony-arm64/package.json 
new/esbuild-0.28.1/npm/@esbuild/openharmony-arm64/package.json
--- old/esbuild-0.28.0/npm/@esbuild/openharmony-arm64/package.json      
2026-04-02 22:23:56.000000000 +0200
+++ new/esbuild-0.28.1/npm/@esbuild/openharmony-arm64/package.json      
2026-06-12 00:26:09.000000000 +0200
@@ -1,6 +1,6 @@
 {
   "name": "@esbuild/openharmony-arm64",
-  "version": "0.28.0",
+  "version": "0.28.1",
   "description": "A WebAssembly shim for esbuild on OpenHarmony ARM64.",
   "repository": {
     "type": "git",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/esbuild-0.28.0/npm/@esbuild/sunos-x64/package.json 
new/esbuild-0.28.1/npm/@esbuild/sunos-x64/package.json
--- old/esbuild-0.28.0/npm/@esbuild/sunos-x64/package.json      2026-04-02 
22:23:56.000000000 +0200
+++ new/esbuild-0.28.1/npm/@esbuild/sunos-x64/package.json      2026-06-12 
00:26:09.000000000 +0200
@@ -1,6 +1,6 @@
 {
   "name": "@esbuild/sunos-x64",
-  "version": "0.28.0",
+  "version": "0.28.1",
   "description": "The illumos 64-bit binary for esbuild, a JavaScript 
bundler.",
   "repository": {
     "type": "git",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/esbuild-0.28.0/npm/@esbuild/wasi-preview1/package.json 
new/esbuild-0.28.1/npm/@esbuild/wasi-preview1/package.json
--- old/esbuild-0.28.0/npm/@esbuild/wasi-preview1/package.json  2026-04-02 
22:23:56.000000000 +0200
+++ new/esbuild-0.28.1/npm/@esbuild/wasi-preview1/package.json  2026-06-12 
00:26:09.000000000 +0200
@@ -1,6 +1,6 @@
 {
   "name": "@esbuild/wasi-preview1",
-  "version": "0.28.0",
+  "version": "0.28.1",
   "description": "The WASI (WebAssembly System Interface) preview 1 binary for 
esbuild, a JavaScript bundler.",
   "repository": {
     "type": "git",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/esbuild-0.28.0/npm/@esbuild/win32-arm64/package.json 
new/esbuild-0.28.1/npm/@esbuild/win32-arm64/package.json
--- old/esbuild-0.28.0/npm/@esbuild/win32-arm64/package.json    2026-04-02 
22:23:56.000000000 +0200
+++ new/esbuild-0.28.1/npm/@esbuild/win32-arm64/package.json    2026-06-12 
00:26:09.000000000 +0200
@@ -1,6 +1,6 @@
 {
   "name": "@esbuild/win32-arm64",
-  "version": "0.28.0",
+  "version": "0.28.1",
   "description": "The Windows ARM 64-bit binary for esbuild, a JavaScript 
bundler.",
   "repository": {
     "type": "git",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/esbuild-0.28.0/npm/@esbuild/win32-ia32/package.json 
new/esbuild-0.28.1/npm/@esbuild/win32-ia32/package.json
--- old/esbuild-0.28.0/npm/@esbuild/win32-ia32/package.json     2026-04-02 
22:23:56.000000000 +0200
+++ new/esbuild-0.28.1/npm/@esbuild/win32-ia32/package.json     2026-06-12 
00:26:09.000000000 +0200
@@ -1,6 +1,6 @@
 {
   "name": "@esbuild/win32-ia32",
-  "version": "0.28.0",
+  "version": "0.28.1",
   "description": "The Windows 32-bit binary for esbuild, a JavaScript 
bundler.",
   "repository": {
     "type": "git",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/esbuild-0.28.0/npm/@esbuild/win32-x64/package.json 
new/esbuild-0.28.1/npm/@esbuild/win32-x64/package.json
--- old/esbuild-0.28.0/npm/@esbuild/win32-x64/package.json      2026-04-02 
22:23:56.000000000 +0200
+++ new/esbuild-0.28.1/npm/@esbuild/win32-x64/package.json      2026-06-12 
00:26:09.000000000 +0200
@@ -1,6 +1,6 @@
 {
   "name": "@esbuild/win32-x64",
-  "version": "0.28.0",
+  "version": "0.28.1",
   "description": "The Windows 64-bit binary for esbuild, a JavaScript 
bundler.",
   "repository": {
     "type": "git",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/esbuild-0.28.0/npm/esbuild/package.json 
new/esbuild-0.28.1/npm/esbuild/package.json
--- old/esbuild-0.28.0/npm/esbuild/package.json 2026-04-02 22:23:56.000000000 
+0200
+++ new/esbuild-0.28.1/npm/esbuild/package.json 2026-06-12 00:26:09.000000000 
+0200
@@ -1,6 +1,6 @@
 {
   "name": "esbuild",
-  "version": "0.28.0",
+  "version": "0.28.1",
   "description": "An extremely fast JavaScript and CSS bundler and minifier.",
   "repository": {
     "type": "git",
@@ -18,57 +18,57 @@
     "esbuild": "bin/esbuild"
   },
   "optionalDependencies": {
-    "@esbuild/aix-ppc64": "0.28.0",
-    "@esbuild/android-arm": "0.28.0",
-    "@esbuild/android-arm64": "0.28.0",
-    "@esbuild/android-x64": "0.28.0",
-    "@esbuild/darwin-arm64": "0.28.0",
-    "@esbuild/darwin-x64": "0.28.0",
-    "@esbuild/freebsd-arm64": "0.28.0",
-    "@esbuild/freebsd-x64": "0.28.0",
-    "@esbuild/linux-arm": "0.28.0",
-    "@esbuild/linux-arm64": "0.28.0",
-    "@esbuild/linux-ia32": "0.28.0",
-    "@esbuild/linux-loong64": "0.28.0",
-    "@esbuild/linux-mips64el": "0.28.0",
-    "@esbuild/linux-ppc64": "0.28.0",
-    "@esbuild/linux-riscv64": "0.28.0",
-    "@esbuild/linux-s390x": "0.28.0",
-    "@esbuild/linux-x64": "0.28.0",
-    "@esbuild/netbsd-arm64": "0.28.0",
-    "@esbuild/netbsd-x64": "0.28.0",
-    "@esbuild/openbsd-arm64": "0.28.0",
-    "@esbuild/openbsd-x64": "0.28.0",
-    "@esbuild/openharmony-arm64": "0.28.0",
-    "@esbuild/sunos-x64": "0.28.0",
-    "@esbuild/win32-arm64": "0.28.0",
-    "@esbuild/win32-ia32": "0.28.0",
-    "@esbuild/win32-x64": "0.28.0"
+    "@esbuild/aix-ppc64": "0.28.1",
+    "@esbuild/android-arm": "0.28.1",
+    "@esbuild/android-arm64": "0.28.1",
+    "@esbuild/android-x64": "0.28.1",
+    "@esbuild/darwin-arm64": "0.28.1",
+    "@esbuild/darwin-x64": "0.28.1",
+    "@esbuild/freebsd-arm64": "0.28.1",
+    "@esbuild/freebsd-x64": "0.28.1",
+    "@esbuild/linux-arm": "0.28.1",
+    "@esbuild/linux-arm64": "0.28.1",
+    "@esbuild/linux-ia32": "0.28.1",
+    "@esbuild/linux-loong64": "0.28.1",
+    "@esbuild/linux-mips64el": "0.28.1",
+    "@esbuild/linux-ppc64": "0.28.1",
+    "@esbuild/linux-riscv64": "0.28.1",
+    "@esbuild/linux-s390x": "0.28.1",
+    "@esbuild/linux-x64": "0.28.1",
+    "@esbuild/netbsd-arm64": "0.28.1",
+    "@esbuild/netbsd-x64": "0.28.1",
+    "@esbuild/openbsd-arm64": "0.28.1",
+    "@esbuild/openbsd-x64": "0.28.1",
+    "@esbuild/openharmony-arm64": "0.28.1",
+    "@esbuild/sunos-x64": "0.28.1",
+    "@esbuild/win32-arm64": "0.28.1",
+    "@esbuild/win32-ia32": "0.28.1",
+    "@esbuild/win32-x64": "0.28.1"
   },
   "license": "MIT",
   "esbuild.binaryHashes": {
-    "@esbuild/aix-ppc64/bin/esbuild": 
"2037fe2a315e737da7d8fbfff5a582243e0a2ee32462f08c69d4833b4e3f9e06",
-    "@esbuild/android-arm64/bin/esbuild": 
"6acacac48d2104e6e58bd92104e86acfb3c8f344e965a910a749ea024ec044e5",
-    "@esbuild/darwin-arm64/bin/esbuild": 
"6f0e1237f63fa3bc03963e58f0b0be1b9bfacd8f2dc9a3f28483e8f97e4ef2d6",
-    "@esbuild/darwin-x64/bin/esbuild": 
"23dadf855f4ef8cf7c159ed5e4018b8f95d66f7e230a3a04f0add7fb809640ad",
-    "@esbuild/freebsd-arm64/bin/esbuild": 
"94f2b3af237a7fb2c5061f311e35b7fca15553304f77222b4da7996a35049b88",
-    "@esbuild/freebsd-x64/bin/esbuild": 
"c9f571484b1661b93c90cca5781fccd8fc08116eccd4c77079452e51aa2a8240",
-    "@esbuild/linux-arm/bin/esbuild": 
"cd2cf1814f32e671c3765e9a26da6a28fc659be2f95426e8f4a116a1f4eb6949",
-    "@esbuild/linux-arm64/bin/esbuild": 
"f76afb23c4c27f7837a4fc5fc7123e2e2c75c7f8c6a54e09bddfc06d39e288dd",
-    "@esbuild/linux-ia32/bin/esbuild": 
"37ce681c3d0193063cbbf95267d191583f2ffbb818fc81716915f99613af42e9",
-    "@esbuild/linux-loong64/bin/esbuild": 
"0565b36f66537e657447aacf6a79f0d4fb91bca78803d20e46c9077e75af8230",
-    "@esbuild/linux-mips64el/bin/esbuild": 
"33e1bdf0e9423efddb2515b0a29fa409826a18eadd6340fff0e3927574b58475",
-    "@esbuild/linux-ppc64/bin/esbuild": 
"38a3dbbce29bb4ffb5fa2121478f46eb0d6d4979687718c20111372ccfdba169",
-    "@esbuild/linux-riscv64/bin/esbuild": 
"2a7317332a2d2bc27dc0ad33123571fa1a9f3aa448c07f6eb7b7c11354e49da8",
-    "@esbuild/linux-s390x/bin/esbuild": 
"d4eb9dcf9f112fee07d3f2256b397cc1ff49ac097d579d07dc5ceacec1276c12",
-    "@esbuild/linux-x64/bin/esbuild": 
"aafacdf135322bf47c882a4ea4db33d0375583f5b9c3fd2d4e12258e470568be",
-    "@esbuild/netbsd-arm64/bin/esbuild": 
"b4d529ea102b3d8e1d77f136be1d8b8496d641c216db8e4ce314f01b9ba02cd1",
-    "@esbuild/netbsd-x64/bin/esbuild": 
"ef999b6e59c2f7ed319f0bc804bffd9c5fec4dd7fd60c77f52300a7ffde2f12d",
-    "@esbuild/openbsd-arm64/bin/esbuild": 
"5de4790175cb306939af247b0a33036067a2677162d1a79635c77161c13cebee",
-    "@esbuild/openbsd-x64/bin/esbuild": 
"1b0dffef766fd0443f76b3031535a79ebf91050e0438399569539f9eae940d24",
-    "@esbuild/sunos-x64/bin/esbuild": 
"81ded843321d3d7a51986859ce859ea8d497e6fa4e3400c9d5ba3df0671a12df",
-    "@esbuild/win32-arm64/esbuild.exe": 
"ab1477cf488a7f961c3cd7da0689e4a78f8cac3c30eb1021ca0dba46aab25493",
-    "@esbuild/win32-ia32/esbuild.exe": 
"6b687d79c8d59bee797ac9872f3e25f229451059e12e60951f476a32d0e8ee71",
-    "@esbuild/win32-x64/esbuild.exe": 
"2ccfd6d5292493a810d21c0b40f9de3ff5252a0a24eb5dea3df07f33dcea0c0e"
+    "@esbuild/aix-ppc64/bin/esbuild": 
"0dd860154344f94b7a9367e64ffc2bc5b89a4313b4a399e5127cdc4ff5000303",
+    "@esbuild/android-arm64/bin/esbuild": 
"087671da02d323e7915fafc13567c0929192633ed544bd8adee9bc020fddf5b4",
+    "@esbuild/darwin-arm64/bin/esbuild": 
"e2dc9a52440a2a34f09434a2f4843cb1e30f84e40dcf238976ec61ef8cd7f36a",
+    "@esbuild/darwin-x64/bin/esbuild": 
"dd53ccf32f9b5b3ab30d41388ef1fc8f81c44ca57ee7a32a7364a1753308d009",
+    "@esbuild/freebsd-arm64/bin/esbuild": 
"5fef5a5ef24d9660d7711b756be5ddeba1fb3ca8dd62d703682ebb9fab3b68b0",
+    "@esbuild/freebsd-x64/bin/esbuild": 
"4427a8cbfa0661943ccfef2606a65b35f3411ac73e447e86f7732aace61e4609",
+    "@esbuild/linux-arm/bin/esbuild": 
"a2d93f7a8b1c9f91d47beec987888b4765c890501b6274f4bdff4061a5e0d9fd",
+    "@esbuild/linux-arm64/bin/esbuild": 
"51e829ba36f36be6d9aea6e329ddc4f9350302339b16aaca96a3cb97f64a8ebb",
+    "@esbuild/linux-ia32/bin/esbuild": 
"9cd7515a75d6f96b0aa055861cf987498315428088cd6d18de5082f904ae5794",
+    "@esbuild/linux-loong64/bin/esbuild": 
"73fa76af9b13f7a27fdb20673b8c2af927fe1511d14e51edeb4b7b71f7f03d0e",
+    "@esbuild/linux-mips64el/bin/esbuild": 
"d734787abc3c99d95242805047fe32da85a5822f04bf33d766a966bf5fd85488",
+    "@esbuild/linux-ppc64/bin/esbuild": 
"90709144617c2adf8f6c14937f03b114c259de0b9309666e3a9d89a1fb266d04",
+    "@esbuild/linux-riscv64/bin/esbuild": 
"86df35a46bedde8b756edb6565a1df7b5a832ad74dd0e179608cbf6509a2582a",
+    "@esbuild/linux-s390x/bin/esbuild": 
"f8cad0db35132e5ac3065c4345c36e7ffe18fdc98417a61bcf5a95a6c694e57c",
+    "@esbuild/linux-x64/bin/esbuild": 
"0c6588b092a2c291a72bab90659f3c9e0e25e0fe59c9ac12b4dae4d945e5548c",
+    "@esbuild/netbsd-arm64/bin/esbuild": 
"490cfdac2d96d5608d91cf55bdf4052bbde7013dafe87ec7adc7784778ad4d4c",
+    "@esbuild/netbsd-x64/bin/esbuild": 
"c61e0e4c553a4986fd0e9d63a0425e93be831ff7b13bfb8a564368fb7590f85d",
+    "@esbuild/openbsd-arm64/bin/esbuild": 
"f9d814698e26c09c3f90d4c103cbdf3832c9f2c841d64a93889d63d23da9b8cf",
+    "@esbuild/openbsd-x64/bin/esbuild": 
"2e30dce11f7236aa362c1c57212cc696f51472169aa417f30e9b641f3b7dcade",
+    "@esbuild/sunos-x64/bin/esbuild": 
"770e0d2bc930b1a1d19d3f43243ff8f393efddb599e7f5843160feacd253267d",
+    "@esbuild/win32-arm64/esbuild.exe": 
"bfb8798ab678f1ce4a723739f4a3eabab3244d7a04eeb12be2eb9f58095c13ef",
+    "@esbuild/win32-ia32/esbuild.exe": 
"8fa99b6e0945830fce8d7e208fdb21763aa4aea875751f4a0eec7f6e262af1dd",
+    "@esbuild/win32-x64/esbuild.exe": 
"ec02ee9b14ab332416fedd10614dfb80eed5304d94f67745067c011934a8c3c3"
   }
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/esbuild-0.28.0/npm/esbuild-wasm/package.json 
new/esbuild-0.28.1/npm/esbuild-wasm/package.json
--- old/esbuild-0.28.0/npm/esbuild-wasm/package.json    2026-04-02 
22:23:56.000000000 +0200
+++ new/esbuild-0.28.1/npm/esbuild-wasm/package.json    2026-06-12 
00:26:09.000000000 +0200
@@ -1,6 +1,6 @@
 {
   "name": "esbuild-wasm",
-  "version": "0.28.0",
+  "version": "0.28.1",
   "description": "The cross-platform WebAssembly binary for esbuild, a 
JavaScript bundler.",
   "repository": {
     "type": "git",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/esbuild-0.28.0/pkg/api/serve_other.go 
new/esbuild-0.28.1/pkg/api/serve_other.go
--- old/esbuild-0.28.0/pkg/api/serve_other.go   2026-04-02 22:23:56.000000000 
+0200
+++ new/esbuild-0.28.1/pkg/api/serve_other.go   2026-06-12 00:26:09.000000000 
+0200
@@ -9,7 +9,7 @@
 // esbuild will automatically generate a directory listing page with links for
 // each file in the directory. If there is a build configured that generates
 // output files, those output files are not written to disk but are instead
-// "overlayed" virtually on top of the real file system. The server responds to
+// "overlaid" virtually on top of the real file system. The server responds to
 // HTTP requests for output files from the build with the latest in-memory
 // build results.
 
@@ -154,6 +154,14 @@
                }
        }
 
+       // All requests containing Windows-style path separators are invalid
+       if strings.ContainsRune(req.URL.Path, '\\') {
+               go h.notifyRequest(time.Since(start), req, 
http.StatusBadRequest)
+               res.WriteHeader(http.StatusBadRequest)
+               maybeWriteResponseBody([]byte("400 - Bad Request"))
+               return
+       }
+
        // Special-case the esbuild event stream
        if req.Method == "GET" && req.URL.Path == "/esbuild" && 
req.Header.Get("Accept") == "text/event-stream" {
                h.serveEventStream(start, req, res)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/esbuild-0.28.0/scripts/end-to-end-tests.js 
new/esbuild-0.28.1/scripts/end-to-end-tests.js
--- old/esbuild-0.28.0/scripts/end-to-end-tests.js      2026-04-02 
22:23:56.000000000 +0200
+++ new/esbuild-0.28.1/scripts/end-to-end-tests.js      2026-06-12 
00:26:09.000000000 +0200
@@ -2104,6 +2104,77 @@
         export let async = async () => { if (42 !== await B()) throw 'fail' }
       `,
     }, { async: true }),
+
+    // https://github.com/evanw/esbuild/issues/4461
+    test(['--bundle', 'in.js', '--outfile=node.js', 
'--format=esm'].concat(minify), {
+      'in.js': `export let async = async () => {
+        let error
+        for (let i = 0; i < 3; i++) {
+          try {
+            await import('./foo')
+            throw new Error('Expected an error')
+          } catch (e) {
+            if (!e || e.message !== 'stop') throw 'fail ' + i + ': ' + e
+            if (i > 0 && e !== error) throw 'fail ' + i + ': wrong object'
+            error = e
+          }
+        }
+      }`,
+      'foo.js': `
+        export let foo
+        throw new Error('stop')
+      `,
+    }, { async: true }),
+    test(['--bundle', 'in.js', '--outfile=node.js', 
'--format=esm'].concat(minify), {
+      'in.js': `export let async = async () => {
+        for (let i = 0; i < 3; i++) {
+          try {
+            await import('./foo')
+            throw new Error('Expected an error')
+          } catch (e) {
+            if (e !== null) throw 'fail ' + i + ': ' + e
+          }
+        }
+      }`,
+      'foo.js': `
+        export let foo
+        throw null
+      `,
+    }, { async: true }),
+    test(['--bundle', 'in.js', '--outfile=node.js'].concat(minify), {
+      'in.js': `
+        let errors = []
+        for (let i = 0; i < 3; i++) {
+          try {
+            require('./foo')
+            throw new Error('Expected an error')
+          } catch (e) {
+            if (e.message !== 'stop1') throw 'fail ' + i + ': ' + e
+            if (errors.includes(e)) throw 'fail ' + i + ': wrong object'
+            errors.push(e)
+          }
+        }
+      `,
+      'foo.js': `
+        exports.counter = (exports.counter | 0) + 1
+        throw new Error('stop' + exports.counter)
+      `,
+    }),
+    test(['--bundle', 'in.js', '--outfile=node.js'].concat(minify), {
+      'in.js': `
+        for (let i = 0; i < 3; i++) {
+          try {
+            require('./foo')
+            throw new Error('Expected an error')
+          } catch (e) {
+            if (e !== null) throw 'fail ' + i + ': ' + e
+          }
+        }
+      `,
+      'foo.js': `
+        throw null
+      `,
+    }),
   )
 }
 
@@ -3037,6 +3108,39 @@
     `,
   }),
 )
+
+// These edge cases shouldn't be printed incorrectly
+// https://github.com/evanw/esbuild/issues/4477
+tests.push(
+  test(['in.js', '--outfile=node.js'], {
+    'in.js': `
+      class Foo {
+        constructor(x) {
+          this.x = x
+        }
+      }
+      var foo1 = () => Foo
+      var foo2 = () => () => Foo
+      if ((new (foo1\`bar\`)(1)).x !== 1) throw 'fail 1'
+      if ((new (foo2()\`bar\`)(2)).x !== 2) throw 'fail 2'
+    `,
+  }),
+  test(['in.js', '--outfile=node.js'], {
+    'in.js': `
+      class Foo {
+        constructor(x) {
+          this.x = x
+        }
+      }
+      var foo0 = { bar: Foo }
+      var foo1 = () => ({ bar: Foo })
+      if ((new (foo0?.bar)(1)).x !== 1) throw 'fail 1'
+      if ((new (foo1()?.bar)(2)).x !== 2) throw 'fail 2'
+      if ((new (foo0?.['bar'])(3)).x !== 3) throw 'fail 3'
+      if ((new (foo1()?.['bar'])(4)).x !== 4) throw 'fail 4'
+    `,
+  }),
+)
 
 // Check for file names of wrapped modules in non-minified stack traces (for 
profiling)
 // Context: https://github.com/evanw/esbuild/pull/1236
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/esbuild-0.28.0/scripts/esbuild.js 
new/esbuild-0.28.1/scripts/esbuild.js
--- old/esbuild-0.28.0/scripts/esbuild.js       2026-04-02 22:23:56.000000000 
+0200
+++ new/esbuild-0.28.1/scripts/esbuild.js       2026-06-12 00:26:09.000000000 
+0200
@@ -273,12 +273,14 @@
 
 const buildDenoLib = async (esbuildPath) => {
   // Generate "deno/mod.js"
+  const packageJSON = JSON.parse(fs.readFileSync(path.join(npmDir, 
'package.json'), 'utf8'))
   childProcess.execFileSync(esbuildPath, [
     path.join(repoDir, 'lib', 'deno', 'mod.ts'),
     '--bundle',
     '--outfile=' + path.join(denoDir, 'mod.js'),
     '--target=' + denoTarget,
     '--define:ESBUILD_VERSION=' + JSON.stringify(version),
+    '--define:ESBUILD_BINARY_HASHES=' + 
JSON.stringify(packageJSON['esbuild.binaryHashes'], null, 2),
     '--platform=neutral',
     '--log-level=warning',
     '--banner:js=/// <reference types="./mod.d.ts" />',
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/esbuild-0.28.0/scripts/js-api-tests.js 
new/esbuild-0.28.1/scripts/js-api-tests.js
--- old/esbuild-0.28.0/scripts/js-api-tests.js  2026-04-02 22:23:56.000000000 
+0200
+++ new/esbuild-0.28.1/scripts/js-api-tests.js  2026-06-12 00:26:09.000000000 
+0200
@@ -5602,6 +5602,62 @@
       await context.dispose();
     }
   },
+
+  // https://github.com/evanw/esbuild/security/advisories/GHSA-g7r4-m6w7-qqqr
+  async serveDirectoryTraversalUsingBackslash({ esbuild, testDir }) {
+    const failure = path.join(testDir, 'failure.txt')
+    const servedir = path.join(testDir, 'root')
+    const input = path.join(servedir, 'in.ts')
+    await mkdirAsync(servedir)
+    await writeFileAsync(failure, `TEST FAILURE`)
+    await writeFileAsync(input, `console.log(123)`)
+
+    let onRequest;
+
+    const context = await esbuild.context({
+      entryPoints: [input],
+      format: 'esm',
+      outdir: servedir,
+      write: false,
+    });
+    try {
+      const result = await context.serve({
+        host: '127.0.0.1',
+        servedir,
+        onRequest: args => onRequest(args),
+      })
+      assert.deepStrictEqual(result.hosts, ['127.0.0.1']);
+      assert.strictEqual(typeof result.port, 'number');
+
+      // GET ..\failure.txt
+      {
+        const singleRequestPromise = new Promise(resolve => { onRequest = 
resolve });
+        try {
+          const buffer = await fetch(result.hosts[0], result.port, 
'/..\\failure.txt')
+          throw new Error('Unexpected response: ' + buffer)
+        } catch (e) {
+          if (e.statusCode !== 400) throw e
+        }
+        const args = await singleRequestPromise
+        if (args.status !== 400) throw new Error('Unexpected args: ' + 
JSON.stringify(args))
+      }
+
+      // GET ..%5cfailure.txt
+      {
+        const singleRequestPromise = new Promise(resolve => { onRequest = 
resolve });
+        try {
+          const buffer = await fetch(result.hosts[0], result.port, 
'/..%5cfailure.txt')
+          throw new Error('Unexpected response: ' + buffer)
+        } catch (e) {
+          if (e.statusCode !== 400) throw e
+        }
+        const args = await singleRequestPromise
+        if (args.status !== 400) throw new Error('Unexpected args: ' + 
JSON.stringify(args))
+      }
+    } finally {
+      await context.dispose();
+    }
+  },
 }
 
 async function futureSyntax(esbuild, js, targetBelow, targetAbove) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/esbuild-0.28.0/version.txt 
new/esbuild-0.28.1/version.txt
--- old/esbuild-0.28.0/version.txt      2026-04-02 22:23:56.000000000 +0200
+++ new/esbuild-0.28.1/version.txt      2026-06-12 00:26:09.000000000 +0200
@@ -1 +1 @@
-0.28.0
+0.28.1

Reply via email to