[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#1107931: unblock: golang-github-evanw-esbuild/0.25.5-1



Package: release.debian.org
Severity: normal
X-Debbugs-Cc: golang-github-evanw-esbuild@packages.debian.org
Control: affects -1 + src:golang-github-evanw-esbuild
User: release.debian.org@packages.debian.org
Usertags: unblock

Please unblock package golang-github-evanw-esbuild

[ Reason ]
This version fixes a few bugs w.r.t. version in testing,
and I think these fixes should be in trixie.

[ Impact ]
Those fixes are not fixed, and they are potentially bad bugs:
- Handle exports named __proto__ in ES modules
- Fix a regression with browser in package.json

[ Tests ]
esbuild test suite is thorough and run during debci.

[ Risks ]
While esbuild is a key package, there has been no regressions during 20 days,
and the changes go in the direction of quality improvement.

[ Checklist ]
  [x] all changes are documented in the d/changelog
  [x] I reviewed all changes and I approve them
  [x] attach debdiff against the package in testing


unblock golang-github-evanw-esbuild/0.25.5-1
diff -Nru golang-github-evanw-esbuild-0.25.3/CHANGELOG.md golang-github-evanw-esbuild-0.25.5/CHANGELOG.md
--- golang-github-evanw-esbuild-0.25.3/CHANGELOG.md	2025-04-23 05:51:33.000000000 +0200
+++ golang-github-evanw-esbuild-0.25.5/CHANGELOG.md	2025-05-27 05:11:58.000000000 +0200
@@ -1,5 +1,86 @@
 # Changelog
 
+## 0.25.5
+
+* Fix a regression with `browser` in `package.json` ([#4187](https://github.com/evanw/esbuild/issues/4187))
+
+    The fix to [#4144](https://github.com/evanw/esbuild/issues/4144) in version 0.25.3 introduced a regression that caused `browser` overrides specified in `package.json` to fail to override relative path names that end in a trailing slash. That behavior change affected the `axios@0.30.0` package. This regression has been fixed, and now has test coverage.
+
+* Add support for certain keywords as TypeScript tuple labels ([#4192](https://github.com/evanw/esbuild/issues/4192))
+
+    Previously esbuild could incorrectly fail to parse certain keywords as TypeScript tuple labels that are parsed by the official TypeScript compiler if they were followed by a `?` modifier. These labels included `function`, `import`, `infer`, `new`, `readonly`, and `typeof`. With this release, these keywords will now be parsed correctly. Here's an example of some affected code:
+
+    ```ts
+    type Foo = [
+      value: any,
+      readonly?: boolean, // This is now parsed correctly
+    ]
+    ```
+
+* Add CSS prefixes for the `stretch` sizing value ([#4184](https://github.com/evanw/esbuild/issues/4184))
+
+    This release adds support for prefixing CSS declarations such as `div { width: stretch }`. That CSS is now transformed into this depending on what the `--target=` setting includes:
+
+    ```css
+    div {
+      width: -webkit-fill-available;
+      width: -moz-available;
+      width: stretch;
+    }
+    ```
+
+## 0.25.4
+
+* Add simple support for CORS to esbuild's development server ([#4125](https://github.com/evanw/esbuild/issues/4125))
+
+    Starting with version 0.25.0, esbuild's development server is no longer configured to serve cross-origin requests. This was a deliberate change to prevent any website you visit from accessing your running esbuild development server. However, this change prevented (by design) certain use cases such as "debugging in production" by having your production website load code from `localhost` where the esbuild development server is running.
+
+    To enable this use case, esbuild is adding a feature to allow [Cross-Origin Resource Sharing](https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/CORS) (a.k.a. CORS) for [simple requests](https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/CORS#simple_requests). Specifically, passing your origin to the new `cors` option will now set the `Access-Control-Allow-Origin` response header when the request has a matching `Origin` header. Note that this currently only works for requests that don't send a preflight `OPTIONS` request, as esbuild's development server doesn't currently support `OPTIONS` requests.
+
+    Some examples:
+
+    * **CLI:**
+
+        ```
+        esbuild --servedir=. --cors-origin=https://example.com
+        ```
+
+    * **JS:**
+
+        ```js
+        const ctx = await esbuild.context({})
+        await ctx.serve({
+          servedir: '.',
+          cors: {
+            origin: 'https://example.com',
+          },
+        })
+        ```
+
+    * **Go:**
+
+        ```go
+        ctx, _ := api.Context(api.BuildOptions{})
+        ctx.Serve(api.ServeOptions{
+          Servedir: ".",
+          CORS: api.CORSOptions{
+            Origin: []string{"https://example.com"},
+          },
+        })
+        ```
+
+    The special origin `*` can be used to allow any origin to access esbuild's development server. Note that this means any website you visit will be able to read everything served by esbuild.
+
+* Pass through invalid URLs in source maps unmodified ([#4169](https://github.com/evanw/esbuild/issues/4169))
+
+    This fixes a regression in version 0.25.0 where `sources` in source maps that form invalid URLs were not being passed through to the output. Version 0.25.0 changed the interpretation of `sources` from file paths to URLs, which means that URL parsing can now fail. Previously URLs that couldn't be parsed were replaced with the empty string. With this release, invalid URLs in `sources` should now be passed through unmodified.
+
+* Handle exports named `__proto__` in ES modules ([#4162](https://github.com/evanw/esbuild/issues/4162), [#4163](https://github.com/evanw/esbuild/pull/4163))
+
+    In JavaScript, the special property name `__proto__` sets the prototype when used inside an object literal. Previously esbuild's ESM-to-CommonJS conversion didn't special-case the property name of exports named `__proto__` so the exported getter accidentally became the prototype of the object literal. It's unclear what this affects, if anything, but it's better practice to avoid this by using a computed property name in this case.
+
+    This fix was contributed by [@magic-akari](https://github.com/magic-akari).
+
 ## 0.25.3
 
 * Fix lowered `async` arrow functions before `super()` ([#4141](https://github.com/evanw/esbuild/issues/4141), [#4142](https://github.com/evanw/esbuild/pull/4142))
diff -Nru golang-github-evanw-esbuild-0.25.3/cmd/esbuild/main.go golang-github-evanw-esbuild-0.25.5/cmd/esbuild/main.go
--- golang-github-evanw-esbuild-0.25.3/cmd/esbuild/main.go	2025-04-23 05:51:33.000000000 +0200
+++ golang-github-evanw-esbuild-0.25.5/cmd/esbuild/main.go	2025-05-27 05:11:58.000000000 +0200
@@ -68,6 +68,7 @@
   --chunk-names=...         Path template to use for code splitting chunks
                             (default "[name]-[hash]")
   --color=...               Force use of color terminal escapes (true | false)
+  --cors-origin=...         Allow cross-origin requests from this origin
   --drop:...                Remove certain constructs (console | debugger)
   --drop-labels=...         Remove labeled statements with these label names
   --entry-names=...         Path template to use for entry point output paths
diff -Nru golang-github-evanw-esbuild-0.25.3/cmd/esbuild/service.go golang-github-evanw-esbuild-0.25.5/cmd/esbuild/service.go
--- golang-github-evanw-esbuild-0.25.3/cmd/esbuild/service.go	2025-04-23 05:51:33.000000000 +0200
+++ golang-github-evanw-esbuild-0.25.5/cmd/esbuild/service.go	2025-05-27 05:11:58.000000000 +0200
@@ -392,6 +392,11 @@
 					if value, ok := request["fallback"]; ok {
 						options.Fallback = value.(string)
 					}
+					if value, ok := request["corsOrigin"].([]interface{}); ok {
+						for _, it := range value {
+							options.CORS.Origin = append(options.CORS.Origin, it.(string))
+						}
+					}
 					if request["onRequest"].(bool) {
 						options.OnRequest = func(args api.ServeOnRequestArgs) {
 							// This could potentially be called after we return from
diff -Nru golang-github-evanw-esbuild-0.25.3/cmd/esbuild/version.go golang-github-evanw-esbuild-0.25.5/cmd/esbuild/version.go
--- golang-github-evanw-esbuild-0.25.3/cmd/esbuild/version.go	2025-04-23 05:51:33.000000000 +0200
+++ golang-github-evanw-esbuild-0.25.5/cmd/esbuild/version.go	2025-05-27 05:11:58.000000000 +0200
@@ -1,3 +1,3 @@
 package main
 
-const esbuildVersion = "0.25.3"
+const esbuildVersion = "0.25.5"
diff -Nru golang-github-evanw-esbuild-0.25.3/compat-table/package.json golang-github-evanw-esbuild-0.25.5/compat-table/package.json
--- golang-github-evanw-esbuild-0.25.3/compat-table/package.json	2025-04-23 05:51:33.000000000 +0200
+++ golang-github-evanw-esbuild-0.25.5/compat-table/package.json	2025-05-27 05:11:58.000000000 +0200
@@ -1,12 +1,12 @@
 {
   "githubDependencies": {
     "kangax/compat-table": "b3427ba3a2d6fd2dc427c3dfcf191832f634eb06",
-    "williamkapke/node-compat-table": "abc812c34335866ee4fd4e94d9208ebd310de444"
+    "williamkapke/node-compat-table": "c10606cfc85fbe3a31cfd58f23fad872ad5fa5bc"
   },
   "dependencies": {
-    "@mdn/browser-compat-data": "^6.0.8",
+    "@mdn/browser-compat-data": "^6.0.15",
     "@types/caniuse-lite": "1.0.1",
     "@types/node": "20.3.2",
-    "caniuse-lite": "^1.0.30001715"
+    "caniuse-lite": "^1.0.30001718"
   }
 }
diff -Nru golang-github-evanw-esbuild-0.25.3/compat-table/package-lock.json golang-github-evanw-esbuild-0.25.5/compat-table/package-lock.json
--- golang-github-evanw-esbuild-0.25.3/compat-table/package-lock.json	2025-04-23 05:51:33.000000000 +0200
+++ golang-github-evanw-esbuild-0.25.5/compat-table/package-lock.json	2025-05-27 05:11:58.000000000 +0200
@@ -5,16 +5,16 @@
   "packages": {
     "": {
       "dependencies": {
-        "@mdn/browser-compat-data": "^6.0.8",
+        "@mdn/browser-compat-data": "^6.0.15",
         "@types/caniuse-lite": "1.0.1",
         "@types/node": "20.3.2",
-        "caniuse-lite": "^1.0.30001715"
+        "caniuse-lite": "^1.0.30001718"
       }
     },
     "node_modules/@mdn/browser-compat-data": {
-      "version": "6.0.8",
-      "resolved": "https://registry.npmjs.org/@mdn/browser-compat-data/-/browser-compat-data-6.0.8.tgz";,
-      "integrity": "sha512-l21VIVT7ozAQJFT16HHmCndeNMhMuYMlhRA8+W59cCsorW6oXZDm3v+lQKxIZwTLHnKfAt0i6f2ih6h9GS0OaQ==",
+      "version": "6.0.15",
+      "resolved": "https://registry.npmjs.org/@mdn/browser-compat-data/-/browser-compat-data-6.0.15.tgz";,
+      "integrity": "sha512-f5R+fOk6bFbjw6Pu/jDJC9SC3mYiYG+ok+t2cQqgvjKHhID/9WiisnhJFzqNSP+i/EAfaN5xrwuj4VHnZhHwxw==",
       "license": "CC0-1.0"
     },
     "node_modules/@types/caniuse-lite": {
@@ -28,9 +28,9 @@
       "integrity": "sha512-vOBLVQeCQfIcF/2Y7eKFTqrMnizK5lRNQ7ykML/5RuwVXVWxYkgwS7xbt4B6fKCUPgbSL5FSsjHQpaGQP/dQmw=="
     },
     "node_modules/caniuse-lite": {
-      "version": "1.0.30001715",
-      "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001715.tgz";,
-      "integrity": "sha512-7ptkFGMm2OAOgvZpwgA4yjQ5SQbrNVGdRjzH0pBdy1Fasvcr+KAeECmbCAECzTuDuoX0FCY8KzUxjf9+9kfZEw==",
+      "version": "1.0.30001718",
+      "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001718.tgz";,
+      "integrity": "sha512-AflseV1ahcSunK53NfEs9gFWgOEmzr0f+kaMFA4xiLZlr9Hzt7HxcSpIFcnNCUkz6R6dWKa54rUz3HUmI3nVcw==",
       "funding": [
         {
           "type": "opencollective",
diff -Nru golang-github-evanw-esbuild-0.25.3/compat-table/src/index.ts golang-github-evanw-esbuild-0.25.5/compat-table/src/index.ts
--- golang-github-evanw-esbuild-0.25.3/compat-table/src/index.ts	2025-04-23 05:51:33.000000000 +0200
+++ golang-github-evanw-esbuild-0.25.5/compat-table/src/index.ts	2025-05-27 05:11:58.000000000 +0200
@@ -111,6 +111,7 @@
   DBoxDecorationBreak: true,
   DClipPath: true,
   DFontKerning: true,
+  DHeight: true,
   DHyphens: true,
   DInitialLetter: true,
   DMaskComposite: true,
@@ -119,6 +120,10 @@
   DMaskPosition: true,
   DMaskRepeat: true,
   DMaskSize: true,
+  DMaxHeight: true,
+  DMaxWidth: true,
+  DMinHeight: true,
+  DMinWidth: true,
   DPosition: true,
   DPrintColorAdjust: true,
   DTabSize: true,
@@ -131,6 +136,7 @@
   DTextOrientation: true,
   DTextSizeAdjust: true,
   DUserSelect: true,
+  DWidth: true,
 }
 
 export interface Support {
@@ -511,6 +517,25 @@
   // MDN data is wrong here: https://www.chromestatus.com/feature/6482797915013120
   js.ClassStaticBlocks.Chrome = { 91: { force: true } }
 
+  // WebKit has now been marked as not supporting top-level await because it
+  // turns out they have a pretty severe bug: Importing a module that uses
+  // top-level await twice causes the second import to fail. For more info see:
+  // https://bugs.webkit.org/show_bug.cgi?id=242740
+  //
+  // However, we're going to override this to say it's still supported because:
+  // - It always fails loudly when this happens (the import fails)
+  // - People would otherwise be blocked from using this feature at all in
+  //   WebKit-based browsers
+  // - From what I understand, most use of top-level await is in the entry-point
+  //   module, where this isn't an issue
+  // - When you bundle your code, nested modules become entry points so this
+  //   issue also wouldn't come up
+  // - The top-level await implementation in esbuild isn't even correct for
+  //   nested modules as they become linearized in the bundle (like Rollup, but
+  //   not like Webpack)
+  js.TopLevelAwait.IOS = { 15: { force: true } }
+  js.TopLevelAwait.Safari = { 15: { force: true } }
+
   const [jsVersionRanges, jsWhyNot] = supportMapToVersionRanges(js)
   generateTableForJS(jsVersionRanges, jsWhyNot)
 })
diff -Nru golang-github-evanw-esbuild-0.25.3/compat-table/src/mdn.ts golang-github-evanw-esbuild-0.25.5/compat-table/src/mdn.ts
--- golang-github-evanw-esbuild-0.25.3/compat-table/src/mdn.ts	2025-04-23 05:51:33.000000000 +0200
+++ golang-github-evanw-esbuild-0.25.5/compat-table/src/mdn.ts	2025-05-27 05:11:58.000000000 +0200
@@ -82,12 +82,17 @@
 }
 
 const cssPrefixFeatures: Record<string, CSSProperty> = {
+  'css.properties.height.stretch': 'DHeight',
   'css.properties.mask-composite': 'DMaskComposite',
   'css.properties.mask-image': 'DMaskImage',
   'css.properties.mask-origin': 'DMaskOrigin',
   'css.properties.mask-position': 'DMaskPosition',
   'css.properties.mask-repeat': 'DMaskRepeat',
   'css.properties.mask-size': 'DMaskSize',
+  'css.properties.max-height.stretch': 'DMaxHeight',
+  'css.properties.max-width.stretch': 'DMaxWidth',
+  'css.properties.min-height.stretch': 'DMinHeight',
+  'css.properties.min-width.stretch': 'DMinWidth',
   'css.properties.text-decoration-color': 'DTextDecorationColor',
   'css.properties.text-decoration-line': 'DTextDecorationLine',
   'css.properties.text-decoration-skip': 'DTextDecorationSkip',
@@ -95,6 +100,12 @@
   'css.properties.text-emphasis-position': 'DTextEmphasisPosition',
   'css.properties.text-emphasis-style': 'DTextEmphasisStyle',
   'css.properties.user-select': 'DUserSelect',
+  'css.properties.width.stretch': 'DWidth',
+}
+
+const alternativeNameToPrefix: Record<string, string> = {
+  '-webkit-fill-available': '-webkit-',
+  '-moz-available': '-moz-',
 }
 
 export const js: SupportMap<JSFeature> = {} as SupportMap<JSFeature>
@@ -186,8 +197,8 @@
       // its engine from EdgeHTML to Blink, basically becoming another browser)
       // but we ignore those cases for now.
       let version_unprefixed: string | undefined
-      for (const { prefix, flags, version_added, version_removed } of entries) {
-        if (!prefix && !flags && typeof version_added === 'string' && !version_removed && isSemver.test(version_added)) {
+      for (const { prefix, flags, version_added, version_removed, alternative_name } of entries) {
+        if (!prefix && !alternative_name && !flags && typeof version_added === 'string' && !version_removed && isSemver.test(version_added)) {
           version_unprefixed = version_added
         }
       }
@@ -208,15 +219,15 @@
 
       // Find all version ranges where a given prefix is supported
       for (let i = 0; i < entries.length; i++) {
-        let { prefix, flags, version_added, version_removed } = entries[i]
+        let { prefix, flags, version_added, version_removed, alternative_name } = entries[i]
 
         if (similar) {
           if (prefix) throw new Error(`Unexpected prefix "${prefix}" for similar property "${similar.property}"`)
           prefix = similar.prefix
         }
 
-        if (prefix && !flags && typeof version_added === 'string' && isSemver.test(version_added)) {
-          const range: PrefixRange = { prefix, start: version_added }
+        if ((prefix || alternative_name) && !flags && typeof version_added === 'string' && isSemver.test(version_added)) {
+          const range: PrefixRange = { prefix: prefix || alternativeNameToPrefix[alternative_name!], start: version_added }
           let withoutPrefix: string | undefined
 
           // The prefix is no longer needed if support for the feature was removed
diff -Nru golang-github-evanw-esbuild-0.25.3/debian/changelog golang-github-evanw-esbuild-0.25.5/debian/changelog
--- golang-github-evanw-esbuild-0.25.3/debian/changelog	2025-04-23 09:53:59.000000000 +0200
+++ golang-github-evanw-esbuild-0.25.5/debian/changelog	2025-05-27 08:07:07.000000000 +0200
@@ -1,3 +1,10 @@
+golang-github-evanw-esbuild (0.25.5-1) unstable; urgency=medium
+
+  * Team upload
+  * New upstream version 0.25.5
+
+ -- Jérémy Lal <kapouer@melix.org>  Tue, 27 May 2025 08:07:07 +0200
+
 golang-github-evanw-esbuild (0.25.3-1) unstable; urgency=medium
 
   * Team upload
diff -Nru golang-github-evanw-esbuild-0.25.3/internal/bundler/bundler.go golang-github-evanw-esbuild-0.25.5/internal/bundler/bundler.go
--- golang-github-evanw-esbuild-0.25.3/internal/bundler/bundler.go	2025-04-23 05:51:33.000000000 +0200
+++ golang-github-evanw-esbuild-0.25.5/internal/bundler/bundler.go	2025-05-27 05:11:58.000000000 +0200
@@ -1616,6 +1616,7 @@
 			KeyPath:        visitedKey,
 			PrettyPath:     resolver.PrettyPath(s.fs, visitedKey),
 			IdentifierName: js_ast.EnsureValidIdentifier(visitedKey.Text),
+			Contents:       define.Source.Contents,
 		}
 
 		// The first "len(InjectedDefine)" injected files intentionally line up
diff -Nru golang-github-evanw-esbuild-0.25.3/internal/bundler_tests/bundler_default_test.go golang-github-evanw-esbuild-0.25.5/internal/bundler_tests/bundler_default_test.go
--- golang-github-evanw-esbuild-0.25.3/internal/bundler_tests/bundler_default_test.go	2025-04-23 05:51:33.000000000 +0200
+++ golang-github-evanw-esbuild-0.25.5/internal/bundler_tests/bundler_default_test.go	2025-05-27 05:11:58.000000000 +0200
@@ -1673,6 +1673,44 @@
 	})
 }
 
+func TestExportSpecialName(t *testing.T) {
+	default_suite.expectBundled(t, bundled{
+		files: map[string]string{
+			"/entry.mjs": `
+			export const __proto__ = 123;
+			`,
+		},
+		entryPaths: []string{"/entry.mjs"},
+		options: config.Options{
+			Mode:          config.ModeConvertFormat,
+			OutputFormat:  config.FormatCommonJS,
+			AbsOutputFile: "/out.js",
+			Platform:      config.PlatformNode,
+		},
+	})
+}
+
+func TestExportSpecialNameBundle(t *testing.T) {
+	default_suite.expectBundled(t, bundled{
+		files: map[string]string{
+			"/entry.js": `
+				const lib = require('./lib.mjs');
+				console.log(lib.__proto__);
+			`,
+			"/lib.mjs": `
+				export const __proto__ = 123;
+			`,
+		},
+		entryPaths: []string{"/entry.js"},
+		options: config.Options{
+			Mode:          config.ModeBundle,
+			OutputFormat:  config.FormatCommonJS,
+			AbsOutputFile: "/out.js",
+			Platform:      config.PlatformNode,
+		},
+	})
+}
+
 // https://github.com/evanw/esbuild/issues/3544
 func TestNodeAnnotationFalsePositiveIssue3544(t *testing.T) {
 	default_suite.expectBundled(t, bundled{
diff -Nru golang-github-evanw-esbuild-0.25.3/internal/bundler_tests/bundler_packagejson_test.go golang-github-evanw-esbuild-0.25.5/internal/bundler_tests/bundler_packagejson_test.go
--- golang-github-evanw-esbuild-0.25.3/internal/bundler_tests/bundler_packagejson_test.go	2025-04-23 05:51:33.000000000 +0200
+++ golang-github-evanw-esbuild-0.25.5/internal/bundler_tests/bundler_packagejson_test.go	2025-05-27 05:11:58.000000000 +0200
@@ -3069,3 +3069,35 @@
 		},
 	})
 }
+
+// https://github.com/evanw/esbuild/issues/4187
+func TestPackageJsonBrowserMatchingTrailingSlashIssue4187(t *testing.T) {
+	packagejson_suite.expectBundled(t, bundled{
+		files: map[string]string{
+			"/entry.js": `
+				import axios from "axios"
+			`,
+			"/node_modules/axios/package.json": `
+				{
+					"browser": {
+						"./node/index.js": "./browser/index.js"
+					}
+				}
+			`,
+			"/node_modules/axios/index.js": `
+				module.exports = require('./node/');
+			`,
+			"/node_modules/axios/node/index.js": `
+				module.exports = { get: () => new Promise('Node') }
+			`,
+			"/node_modules/axios/browser/index.js": `
+				module.exports = { get: () => new Promise('Browser') }
+			`,
+		},
+		entryPaths: []string{"/entry.js"},
+		options: config.Options{
+			Mode:          config.ModeBundle,
+			AbsOutputFile: "/out.js",
+		},
+	})
+}
diff -Nru golang-github-evanw-esbuild-0.25.3/internal/bundler_tests/snapshots/snapshots_default.txt golang-github-evanw-esbuild-0.25.5/internal/bundler_tests/snapshots/snapshots_default.txt
--- golang-github-evanw-esbuild-0.25.3/internal/bundler_tests/snapshots/snapshots_default.txt	2025-04-23 05:51:33.000000000 +0200
+++ golang-github-evanw-esbuild-0.25.5/internal/bundler_tests/snapshots/snapshots_default.txt	2025-05-27 05:11:58.000000000 +0200
@@ -1564,6 +1564,39 @@
 }
 
 ================================================================================
+TestExportSpecialName
+---------- /out.js ----------
+var entry_exports = {};
+__export(entry_exports, {
+  ["__proto__"]: () => __proto__
+});
+module.exports = __toCommonJS(entry_exports);
+const __proto__ = 123;
+// Annotate the CommonJS export names for ESM import in node:
+0 && (module.exports = {
+  __proto__
+});
+
+================================================================================
+TestExportSpecialNameBundle
+---------- /out.js ----------
+// lib.mjs
+var lib_exports = {};
+__export(lib_exports, {
+  ["__proto__"]: () => __proto__
+});
+var __proto__;
+var init_lib = __esm({
+  "lib.mjs"() {
+    __proto__ = 123;
+  }
+});
+
+// entry.js
+var lib = (init_lib(), __toCommonJS(lib_exports));
+console.log(lib.__proto__);
+
+================================================================================
 TestExportWildcardFSNodeCommonJS
 ---------- /out.js ----------
 // entry.js
diff -Nru golang-github-evanw-esbuild-0.25.3/internal/bundler_tests/snapshots/snapshots_packagejson.txt golang-github-evanw-esbuild-0.25.5/internal/bundler_tests/snapshots/snapshots_packagejson.txt
--- golang-github-evanw-esbuild-0.25.3/internal/bundler_tests/snapshots/snapshots_packagejson.txt	2025-04-23 05:51:33.000000000 +0200
+++ golang-github-evanw-esbuild-0.25.5/internal/bundler_tests/snapshots/snapshots_packagejson.txt	2025-05-27 05:11:58.000000000 +0200
@@ -309,6 +309,26 @@
 console.log((0, import_demo_pkg.default)());
 
 ================================================================================
+TestPackageJsonBrowserMatchingTrailingSlashIssue4187
+---------- /out.js ----------
+// node_modules/axios/browser/index.js
+var require_browser = __commonJS({
+  "node_modules/axios/browser/index.js"(exports, module) {
+    module.exports = { get: () => new Promise("Browser") };
+  }
+});
+
+// node_modules/axios/index.js
+var require_axios = __commonJS({
+  "node_modules/axios/index.js"(exports, module) {
+    module.exports = require_browser();
+  }
+});
+
+// entry.js
+var import_axios = __toESM(require_axios());
+
+================================================================================
 TestPackageJsonBrowserNoExt
 ---------- /Users/user/project/out.js ----------
 // Users/user/project/src/demo-pkg/no-ext-browser.js
diff -Nru golang-github-evanw-esbuild-0.25.3/internal/compat/css_table.go golang-github-evanw-esbuild-0.25.5/internal/compat/css_table.go
--- golang-github-evanw-esbuild-0.25.3/internal/compat/css_table.go	2025-04-23 05:51:33.000000000 +0200
+++ golang-github-evanw-esbuild-0.25.5/internal/compat/css_table.go	2025-05-27 05:11:58.000000000 +0200
@@ -220,6 +220,13 @@
 		{engine: Opera, prefix: WebkitPrefix, withoutPrefix: v{20, 0, 0}},
 		{engine: Safari, prefix: WebkitPrefix, withoutPrefix: v{9, 1, 0}},
 	},
+	css_ast.DHeight: {
+		{engine: Chrome, prefix: WebkitPrefix},
+		{engine: Edge, prefix: WebkitPrefix},
+		{engine: IOS, prefix: WebkitPrefix},
+		{engine: Opera, prefix: WebkitPrefix},
+		{engine: Safari, prefix: WebkitPrefix},
+	},
 	css_ast.DHyphens: {
 		{engine: Edge, prefix: MsPrefix, withoutPrefix: v{79, 0, 0}},
 		{engine: Firefox, prefix: MozPrefix, withoutPrefix: v{43, 0, 0}},
@@ -273,6 +280,34 @@
 		{engine: Opera, prefix: WebkitPrefix, withoutPrefix: v{106, 0, 0}},
 		{engine: Safari, prefix: WebkitPrefix, withoutPrefix: v{15, 4, 0}},
 	},
+	css_ast.DMaxHeight: {
+		{engine: Chrome, prefix: WebkitPrefix},
+		{engine: Edge, prefix: WebkitPrefix},
+		{engine: IOS, prefix: WebkitPrefix},
+		{engine: Opera, prefix: WebkitPrefix},
+		{engine: Safari, prefix: WebkitPrefix},
+	},
+	css_ast.DMaxWidth: {
+		{engine: Chrome, prefix: WebkitPrefix},
+		{engine: Edge, prefix: WebkitPrefix},
+		{engine: IOS, prefix: WebkitPrefix},
+		{engine: Opera, prefix: WebkitPrefix},
+		{engine: Safari, prefix: WebkitPrefix},
+	},
+	css_ast.DMinHeight: {
+		{engine: Chrome, prefix: WebkitPrefix},
+		{engine: Edge, prefix: WebkitPrefix},
+		{engine: IOS, prefix: WebkitPrefix},
+		{engine: Opera, prefix: WebkitPrefix},
+		{engine: Safari, prefix: WebkitPrefix},
+	},
+	css_ast.DMinWidth: {
+		{engine: Chrome, prefix: WebkitPrefix},
+		{engine: Edge, prefix: WebkitPrefix},
+		{engine: IOS, prefix: WebkitPrefix},
+		{engine: Opera, prefix: WebkitPrefix},
+		{engine: Safari, prefix: WebkitPrefix},
+	},
 	css_ast.DPosition: {
 		{engine: IOS, prefix: WebkitPrefix, withoutPrefix: v{13, 0, 0}},
 		{engine: Safari, prefix: WebkitPrefix, withoutPrefix: v{13, 0, 0}},
@@ -333,6 +368,14 @@
 		{engine: Safari, prefix: KhtmlPrefix, withoutPrefix: v{3, 0, 0}},
 		{engine: Safari, prefix: WebkitPrefix},
 	},
+	css_ast.DWidth: {
+		{engine: Chrome, prefix: WebkitPrefix},
+		{engine: Edge, prefix: WebkitPrefix},
+		{engine: Firefox, prefix: MozPrefix},
+		{engine: IOS, prefix: WebkitPrefix},
+		{engine: Opera, prefix: WebkitPrefix},
+		{engine: Safari, prefix: WebkitPrefix},
+	},
 }
 
 func CSSPrefixData(constraints map[Engine]Semver) (entries map[css_ast.D]CSSPrefix) {
diff -Nru golang-github-evanw-esbuild-0.25.3/internal/compat/js_table.go golang-github-evanw-esbuild-0.25.5/internal/compat/js_table.go
--- golang-github-evanw-esbuild-0.25.3/internal/compat/js_table.go	2025-04-23 05:51:33.000000000 +0200
+++ golang-github-evanw-esbuild-0.25.5/internal/compat/js_table.go	2025-05-27 05:11:58.000000000 +0200
@@ -588,13 +588,14 @@
 		Node:   {{start: v{16, 14, 0}, end: v{22, 0, 0}}},
 	},
 	ImportAttributes: {
-		Chrome: {{start: v{123, 0, 0}}},
-		Deno:   {{start: v{1, 37, 0}}},
-		Edge:   {{start: v{123, 0, 0}}},
-		IOS:    {{start: v{17, 2, 0}}},
-		Node:   {{start: v{18, 20, 0}, end: v{19, 0, 0}}, {start: v{20, 10, 0}}},
-		Opera:  {{start: v{109, 0, 0}}},
-		Safari: {{start: v{17, 2, 0}}},
+		Chrome:  {{start: v{123, 0, 0}}},
+		Deno:    {{start: v{1, 37, 0}}},
+		Edge:    {{start: v{123, 0, 0}}},
+		Firefox: {{start: v{138, 0, 0}}},
+		IOS:     {{start: v{17, 2, 0}}},
+		Node:    {{start: v{18, 20, 0}, end: v{19, 0, 0}}, {start: v{20, 10, 0}}},
+		Opera:   {{start: v{109, 0, 0}}},
+		Safari:  {{start: v{17, 2, 0}}},
 	},
 	ImportMeta: {
 		Chrome:  {{start: v{64, 0, 0}}},
diff -Nru golang-github-evanw-esbuild-0.25.3/internal/css_parser/css_decls.go golang-github-evanw-esbuild-0.25.5/internal/css_parser/css_decls.go
--- golang-github-evanw-esbuild-0.25.3/internal/css_parser/css_decls.go	2025-04-23 05:51:33.000000000 +0200
+++ golang-github-evanw-esbuild-0.25.5/internal/css_parser/css_decls.go	2025-05-27 05:11:58.000000000 +0200
@@ -223,7 +223,7 @@
 		case css_ast.DContainerName:
 			p.processContainerName(decl.Value)
 
-			// Animation name
+		// Animation name
 		case css_ast.DAnimation:
 			p.processAnimationShorthand(decl.Value)
 		case css_ast.DAnimationName:
@@ -237,7 +237,7 @@
 				p.processListStyleType(&decl.Value[0])
 			}
 
-			// Font
+		// Font
 		case css_ast.DFont:
 			if p.options.minifySyntax {
 				decl.Value = p.mangleFont(decl.Value)
@@ -253,7 +253,7 @@
 				decl.Value[0] = p.mangleFontWeight(decl.Value[0])
 			}
 
-			// Margin
+		// Margin
 		case css_ast.DMargin:
 			if p.options.minifySyntax {
 				margin.mangleSides(rewrittenRules, decl, p.options.minifyWhitespace)
@@ -444,6 +444,13 @@
 		if len(decl.Value) != 1 || decl.Value[0].Kind != css_lexer.TIdent || !strings.EqualFold(decl.Value[0].Text, "sticky") {
 			return rules
 		}
+
+	case css_ast.DWidth, css_ast.DMinWidth, css_ast.DMaxWidth,
+		css_ast.DHeight, css_ast.DMinHeight, css_ast.DMaxHeight:
+		// The prefix is only needed for "width: stretch"
+		if len(decl.Value) != 1 || decl.Value[0].Kind != css_lexer.TIdent || !strings.EqualFold(decl.Value[0].Text, "stretch") {
+			return rules
+		}
 	}
 
 	value := css_ast.CloneTokensWithoutImportRecords(decl.Value)
@@ -455,6 +462,19 @@
 		keyText = decl.KeyText
 		value[0].Text = "-webkit-sticky"
 
+	case css_ast.DWidth, css_ast.DMinWidth, css_ast.DMaxWidth,
+		css_ast.DHeight, css_ast.DMinHeight, css_ast.DMaxHeight:
+		// The prefix applies to the value, not the property
+		keyText = decl.KeyText
+
+		// This currently only applies to "stretch" (already checked above)
+		switch prefix {
+		case "-webkit-":
+			value[0].Text = "-webkit-fill-available"
+		case "-moz-":
+			value[0].Text = "-moz-available"
+		}
+
 	case css_ast.DUserSelect:
 		// The prefix applies to the value as well as the property
 		if prefix == "-moz-" && len(value) == 1 && value[0].Kind == css_lexer.TIdent && strings.EqualFold(value[0].Text, "none") {
@@ -480,6 +500,15 @@
 			}
 		}
 	}
+
+	// If we didn't change the key, manually search for a previous duplicate rule
+	if keyText == decl.KeyText {
+		for _, rule := range rules {
+			if prevDecl, ok := rule.Data.(*css_ast.RDeclaration); ok && prevDecl.KeyText == keyText && css_ast.TokensEqual(prevDecl.Value, value, nil) {
+				return rules
+			}
+		}
+	}
 
 	// Overwrite the latest declaration with the prefixed declaration
 	rules[len(rules)-1] = css_ast.Rule{Loc: loc, Data: &css_ast.RDeclaration{
diff -Nru golang-github-evanw-esbuild-0.25.3/internal/css_parser/css_nesting.go golang-github-evanw-esbuild-0.25.5/internal/css_parser/css_nesting.go
--- golang-github-evanw-esbuild-0.25.3/internal/css_parser/css_nesting.go	2025-04-23 05:51:33.000000000 +0200
+++ golang-github-evanw-esbuild-0.25.5/internal/css_parser/css_nesting.go	2025-05-27 05:11:58.000000000 +0200
@@ -101,6 +101,34 @@
 	return rules[:n]
 }
 
+func compoundSelectorTermCount(sel css_ast.CompoundSelector) int {
+	count := 0
+	for _, ss := range sel.SubclassSelectors {
+		count++
+		if list, ok := ss.Data.(*css_ast.SSPseudoClassWithSelectorList); ok {
+			count += complexSelectorTermCount(list.Selectors)
+		}
+	}
+	return count
+}
+
+func complexSelectorTermCount(selectors []css_ast.ComplexSelector) int {
+	count := 0
+	for _, sel := range selectors {
+		for _, inner := range sel.Selectors {
+			count += compoundSelectorTermCount(inner)
+		}
+	}
+	return count
+}
+
+func (p *parser) addExpansionError(loc logger.Loc, n int) {
+	p.log.AddErrorWithNotes(&p.tracker, logger.Range{Loc: loc}, "CSS nesting is causing too much expansion",
+		[]logger.MsgData{{Text: fmt.Sprintf("CSS nesting expansion was terminated because a rule was generated with %d selectors. "+
+			"This limit exists to prevent esbuild from using too much time and/or memory. "+
+			"Please change your CSS to use fewer levels of nesting.", n)}})
+}
+
 type lowerNestingContext struct {
 	parentSelectors []css_ast.ComplexSelector
 	loweredRules    []css_ast.Rule
@@ -110,6 +138,7 @@
 	switch r := rule.Data.(type) {
 	case *css_ast.RSelector:
 		oldSelectorsLen := len(r.Selectors)
+		oldSelectorsComplexity := complexSelectorTermCount(r.Selectors)
 
 		// "a { & b {} }" => "a b {}"
 		// "a { &b {} }" => "a:is(b) {}"
@@ -229,13 +258,13 @@
 			r.Selectors = selectors
 		}
 
-		// Put limits on the combinatorial explosion to avoid using too much time
-		// and/or memory.
-		if n := len(r.Selectors); n > oldSelectorsLen && n > 0xFFFF {
-			p.log.AddErrorWithNotes(&p.tracker, logger.Range{Loc: rule.Loc}, "CSS nesting is causing too much expansion",
-				[]logger.MsgData{{Text: fmt.Sprintf("CSS nesting expansion was terminated because a rule was generated with %d selectors. "+
-					"This limit exists to prevent esbuild from using too much time and/or memory. "+
-					"Please change your CSS to use fewer levels of nesting.", n)}})
+		// Put limits on the combinatorial explosion to avoid using too much time and/or memory
+		if n := len(r.Selectors); n > oldSelectorsLen && n > 0xFF00 {
+			p.addExpansionError(rule.Loc, n)
+			return css_ast.Rule{}
+		}
+		if n := complexSelectorTermCount(r.Selectors); n > oldSelectorsComplexity && n > 0xFF00 {
+			p.addExpansionError(rule.Loc, n)
 			return css_ast.Rule{}
 		}
 
diff -Nru golang-github-evanw-esbuild-0.25.3/internal/css_parser/css_parser_test.go golang-github-evanw-esbuild-0.25.5/internal/css_parser/css_parser_test.go
--- golang-github-evanw-esbuild-0.25.3/internal/css_parser/css_parser_test.go	2025-04-23 05:51:33.000000000 +0200
+++ golang-github-evanw-esbuild-0.25.5/internal/css_parser/css_parser_test.go	2025-05-27 05:11:58.000000000 +0200
@@ -2646,7 +2646,8 @@
 	// Special-case tests
 	expectPrintedWithAllPrefixes(t, "a { appearance: none }", "a {\n  -webkit-appearance: none;\n  -moz-appearance: none;\n  appearance: none;\n}\n", "")
 	expectPrintedWithAllPrefixes(t, "a { background-clip: not-text }", "a {\n  background-clip: not-text;\n}\n", "")
-	expectPrintedWithAllPrefixes(t, "a { background-clip: text !important }", "a {\n  -webkit-background-clip: text !important;\n  -ms-background-clip: text !important;\n  background-clip: text !important;\n}\n", "")
+	expectPrintedWithAllPrefixes(t, "a { background-clip: text !important }",
+		"a {\n  -webkit-background-clip: text !important;\n  -ms-background-clip: text !important;\n  background-clip: text !important;\n}\n", "")
 	expectPrintedWithAllPrefixes(t, "a { background-clip: text }", "a {\n  -webkit-background-clip: text;\n  -ms-background-clip: text;\n  background-clip: text;\n}\n", "")
 	expectPrintedWithAllPrefixes(t, "a { hyphens: auto }", "a {\n  -webkit-hyphens: auto;\n  -moz-hyphens: auto;\n  -ms-hyphens: auto;\n  hyphens: auto;\n}\n", "")
 	expectPrintedWithAllPrefixes(t, "a { position: absolute }", "a {\n  position: absolute;\n}\n", "")
@@ -2656,9 +2657,12 @@
 	expectPrintedWithAllPrefixes(t, "a { text-decoration-color: none }", "a {\n  -webkit-text-decoration-color: none;\n  -moz-text-decoration-color: none;\n  text-decoration-color: none;\n}\n", "")
 	expectPrintedWithAllPrefixes(t, "a { text-decoration-line: none }", "a {\n  -webkit-text-decoration-line: none;\n  -moz-text-decoration-line: none;\n  text-decoration-line: none;\n}\n", "")
 	expectPrintedWithAllPrefixes(t, "a { text-size-adjust: none }", "a {\n  -webkit-text-size-adjust: none;\n  -ms-text-size-adjust: none;\n  text-size-adjust: none;\n}\n", "")
-	expectPrintedWithAllPrefixes(t, "a { user-select: none }", "a {\n  -webkit-user-select: none;\n  -khtml-user-select: none;\n  -moz-user-select: -moz-none;\n  -ms-user-select: none;\n  user-select: none;\n}\n", "")
+	expectPrintedWithAllPrefixes(t, "a { user-select: none }",
+		"a {\n  -webkit-user-select: none;\n  -khtml-user-select: none;\n  -moz-user-select: -moz-none;\n  -ms-user-select: none;\n  user-select: none;\n}\n", "")
 	expectPrintedWithAllPrefixes(t, "a { mask-composite: add, subtract, intersect, exclude }",
 		"a {\n  -webkit-mask-composite:\n    source-over,\n    source-out,\n    source-in,\n    xor;\n  mask-composite:\n    add,\n    subtract,\n    intersect,\n    exclude;\n}\n", "")
+	expectPrintedWithAllPrefixes(t, "a { width: stretch }",
+		"a {\n  width: -webkit-fill-available;\n  width: -moz-available;\n  width: stretch;\n}\n", "")
 
 	// Check that we insert prefixed rules each time an unprefixed rule is
 	// encountered. This matches the behavior of the popular "autoprefixer" tool.
@@ -2677,6 +2681,12 @@
 	expectPrintedWithAllPrefixes(t,
 		"a { before: value; -ms-text-size-adjust: 2; text-size-adjust: 3; after: value }",
 		"a {\n  before: value;\n  -ms-text-size-adjust: 2;\n  -webkit-text-size-adjust: 3;\n  text-size-adjust: 3;\n  after: value;\n}\n", "")
+	expectPrintedWithAllPrefixes(t, "a { width: -moz-available; width: stretch }",
+		"a {\n  width: -moz-available;\n  width: -webkit-fill-available;\n  width: stretch;\n}\n", "")
+	expectPrintedWithAllPrefixes(t, "a { width: -webkit-fill-available; width: stretch }",
+		"a {\n  width: -webkit-fill-available;\n  width: -moz-available;\n  width: stretch;\n}\n", "")
+	expectPrintedWithAllPrefixes(t, "a { width: -webkit-fill-available; width: -moz-available; width: stretch }",
+		"a {\n  width: -webkit-fill-available;\n  width: -moz-available;\n  width: stretch;\n}\n", "")
 }
 
 func TestNthChild(t *testing.T) {
diff -Nru golang-github-evanw-esbuild-0.25.3/internal/js_parser/js_parser_lower.go golang-github-evanw-esbuild-0.25.5/internal/js_parser/js_parser_lower.go
--- golang-github-evanw-esbuild-0.25.3/internal/js_parser/js_parser_lower.go	2025-04-23 05:51:33.000000000 +0200
+++ golang-github-evanw-esbuild-0.25.5/internal/js_parser/js_parser_lower.go	2025-05-27 05:11:58.000000000 +0200
@@ -1892,7 +1892,6 @@
 	}
 }
 
-// If this returns "nil", then no lowering needed to be done
 func (ctx *lowerUsingDeclarationContext) scanStmts(p *parser, stmts []js_ast.Stmt) {
 	for _, stmt := range stmts {
 		if local, ok := stmt.Data.(*js_ast.SLocal); ok && local.Kind.IsUsing() {
@@ -2116,6 +2115,7 @@
 	id.Ref = tempRef
 }
 
+// If this returns "nil", then no lowering needed to be done
 func (p *parser) maybeLowerUsingDeclarationsInSwitch(loc logger.Loc, s *js_ast.SSwitch) []js_ast.Stmt {
 	// Check for a "using" declaration in any case
 	shouldLower := false
diff -Nru golang-github-evanw-esbuild-0.25.3/internal/js_parser/sourcemap_parser.go golang-github-evanw-esbuild-0.25.5/internal/js_parser/sourcemap_parser.go
--- golang-github-evanw-esbuild-0.25.3/internal/js_parser/sourcemap_parser.go	2025-04-23 05:51:33.000000000 +0200
+++ golang-github-evanw-esbuild-0.25.5/internal/js_parser/sourcemap_parser.go	2025-05-27 05:11:58.000000000 +0200
@@ -342,14 +342,9 @@
 				sourcePath := sourceURLPrefix + helpers.UTF16ToString(element.Value)
 				sourceURL, err := url.Parse(sourcePath)
 
-				// Report URL parse errors (such as "%XY" being an invalid escape)
+				// Ignore URL parse errors (such as "%XY" being an invalid escape)
 				if err != nil {
-					if urlErr, ok := err.(*url.Error); ok {
-						err = urlErr.Err // Use the underlying error to reduce noise
-					}
-					log.AddID(logger.MsgID_SourceMap_InvalidSourceURL, logger.Warning, &tracker, source.RangeOfString(item.Loc),
-						fmt.Sprintf("Invalid source URL: %s", err.Error()))
-					sources = append(sources, "")
+					sources = append(sources, sourcePath)
 					continue
 				}
 
diff -Nru golang-github-evanw-esbuild-0.25.3/internal/js_parser/ts_parser.go golang-github-evanw-esbuild-0.25.5/internal/js_parser/ts_parser.go
--- golang-github-evanw-esbuild-0.25.3/internal/js_parser/ts_parser.go	2025-04-23 05:51:33.000000000 +0200
+++ golang-github-evanw-esbuild-0.25.5/internal/js_parser/ts_parser.go	2025-05-27 05:11:58.000000000 +0200
@@ -262,7 +262,8 @@
 			p.lexer.Next()
 
 			// "[import: number]"
-			if flags.has(allowTupleLabelsFlag) && p.lexer.Token == js_lexer.TColon {
+			// "[import?: number]"
+			if flags.has(allowTupleLabelsFlag) && (p.lexer.Token == js_lexer.TColon || p.lexer.Token == js_lexer.TQuestion) {
 				return
 			}
 
@@ -288,7 +289,8 @@
 			p.lexer.Next()
 
 			// "[new: number]"
-			if flags.has(allowTupleLabelsFlag) && p.lexer.Token == js_lexer.TColon {
+			// "[new?: number]"
+			if flags.has(allowTupleLabelsFlag) && (p.lexer.Token == js_lexer.TColon || p.lexer.Token == js_lexer.TQuestion) {
 				return
 			}
 
@@ -314,13 +316,15 @@
 
 				// Valid:
 				//   "[keyof: string]"
+				//   "[keyof?: string]"
 				//   "{[keyof: string]: number}"
 				//   "{[keyof in string]: number}"
 				//
 				// Invalid:
 				//   "A extends B ? keyof : string"
 				//
-				if (p.lexer.Token != js_lexer.TColon && p.lexer.Token != js_lexer.TIn) || (!flags.has(isIndexSignatureFlag) && !flags.has(allowTupleLabelsFlag)) {
+				if (p.lexer.Token != js_lexer.TColon && p.lexer.Token != js_lexer.TQuestion && p.lexer.Token != js_lexer.TIn) ||
+					(!flags.has(isIndexSignatureFlag) && !flags.has(allowTupleLabelsFlag)) {
 					p.skipTypeScriptType(js_ast.LPrefix)
 				}
 				break loop
@@ -332,7 +336,10 @@
 				// "type Foo = Bar extends [infer T extends string] ? T : null"
 				// "type Foo = Bar extends [infer T extends string ? infer T : never] ? T : null"
 				// "type Foo = { [infer in Bar]: number }"
-				if (p.lexer.Token != js_lexer.TColon && p.lexer.Token != js_lexer.TIn) || (!flags.has(isIndexSignatureFlag) && !flags.has(allowTupleLabelsFlag)) {
+				// "type Foo = [infer: number]"
+				// "type Foo = [infer?: number]"
+				if (p.lexer.Token != js_lexer.TColon && p.lexer.Token != js_lexer.TQuestion && p.lexer.Token != js_lexer.TIn) ||
+					(!flags.has(isIndexSignatureFlag) && !flags.has(allowTupleLabelsFlag)) {
 					p.lexer.Expect(js_lexer.TIdentifier)
 					if p.lexer.Token == js_lexer.TExtends {
 						p.trySkipTypeScriptConstraintOfInferTypeWithBacktracking(flags)
@@ -390,7 +397,8 @@
 			p.lexer.Next()
 
 			// "[typeof: number]"
-			if flags.has(allowTupleLabelsFlag) && p.lexer.Token == js_lexer.TColon {
+			// "[typeof?: number]"
+			if flags.has(allowTupleLabelsFlag) && (p.lexer.Token == js_lexer.TColon || p.lexer.Token == js_lexer.TQuestion) {
 				return
 			}
 
@@ -459,12 +467,13 @@
 
 		default:
 			// "[function: number]"
+			// "[function?: number]"
 			if flags.has(allowTupleLabelsFlag) && p.lexer.IsIdentifierOrKeyword() {
 				if p.lexer.Token != js_lexer.TFunction {
 					p.log.AddError(&p.tracker, p.lexer.Range(), fmt.Sprintf("Unexpected %q", p.lexer.Raw()))
 				}
 				p.lexer.Next()
-				if p.lexer.Token != js_lexer.TColon {
+				if p.lexer.Token != js_lexer.TColon && p.lexer.Token != js_lexer.TQuestion {
 					p.lexer.Expect(js_lexer.TColon)
 				}
 				return
diff -Nru golang-github-evanw-esbuild-0.25.3/internal/js_parser/ts_parser_test.go golang-github-evanw-esbuild-0.25.5/internal/js_parser/ts_parser_test.go
--- golang-github-evanw-esbuild-0.25.3/internal/js_parser/ts_parser_test.go	2025-04-23 05:51:33.000000000 +0200
+++ golang-github-evanw-esbuild-0.25.5/internal/js_parser/ts_parser_test.go	2025-05-27 05:11:58.000000000 +0200
@@ -369,16 +369,55 @@
 	expectParseErrorTS(t, "x as Foo < 1", "<stdin>: ERROR: Expected \">\" but found end of file\n")
 
 	// These keywords are valid tuple labels
+	expectPrintedTS(t, "type _any = [any: string]", "")
+	expectPrintedTS(t, "type _asserts = [asserts: string]", "")
+	expectPrintedTS(t, "type _bigint = [bigint: string]", "")
+	expectPrintedTS(t, "type _boolean = [boolean: string]", "")
 	expectPrintedTS(t, "type _false = [false: string]", "")
 	expectPrintedTS(t, "type _function = [function: string]", "")
 	expectPrintedTS(t, "type _import = [import: string]", "")
+	expectPrintedTS(t, "type _infer = [infer: string]", "")
+	expectPrintedTS(t, "type _never = [never: string]", "")
 	expectPrintedTS(t, "type _new = [new: string]", "")
 	expectPrintedTS(t, "type _null = [null: string]", "")
+	expectPrintedTS(t, "type _number = [number: string]", "")
+	expectPrintedTS(t, "type _object = [object: string]", "")
+	expectPrintedTS(t, "type _readonly = [readonly: string]", "")
+	expectPrintedTS(t, "type _string = [string: string]", "")
+	expectPrintedTS(t, "type _symbol = [symbol: string]", "")
 	expectPrintedTS(t, "type _this = [this: string]", "")
 	expectPrintedTS(t, "type _true = [true: string]", "")
 	expectPrintedTS(t, "type _typeof = [typeof: string]", "")
+	expectPrintedTS(t, "type _undefined = [undefined: string]", "")
+	expectPrintedTS(t, "type _unique = [unique: string]", "")
+	expectPrintedTS(t, "type _unknown = [unknown: string]", "")
 	expectPrintedTS(t, "type _void = [void: string]", "")
 
+	// Also check tuple labels with a question mark
+	expectPrintedTS(t, "type _any = [any?: string]", "")
+	expectPrintedTS(t, "type _asserts = [asserts?: string]", "")
+	expectPrintedTS(t, "type _bigint = [bigint?: string]", "")
+	expectPrintedTS(t, "type _boolean = [boolean?: string]", "")
+	expectPrintedTS(t, "type _false = [false?: string]", "")
+	expectPrintedTS(t, "type _function = [function?: string]", "")
+	expectPrintedTS(t, "type _import = [import?: string]", "")
+	expectPrintedTS(t, "type _infer = [infer?: string]", "")
+	expectPrintedTS(t, "type _never = [never?: string]", "")
+	expectPrintedTS(t, "type _new = [new?: string]", "")
+	expectPrintedTS(t, "type _null = [null?: string]", "")
+	expectPrintedTS(t, "type _number = [number?: string]", "")
+	expectPrintedTS(t, "type _object = [object?: string]", "")
+	expectPrintedTS(t, "type _readonly = [readonly?: string]", "")
+	expectPrintedTS(t, "type _string = [string?: string]", "")
+	expectPrintedTS(t, "type _symbol = [symbol?: string]", "")
+	expectPrintedTS(t, "type _this = [this?: string]", "")
+	expectPrintedTS(t, "type _true = [true?: string]", "")
+	expectPrintedTS(t, "type _typeof = [typeof?: string]", "")
+	expectPrintedTS(t, "type _undefined = [undefined?: string]", "")
+	expectPrintedTS(t, "type _unique = [unique?: string]", "")
+	expectPrintedTS(t, "type _unknown = [unknown?: string]", "")
+	expectPrintedTS(t, "type _void = [void?: string]", "")
+
 	// These keywords are invalid tuple labels
 	expectParseErrorTS(t, "type _break = [break: string]", "<stdin>: ERROR: Unexpected \"break\"\n")
 	expectParseErrorTS(t, "type _case = [case: string]", "<stdin>: ERROR: Unexpected \"case\"\n")
diff -Nru golang-github-evanw-esbuild-0.25.3/internal/linker/linker.go golang-github-evanw-esbuild-0.25.5/internal/linker/linker.go
--- golang-github-evanw-esbuild-0.25.3/internal/linker/linker.go	2025-04-23 05:51:33.000000000 +0200
+++ golang-github-evanw-esbuild-0.25.5/internal/linker/linker.go	2025-05-27 05:11:58.000000000 +0200
@@ -2293,7 +2293,16 @@
 		} else {
 			getter = js_ast.Expr{Data: &js_ast.EArrow{PreferExpr: true, Body: body}}
 		}
+
+		// Special case for __proto__ property: use a computed property
+		// name to avoid it being treated as the object's prototype
+		var flags js_ast.PropertyFlags
+		if alias == "__proto__" && !c.options.UnsupportedJSFeatures.Has(compat.ObjectExtensions) {
+			flags |= js_ast.PropertyIsComputed
+		}
+
 		properties = append(properties, js_ast.Property{
+			Flags:      flags,
 			Key:        js_ast.Expr{Data: &js_ast.EString{Value: helpers.StringToUTF16(alias)}},
 			ValueOrNil: getter,
 		})
diff -Nru golang-github-evanw-esbuild-0.25.3/internal/logger/msg_ids.go golang-github-evanw-esbuild-0.25.5/internal/logger/msg_ids.go
--- golang-github-evanw-esbuild-0.25.3/internal/logger/msg_ids.go	2025-04-23 05:51:33.000000000 +0200
+++ golang-github-evanw-esbuild-0.25.5/internal/logger/msg_ids.go	2025-05-27 05:11:58.000000000 +0200
@@ -69,7 +69,6 @@
 
 	// Source maps
 	MsgID_SourceMap_InvalidSourceMappings
-	MsgID_SourceMap_InvalidSourceURL
 	MsgID_SourceMap_MissingSourceMap
 	MsgID_SourceMap_UnsupportedSourceMapComment
 
@@ -207,8 +206,6 @@
 	// Source maps
 	case "invalid-source-mappings":
 		overrides[MsgID_SourceMap_InvalidSourceMappings] = logLevel
-	case "invalid-source-url":
-		overrides[MsgID_SourceMap_InvalidSourceURL] = logLevel
 	case "missing-source-map":
 		overrides[MsgID_SourceMap_MissingSourceMap] = logLevel
 	case "unsupported-source-map-comment":
@@ -341,8 +338,6 @@
 	// Source maps
 	case MsgID_SourceMap_InvalidSourceMappings:
 		return "invalid-source-mappings"
-	case MsgID_SourceMap_InvalidSourceURL:
-		return "invalid-source-url"
 	case MsgID_SourceMap_MissingSourceMap:
 		return "missing-source-map"
 	case MsgID_SourceMap_UnsupportedSourceMapComment:
diff -Nru golang-github-evanw-esbuild-0.25.3/internal/resolver/resolver.go golang-github-evanw-esbuild-0.25.5/internal/resolver/resolver.go
--- golang-github-evanw-esbuild-0.25.3/internal/resolver/resolver.go	2025-04-23 05:51:33.000000000 +0200
+++ golang-github-evanw-esbuild-0.25.5/internal/resolver/resolver.go	2025-05-27 05:11:58.000000000 +0200
@@ -1012,6 +1012,21 @@
 			strings.HasSuffix(importPath, "/.") ||
 			strings.HasSuffix(importPath, "/..")
 
+		// Check the "browser" map
+		if importDirInfo := r.dirInfoCached(r.fs.Dir(absPath)); importDirInfo != nil {
+			if remapped, ok := r.checkBrowserMap(importDirInfo, absPath, absolutePathKind); ok {
+				if remapped == nil {
+					return &ResolveResult{PathPair: PathPair{Primary: logger.Path{Text: absPath, Namespace: "file", Flags: logger.PathDisabled}}}
+				}
+				if remappedResult, ok, diffCase, sideEffects := r.resolveWithoutRemapping(importDirInfo.enclosingBrowserScope, *remapped); ok {
+					result = ResolveResult{PathPair: remappedResult, DifferentCase: diffCase, PrimarySideEffectsData: sideEffects}
+					hasTrailingSlash = false
+					checkRelative = false
+					checkPackage = false
+				}
+			}
+		}
+
 		if hasTrailingSlash {
 			if absolute, ok, diffCase := r.loadAsDirectory(absPath); ok {
 				checkPackage = false
@@ -1020,20 +1035,6 @@
 				return nil
 			}
 		} else {
-			// Check the "browser" map
-			if importDirInfo := r.dirInfoCached(r.fs.Dir(absPath)); importDirInfo != nil {
-				if remapped, ok := r.checkBrowserMap(importDirInfo, absPath, absolutePathKind); ok {
-					if remapped == nil {
-						return &ResolveResult{PathPair: PathPair{Primary: logger.Path{Text: absPath, Namespace: "file", Flags: logger.PathDisabled}}}
-					}
-					if remappedResult, ok, diffCase, sideEffects := r.resolveWithoutRemapping(importDirInfo.enclosingBrowserScope, *remapped); ok {
-						result = ResolveResult{PathPair: remappedResult, DifferentCase: diffCase, PrimarySideEffectsData: sideEffects}
-						checkRelative = false
-						checkPackage = false
-					}
-				}
-			}
-
 			if checkRelative {
 				if absolute, ok, diffCase := r.loadAsFileOrDirectory(absPath); ok {
 					checkPackage = false
diff -Nru golang-github-evanw-esbuild-0.25.3/lib/shared/common.ts golang-github-evanw-esbuild-0.25.5/lib/shared/common.ts
--- golang-github-evanw-esbuild-0.25.3/lib/shared/common.ts	2025-04-23 05:51:33.000000000 +0200
+++ golang-github-evanw-esbuild-0.25.5/lib/shared/common.ts	2025-05-27 05:11:58.000000000 +0200
@@ -8,10 +8,14 @@
 const buildLogLevelDefault = 'warning'
 const transformLogLevelDefault = 'silent'
 
-function validateTarget(target: string): string {
-  validateStringValue(target, 'target')
-  if (target.indexOf(',') >= 0) throw new Error(`Invalid target: ${target}`)
-  return target
+function validateAndJoinStringArray(values: string[], what: string): string {
+  const toJoin: string[] = []
+  for (const value of values) {
+    validateStringValue(value, what)
+    if (value.indexOf(',') >= 0) throw new Error(`Invalid ${what}: ${value}`)
+    toJoin.push(value)
+  }
+  return toJoin.join(',')
 }
 
 let canBeAnything = () => null
@@ -37,6 +41,9 @@
 let mustBeArray = <T>(value: T[] | undefined): string | null =>
   Array.isArray(value) ? null : 'an array'
 
+let mustBeArrayOfStrings = (value: string[] | undefined): string | null =>
+  Array.isArray(value) && value.every(x => typeof x === 'string') ? null : 'an array of strings'
+
 let mustBeObject = (value: Object | undefined): string | null =>
   typeof value === 'object' && value !== null && !Array.isArray(value) ? null : 'an object'
 
@@ -55,8 +62,8 @@
 let mustBeStringOrObject = (value: string | Object | undefined): string | null =>
   typeof value === 'string' || typeof value === 'object' && value !== null && !Array.isArray(value) ? null : 'a string or an object'
 
-let mustBeStringOrArray = (value: string | string[] | undefined): string | null =>
-  typeof value === 'string' || Array.isArray(value) ? null : 'a string or an array'
+let mustBeStringOrArrayOfStrings = (value: string | string[] | undefined): string | null =>
+  typeof value === 'string' || (Array.isArray(value) && value.every(x => typeof x === 'string')) ? null : 'a string or an array of strings'
 
 let mustBeStringOrUint8Array = (value: string | Uint8Array | undefined): string | null =>
   typeof value === 'string' || value instanceof Uint8Array ? null : 'a string or a Uint8Array'
@@ -138,7 +145,7 @@
   let legalComments = getFlag(options, keys, 'legalComments', mustBeString)
   let sourceRoot = getFlag(options, keys, 'sourceRoot', mustBeString)
   let sourcesContent = getFlag(options, keys, 'sourcesContent', mustBeBoolean)
-  let target = getFlag(options, keys, 'target', mustBeStringOrArray)
+  let target = getFlag(options, keys, 'target', mustBeStringOrArrayOfStrings)
   let format = getFlag(options, keys, 'format', mustBeString)
   let globalName = getFlag(options, keys, 'globalName', mustBeString)
   let mangleProps = getFlag(options, keys, 'mangleProps', mustBeRegExp)
@@ -149,8 +156,8 @@
   let minifyWhitespace = getFlag(options, keys, 'minifyWhitespace', mustBeBoolean)
   let minifyIdentifiers = getFlag(options, keys, 'minifyIdentifiers', mustBeBoolean)
   let lineLimit = getFlag(options, keys, 'lineLimit', mustBeInteger)
-  let drop = getFlag(options, keys, 'drop', mustBeArray)
-  let dropLabels = getFlag(options, keys, 'dropLabels', mustBeArray)
+  let drop = getFlag(options, keys, 'drop', mustBeArrayOfStrings)
+  let dropLabels = getFlag(options, keys, 'dropLabels', mustBeArrayOfStrings)
   let charset = getFlag(options, keys, 'charset', mustBeString)
   let treeShaking = getFlag(options, keys, 'treeShaking', mustBeBoolean)
   let ignoreAnnotations = getFlag(options, keys, 'ignoreAnnotations', mustBeBoolean)
@@ -163,7 +170,7 @@
   let define = getFlag(options, keys, 'define', mustBeObject)
   let logOverride = getFlag(options, keys, 'logOverride', mustBeObject)
   let supported = getFlag(options, keys, 'supported', mustBeObject)
-  let pure = getFlag(options, keys, 'pure', mustBeArray)
+  let pure = getFlag(options, keys, 'pure', mustBeArrayOfStrings)
   let keepNames = getFlag(options, keys, 'keepNames', mustBeBoolean)
   let platform = getFlag(options, keys, 'platform', mustBeString)
   let tsconfigRaw = getFlag(options, keys, 'tsconfigRaw', mustBeStringOrObject)
@@ -171,10 +178,7 @@
   if (legalComments) flags.push(`--legal-comments=${legalComments}`)
   if (sourceRoot !== void 0) flags.push(`--source-root=${sourceRoot}`)
   if (sourcesContent !== void 0) flags.push(`--sources-content=${sourcesContent}`)
-  if (target) {
-    if (Array.isArray(target)) flags.push(`--target=${Array.from(target).map(validateTarget).join(',')}`)
-    else flags.push(`--target=${validateTarget(target)}`)
-  }
+  if (target) flags.push(`--target=${validateAndJoinStringArray(Array.isArray(target) ? target : [target], 'target')}`)
   if (format) flags.push(`--format=${format}`)
   if (globalName) flags.push(`--global-name=${globalName}`)
   if (platform) flags.push(`--platform=${platform}`)
@@ -189,7 +193,7 @@
   if (treeShaking !== void 0) flags.push(`--tree-shaking=${treeShaking}`)
   if (ignoreAnnotations) flags.push(`--ignore-annotations`)
   if (drop) for (let what of drop) flags.push(`--drop:${validateStringValue(what, 'drop')}`)
-  if (dropLabels) flags.push(`--drop-labels=${Array.from(dropLabels).map(what => validateStringValue(what, 'dropLabels')).join(',')}`)
+  if (dropLabels) flags.push(`--drop-labels=${validateAndJoinStringArray(dropLabels, 'drop label')}`)
   if (mangleProps) flags.push(`--mangle-props=${jsRegExpToGoRegExp(mangleProps)}`)
   if (reserveProps) flags.push(`--reserve-props=${jsRegExpToGoRegExp(reserveProps)}`)
   if (mangleQuoted !== void 0) flags.push(`--mangle-quoted=${mangleQuoted}`)
@@ -258,11 +262,11 @@
   let outdir = getFlag(options, keys, 'outdir', mustBeString)
   let outbase = getFlag(options, keys, 'outbase', mustBeString)
   let tsconfig = getFlag(options, keys, 'tsconfig', mustBeString)
-  let resolveExtensions = getFlag(options, keys, 'resolveExtensions', mustBeArray)
-  let nodePathsInput = getFlag(options, keys, 'nodePaths', mustBeArray)
-  let mainFields = getFlag(options, keys, 'mainFields', mustBeArray)
-  let conditions = getFlag(options, keys, 'conditions', mustBeArray)
-  let external = getFlag(options, keys, 'external', mustBeArray)
+  let resolveExtensions = getFlag(options, keys, 'resolveExtensions', mustBeArrayOfStrings)
+  let nodePathsInput = getFlag(options, keys, 'nodePaths', mustBeArrayOfStrings)
+  let mainFields = getFlag(options, keys, 'mainFields', mustBeArrayOfStrings)
+  let conditions = getFlag(options, keys, 'conditions', mustBeArrayOfStrings)
+  let external = getFlag(options, keys, 'external', mustBeArrayOfStrings)
   let packages = getFlag(options, keys, 'packages', mustBeString)
   let alias = getFlag(options, keys, 'alias', mustBeObject)
   let loader = getFlag(options, keys, 'loader', mustBeObject)
@@ -271,7 +275,7 @@
   let entryNames = getFlag(options, keys, 'entryNames', mustBeString)
   let chunkNames = getFlag(options, keys, 'chunkNames', mustBeString)
   let assetNames = getFlag(options, keys, 'assetNames', mustBeString)
-  let inject = getFlag(options, keys, 'inject', mustBeArray)
+  let inject = getFlag(options, keys, 'inject', mustBeArrayOfStrings)
   let banner = getFlag(options, keys, 'banner', mustBeObject)
   let footer = getFlag(options, keys, 'footer', mustBeObject)
   let entryPoints = getFlag(options, keys, 'entryPoints', mustBeEntryPoints)
@@ -294,37 +298,13 @@
   if (outbase) flags.push(`--outbase=${outbase}`)
   if (tsconfig) flags.push(`--tsconfig=${tsconfig}`)
   if (packages) flags.push(`--packages=${packages}`)
-  if (resolveExtensions) {
-    let values: string[] = []
-    for (let value of resolveExtensions) {
-      validateStringValue(value, 'resolve extension')
-      if (value.indexOf(',') >= 0) throw new Error(`Invalid resolve extension: ${value}`)
-      values.push(value)
-    }
-    flags.push(`--resolve-extensions=${values.join(',')}`)
-  }
+  if (resolveExtensions) flags.push(`--resolve-extensions=${validateAndJoinStringArray(resolveExtensions, 'resolve extension')}`)
   if (publicPath) flags.push(`--public-path=${publicPath}`)
   if (entryNames) flags.push(`--entry-names=${entryNames}`)
   if (chunkNames) flags.push(`--chunk-names=${chunkNames}`)
   if (assetNames) flags.push(`--asset-names=${assetNames}`)
-  if (mainFields) {
-    let values: string[] = []
-    for (let value of mainFields) {
-      validateStringValue(value, 'main field')
-      if (value.indexOf(',') >= 0) throw new Error(`Invalid main field: ${value}`)
-      values.push(value)
-    }
-    flags.push(`--main-fields=${values.join(',')}`)
-  }
-  if (conditions) {
-    let values: string[] = []
-    for (let value of conditions) {
-      validateStringValue(value, 'condition')
-      if (value.indexOf(',') >= 0) throw new Error(`Invalid condition: ${value}`)
-      values.push(value)
-    }
-    flags.push(`--conditions=${values.join(',')}`)
-  }
+  if (mainFields) flags.push(`--main-fields=${validateAndJoinStringArray(mainFields, 'main field')}`)
+  if (conditions) flags.push(`--conditions=${validateAndJoinStringArray(conditions, 'condition')}`)
   if (external) for (let name of external) flags.push(`--external:${validateStringValue(name, 'external')}`)
   if (alias) {
     for (let old in alias) {
@@ -1100,6 +1080,7 @@
           const keyfile = getFlag(options, keys, 'keyfile', mustBeString)
           const certfile = getFlag(options, keys, 'certfile', mustBeString)
           const fallback = getFlag(options, keys, 'fallback', mustBeString)
+          const cors = getFlag(options, keys, 'cors', mustBeObject)
           const onRequest = getFlag(options, keys, 'onRequest', mustBeFunction)
           checkForInvalidFlags(options, keys, `in serve() call`)
 
@@ -1115,6 +1096,14 @@
           if (certfile !== void 0) request.certfile = certfile
           if (fallback !== void 0) request.fallback = fallback
 
+          if (cors) {
+            const corsKeys: OptionKeys = {}
+            const origin = getFlag(cors, corsKeys, 'origin', mustBeStringOrArrayOfStrings)
+            checkForInvalidFlags(cors, corsKeys, `on "cors" object`)
+            if (Array.isArray(origin)) request.corsOrigin = origin
+            else if (origin !== void 0) request.corsOrigin = [origin]
+          }
+
           sendRequest<protocol.ServeRequest, protocol.ServeResponse>(refs, request, (error, response) => {
             if (error) return reject(new Error(error))
             if (onRequest) {
@@ -1409,8 +1398,8 @@
           let pluginData = getFlag(result, keys, 'pluginData', canBeAnything)
           let errors = getFlag(result, keys, 'errors', mustBeArray)
           let warnings = getFlag(result, keys, 'warnings', mustBeArray)
-          let watchFiles = getFlag(result, keys, 'watchFiles', mustBeArray)
-          let watchDirs = getFlag(result, keys, 'watchDirs', mustBeArray)
+          let watchFiles = getFlag(result, keys, 'watchFiles', mustBeArrayOfStrings)
+          let watchDirs = getFlag(result, keys, 'watchDirs', mustBeArrayOfStrings)
           checkForInvalidFlags(result, keys, `from onResolve() callback in plugin ${quote(name)}`)
 
           response.id = id
@@ -1458,8 +1447,8 @@
           let loader = getFlag(result, keys, 'loader', mustBeString)
           let errors = getFlag(result, keys, 'errors', mustBeArray)
           let warnings = getFlag(result, keys, 'warnings', mustBeArray)
-          let watchFiles = getFlag(result, keys, 'watchFiles', mustBeArray)
-          let watchDirs = getFlag(result, keys, 'watchDirs', mustBeArray)
+          let watchFiles = getFlag(result, keys, 'watchFiles', mustBeArrayOfStrings)
+          let watchDirs = getFlag(result, keys, 'watchDirs', mustBeArrayOfStrings)
           checkForInvalidFlags(result, keys, `from onLoad() callback in plugin ${quote(name)}`)
 
           response.id = id
diff -Nru golang-github-evanw-esbuild-0.25.3/lib/shared/stdio_protocol.ts golang-github-evanw-esbuild-0.25.5/lib/shared/stdio_protocol.ts
--- golang-github-evanw-esbuild-0.25.3/lib/shared/stdio_protocol.ts	2025-04-23 05:51:33.000000000 +0200
+++ golang-github-evanw-esbuild-0.25.5/lib/shared/stdio_protocol.ts	2025-05-27 05:11:58.000000000 +0200
@@ -31,6 +31,7 @@
   keyfile?: string
   certfile?: string
   fallback?: string
+  corsOrigin?: string[]
 }
 
 export interface ServeResponse {
diff -Nru golang-github-evanw-esbuild-0.25.3/lib/shared/types.ts golang-github-evanw-esbuild-0.25.5/lib/shared/types.ts
--- golang-github-evanw-esbuild-0.25.3/lib/shared/types.ts	2025-04-23 05:51:33.000000000 +0200
+++ golang-github-evanw-esbuild-0.25.5/lib/shared/types.ts	2025-05-27 05:11:58.000000000 +0200
@@ -241,9 +241,15 @@
   keyfile?: string
   certfile?: string
   fallback?: string
+  cors?: CORSOptions
   onRequest?: (args: ServeOnRequestArgs) => void
 }
 
+/** Documentation: https://esbuild.github.io/api/#cors */
+export interface CORSOptions {
+  origin?: string | string[]
+}
+
 export interface ServeOnRequestArgs {
   remoteAddress: string
   method: string
diff -Nru golang-github-evanw-esbuild-0.25.3/npm/@esbuild/aix-ppc64/package.json golang-github-evanw-esbuild-0.25.5/npm/@esbuild/aix-ppc64/package.json
--- golang-github-evanw-esbuild-0.25.3/npm/@esbuild/aix-ppc64/package.json	2025-04-23 05:51:33.000000000 +0200
+++ golang-github-evanw-esbuild-0.25.5/npm/@esbuild/aix-ppc64/package.json	2025-05-27 05:11:58.000000000 +0200
@@ -1,6 +1,6 @@
 {
   "name": "@esbuild/aix-ppc64",
-  "version": "0.25.3",
+  "version": "0.25.5",
   "description": "The IBM AIX PowerPC 64-bit binary for esbuild, a JavaScript bundler.",
   "repository": {
     "type": "git",
diff -Nru golang-github-evanw-esbuild-0.25.3/npm/@esbuild/android-arm/package.json golang-github-evanw-esbuild-0.25.5/npm/@esbuild/android-arm/package.json
--- golang-github-evanw-esbuild-0.25.3/npm/@esbuild/android-arm/package.json	2025-04-23 05:51:33.000000000 +0200
+++ golang-github-evanw-esbuild-0.25.5/npm/@esbuild/android-arm/package.json	2025-05-27 05:11:58.000000000 +0200
@@ -1,6 +1,6 @@
 {
   "name": "@esbuild/android-arm",
-  "version": "0.25.3",
+  "version": "0.25.5",
   "description": "A WebAssembly shim for esbuild on Android ARM.",
   "repository": {
     "type": "git",
diff -Nru golang-github-evanw-esbuild-0.25.3/npm/@esbuild/android-arm64/package.json golang-github-evanw-esbuild-0.25.5/npm/@esbuild/android-arm64/package.json
--- golang-github-evanw-esbuild-0.25.3/npm/@esbuild/android-arm64/package.json	2025-04-23 05:51:33.000000000 +0200
+++ golang-github-evanw-esbuild-0.25.5/npm/@esbuild/android-arm64/package.json	2025-05-27 05:11:58.000000000 +0200
@@ -1,6 +1,6 @@
 {
   "name": "@esbuild/android-arm64",
-  "version": "0.25.3",
+  "version": "0.25.5",
   "description": "The Android ARM 64-bit binary for esbuild, a JavaScript bundler.",
   "repository": {
     "type": "git",
diff -Nru golang-github-evanw-esbuild-0.25.3/npm/@esbuild/android-x64/package.json golang-github-evanw-esbuild-0.25.5/npm/@esbuild/android-x64/package.json
--- golang-github-evanw-esbuild-0.25.3/npm/@esbuild/android-x64/package.json	2025-04-23 05:51:33.000000000 +0200
+++ golang-github-evanw-esbuild-0.25.5/npm/@esbuild/android-x64/package.json	2025-05-27 05:11:58.000000000 +0200
@@ -1,6 +1,6 @@
 {
   "name": "@esbuild/android-x64",
-  "version": "0.25.3",
+  "version": "0.25.5",
   "description": "A WebAssembly shim for esbuild on Android x64.",
   "repository": {
     "type": "git",
diff -Nru golang-github-evanw-esbuild-0.25.3/npm/@esbuild/darwin-arm64/package.json golang-github-evanw-esbuild-0.25.5/npm/@esbuild/darwin-arm64/package.json
--- golang-github-evanw-esbuild-0.25.3/npm/@esbuild/darwin-arm64/package.json	2025-04-23 05:51:33.000000000 +0200
+++ golang-github-evanw-esbuild-0.25.5/npm/@esbuild/darwin-arm64/package.json	2025-05-27 05:11:58.000000000 +0200
@@ -1,6 +1,6 @@
 {
   "name": "@esbuild/darwin-arm64",
-  "version": "0.25.3",
+  "version": "0.25.5",
   "description": "The macOS ARM 64-bit binary for esbuild, a JavaScript bundler.",
   "repository": {
     "type": "git",
diff -Nru golang-github-evanw-esbuild-0.25.3/npm/@esbuild/darwin-x64/package.json golang-github-evanw-esbuild-0.25.5/npm/@esbuild/darwin-x64/package.json
--- golang-github-evanw-esbuild-0.25.3/npm/@esbuild/darwin-x64/package.json	2025-04-23 05:51:33.000000000 +0200
+++ golang-github-evanw-esbuild-0.25.5/npm/@esbuild/darwin-x64/package.json	2025-05-27 05:11:58.000000000 +0200
@@ -1,6 +1,6 @@
 {
   "name": "@esbuild/darwin-x64",
-  "version": "0.25.3",
+  "version": "0.25.5",
   "description": "The macOS 64-bit binary for esbuild, a JavaScript bundler.",
   "repository": {
     "type": "git",
diff -Nru golang-github-evanw-esbuild-0.25.3/npm/@esbuild/freebsd-arm64/package.json golang-github-evanw-esbuild-0.25.5/npm/@esbuild/freebsd-arm64/package.json
--- golang-github-evanw-esbuild-0.25.3/npm/@esbuild/freebsd-arm64/package.json	2025-04-23 05:51:33.000000000 +0200
+++ golang-github-evanw-esbuild-0.25.5/npm/@esbuild/freebsd-arm64/package.json	2025-05-27 05:11:58.000000000 +0200
@@ -1,6 +1,6 @@
 {
   "name": "@esbuild/freebsd-arm64",
-  "version": "0.25.3",
+  "version": "0.25.5",
   "description": "The FreeBSD ARM 64-bit binary for esbuild, a JavaScript bundler.",
   "repository": {
     "type": "git",
diff -Nru golang-github-evanw-esbuild-0.25.3/npm/@esbuild/freebsd-x64/package.json golang-github-evanw-esbuild-0.25.5/npm/@esbuild/freebsd-x64/package.json
--- golang-github-evanw-esbuild-0.25.3/npm/@esbuild/freebsd-x64/package.json	2025-04-23 05:51:33.000000000 +0200
+++ golang-github-evanw-esbuild-0.25.5/npm/@esbuild/freebsd-x64/package.json	2025-05-27 05:11:58.000000000 +0200
@@ -1,6 +1,6 @@
 {
   "name": "@esbuild/freebsd-x64",
-  "version": "0.25.3",
+  "version": "0.25.5",
   "description": "The FreeBSD 64-bit binary for esbuild, a JavaScript bundler.",
   "repository": {
     "type": "git",
diff -Nru golang-github-evanw-esbuild-0.25.3/npm/@esbuild/linux-arm/package.json golang-github-evanw-esbuild-0.25.5/npm/@esbuild/linux-arm/package.json
--- golang-github-evanw-esbuild-0.25.3/npm/@esbuild/linux-arm/package.json	2025-04-23 05:51:33.000000000 +0200
+++ golang-github-evanw-esbuild-0.25.5/npm/@esbuild/linux-arm/package.json	2025-05-27 05:11:58.000000000 +0200
@@ -1,6 +1,6 @@
 {
   "name": "@esbuild/linux-arm",
-  "version": "0.25.3",
+  "version": "0.25.5",
   "description": "The Linux ARM binary for esbuild, a JavaScript bundler.",
   "repository": {
     "type": "git",
diff -Nru golang-github-evanw-esbuild-0.25.3/npm/@esbuild/linux-arm64/package.json golang-github-evanw-esbuild-0.25.5/npm/@esbuild/linux-arm64/package.json
--- golang-github-evanw-esbuild-0.25.3/npm/@esbuild/linux-arm64/package.json	2025-04-23 05:51:33.000000000 +0200
+++ golang-github-evanw-esbuild-0.25.5/npm/@esbuild/linux-arm64/package.json	2025-05-27 05:11:58.000000000 +0200
@@ -1,6 +1,6 @@
 {
   "name": "@esbuild/linux-arm64",
-  "version": "0.25.3",
+  "version": "0.25.5",
   "description": "The Linux ARM 64-bit binary for esbuild, a JavaScript bundler.",
   "repository": {
     "type": "git",
diff -Nru golang-github-evanw-esbuild-0.25.3/npm/@esbuild/linux-ia32/package.json golang-github-evanw-esbuild-0.25.5/npm/@esbuild/linux-ia32/package.json
--- golang-github-evanw-esbuild-0.25.3/npm/@esbuild/linux-ia32/package.json	2025-04-23 05:51:33.000000000 +0200
+++ golang-github-evanw-esbuild-0.25.5/npm/@esbuild/linux-ia32/package.json	2025-05-27 05:11:58.000000000 +0200
@@ -1,6 +1,6 @@
 {
   "name": "@esbuild/linux-ia32",
-  "version": "0.25.3",
+  "version": "0.25.5",
   "description": "The Linux 32-bit binary for esbuild, a JavaScript bundler.",
   "repository": {
     "type": "git",
diff -Nru golang-github-evanw-esbuild-0.25.3/npm/@esbuild/linux-loong64/package.json golang-github-evanw-esbuild-0.25.5/npm/@esbuild/linux-loong64/package.json
--- golang-github-evanw-esbuild-0.25.3/npm/@esbuild/linux-loong64/package.json	2025-04-23 05:51:33.000000000 +0200
+++ golang-github-evanw-esbuild-0.25.5/npm/@esbuild/linux-loong64/package.json	2025-05-27 05:11:58.000000000 +0200
@@ -1,6 +1,6 @@
 {
   "name": "@esbuild/linux-loong64",
-  "version": "0.25.3",
+  "version": "0.25.5",
   "description": "The Linux LoongArch 64-bit binary for esbuild, a JavaScript bundler.",
   "repository": {
     "type": "git",
diff -Nru golang-github-evanw-esbuild-0.25.3/npm/@esbuild/linux-mips64el/package.json golang-github-evanw-esbuild-0.25.5/npm/@esbuild/linux-mips64el/package.json
--- golang-github-evanw-esbuild-0.25.3/npm/@esbuild/linux-mips64el/package.json	2025-04-23 05:51:33.000000000 +0200
+++ golang-github-evanw-esbuild-0.25.5/npm/@esbuild/linux-mips64el/package.json	2025-05-27 05:11:58.000000000 +0200
@@ -1,6 +1,6 @@
 {
   "name": "@esbuild/linux-mips64el",
-  "version": "0.25.3",
+  "version": "0.25.5",
   "description": "The Linux MIPS 64-bit Little Endian binary for esbuild, a JavaScript bundler.",
   "repository": {
     "type": "git",
diff -Nru golang-github-evanw-esbuild-0.25.3/npm/@esbuild/linux-ppc64/package.json golang-github-evanw-esbuild-0.25.5/npm/@esbuild/linux-ppc64/package.json
--- golang-github-evanw-esbuild-0.25.3/npm/@esbuild/linux-ppc64/package.json	2025-04-23 05:51:33.000000000 +0200
+++ golang-github-evanw-esbuild-0.25.5/npm/@esbuild/linux-ppc64/package.json	2025-05-27 05:11:58.000000000 +0200
@@ -1,6 +1,6 @@
 {
   "name": "@esbuild/linux-ppc64",
-  "version": "0.25.3",
+  "version": "0.25.5",
   "description": "The Linux PowerPC 64-bit Little Endian binary for esbuild, a JavaScript bundler.",
   "repository": {
     "type": "git",
diff -Nru golang-github-evanw-esbuild-0.25.3/npm/@esbuild/linux-riscv64/package.json golang-github-evanw-esbuild-0.25.5/npm/@esbuild/linux-riscv64/package.json
--- golang-github-evanw-esbuild-0.25.3/npm/@esbuild/linux-riscv64/package.json	2025-04-23 05:51:33.000000000 +0200
+++ golang-github-evanw-esbuild-0.25.5/npm/@esbuild/linux-riscv64/package.json	2025-05-27 05:11:58.000000000 +0200
@@ -1,6 +1,6 @@
 {
   "name": "@esbuild/linux-riscv64",
-  "version": "0.25.3",
+  "version": "0.25.5",
   "description": "The Linux RISC-V 64-bit binary for esbuild, a JavaScript bundler.",
   "repository": {
     "type": "git",
diff -Nru golang-github-evanw-esbuild-0.25.3/npm/@esbuild/linux-s390x/package.json golang-github-evanw-esbuild-0.25.5/npm/@esbuild/linux-s390x/package.json
--- golang-github-evanw-esbuild-0.25.3/npm/@esbuild/linux-s390x/package.json	2025-04-23 05:51:33.000000000 +0200
+++ golang-github-evanw-esbuild-0.25.5/npm/@esbuild/linux-s390x/package.json	2025-05-27 05:11:58.000000000 +0200
@@ -1,6 +1,6 @@
 {
   "name": "@esbuild/linux-s390x",
-  "version": "0.25.3",
+  "version": "0.25.5",
   "description": "The Linux IBM Z 64-bit Big Endian binary for esbuild, a JavaScript bundler.",
   "repository": {
     "type": "git",
diff -Nru golang-github-evanw-esbuild-0.25.3/npm/@esbuild/linux-x64/package.json golang-github-evanw-esbuild-0.25.5/npm/@esbuild/linux-x64/package.json
--- golang-github-evanw-esbuild-0.25.3/npm/@esbuild/linux-x64/package.json	2025-04-23 05:51:33.000000000 +0200
+++ golang-github-evanw-esbuild-0.25.5/npm/@esbuild/linux-x64/package.json	2025-05-27 05:11:58.000000000 +0200
@@ -1,6 +1,6 @@
 {
   "name": "@esbuild/linux-x64",
-  "version": "0.25.3",
+  "version": "0.25.5",
   "description": "The Linux 64-bit binary for esbuild, a JavaScript bundler.",
   "repository": {
     "type": "git",
diff -Nru golang-github-evanw-esbuild-0.25.3/npm/@esbuild/netbsd-arm64/package.json golang-github-evanw-esbuild-0.25.5/npm/@esbuild/netbsd-arm64/package.json
--- golang-github-evanw-esbuild-0.25.3/npm/@esbuild/netbsd-arm64/package.json	2025-04-23 05:51:33.000000000 +0200
+++ golang-github-evanw-esbuild-0.25.5/npm/@esbuild/netbsd-arm64/package.json	2025-05-27 05:11:58.000000000 +0200
@@ -1,6 +1,6 @@
 {
   "name": "@esbuild/netbsd-arm64",
-  "version": "0.25.3",
+  "version": "0.25.5",
   "description": "The NetBSD ARM 64-bit binary for esbuild, a JavaScript bundler.",
   "repository": {
     "type": "git",
diff -Nru golang-github-evanw-esbuild-0.25.3/npm/@esbuild/netbsd-x64/package.json golang-github-evanw-esbuild-0.25.5/npm/@esbuild/netbsd-x64/package.json
--- golang-github-evanw-esbuild-0.25.3/npm/@esbuild/netbsd-x64/package.json	2025-04-23 05:51:33.000000000 +0200
+++ golang-github-evanw-esbuild-0.25.5/npm/@esbuild/netbsd-x64/package.json	2025-05-27 05:11:58.000000000 +0200
@@ -1,6 +1,6 @@
 {
   "name": "@esbuild/netbsd-x64",
-  "version": "0.25.3",
+  "version": "0.25.5",
   "description": "The NetBSD AMD64 binary for esbuild, a JavaScript bundler.",
   "repository": {
     "type": "git",
diff -Nru golang-github-evanw-esbuild-0.25.3/npm/@esbuild/openbsd-arm64/package.json golang-github-evanw-esbuild-0.25.5/npm/@esbuild/openbsd-arm64/package.json
--- golang-github-evanw-esbuild-0.25.3/npm/@esbuild/openbsd-arm64/package.json	2025-04-23 05:51:33.000000000 +0200
+++ golang-github-evanw-esbuild-0.25.5/npm/@esbuild/openbsd-arm64/package.json	2025-05-27 05:11:58.000000000 +0200
@@ -1,6 +1,6 @@
 {
   "name": "@esbuild/openbsd-arm64",
-  "version": "0.25.3",
+  "version": "0.25.5",
   "description": "The OpenBSD ARM 64-bit binary for esbuild, a JavaScript bundler.",
   "repository": {
     "type": "git",
diff -Nru golang-github-evanw-esbuild-0.25.3/npm/@esbuild/openbsd-x64/package.json golang-github-evanw-esbuild-0.25.5/npm/@esbuild/openbsd-x64/package.json
--- golang-github-evanw-esbuild-0.25.3/npm/@esbuild/openbsd-x64/package.json	2025-04-23 05:51:33.000000000 +0200
+++ golang-github-evanw-esbuild-0.25.5/npm/@esbuild/openbsd-x64/package.json	2025-05-27 05:11:58.000000000 +0200
@@ -1,6 +1,6 @@
 {
   "name": "@esbuild/openbsd-x64",
-  "version": "0.25.3",
+  "version": "0.25.5",
   "description": "The OpenBSD 64-bit binary for esbuild, a JavaScript bundler.",
   "repository": {
     "type": "git",
diff -Nru golang-github-evanw-esbuild-0.25.3/npm/@esbuild/sunos-x64/package.json golang-github-evanw-esbuild-0.25.5/npm/@esbuild/sunos-x64/package.json
--- golang-github-evanw-esbuild-0.25.3/npm/@esbuild/sunos-x64/package.json	2025-04-23 05:51:33.000000000 +0200
+++ golang-github-evanw-esbuild-0.25.5/npm/@esbuild/sunos-x64/package.json	2025-05-27 05:11:58.000000000 +0200
@@ -1,6 +1,6 @@
 {
   "name": "@esbuild/sunos-x64",
-  "version": "0.25.3",
+  "version": "0.25.5",
   "description": "The illumos 64-bit binary for esbuild, a JavaScript bundler.",
   "repository": {
     "type": "git",
diff -Nru golang-github-evanw-esbuild-0.25.3/npm/@esbuild/wasi-preview1/package.json golang-github-evanw-esbuild-0.25.5/npm/@esbuild/wasi-preview1/package.json
--- golang-github-evanw-esbuild-0.25.3/npm/@esbuild/wasi-preview1/package.json	2025-04-23 05:51:33.000000000 +0200
+++ golang-github-evanw-esbuild-0.25.5/npm/@esbuild/wasi-preview1/package.json	2025-05-27 05:11:58.000000000 +0200
@@ -1,6 +1,6 @@
 {
   "name": "@esbuild/wasi-preview1",
-  "version": "0.25.3",
+  "version": "0.25.5",
   "description": "The WASI (WebAssembly System Interface) preview 1 binary for esbuild, a JavaScript bundler.",
   "repository": {
     "type": "git",
diff -Nru golang-github-evanw-esbuild-0.25.3/npm/@esbuild/win32-arm64/package.json golang-github-evanw-esbuild-0.25.5/npm/@esbuild/win32-arm64/package.json
--- golang-github-evanw-esbuild-0.25.3/npm/@esbuild/win32-arm64/package.json	2025-04-23 05:51:33.000000000 +0200
+++ golang-github-evanw-esbuild-0.25.5/npm/@esbuild/win32-arm64/package.json	2025-05-27 05:11:58.000000000 +0200
@@ -1,6 +1,6 @@
 {
   "name": "@esbuild/win32-arm64",
-  "version": "0.25.3",
+  "version": "0.25.5",
   "description": "The Windows ARM 64-bit binary for esbuild, a JavaScript bundler.",
   "repository": {
     "type": "git",
diff -Nru golang-github-evanw-esbuild-0.25.3/npm/@esbuild/win32-ia32/package.json golang-github-evanw-esbuild-0.25.5/npm/@esbuild/win32-ia32/package.json
--- golang-github-evanw-esbuild-0.25.3/npm/@esbuild/win32-ia32/package.json	2025-04-23 05:51:33.000000000 +0200
+++ golang-github-evanw-esbuild-0.25.5/npm/@esbuild/win32-ia32/package.json	2025-05-27 05:11:58.000000000 +0200
@@ -1,6 +1,6 @@
 {
   "name": "@esbuild/win32-ia32",
-  "version": "0.25.3",
+  "version": "0.25.5",
   "description": "The Windows 32-bit binary for esbuild, a JavaScript bundler.",
   "repository": {
     "type": "git",
diff -Nru golang-github-evanw-esbuild-0.25.3/npm/@esbuild/win32-x64/package.json golang-github-evanw-esbuild-0.25.5/npm/@esbuild/win32-x64/package.json
--- golang-github-evanw-esbuild-0.25.3/npm/@esbuild/win32-x64/package.json	2025-04-23 05:51:33.000000000 +0200
+++ golang-github-evanw-esbuild-0.25.5/npm/@esbuild/win32-x64/package.json	2025-05-27 05:11:58.000000000 +0200
@@ -1,6 +1,6 @@
 {
   "name": "@esbuild/win32-x64",
-  "version": "0.25.3",
+  "version": "0.25.5",
   "description": "The Windows 64-bit binary for esbuild, a JavaScript bundler.",
   "repository": {
     "type": "git",
diff -Nru golang-github-evanw-esbuild-0.25.3/npm/esbuild/package.json golang-github-evanw-esbuild-0.25.5/npm/esbuild/package.json
--- golang-github-evanw-esbuild-0.25.3/npm/esbuild/package.json	2025-04-23 05:51:33.000000000 +0200
+++ golang-github-evanw-esbuild-0.25.5/npm/esbuild/package.json	2025-05-27 05:11:58.000000000 +0200
@@ -1,6 +1,6 @@
 {
   "name": "esbuild",
-  "version": "0.25.3",
+  "version": "0.25.5",
   "description": "An extremely fast JavaScript and CSS bundler and minifier.",
   "repository": {
     "type": "git",
@@ -18,31 +18,31 @@
     "esbuild": "bin/esbuild"
   },
   "optionalDependencies": {
-    "@esbuild/aix-ppc64": "0.25.3",
-    "@esbuild/android-arm": "0.25.3",
-    "@esbuild/android-arm64": "0.25.3",
-    "@esbuild/android-x64": "0.25.3",
-    "@esbuild/darwin-arm64": "0.25.3",
-    "@esbuild/darwin-x64": "0.25.3",
-    "@esbuild/freebsd-arm64": "0.25.3",
-    "@esbuild/freebsd-x64": "0.25.3",
-    "@esbuild/linux-arm": "0.25.3",
-    "@esbuild/linux-arm64": "0.25.3",
-    "@esbuild/linux-ia32": "0.25.3",
-    "@esbuild/linux-loong64": "0.25.3",
-    "@esbuild/linux-mips64el": "0.25.3",
-    "@esbuild/linux-ppc64": "0.25.3",
-    "@esbuild/linux-riscv64": "0.25.3",
-    "@esbuild/linux-s390x": "0.25.3",
-    "@esbuild/linux-x64": "0.25.3",
-    "@esbuild/netbsd-arm64": "0.25.3",
-    "@esbuild/netbsd-x64": "0.25.3",
-    "@esbuild/openbsd-arm64": "0.25.3",
-    "@esbuild/openbsd-x64": "0.25.3",
-    "@esbuild/sunos-x64": "0.25.3",
-    "@esbuild/win32-arm64": "0.25.3",
-    "@esbuild/win32-ia32": "0.25.3",
-    "@esbuild/win32-x64": "0.25.3"
+    "@esbuild/aix-ppc64": "0.25.5",
+    "@esbuild/android-arm": "0.25.5",
+    "@esbuild/android-arm64": "0.25.5",
+    "@esbuild/android-x64": "0.25.5",
+    "@esbuild/darwin-arm64": "0.25.5",
+    "@esbuild/darwin-x64": "0.25.5",
+    "@esbuild/freebsd-arm64": "0.25.5",
+    "@esbuild/freebsd-x64": "0.25.5",
+    "@esbuild/linux-arm": "0.25.5",
+    "@esbuild/linux-arm64": "0.25.5",
+    "@esbuild/linux-ia32": "0.25.5",
+    "@esbuild/linux-loong64": "0.25.5",
+    "@esbuild/linux-mips64el": "0.25.5",
+    "@esbuild/linux-ppc64": "0.25.5",
+    "@esbuild/linux-riscv64": "0.25.5",
+    "@esbuild/linux-s390x": "0.25.5",
+    "@esbuild/linux-x64": "0.25.5",
+    "@esbuild/netbsd-arm64": "0.25.5",
+    "@esbuild/netbsd-x64": "0.25.5",
+    "@esbuild/openbsd-arm64": "0.25.5",
+    "@esbuild/openbsd-x64": "0.25.5",
+    "@esbuild/sunos-x64": "0.25.5",
+    "@esbuild/win32-arm64": "0.25.5",
+    "@esbuild/win32-ia32": "0.25.5",
+    "@esbuild/win32-x64": "0.25.5"
   },
   "license": "MIT"
 }
diff -Nru golang-github-evanw-esbuild-0.25.3/npm/esbuild-wasm/package.json golang-github-evanw-esbuild-0.25.5/npm/esbuild-wasm/package.json
--- golang-github-evanw-esbuild-0.25.3/npm/esbuild-wasm/package.json	2025-04-23 05:51:33.000000000 +0200
+++ golang-github-evanw-esbuild-0.25.5/npm/esbuild-wasm/package.json	2025-05-27 05:11:58.000000000 +0200
@@ -1,6 +1,6 @@
 {
   "name": "esbuild-wasm",
-  "version": "0.25.3",
+  "version": "0.25.5",
   "description": "The cross-platform WebAssembly binary for esbuild, a JavaScript bundler.",
   "repository": {
     "type": "git",
diff -Nru golang-github-evanw-esbuild-0.25.3/pkg/api/api.go golang-github-evanw-esbuild-0.25.5/pkg/api/api.go
--- golang-github-evanw-esbuild-0.25.3/pkg/api/api.go	2025-04-23 05:51:33.000000000 +0200
+++ golang-github-evanw-esbuild-0.25.5/pkg/api/api.go	2025-05-27 05:11:58.000000000 +0200
@@ -478,9 +478,15 @@
 	Keyfile   string
 	Certfile  string
 	Fallback  string
+	CORS      CORSOptions
 	OnRequest func(ServeOnRequestArgs)
 }
 
+// Documentation: https://esbuild.github.io/api/#cors
+type CORSOptions struct {
+	Origin []string
+}
+
 type ServeOnRequestArgs struct {
 	RemoteAddress string
 	Method        string
diff -Nru golang-github-evanw-esbuild-0.25.3/pkg/api/serve_other.go golang-github-evanw-esbuild-0.25.5/pkg/api/serve_other.go
--- golang-github-evanw-esbuild-0.25.3/pkg/api/serve_other.go	2025-04-23 05:51:33.000000000 +0200
+++ golang-github-evanw-esbuild-0.25.5/pkg/api/serve_other.go	2025-05-27 05:11:58.000000000 +0200
@@ -49,6 +49,7 @@
 	certfileToLower  string
 	fallback         string
 	hosts            []string
+	corsOrigin       []string
 	serveWaitGroup   sync.WaitGroup
 	activeStreams    []chan serverSentEvent
 	currentHashes    map[string]string
@@ -104,6 +105,25 @@
 func (h *apiHandler) ServeHTTP(res http.ResponseWriter, req *http.Request) {
 	start := time.Now()
 
+	// Add CORS headers to all relevant requests
+	if origin := req.Header.Get("Origin"); origin != "" {
+		for _, allowed := range h.corsOrigin {
+			if allowed == "*" {
+				res.Header().Set("Access-Control-Allow-Origin", "*")
+				break
+			} else if star := strings.IndexByte(allowed, '*'); star >= 0 {
+				prefix, suffix := allowed[:star], allowed[star+1:]
+				if len(origin) >= len(prefix)+len(suffix) && strings.HasPrefix(origin, prefix) && strings.HasSuffix(origin, suffix) {
+					res.Header().Set("Access-Control-Allow-Origin", origin)
+					break
+				}
+			} else if origin == allowed {
+				res.Header().Set("Access-Control-Allow-Origin", origin)
+				break
+			}
+		}
+	}
+
 	// HEAD requests omit the body
 	maybeWriteResponseBody := func(bytes []byte) { res.Write(bytes) }
 	isHEAD := req.Method == "HEAD"
@@ -736,6 +756,13 @@
 		}
 	}
 
+	// Validate the CORS origins
+	for _, origin := range serveOptions.CORS.Origin {
+		if star := strings.IndexByte(origin, '*'); star >= 0 && strings.ContainsRune(origin[star+1:], '*') {
+			return ServeResult{}, fmt.Errorf("Invalid origin: %s", origin)
+		}
+	}
+
 	// Stuff related to the output directory only matters if there are entry points
 	outdirPathPrefix := ""
 	if len(ctx.args.entryPoints) > 0 {
@@ -868,6 +895,7 @@
 		certfileToLower:  strings.ToLower(serveOptions.Certfile),
 		fallback:         serveOptions.Fallback,
 		hosts:            append([]string{}, result.Hosts...),
+		corsOrigin:       append([]string{}, serveOptions.CORS.Origin...),
 		rebuild: func() BuildResult {
 			if atomic.LoadInt32(&shouldStop) != 0 {
 				// Don't start more rebuilds if we were told to stop
diff -Nru golang-github-evanw-esbuild-0.25.3/pkg/cli/cli_impl.go golang-github-evanw-esbuild-0.25.5/pkg/cli/cli_impl.go
--- golang-github-evanw-esbuild-0.25.3/pkg/cli/cli_impl.go	2025-04-23 05:51:33.000000000 +0200
+++ golang-github-evanw-esbuild-0.25.5/pkg/cli/cli_impl.go	2025-05-27 05:11:58.000000000 +0200
@@ -845,6 +845,7 @@
 				"chunk-names":        true,
 				"color":              true,
 				"conditions":         true,
+				"cors-origin":        true,
 				"drop-labels":        true,
 				"entry-names":        true,
 				"footer":             true,
@@ -1375,6 +1376,7 @@
 	keyfile := ""
 	certfile := ""
 	fallback := ""
+	var corsOrigin []string
 
 	// Filter out server-specific flags
 	filteredArgs := make([]string, 0, len(osArgs))
@@ -1391,6 +1393,8 @@
 			certfile = arg[len("--certfile="):]
 		} else if strings.HasPrefix(arg, "--serve-fallback=") {
 			fallback = arg[len("--serve-fallback="):]
+		} else if strings.HasPrefix(arg, "--cors-origin=") {
+			corsOrigin = strings.Split(arg[len("--cors-origin="):], ",")
 		} else {
 			filteredArgs = append(filteredArgs, arg)
 		}
@@ -1429,6 +1433,9 @@
 		Keyfile:  keyfile,
 		Certfile: certfile,
 		Fallback: fallback,
+		CORS: api.CORSOptions{
+			Origin: corsOrigin,
+		},
 	}, filteredArgs, nil
 }
 
diff -Nru golang-github-evanw-esbuild-0.25.3/scripts/js-api-tests.js golang-github-evanw-esbuild-0.25.5/scripts/js-api-tests.js
--- golang-github-evanw-esbuild-0.25.3/scripts/js-api-tests.js	2025-04-23 05:51:33.000000000 +0200
+++ golang-github-evanw-esbuild-0.25.5/scripts/js-api-tests.js	2025-05-27 05:11:58.000000000 +0200
@@ -5305,6 +5305,121 @@
       await context.dispose();
     }
   },
+
+  async serveCORSNoOrigins({ esbuild, testDir }) {
+    const input = path.join(testDir, 'in.js')
+    await writeFileAsync(input, `console.log(123)`)
+
+    const context = await esbuild.context({
+      entryPoints: [input],
+      format: 'esm',
+      outdir: testDir,
+      write: false,
+    });
+    try {
+      const result = await context.serve({
+        port: 0,
+        cors: {},
+      })
+      assert(result.hosts.length > 0);
+      assert.strictEqual(typeof result.port, 'number');
+
+      // There should be no CORS header
+      const origin = 'https://example.com'
+      const buffer = await fetch(result.hosts[0], result.port, '/in.js', { headers: { Origin: origin } })
+      assert.strictEqual(buffer.toString(), `console.log(123);\n`);
+      assert.strictEqual(fs.readFileSync(input, 'utf8'), `console.log(123)`)
+      assert.strictEqual(buffer.headers['access-control-allow-origin'], undefined)
+    } finally {
+      await context.dispose();
+    }
+  },
+
+  async serveCORSAllOrigins({ esbuild, testDir }) {
+    const input = path.join(testDir, 'in.js')
+    await writeFileAsync(input, `console.log(123)`)
+
+    const context = await esbuild.context({
+      entryPoints: [input],
+      format: 'esm',
+      outdir: testDir,
+      write: false,
+    });
+    try {
+      const result = await context.serve({
+        port: 0,
+        cors: { origin: '*' },
+      })
+      assert(result.hosts.length > 0);
+      assert.strictEqual(typeof result.port, 'number');
+
+      // There should be a CORS header allowing all origins
+      const origin = 'https://example.com'
+      const buffer = await fetch(result.hosts[0], result.port, '/in.js', { headers: { Origin: origin } })
+      assert.strictEqual(buffer.toString(), `console.log(123);\n`);
+      assert.strictEqual(fs.readFileSync(input, 'utf8'), `console.log(123)`)
+      assert.strictEqual(buffer.headers['access-control-allow-origin'], '*')
+    } finally {
+      await context.dispose();
+    }
+  },
+
+  async serveCORSSpecificOrigins({ esbuild, testDir }) {
+    const input = path.join(testDir, 'in.js')
+    await writeFileAsync(input, `console.log(123)`)
+
+    const context = await esbuild.context({
+      entryPoints: [input],
+      format: 'esm',
+      outdir: testDir,
+      write: false,
+    });
+    try {
+      const result = await context.serve({
+        port: 0,
+        cors: {
+          origin: [
+            'http://example.com',
+            'http://foo.example.com',
+            'https://*.example.com',
+          ],
+        },
+      })
+      assert(result.hosts.length > 0);
+      assert.strictEqual(typeof result.port, 'number');
+
+      const allowedOrigins = [
+        'http://example.com',
+        'http://foo.example.com',
+        'https://bar.example.com',
+      ]
+
+      const forbiddenOrigins = [
+        'http://bar.example.com',
+        'https://example.com',
+        'http://evil.com',
+        'https://evil.com',
+      ]
+
+      // GET /in.js from each allowed origin
+      for (const origin of allowedOrigins) {
+        const buffer = await fetch(result.hosts[0], result.port, '/in.js', { headers: { Origin: origin } })
+        assert.strictEqual(buffer.toString(), `console.log(123);\n`);
+        assert.strictEqual(fs.readFileSync(input, 'utf8'), `console.log(123)`)
+        assert.strictEqual(buffer.headers['access-control-allow-origin'], origin)
+      }
+
+      // GET /in.js from each forbidden origin
+      for (const origin of forbiddenOrigins) {
+        const buffer = await fetch(result.hosts[0], result.port, '/in.js', { headers: { Origin: origin } })
+        assert.strictEqual(buffer.toString(), `console.log(123);\n`);
+        assert.strictEqual(fs.readFileSync(input, 'utf8'), `console.log(123)`)
+        assert.strictEqual(buffer.headers['access-control-allow-origin'], undefined)
+      }
+    } finally {
+      await context.dispose();
+    }
+  },
 }
 
 async function futureSyntax(esbuild, js, targetBelow, targetAbove) {
@@ -5963,13 +6078,24 @@
     assert.strictEqual(code, `div{color:#abcd}\n`)
   },
 
-  async cssNestingExpansionLimit({ esbuild }) {
+  async cssNestingExpansionLimitWithoutIs({ esbuild }) {
     const css = `a,b{a,b{a,b{a,b{a,b{a,b{a,b{a,b{a,b{a,b{a,b{a,b{a,b{a,b{a,b{a,b{a,b{a,b{a,b{a,b{color:red}}}}}}}}}}}}}}}}}}}}`
     try {
       await esbuild.transform(css, { loader: 'css', target: 'safari1' })
       throw new Error('Expected a transform failure')
     } catch (e) {
       assert.strictEqual(e.errors.length, 1)
+      assert.strictEqual(e.errors[0].text, 'CSS nesting is causing too much expansion')
+    }
+  },
+
+  async cssNestingExpansionLimitWithIs({ esbuild }) {
+    const css = `a,b{a,b{a,b{a,b{a,b{a,b{a,b{a,b{a,b{a,b{a,b{a,b{a,b{a,b{a,b{a,b{a,b{a,b{a,b{a,b{color:red}}}}}}}}}}}}}}}}}}}}`
+    try {
+      await esbuild.transform(css, { loader: 'css', target: 'safari14' })
+      throw new Error('Expected a transform failure')
+    } catch (e) {
+      assert.strictEqual(e.errors.length, 1)
       assert.strictEqual(e.errors[0].text, 'CSS nesting is causing too much expansion')
     }
   },
diff -Nru golang-github-evanw-esbuild-0.25.3/scripts/verify-source-map.js golang-github-evanw-esbuild-0.25.5/scripts/verify-source-map.js
--- golang-github-evanw-esbuild-0.25.3/scripts/verify-source-map.js	2025-04-23 05:51:33.000000000 +0200
+++ golang-github-evanw-esbuild-0.25.5/scripts/verify-source-map.js	2025-05-27 05:11:58.000000000 +0200
@@ -749,6 +749,15 @@
   'app-root': 'app.component.ts',
 }
 
+const testCaseDefineWithObjectIssue4169 = {
+  'entry.js': `console.log(OBJECT, ARRAY);`,
+}
+
+const toSearchDefineWithObjectIssue4169 = {
+  'test object': '<define:OBJECT>',
+  'test array': '<define:ARRAY>',
+}
+
 async function check(kind, testCase, toSearch, { outfile, flags, entryPoints, crlf, followUpFlags = [], checkFirstChunk }) {
   let failed = 0
 
@@ -1243,6 +1252,12 @@
           crlf,
           followUpFlags: ['--packages=external'],
         }),
+        check('issue-4169' + suffix, testCaseDefineWithObjectIssue4169, toSearchDefineWithObjectIssue4169, {
+          outfile: 'out.js',
+          flags: flags.concat('--format=esm', '--sourcemap', '--bundle', '--define:OBJECT={"test object":1}', '--define:ARRAY=["test array"]'),
+          entryPoints: ['entry.js'],
+          crlf,
+        }),
 
         // Checks for the "names" field
         checkNames('names' + suffix, testCaseNames, {
diff -Nru golang-github-evanw-esbuild-0.25.3/version.txt golang-github-evanw-esbuild-0.25.5/version.txt
--- golang-github-evanw-esbuild-0.25.3/version.txt	2025-04-23 05:51:33.000000000 +0200
+++ golang-github-evanw-esbuild-0.25.5/version.txt	2025-05-27 05:11:58.000000000 +0200
@@ -1 +1 @@
-0.25.3
+0.25.5

Reply to: