Compare commits

...

52 Commits

Author SHA1 Message Date
Claude Bot
c31f2ef407 fix: track duped PTY master FDs for error cleanup
Add duped master FDs to to_close_on_error list so they are properly
cleaned up if spawn fails after duping.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-03 11:48:18 +00:00
autofix-ci[bot]
064b1d36d1 [autofix.ci] apply automated fixes 2025-12-03 11:37:01 +00:00
Claude Bot
e67ed9de05 fix: clarify Writable.zig PTY comment for Windows
Update comment to clearly state PTY stdin is not supported on Windows
rather than misleadingly mentioning "falls back to pipe".

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-03 11:35:11 +00:00
Claude Bot
021dac5748 fix: address CodeRabbit PTY lifecycle and docs review comments
- Fix PTY master FD leak: close original master FD after spawn succeeds
  since parent uses dup()'d copies for stdio/extra_fds
- Fix PosixSpawnResult.close: correct type signature and add PTY handling
- Harmonize shell PTY behavior: change POSIX stdin panic to return ignore
  (consistent with Windows behavior)
- Update docs: add "Not supported with spawnSync" to PTY table entries
- Update docs: expand TS type comments with platform/spawnSync notes

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-03 11:34:37 +00:00
Claude Bot
bc239627a1 fix: handle PTY case in Writable.zig Windows switch
Add .pty case to the Windows switch statement in Writable.zig.
On Windows, PTY falls back to pipe behavior, so stdin with PTY
returns ignore (same as other unsupported stdin types).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-03 11:21:56 +00:00
Claude Bot
0245de5c78 fix: address CodeRabbit review comments for PTY support
- Fix docs example consistency: use array form consistently
- Add spawnSync warning to TypeScript PTY type definitions
- Fix Windows compile error in js_bun_spawn_bindings.zig
- Fix extra_fds PTY to use dup() for consistency
- Add isNumber() type check for PTY width/height options
- Fix error message consistency in stdio.zig
- Fix switch case overlap in shell/subproc.zig (remove .pipe/.readable_stream that were already handled)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-03 11:11:03 +00:00
autofix-ci[bot]
6d4965c79b [autofix.ci] apply automated fixes 2025-12-03 10:48:11 +00:00
Claude Bot
fff68a0fb1 docs: update PTY docs to say it falls back to pipe on Windows
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-03 10:46:30 +00:00
Claude Bot
74bea006fd feat(spawn): finalize PTY support with docs and tests
- Add comprehensive PTY documentation with examples:
  - Basic usage
  - Multiple PTY streams (stdin/stdout/stderr)
  - Custom terminal dimensions (width/height)
  - Colored output from git, grep, etc.
  - Platform support table
  - Limitations section

- Make PTY fall back to pipe on Windows (instead of error)
- Add spawnSync error for PTY (not supported)
- Add tests for spawnSync PTY error

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-03 10:44:04 +00:00
Claude Bot
5d775066b2 test(spawn): expand PTY test coverage
Add tests for:
- stderr: 'pty' only
- stdin: 'pty' only (stdout/stderr not PTY)
- PTY object syntax with custom width/height dimensions
- ANSI color output detection
- Multiple concurrent PTY spawns
- Windows error handling (skipped on non-Windows)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-03 10:27:26 +00:00
Claude Bot
f773816d02 cleanup: remove unused PTY code, add types and docs
- Remove unused uws import from PipeReader.zig
- Remove unused PTY helper functions (setWinSize, getWinSize, setControllingTerminal)
- Remove unused ioctl constants (TIOCSWINSZ, TIOCSCTTY, TIOCGWINSZ)
- Change spawn_bindings log visibility back to hidden
- Add "pty" to TypeScript types in bun.d.ts
- Add PTY documentation to docs/runtime/child-process.mdx

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-03 10:24:36 +00:00
Claude Bot
ee4ace7159 feat(spawn): add PTY support for stdin, stdout, stderr
Add support for `stdin: "pty"`, `stdout: "pty"`, and `stderr: "pty"` options
in `Bun.spawn()`. This allows spawned processes to see `process.stdout.isTTY === true`.

Key implementation details:
- PTY creation via openpty/forkpty syscalls in sys.zig
- When multiple stdios use PTY, they share the same master FD
- Handle epoll EEXIST gracefully when FD is already registered
- Timer-based polling fallback for shared PTY FDs
- EIO treated as normal EOF when PTY slave closes

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-03 09:08:06 +00:00
Dylan Conway
cc3fc5a1d3 fix ENG-24015 (#25222)
### What does this PR do?
Ensures `ptr` is either a number or heap big int before converting to a
number.

also fixes ENG-24039
### How did you verify your code works?
Added a test
2025-11-29 19:13:32 -08:00
Dylan Conway
d83e0eb1f1 fix ENG-24017 (#25224)
### What does this PR do?
Fixes checking for exceptions when creating empty or used readable
streams

also fixes ENG-24038
### How did you verify your code works?
Added a test for creating empty streams
2025-11-29 19:13:06 -08:00
Dylan Conway
72b9525507 update bunfig telemetry docs (#25237)
### What does this PR do?

### How did you verify your code works?
2025-11-29 19:12:18 -08:00
robobun
0f7494569e fix(console): implement %j format specifier for JSON output (#25195)
## Summary
- Implements the `%j` format specifier for `console.log` and related
console methods
- `%j` outputs the JSON stringified representation of the value
- Previously, `%j` was not recognized and was left as literal text in
the output

## Test plan
- [x] Run `bun bd test test/regression/issue/24234.test.ts` - all 5
tests pass
- [x] Verify tests fail with system Bun (`USE_SYSTEM_BUN=1`) to confirm
fix validity
- [x] Manual verification: `console.log('%j', {foo: 'bar'})` outputs
`{"foo":"bar"}`

## Example

Before (bug):
```
$ bun -e "console.log('%j %s', {foo: 'bar'}, 'hello')"
%j [object Object] hello
```

After (fixed):
```
$ bun -e "console.log('%j %s', {foo: 'bar'}, 'hello')"
{"foo":"bar"} hello
```

Closes #24234

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
2025-11-28 22:57:55 -08:00
Meghan Denny
9fd6b54c10 ci: fix windows git dependencies tests (#25213) 2025-11-28 22:56:54 -08:00
robobun
19acc4dcac fix(buffer): handle string allocation failures in encoding operations (#25214)
## Summary
- Add proper bounds checking for encoding operations that produce larger
output than input
- Handle allocation failures gracefully by returning appropriate errors
- Add defensive checks in string initialization functions

## Test plan
- Added test case for encoding operations with large buffers
- Verified existing buffer tests still pass

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
2025-11-28 22:56:28 -08:00
Meghan Denny
56da7c4fd9 zig: address a VM todo (#23678) 2025-11-28 19:38:26 -08:00
Meghan Denny
5bdb8ec0cb all: update to debian 13 (#24055) [publish images] 2025-11-28 15:01:40 -08:00
Meghan Denny
4cf9b794c9 ci: update buildkite agent to v3.114.0 (#25127) [publish images] 2025-11-28 15:01:20 -08:00
Meghan Denny
998ec54da9 test: fix spacing in sql.test.ts (#24691) 2025-11-28 14:40:58 -08:00
Jarred Sumner
0305f3d4d2 feat(url): implement URLPattern API (#25168)
## Summary

Implements the [URLPattern Web
API](https://developer.mozilla.org/en-US/docs/Web/API/URLPattern) based
on WebKit's implementation. URLPattern provides declarative pattern
matching for URLs, similar to how regular expressions work for strings.

### Features

- **Constructor**: Create patterns from strings or `URLPatternInit`
dictionaries
- **`test()`**: Check if a URL matches the pattern (returns boolean)
- **`exec()`**: Extract matched groups from a URL (returns
`URLPatternResult` or null)
- **Pattern properties**: `protocol`, `username`, `password`,
`hostname`, `port`, `pathname`, `search`, `hash`
- **`hasRegExpGroups`**: Detect if the pattern uses custom regular
expressions

### Example Usage

```js
// Match URLs with a user ID parameter
const pattern = new URLPattern({ pathname: '/users/:id' });

pattern.test('https://example.com/users/123'); // true
pattern.test('https://example.com/posts/456'); // false

const result = pattern.exec('https://example.com/users/123');
console.log(result.pathname.groups.id); // "123"

// Wildcard matching
const filesPattern = new URLPattern({ pathname: '/files/*' });
const match = filesPattern.exec('https://example.com/files/image.png');
console.log(match.pathname.groups[0]); // "image.png"
```

## Implementation Notes

- Adapted from WebKit's URLPattern implementation
- Modified JS bindings to work with Bun's infrastructure (simpler
`convertDictionary` patterns, WTF::Variant handling)
- Added IsoSubspaces for proper GC integration

## Test Plan

- [x] 408 tests from Web Platform Tests pass
- [x] Tests fail with system Bun (URLPattern not defined), pass with
debug build
- [x] Manual testing of basic functionality

Fixes https://github.com/oven-sh/bun/issues/2286

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2025-11-28 00:04:30 -08:00
Henrique Fonseca
1006a4fac2 Fix incorrect file name in React component test example 🌟 (#25167)
# What does this PR do?

Nyaa~ This PR fixes a small mistake in the documentation where the code
block for a React component test example was using the wrong filename!
(;ω;)💦

It was previously labeled as `matchers.d.ts`, but it should be something
like `myComponent.test.tsx` to properly reflect a test file for a React
component using `@testing-library/react`. 🧁

This makes the example clearer and more accurate for developers using
Bun to test their React components~! 💻🌸💕

# How did you verify your code works?

It's just docs, one single line 🥺

Pwease review and merge it when you can, senpai~~! UwU 🌈🫧
2025-11-27 23:15:34 -08:00
Michael H
c7f7d9bb82 run fmt (#25148)
prettier released a new update which seems to have changed a few
logistics
2025-11-28 17:51:45 +11:00
robobun
37bce389a0 docs: document inlining process.env.* values in static HTML bundling (#25084)
## Summary

- Add documentation for the `env` option that inlines `process.env.*`
values in frontend code when bundling HTML files
- Document runtime configuration via `bunfig.toml` `[serve.static]`
section for `bun ./index.html`
- Document production build configuration via CLI (`--env=PUBLIC_*`) and
`Bun.build` API (`env: "PUBLIC_*"`)
- Explain prefix filtering to avoid exposing sensitive environment
variables

## Test plan

- [x] Verify documentation renders correctly in local preview
- [x] Cross-reference with existing `env` documentation in
bundler/index.mdx

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Michael H <git@riskymh.dev>
Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2025-11-28 17:51:11 +11:00
robobun
bab583497c fix(cli): correct --dry-run help text for bun publish (#25137)
## Summary
- Fix `bun publish --help` showing incorrect `--dry-run` description
("Don't install anything" → "Perform a dry run without making changes")
- The `--dry-run` flag is in a shared params array used by multiple
commands, so the new generic message works for all of them

Fixes #24806

## Test plan
- [x] Verify `bun publish --help` shows "Perform a dry run without
making changes" for --dry-run
- [x] Regression test added that validates the correct help text is
shown
- [x] Test passes with debug build, fails with system bun (validating it
tests the right thing)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2025-11-27 18:12:07 -08:00
robobun
a83fceafc7 fix(http2): return server from setTimeout for method chaining (#25138)
## Summary
- Make `Http2Server.setTimeout()` and `Http2SecureServer.setTimeout()`
return `this` to enable method chaining
- Matches Node.js behavior where `server.setTimeout(1000).listen()`
works

Fixes #24924

## Test plan
- [x] Test that `Http2Server.setTimeout()` returns server instance
- [x] Test that `Http2SecureServer.setTimeout()` returns server instance
- [x] Test method chaining works (e.g.,
`server.setTimeout(1000).close()`)
- [x] Tests pass with debug build, fail with system bun

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2025-11-27 16:46:15 -08:00
robobun
ef8eef3df8 fix(http): stricter validation in chunked encoding parser (#25159)
## Summary
- Adds stricter validation for chunk boundaries in the HTTP chunked
transfer encoding parser
- Ensures conformance with RFC 9112 requirements for chunk formatting
- Adds additional test coverage for chunked encoding edge cases

## Test plan
- Added new tests in `test/js/bun/http/request-smuggling.test.ts`
- All existing HTTP tests pass
- `bun bd test test/js/bun/http/request-smuggling.test.ts` passes

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
2025-11-27 16:29:35 -08:00
robobun
69b571da41 Delete claude.yml workflow (#25157) 2025-11-27 12:26:50 -08:00
robobun
908ab9ce30 feat(fetch): add proxy object format with headers support (#25090)
## Summary

- Extends `fetch()` proxy option to accept an object format: `proxy: {
url: string, headers?: Headers }`
- Allows sending custom headers to the proxy server (useful for proxy
authentication, custom routing headers, etc.)
- Headers are sent in CONNECT requests (for HTTPS targets) and direct
proxy requests (for HTTP targets)
- User-provided `Proxy-Authorization` header overrides auto-generated
credentials from URL

## Usage

```typescript
// Old format (still works)
fetch(url, { proxy: "http://proxy.example.com:8080" });

// New object format with headers
fetch(url, {
  proxy: {
    url: "http://proxy.example.com:8080",
    headers: {
      "Proxy-Authorization": "Bearer token",
      "X-Custom-Proxy-Header": "value"
    }
  }
});
```

## Test plan

- [x] Test proxy object with url string works same as string proxy
- [x] Test proxy object with headers sends headers to proxy (HTTP
target)
- [x] Test proxy object with headers sends headers in CONNECT request
(HTTPS target)
- [x] Test proxy object with Headers instance
- [x] Test proxy object with empty headers
- [x] Test proxy object with undefined headers
- [x] Test user-provided Proxy-Authorization overrides URL credentials
- [x] All existing proxy tests pass (25 total)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
2025-11-26 15:11:45 -08:00
robobun
43c46b1f77 fix(FormData): throw error instead of assertion failure on very large input (#25006)
## Summary

- Fix crash in `FormData.from()` when called with very large ArrayBuffer
input
- Add length check in C++ `toString` function against both Bun's
synthetic limit and WebKit's `String::MaxLength`
- For UTF-8 tagged strings, use simdutf to calculate actual UTF-16
length only when byte length exceeds the limit

## Root Cause

When `FormData.from()` was called with a very large ArrayBuffer (e.g.,
`new Uint32Array(913148244)` = ~3.6GB), the code would crash with:

```
ASSERTION FAILED: data.size() <= MaxLength
vendor/WebKit/Source/WTF/wtf/text/StringImpl.h(886)
```

The `toString()` function in `helpers.h` was only checking against
`Bun__stringSyntheticAllocationLimit` (which defaults to ~4GB), but not
against WebKit's `String::MaxLength` (INT32_MAX, ~2GB). When the input
exceeded `String::MaxLength`, `createWithoutCopying()` would fail with
an assertion.

## Changes

1. **helpers.h**: Added `|| str.len > WTF::String::MaxLength` checks to
all three code paths in `toString()`:
- UTF-8 tagged pointer path (with simdutf length calculation only when
needed)
   - External pointer path
   - Non-copying creation path

2. **url.zig**: Reverted the incorrect Zig-side check (UTF-8 byte length
!= UTF-16 character length)

## Test plan

- [x] Added test that verifies FormData.from with oversized input
doesn't crash
- [x] Verified original crash case now returns empty FormData instead of
crashing:
  ```js
  const v3 = new Uint32Array(913148244);
  FormData.from(v3); // No longer crashes
  ```

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Jarred Sumner <jarred@jarredsumner.com>
2025-11-26 13:46:08 -08:00
robobun
a0c5f3dc69 fix(mmap): use coerceToInt64 for offset/size to prevent assertion failure (#25101)
## Summary

- Fix assertion failure in `Bun.mmap` when `offset` or `size` options
are non-numeric values
- Add validation to reject negative `offset`/`size` with clear error
messages

Minimal reproduction: `Bun.mmap("", { offset: null });`

## Root Cause

`Bun.mmap` was calling `toInt64()` directly on the `offset` and `size`
options without validating they are numbers first. `toInt64()` has an
assertion that the value must be a number or BigInt, which fails when
non-numeric values like `null` or functions are passed.

## Test plan

- [x] Added tests for negative offset/size rejection
- [x] Added tests for non-number inputs (null, undefined)
- [x] `bun bd test test/js/bun/util/mmap.test.js` passes

Closes ENG-22413

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
2025-11-26 13:37:41 -08:00
robobun
5965ff18ea fix(test): fix assertion failure in expect.extend with non-JSFunction callables (#25099)
## Summary

- Fix debug assertion failure in `JSWrappingFunction` when
`expect.extend()` is called with objects containing non-`JSFunction`
callables
- The crash occurred because `jsCast<JSFunction*>` was used, which
asserts the value inherits from `JSFunction`, but callable class
constructors (like `Expect`) inherit from `InternalFunction` instead

## Changes

- Change `JSWrappingFunction` to store `JSObject*` instead of
`JSFunction*`
- Use `jsDynamicCast` instead of `jsCast` in `getWrappedFunction`
- Use `getObject()` instead of `jsCast` in `create()`

## Reproduction

```js
const jest = Bun.jest();
jest.expect.extend(jest);
```

Before fix (debug build):
```
ASSERTION FAILED: !from || from->JSCell::inherits(std::remove_pointer<To>::type::info())
JSCast.h(40) : To JSC::jsCast(From *) [To = JSC::JSFunction *, From = JSC::JSCell]
```

After fix: Properly throws `TypeError: expect.extend: 'jest' is not a
valid matcher`

## Test plan

- [x] Added regression test
`test/regression/issue/fuzzer-ENG-22942.test.ts`
- [x] Existing `expect-extend.test.js` tests pass (27 tests)
- [x] Build succeeds

Fixes ENG-22942

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
2025-11-26 13:34:02 -08:00
robobun
44f2328111 fix(fs.access): handle Windows device paths correctly (#25023)
## Summary

Fixes #23292

`fs.access()` and `fs.accessSync()` threw EUNKNOWN (-134) when checking
named pipes on Windows (paths like `\.\pipe\name`), but Node.js worked
fine.

**Repro:**
```ts
// Server creates pipe at \.\pipe\bun-test
import net from 'net';
const server = net.createServer();
server.listen('\\.\pipe\bun-test');

// Client tries to check if pipe exists
import fs from 'fs';
fs.accessSync('\\.\pipe\bun-test', fs.constants.F_OK);
// Error: EUNKNOWN: unknown error, access '\.\pipe\bun-test'
```

## Root Cause

The `osPathKernel32` function normalizes paths before passing to Windows
APIs. The normalization logic treats a single `.` as a "current
directory" component and removes it, so `\.\pipe\name` incorrectly
became `\pipe\name` - an invalid path.

## Solution

Detect Windows device paths (starting with `\.\` or `\?\`) and skip
normalization for these special paths, preserving the device prefix.

## Test Plan

- [x] Added regression test `test/regression/issue/23292.test.ts`
- [x] Test fails with system bun (v1.3.3): 3 failures (EUNKNOWN)
- [x] Test passes with fix: 4 pass

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2025-11-26 00:07:51 -08:00
robobun
85e0a723f3 Add analytics tracking for CPU profiling and heap snapshots (#25053)
## Summary

- Add `cpu_profile` and `heap_snapshot` counters to `Analytics.Features`
- Export `heap_snapshot` to C++ as `Bun__Feature__heap_snapshot`
- Increment `cpu_profile` when `--cpu-prof` flag is used
- Increment `heap_snapshot` in all heap snapshot creation locations:
  - `Bun.generateHeapSnapshot()`
  - `bun:jsc` `generateHeapSnapshotForDebugging()`
  - `console.takeHeapSnapshot()`
  - Internal `JSC__JSGlobalObject__generateHeapSnapshot()`

## Test plan

- [x] Build succeeds
- [x] Heap snapshot generation works
- [x] CPU profiling works with `--cpu-prof`
- [x] Existing tests pass: `test/js/bun/util/v8-heap-snapshot.test.ts`
- [x] Existing tests pass: `test/cli/run/cpu-prof.test.ts`

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
2025-11-26 00:02:43 -08:00
robobun
d50c5a385f Add analytics tracking for HTTP client proxy usage (#25056)
## Summary
- Added `http_client_proxy` counter to `analytics.Features` struct
- Incremented counter in `ProxyTunnel.onOpen()` when proxy tunnel
connection opens successfully

This allows tracking HTTP client proxy usage in analytics/crash reports
alongside other features like `fetch`, `WebSocket`, `http_server`, etc.

## Test plan
- [x] Build completes successfully (`bun bd`)
- [x] Existing proxy tests pass (`bun bd test
test/js/bun/http/proxy.test.ts`)
- [x] Counter is properly integrated into the analytics framework

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
2025-11-26 00:02:26 -08:00
Jarred Sumner
bb7641b3b0 fix: use GC-safe operations when populating error stack traces (#25096)
## Summary
- Adds `FinalizerSafety` enum to control whether `functionName` uses
GC-safe operations when iterating over stack traces
- Uses the enum in `populateStackFrameMetadata` to choose between the
richer callee-based path vs the GC-safe path
- Updates call sites in `ZigException.cpp` and
`FormatStackTraceForJS.cpp`

Fixes https://github.com/oven-sh/bun/issues/25094
Fixes https://github.com/oven-sh/bun/issues/20399
Fixes https://github.com/oven-sh/bun/issues/22662

## Test plan
- [ ] Add regression test

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude <noreply@anthropic.com>
2025-11-25 23:55:41 -08:00
Meghan Denny
22f4dfae7c ci: fix release step
don't try to release freebsd yet
2025-11-25 22:27:02 -08:00
Meghan Denny
9fce97bac3 scripts: add freebsd support to bootstrap.sh (#24534) 2025-11-25 17:16:38 -08:00
Dylan Conway
2fb3aa8991 update minimumReleaseAge (#25057)
### What does this PR do?

### How did you verify your code works?
2025-11-25 11:06:24 -08:00
robobun
dc25d66b00 fix(Buffer): improve input validation in *Write methods (#25011)
## Summary
Improve bounds checking logic in Buffer.*Write methods (utf8Write,
base64urlWrite, etc.) to properly handle edge cases with non-numeric
offset and length arguments, matching Node.js behavior.

## Changes
- Handle non-numeric offset by converting to integer (treating invalid
values as 0)
- Clamp length to available buffer space instead of throwing
- Reorder operations to check buffer state after argument conversion

## Node.js Compatibility

This matches Node.js's C++ implementation in `node_buffer.cc`:

**Offset handling via `ParseArrayIndex`**
([node_buffer.cc:211-234](https://github.com/nodejs/node/blob/main/src/node_buffer.cc#L211-L234)):
```cpp
inline MUST_USE_RESULT Maybe<bool> ParseArrayIndex(Environment* env,
                                                   Local<Value> arg,
                                                   size_t def,
                                                   size_t* ret) {
  if (arg->IsUndefined()) {
    *ret = def;
    return Just(true);
  }

  int64_t tmp_i;
  if (!arg->IntegerValue(env->context()).To(&tmp_i))
    return Nothing<bool>();
  // ...
}
```
V8's `IntegerValue` converts non-numeric values (including NaN) to 0.

**Length clamping in `SlowWriteString`**
([node_buffer.cc:1498-1502](https://github.com/nodejs/node/blob/main/src/node_buffer.cc#L1498-L1502)):
```cpp
THROW_AND_RETURN_IF_OOB(ParseArrayIndex(env, args[2], 0, &offset));
THROW_AND_RETURN_IF_OOB(
    ParseArrayIndex(env, args[3], ts_obj_length - offset, &max_length));

max_length = std::min(ts_obj_length - offset, max_length);
```
Node.js clamps `max_length` to available buffer space rather than
throwing.

## Test plan
- Added regression tests for all `*Write` methods verifying proper
handling of edge cases
- Verified behavior matches Node.js
- All 447 buffer tests pass

fixes ENG-21985, fixes ENG-21863, fixes ENG-21751, fixes ENG-21984

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
2025-11-24 23:34:36 -08:00
robobun
ae29340708 fix: prevent calling class constructors marked with call: false (#25047)
## Summary

Fixes a crash (ENG-22243) where calling class constructors marked with
`call: false` would create invalid instances instead of throwing an
error.

## Root Cause

When a class definition has `call: false` (like `Bun.RedisClient`), the
code generator was still allowing the constructor to be invoked without
`new`. This created invalid instances that caused a buffer overflow
during garbage collection.

## The Fix

Modified `src/codegen/generate-classes.ts` to properly check the `call`
property:
- When `call: false`: throws `TypeError: Class constructor X cannot be
invoked without 'new'`
- When `call: true`: behaves as before, allowing construction without
`new`

## Test Plan

- [x] Added regression test in `test/regression/issue/22243.test.ts`
- [x] Test fails with system bun (has the bug)
- [x] Test passes with fixed build
- [x] Verified `Bun.RedisClient()` now throws proper error
- [x] Verified `new Bun.RedisClient()` still works

## Before

```bash
$ bun -e "Bun.RedisClient()"
# Creates invalid instance, no error
```

## After

```bash
$ bun -e "Bun.RedisClient()"
TypeError: Class constructor RedisClient cannot be invoked without 'new'
```

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
2025-11-24 23:34:16 -08:00
robobun
123ac9dc2d chore: disable comment-lint and labeled workflows (#25059)
## Summary
- Disable `comment-lint.yml` (C++ linter comment workflow)
- Disable `labeled.yml` (Issue/PR labeled automation workflow)

Workflows are disabled by renaming them to `.yml.disabled`.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
2025-11-24 21:15:57 -08:00
Marko Vejnovic
48617563b5 ENG-21534: Satisfy aikido (#24880)
### What does this PR do?

- Bumps some packages
- Does some _best practices_ in certain areas to minimize Aikido noise.

### How did you verify your code works?

CI.

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2025-11-24 20:16:03 -08:00
robobun
cc393e43f2 fix(test): use putDirectMayBeIndex in spyOn for indexed property keys (#25020)
## Summary
- Fix `spyOn` crash when using indexed property keys (e.g., `spyOn(arr,
0)`)

## Test plan
- [x] Added tests for `spyOn` with numeric indexed properties
- [x] Added tests for `spyOn` with string indexed properties (e.g.,
`"0"`)
- [x] All existing `spyOn` tests pass
- [x] Full `mock-fn.test.js` test suite passes

Fixes ENG-21973

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
2025-11-24 19:27:33 -08:00
robobun
3f0681996f fix(indexOfLine): properly coerce non-number offset argument (#25021)
## Summary
- Fix assertion failure when `Bun.indexOfLine` is called with a
non-number offset argument
- Changed from `.to(u32)` to `.coerce(i32, globalThis)` for proper
JavaScript type coercion

## Test plan
- [x] Added regression test in `test/js/bun/util/index-of-line.test.ts`
- [x] `bun bd test test/js/bun/util/index-of-line.test.ts` passes

Closes ENG-21997

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Jarred Sumner <jarred@jarredsumner.com>
2025-11-24 19:27:14 -08:00
robobun
e14d5593c5 fix(install): use >= instead of > for resolution bounds check (#25028)
## Summary

- Fix off-by-one error in `preprocessUpdateRequests` where the bounds
check used `>` instead of `>=` when validating package IDs from the
resolution buffer
- When `old_resolution == packages.len`, the check `> packages.len`
passes but `resolutions_of_yore[old_resolution]` is out of bounds since
valid indices are `0` to `packages.len-1`
- This causes an internal assertion failure during `bun install` with
update requests

## The Bug

```zig
// BEFORE (buggy) - at lockfile.zig:484 and :522
if (old_resolution > old.packages.len) continue;
const res = resolutions_of_yore[old_resolution];  // OOB when old_resolution == packages.len

// AFTER (fixed)
if (old_resolution >= old.packages.len) continue;
const res = resolutions_of_yore[old_resolution];  // Now safe
```

## Crash Report

From
[bun.report](https://bun.report/1.3.3/wi1274e01cAggkggB+rt/F+pvBiw3rDqul/Doyi4Emzi5Ewj44FuvbgjMog00yDCYKERNEL32.DLLut0LCSntdll.dll4zijBA0eNrzzCtJLcpLzFFILC5OLSrJzM9TSEvMzCktSgUAiSkKPg/view):

```
panic: Internal assertion failure
- lockfile.zig:523: preprocessUpdateRequests
- install_with_manager.zig:605: installWithManager
- updatePackageJSONAndInstall.zig:340
Features: extracted_packages, text_lockfile
```

## Test plan

- [x] `bun run zig:check` passes
- [ ] CI passes

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
2025-11-24 19:22:45 -08:00
taylor.fish
7335cb747b Fix conversions from JSValue to FFI pointer (#25045)
Fixes this issue, where two identical JS numbers could become two
different FFI pointers:

```c
// gcc -fpic -shared -o main.so
#include <stdio.h>

void* getPtr(void) {
    return (void*)123;
}

void printPtr(void* ptr) {
    printf("%zu\n", (size_t)ptr);
}
```

```js
import { dlopen, FFIType } from "bun:ffi";

const lib = dlopen("./main.so", {
  getPtr: { args: [], returns: FFIType.ptr },
  printPtr: { args: [FFIType.ptr], returns: FFIType.void },
});

const ptr = lib.symbols.getPtr();
console.log(`${typeof ptr} ${ptr}`);

const ptr2 = Number(String(ptr));
console.log(`${typeof ptr2} ${ptr2}`);

console.log(`pointers equal? ${ptr === ptr2}`);
lib.symbols.printPtr(ptr);
lib.symbols.printPtr(ptr2);
```

```console
$ bun main.js
number 123
number 123
pointers equal? true
123
18446744073709551615
```

Fixes #20072

(For internal tracking: fixes ENG-22327)
2025-11-24 17:34:39 -08:00
Marko Vejnovic
9c8575f975 bug(#19588): Fix undici bindings overflow (#25046)
### What does this PR do?

- Fixes an overflow that happened in the undici bindings generator.
- Establishes a pattern using `std::tuple` so this doesn't happen again.

Fixes:

-
https://bun-p9.sentry.io/issues/6597708115/?query=createUndiciInternalBinding&referrer=issue-stream
- https://github.com/oven-sh/bun/issues/19588

### How did you verify your code works?

CI.

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2025-11-24 17:31:11 -08:00
robobun
0da132ef6d fix(test): skip grpc-js resolver tests that use unavailable domain (#25039)
## Summary

- Skip 2 tests that use `grpctest.kleinsch.com` (domain no longer
exists)
- Fix flaky "should not keep repeating failed resolutions" test

These tests were originally skipped when added in #14286, but were
accidentally un-skipped in #20051. This restores them to match upstream
grpc-node.

## To re-enable these tests in the future

Bun could set up its own DNS TXT record at `*.bun.sh`. According to the
[gRPC A2
spec](https://github.com/grpc/proposal/blob/master/A2-service-configs-in-dns.md):

**DNS Setup needed:**
1. A record: `grpctest.bun.sh` → any valid IP (e.g., `127.0.0.1`)
2. TXT record: `_grpc_config.grpctest.bun.sh` with value:
   ```

grpc_config=[{"serviceConfig":{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"service":"MyService","method":"Foo"}],"waitForReady":true}]}}]
   ```

Then update the tests to use `grpctest.bun.sh` instead.

## Test plan

- [x] `bun bd test test/js/third_party/grpc-js/test-resolver.test.ts`
passes (20 pass, 3 skip, 1 todo, 0 fail)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
2025-11-24 10:34:26 -08:00
Jarred Sumner
0d863ba237 Don't use globalThis.takeException when rejecting Promise values (#24986)
### What does this PR do?

We can't use globalThis.takeException() because it throws out of memory
error when we instead need to take the exception.

### How did you verify your code works?
2025-11-23 20:27:15 -08:00
153 changed files with 11821 additions and 1689 deletions

View File

@@ -31,7 +31,7 @@ import {
} from "../scripts/utils.mjs";
/**
* @typedef {"linux" | "darwin" | "windows"} Os
* @typedef {"linux" | "darwin" | "windows" | "freebsd"} Os
* @typedef {"aarch64" | "x64"} Arch
* @typedef {"musl"} Abi
* @typedef {"debian" | "ubuntu" | "alpine" | "amazonlinux"} Distro
@@ -114,6 +114,7 @@ const buildPlatforms = [
{ os: "linux", arch: "x64", abi: "musl", baseline: true, distro: "alpine", release: "3.22" },
{ os: "windows", arch: "x64", release: "2019" },
{ os: "windows", arch: "x64", baseline: true, release: "2019" },
{ os: "freebsd", arch: "x64", release: "14.3" },
];
/**
@@ -124,10 +125,10 @@ const testPlatforms = [
{ os: "darwin", arch: "aarch64", release: "13", tier: "previous" },
{ os: "darwin", arch: "x64", release: "14", tier: "latest" },
{ os: "darwin", arch: "x64", release: "13", tier: "previous" },
{ os: "linux", arch: "aarch64", distro: "debian", release: "12", tier: "latest" },
{ os: "linux", arch: "x64", distro: "debian", release: "12", tier: "latest" },
{ os: "linux", arch: "x64", baseline: true, distro: "debian", release: "12", tier: "latest" },
{ os: "linux", arch: "x64", profile: "asan", distro: "debian", release: "12", tier: "latest" },
{ os: "linux", arch: "aarch64", distro: "debian", release: "13", tier: "latest" },
{ os: "linux", arch: "x64", distro: "debian", release: "13", tier: "latest" },
{ os: "linux", arch: "x64", baseline: true, distro: "debian", release: "13", tier: "latest" },
{ os: "linux", arch: "x64", profile: "asan", distro: "debian", release: "13", tier: "latest" },
{ os: "linux", arch: "aarch64", distro: "ubuntu", release: "25.04", tier: "latest" },
{ os: "linux", arch: "aarch64", distro: "ubuntu", release: "24.04", tier: "latest" },
{ os: "linux", arch: "x64", distro: "ubuntu", release: "25.04", tier: "latest" },
@@ -659,7 +660,7 @@ function getReleaseStep(buildPlatforms, options) {
agents: {
queue: "test-darwin",
},
depends_on: buildPlatforms.map(platform => `${getTargetKey(platform)}-build-bun`),
depends_on: buildPlatforms.filter(p => p.os !== "freebsd").map(platform => `${getTargetKey(platform)}-build-bun`),
env: {
CANARY: revision,
},
@@ -1072,7 +1073,7 @@ async function getPipeline(options = {}) {
const imagePlatforms = new Map(
buildImages || publishImages
? [...buildPlatforms, ...testPlatforms]
.filter(({ os }) => os === "linux" || os === "windows")
.filter(({ os }) => os !== "darwin")
.map(platform => [getImageKey(platform), platform])
: [],
);
@@ -1106,10 +1107,13 @@ async function getPipeline(options = {}) {
const includeASAN = !isMainBranch();
if (!buildId) {
const relevantBuildPlatforms = includeASAN
let relevantBuildPlatforms = includeASAN
? buildPlatforms
: buildPlatforms.filter(({ profile }) => profile !== "asan");
// run build-image but no build-bun yet
relevantBuildPlatforms = relevantBuildPlatforms.filter(({ os }) => os !== "freebsd");
steps.push(
...relevantBuildPlatforms.map(target => {
const imageKey = getImageKey(target);

View File

@@ -1,66 +0,0 @@
name: Claude Code
on:
issue_comment:
types: [created]
pull_request_review_comment:
types: [created]
issues:
types: [opened, assigned]
pull_request_review:
types: [submitted]
jobs:
claude:
if: |
github.repository == 'oven-sh/bun' &&
(
(github.event_name == 'issue_comment' && (github.event.comment.author_association == 'MEMBER' || github.event.comment.author_association == 'OWNER' || github.event.comment.author_association == 'COLLABORATOR')) ||
(github.event_name == 'pull_request_review_comment' && (github.event.comment.author_association == 'MEMBER' || github.event.comment.author_association == 'OWNER' || github.event.comment.author_association == 'COLLABORATOR')) ||
(github.event_name == 'pull_request_review' && (github.event.review.author_association == 'MEMBER' || github.event.review.author_association == 'OWNER' || github.event.review.author_association == 'COLLABORATOR')) ||
(github.event_name == 'issues' && (github.event.issue.author_association == 'MEMBER' || github.event.issue.author_association == 'OWNER' || github.event.issue.author_association == 'COLLABORATOR'))
) &&
(github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) ||
(github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude')) ||
(github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude')) ||
(github.event_name == 'issues' && (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude')))
runs-on: claude
env:
IS_SANDBOX: 1
container:
image: localhost:5000/claude-bun:latest
options: --privileged --user 1000:1000
permissions:
contents: read
id-token: write
steps:
- name: Checkout repository
working-directory: /workspace/bun
run: |
git config --global user.email "claude-bot@bun.sh" && \
git config --global user.name "Claude Bot" && \
git config --global url."git@github.com:".insteadOf "https://github.com/" && \
git config --global url."git@github.com:".insteadOf "http://github.com/" && \
git config --global --add safe.directory /workspace/bun && \
git config --global push.default current && \
git config --global pull.rebase true && \
git config --global init.defaultBranch main && \
git config --global core.editor "vim" && \
git config --global color.ui auto && \
git config --global fetch.prune true && \
git config --global diff.colorMoved zebra && \
git config --global merge.conflictStyle diff3 && \
git config --global rerere.enabled true && \
git config --global core.autocrlf input
git fetch origin ${{ github.event.pull_request.head.sha }}
git checkout ${{ github.event.pull_request.head.ref }}
git reset --hard origin/${{ github.event.pull_request.head.ref }}
- name: Run Claude Code
id: claude
uses: anthropics/claude-code-action@v1
with:
timeout_minutes: "180"
claude_args: |
--dangerously-skip-permissions
--system-prompt "You are working on the Bun codebase"
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}

16
.vscode/settings.json vendored
View File

@@ -27,18 +27,22 @@
"git.ignoreLimitWarning": true,
// Zig
"zig.initialSetupDone": true,
"zig.buildOption": "build",
// "zig.initialSetupDone": true,
// "zig.buildOption": "build",
"zig.zls.zigLibPath": "${workspaceFolder}/vendor/zig/lib",
"zig.buildArgs": ["-Dgenerated-code=./build/debug/codegen", "--watch", "-fincremental"],
"zig.zls.buildOnSaveStep": "check",
"zig.buildOnSaveArgs": [
"-Dgenerated-code=./build/debug/codegen",
"--watch",
"-fincremental"
],
// "zig.zls.buildOnSaveStep": "check",
// "zig.zls.enableBuildOnSave": true,
// "zig.buildOnSave": true,
"zig.buildFilePath": "${workspaceFolder}/build.zig",
// "zig.buildFilePath": "${workspaceFolder}/build.zig",
"zig.path": "${workspaceFolder}/vendor/zig/zig.exe",
"zig.zls.path": "${workspaceFolder}/vendor/zig/zls.exe",
"zig.formattingProvider": "zls",
"zig.zls.enableInlayHints": false,
// "zig.zls.enableInlayHints": false,
"[zig]": {
"editor.tabSize": 4,
"editor.useTabStops": false,

View File

@@ -0,0 +1,48 @@
import { bench, group, run } from "../runner.mjs";
const patterns = [
{ name: "string pattern", input: "https://(sub.)?example(.com/)foo" },
{ name: "hostname IDN", input: { hostname: "xn--caf-dma.com" } },
{
name: "pathname + search + hash + baseURL",
input: {
pathname: "/foo",
search: "bar",
hash: "baz",
baseURL: "https://example.com:8080",
},
},
{ name: "pathname with regex", input: { pathname: "/([[a-z]--a])" } },
{ name: "named groups", input: { pathname: "/users/:id/posts/:postId" } },
{ name: "wildcard", input: { pathname: "/files/*" } },
];
const testURL = "https://sub.example.com/foo";
group("URLPattern parse (constructor)", () => {
for (const { name, input } of patterns) {
bench(name, () => {
return new URLPattern(input);
});
}
});
group("URLPattern.test()", () => {
for (const { name, input } of patterns) {
const pattern = new URLPattern(input);
bench(name, () => {
return pattern.test(testURL);
});
}
});
group("URLPattern.exec()", () => {
for (const { name, input } of patterns) {
const pattern = new URLPattern(input);
bench(name, () => {
return pattern.exec(testURL);
});
}
});
await run();

View File

@@ -1,6 +1,6 @@
{
"lockfileVersion": 1,
"configVersion": 0,
"configVersion": 1,
"workspaces": {
"": {
"name": "bun",
@@ -85,13 +85,13 @@
"@esbuild/win32-x64": ["@esbuild/win32-x64@0.21.5", "", { "os": "win32", "cpu": "x64" }, "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw=="],
"@lezer/common": ["@lezer/common@1.2.3", "", {}, "sha512-w7ojc8ejBqr2REPsWxJjrMFsA/ysDCFICn8zEOR9mrqzOu2amhITYuLD8ag6XZf0CFXDrhKqw7+tW8cX66NaDA=="],
"@lezer/common": ["@lezer/common@1.3.0", "", {}, "sha512-L9X8uHCYU310o99L3/MpJKYxPzXPOS7S0NmBaM7UO/x2Kb2WbmMLSkfvdr1KxRIFYOpbY0Jhn7CfLSUDzL8arQ=="],
"@lezer/cpp": ["@lezer/cpp@1.1.3", "", { "dependencies": { "@lezer/common": "^1.2.0", "@lezer/highlight": "^1.0.0", "@lezer/lr": "^1.0.0" } }, "sha512-ykYvuFQKGsRi6IcE+/hCSGUhb/I4WPjd3ELhEblm2wS2cOznDFzO+ubK2c+ioysOnlZ3EduV+MVQFCPzAIoY3w=="],
"@lezer/highlight": ["@lezer/highlight@1.2.1", "", { "dependencies": { "@lezer/common": "^1.0.0" } }, "sha512-Z5duk4RN/3zuVO7Jq0pGLJ3qynpxUVsh7IbUbGj88+uV2ApSAn6kWg2au3iJb+0Zi7kKtqffIESgNcRXWZWmSA=="],
"@lezer/highlight": ["@lezer/highlight@1.2.3", "", { "dependencies": { "@lezer/common": "^1.3.0" } }, "sha512-qXdH7UqTvGfdVBINrgKhDsVTJTxactNNxLk7+UMwZhU13lMHaOBlJe9Vqp907ya56Y3+ed2tlqzys7jDkTmW0g=="],
"@lezer/lr": ["@lezer/lr@1.4.2", "", { "dependencies": { "@lezer/common": "^1.0.0" } }, "sha512-pu0K1jCIdnQ12aWNaAVU5bzi7Bd1w54J3ECgANPmYLtQKP0HBj2cE/5coBD66MT10xbtIuUr7tg0Shbsvk0mDA=="],
"@lezer/lr": ["@lezer/lr@1.4.3", "", { "dependencies": { "@lezer/common": "^1.0.0" } }, "sha512-yenN5SqAxAPv/qMnpWW0AT7l+SxVrgG+u0tNsRQWqbrz66HIl8DnEbBObvy21J5K7+I1v7gsAnlE2VQ5yYVSeA=="],
"@octokit/app": ["@octokit/app@14.1.0", "", { "dependencies": { "@octokit/auth-app": "^6.0.0", "@octokit/auth-unauthenticated": "^5.0.0", "@octokit/core": "^5.0.0", "@octokit/oauth-app": "^6.0.0", "@octokit/plugin-paginate-rest": "^9.0.0", "@octokit/types": "^12.0.0", "@octokit/webhooks": "^12.0.4" } }, "sha512-g3uEsGOQCBl1+W1rgfwoRFUIR6PtvB2T1E4RpygeUU5LrLvlOqcxrt5lfykIeRpUPpupreGJUYl70fqMDXdTpw=="],
@@ -145,7 +145,7 @@
"@sentry/types": ["@sentry/types@7.120.4", "", {}, "sha512-cUq2hSSe6/qrU6oZsEP4InMI5VVdD86aypE+ENrQ6eZEVLTCYm1w6XhW1NvIu3UuWh7gZec4a9J7AFpYxki88Q=="],
"@types/aws-lambda": ["@types/aws-lambda@8.10.152", "", {}, "sha512-soT/c2gYBnT5ygwiHPmd9a1bftj462NWVk2tKCc1PYHSIacB2UwbTS2zYG4jzag1mRDuzg/OjtxQjQ2NKRB6Rw=="],
"@types/aws-lambda": ["@types/aws-lambda@8.10.159", "", {}, "sha512-SAP22WSGNN12OQ8PlCzGzRCZ7QDCwI85dQZbmpz7+mAk+L7j+wI7qnvmdKh+o7A5LaOp6QnOZ2NJphAZQTTHQg=="],
"@types/btoa-lite": ["@types/btoa-lite@1.0.2", "", {}, "sha512-ZYbcE2x7yrvNFJiU7xJGrpF/ihpkM7zKgw8bha3LNJSesvTtUNxbpzaT7WXBIryf6jovisrxTBvymxMeLLj1Mg=="],
@@ -155,7 +155,7 @@
"@types/ms": ["@types/ms@2.1.0", "", {}, "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA=="],
"@types/node": ["@types/node@24.2.1", "", { "dependencies": { "undici-types": "~7.10.0" } }, "sha512-DRh5K+ka5eJic8CjH7td8QpYEV6Zo10gfRkjHCO3weqZHWDtAaSTFtl4+VMqOJ4N5jcuhZ9/l+yy8rVgw7BQeQ=="],
"@types/node": ["@types/node@24.10.1", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-GNWcUTRBgIRJD5zj+Tq0fKOJ5XZajIiBroOF0yvj2bSU1WvNdYS/dn9UxwsujGW4JX06dnHyjV2y9rRaybH0iQ=="],
"aggregate-error": ["aggregate-error@3.1.0", "", { "dependencies": { "clean-stack": "^2.0.0", "indent-string": "^4.0.0" } }, "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA=="],
@@ -187,7 +187,7 @@
"deprecation": ["deprecation@2.3.1", "", {}, "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ=="],
"detect-libc": ["detect-libc@2.0.4", "", {}, "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA=="],
"detect-libc": ["detect-libc@2.1.2", "", {}, "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ=="],
"dot-case": ["dot-case@3.0.4", "", { "dependencies": { "no-case": "^3.0.4", "tslib": "^2.0.3" } }, "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w=="],
@@ -211,27 +211,29 @@
"jws": ["jws@3.2.2", "", { "dependencies": { "jwa": "^1.4.1", "safe-buffer": "^5.0.1" } }, "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA=="],
"lightningcss": ["lightningcss@1.30.1", "", { "dependencies": { "detect-libc": "^2.0.3" }, "optionalDependencies": { "lightningcss-darwin-arm64": "1.30.1", "lightningcss-darwin-x64": "1.30.1", "lightningcss-freebsd-x64": "1.30.1", "lightningcss-linux-arm-gnueabihf": "1.30.1", "lightningcss-linux-arm64-gnu": "1.30.1", "lightningcss-linux-arm64-musl": "1.30.1", "lightningcss-linux-x64-gnu": "1.30.1", "lightningcss-linux-x64-musl": "1.30.1", "lightningcss-win32-arm64-msvc": "1.30.1", "lightningcss-win32-x64-msvc": "1.30.1" } }, "sha512-xi6IyHML+c9+Q3W0S4fCQJOym42pyurFiJUHEcEyHS0CeKzia4yZDEsLlqOFykxOdHpNy0NmvVO31vcSqAxJCg=="],
"lightningcss": ["lightningcss@1.30.2", "", { "dependencies": { "detect-libc": "^2.0.3" }, "optionalDependencies": { "lightningcss-android-arm64": "1.30.2", "lightningcss-darwin-arm64": "1.30.2", "lightningcss-darwin-x64": "1.30.2", "lightningcss-freebsd-x64": "1.30.2", "lightningcss-linux-arm-gnueabihf": "1.30.2", "lightningcss-linux-arm64-gnu": "1.30.2", "lightningcss-linux-arm64-musl": "1.30.2", "lightningcss-linux-x64-gnu": "1.30.2", "lightningcss-linux-x64-musl": "1.30.2", "lightningcss-win32-arm64-msvc": "1.30.2", "lightningcss-win32-x64-msvc": "1.30.2" } }, "sha512-utfs7Pr5uJyyvDETitgsaqSyjCb2qNRAtuqUeWIAKztsOYdcACf2KtARYXg2pSvhkt+9NfoaNY7fxjl6nuMjIQ=="],
"lightningcss-darwin-arm64": ["lightningcss-darwin-arm64@1.30.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-c8JK7hyE65X1MHMN+Viq9n11RRC7hgin3HhYKhrMyaXflk5GVplZ60IxyoVtzILeKr+xAJwg6zK6sjTBJ0FKYQ=="],
"lightningcss-android-arm64": ["lightningcss-android-arm64@1.30.2", "", { "os": "android", "cpu": "arm64" }, "sha512-BH9sEdOCahSgmkVhBLeU7Hc9DWeZ1Eb6wNS6Da8igvUwAe0sqROHddIlvU06q3WyXVEOYDZ6ykBZQnjTbmo4+A=="],
"lightningcss-darwin-x64": ["lightningcss-darwin-x64@1.30.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-k1EvjakfumAQoTfcXUcHQZhSpLlkAuEkdMBsI/ivWw9hL+7FtilQc0Cy3hrx0AAQrVtQAbMI7YjCgYgvn37PzA=="],
"lightningcss-darwin-arm64": ["lightningcss-darwin-arm64@1.30.2", "", { "os": "darwin", "cpu": "arm64" }, "sha512-ylTcDJBN3Hp21TdhRT5zBOIi73P6/W0qwvlFEk22fkdXchtNTOU4Qc37SkzV+EKYxLouZ6M4LG9NfZ1qkhhBWA=="],
"lightningcss-freebsd-x64": ["lightningcss-freebsd-x64@1.30.1", "", { "os": "freebsd", "cpu": "x64" }, "sha512-kmW6UGCGg2PcyUE59K5r0kWfKPAVy4SltVeut+umLCFoJ53RdCUWxcRDzO1eTaxf/7Q2H7LTquFHPL5R+Gjyig=="],
"lightningcss-darwin-x64": ["lightningcss-darwin-x64@1.30.2", "", { "os": "darwin", "cpu": "x64" }, "sha512-oBZgKchomuDYxr7ilwLcyms6BCyLn0z8J0+ZZmfpjwg9fRVZIR5/GMXd7r9RH94iDhld3UmSjBM6nXWM2TfZTQ=="],
"lightningcss-linux-arm-gnueabihf": ["lightningcss-linux-arm-gnueabihf@1.30.1", "", { "os": "linux", "cpu": "arm" }, "sha512-MjxUShl1v8pit+6D/zSPq9S9dQ2NPFSQwGvxBCYaBYLPlCWuPh9/t1MRS8iUaR8i+a6w7aps+B4N0S1TYP/R+Q=="],
"lightningcss-freebsd-x64": ["lightningcss-freebsd-x64@1.30.2", "", { "os": "freebsd", "cpu": "x64" }, "sha512-c2bH6xTrf4BDpK8MoGG4Bd6zAMZDAXS569UxCAGcA7IKbHNMlhGQ89eRmvpIUGfKWNVdbhSbkQaWhEoMGmGslA=="],
"lightningcss-linux-arm64-gnu": ["lightningcss-linux-arm64-gnu@1.30.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-gB72maP8rmrKsnKYy8XUuXi/4OctJiuQjcuqWNlJQ6jZiWqtPvqFziskH3hnajfvKB27ynbVCucKSm2rkQp4Bw=="],
"lightningcss-linux-arm-gnueabihf": ["lightningcss-linux-arm-gnueabihf@1.30.2", "", { "os": "linux", "cpu": "arm" }, "sha512-eVdpxh4wYcm0PofJIZVuYuLiqBIakQ9uFZmipf6LF/HRj5Bgm0eb3qL/mr1smyXIS1twwOxNWndd8z0E374hiA=="],
"lightningcss-linux-arm64-musl": ["lightningcss-linux-arm64-musl@1.30.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-jmUQVx4331m6LIX+0wUhBbmMX7TCfjF5FoOH6SD1CttzuYlGNVpA7QnrmLxrsub43ClTINfGSYyHe2HWeLl5CQ=="],
"lightningcss-linux-arm64-gnu": ["lightningcss-linux-arm64-gnu@1.30.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-UK65WJAbwIJbiBFXpxrbTNArtfuznvxAJw4Q2ZGlU8kPeDIWEX1dg3rn2veBVUylA2Ezg89ktszWbaQnxD/e3A=="],
"lightningcss-linux-x64-gnu": ["lightningcss-linux-x64-gnu@1.30.1", "", { "os": "linux", "cpu": "x64" }, "sha512-piWx3z4wN8J8z3+O5kO74+yr6ze/dKmPnI7vLqfSqI8bccaTGY5xiSGVIJBDd5K5BHlvVLpUB3S2YCfelyJ1bw=="],
"lightningcss-linux-arm64-musl": ["lightningcss-linux-arm64-musl@1.30.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-5Vh9dGeblpTxWHpOx8iauV02popZDsCYMPIgiuw97OJ5uaDsL86cnqSFs5LZkG3ghHoX5isLgWzMs+eD1YzrnA=="],
"lightningcss-linux-x64-musl": ["lightningcss-linux-x64-musl@1.30.1", "", { "os": "linux", "cpu": "x64" }, "sha512-rRomAK7eIkL+tHY0YPxbc5Dra2gXlI63HL+v1Pdi1a3sC+tJTcFrHX+E86sulgAXeI7rSzDYhPSeHHjqFhqfeQ=="],
"lightningcss-linux-x64-gnu": ["lightningcss-linux-x64-gnu@1.30.2", "", { "os": "linux", "cpu": "x64" }, "sha512-Cfd46gdmj1vQ+lR6VRTTadNHu6ALuw2pKR9lYq4FnhvgBc4zWY1EtZcAc6EffShbb1MFrIPfLDXD6Xprbnni4w=="],
"lightningcss-win32-arm64-msvc": ["lightningcss-win32-arm64-msvc@1.30.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-mSL4rqPi4iXq5YVqzSsJgMVFENoa4nGTT/GjO2c0Yl9OuQfPsIfncvLrEW6RbbB24WtZ3xP/2CCmI3tNkNV4oA=="],
"lightningcss-linux-x64-musl": ["lightningcss-linux-x64-musl@1.30.2", "", { "os": "linux", "cpu": "x64" }, "sha512-XJaLUUFXb6/QG2lGIW6aIk6jKdtjtcffUT0NKvIqhSBY3hh9Ch+1LCeH80dR9q9LBjG3ewbDjnumefsLsP6aiA=="],
"lightningcss-win32-x64-msvc": ["lightningcss-win32-x64-msvc@1.30.1", "", { "os": "win32", "cpu": "x64" }, "sha512-PVqXh48wh4T53F/1CCu8PIPCxLzWyCnn/9T5W1Jpmdy5h9Cwd+0YQS6/LwhHXSafuc61/xg9Lv5OrCby6a++jg=="],
"lightningcss-win32-arm64-msvc": ["lightningcss-win32-arm64-msvc@1.30.2", "", { "os": "win32", "cpu": "arm64" }, "sha512-FZn+vaj7zLv//D/192WFFVA0RgHawIcHqLX9xuWiQt7P0PtdFEVaxgF9rjM/IRYHQXNnk61/H/gb2Ei+kUQ4xQ=="],
"lightningcss-win32-x64-msvc": ["lightningcss-win32-x64-msvc@1.30.2", "", { "os": "win32", "cpu": "x64" }, "sha512-5g1yc73p+iAkid5phb4oVFMB45417DkRevRbt/El/gKXJk4jid+vPFF/AXbxn05Aky8PapwzZrdJShv5C0avjw=="],
"lodash.includes": ["lodash.includes@4.3.0", "", {}, "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w=="],
@@ -287,7 +289,7 @@
"scheduler": ["scheduler@0.23.2", "", { "dependencies": { "loose-envify": "^1.1.0" } }, "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ=="],
"semver": ["semver@7.7.2", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA=="],
"semver": ["semver@7.7.3", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q=="],
"sentence-case": ["sentence-case@3.0.4", "", { "dependencies": { "no-case": "^3.0.4", "tslib": "^2.0.3", "upper-case-first": "^2.0.2" } }, "sha512-8LS0JInaQMCRoQ7YUytAo/xUu5W2XnQxV2HI/6uM6U7CITS1RqPElr30V6uIqyMKM9lJGRVFy5/4CuzcixNYSg=="],
@@ -303,7 +305,7 @@
"uglify-js": ["uglify-js@3.19.3", "", { "bin": { "uglifyjs": "bin/uglifyjs" } }, "sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ=="],
"undici-types": ["undici-types@7.10.0", "", {}, "sha512-t5Fy/nfn+14LuOc2KNYg75vZqClpAiqscVvMygNnlsHBFpSXdJaYtXMcdNLpl/Qvc3P2cB3s6lOV51nqsFq4ag=="],
"undici-types": ["undici-types@7.16.0", "", {}, "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw=="],
"universal-github-app-jwt": ["universal-github-app-jwt@1.2.0", "", { "dependencies": { "@types/jsonwebtoken": "^9.0.0", "jsonwebtoken": "^9.0.2" } }, "sha512-dncpMpnsKBk0eetwfN8D8OUHGfiDhhJ+mtsbMl+7PfW7mYjiH8LIcqRmYMtzYLgSh47HjfdBtrBwIQ/gizKR3g=="],

View File

@@ -10,4 +10,4 @@ preload = "./test/preload.ts"
[install]
linker = "isolated"
minimumReleaseAge = 1
minimumReleaseAge = 259200 # three days

View File

@@ -1,4 +1,4 @@
FROM debian:bookworm-slim AS build
FROM debian:trixie-slim AS build
# https://github.com/oven-sh/bun/releases
ARG BUN_VERSION=latest
@@ -55,7 +55,7 @@ RUN apt-get update -qq \
&& which bun \
&& bun --version
FROM debian:bookworm-slim
FROM debian:trixie-slim
# Disable the runtime transpiler cache by default inside Docker containers.
# On ephemeral containers, the cache is not useful

View File

@@ -1,4 +1,4 @@
FROM debian:bookworm-slim AS build
FROM debian:trixie-slim AS build
# https://github.com/oven-sh/bun/releases
ARG BUN_VERSION=latest
@@ -56,7 +56,7 @@ RUN apt-get update -qq \
&& rm -f "bun-linux-$build.zip" SHASUMS256.txt.asc SHASUMS256.txt \
&& chmod +x /usr/local/bin/bun
FROM debian:bookworm
FROM debian:trixie
COPY docker-entrypoint.sh /usr/local/bin
COPY --from=build /usr/local/bin/bun /usr/local/bin/bun

View File

@@ -1,4 +1,4 @@
FROM debian:bookworm-slim AS build
FROM debian:trixie-slim AS build
# https://github.com/oven-sh/bun/releases
ARG BUN_VERSION=latest
@@ -55,7 +55,7 @@ RUN apt-get update -qq \
&& which bun \
&& bun --version
FROM gcr.io/distroless/base-nossl-debian11
FROM gcr.io/distroless/base-nossl-debian13
# Disable the runtime transpiler cache by default inside Docker containers.
# On ephemeral containers, the cache is not useful

View File

@@ -492,6 +492,28 @@ Bun will lazily resolve and load each plugin and use them to bundle your routes.
the CLI.
</Note>
## Inline Environment Variables
Bun can replace `process.env.*` references in your frontend JavaScript and TypeScript with their actual values at build time. Configure the `env` option in your `bunfig.toml`:
```toml title="bunfig.toml" icon="settings"
[serve.static]
env = "PUBLIC_*" # only inline env vars starting with PUBLIC_ (recommended)
# env = "inline" # inline all environment variables
# env = "disable" # disable env var replacement (default)
```
<Note>
This only works with literal `process.env.FOO` references, not `import.meta.env` or indirect access like `const env =
process.env; env.FOO`.
If an environment variable is not set, you may see runtime errors like `ReferenceError: process
is not defined` in the browser.
</Note>
See the [HTML & static sites documentation](/bundler/html-static#inline-environment-variables) for more details on build-time configuration and examples.
## How It Works
Bun uses `HTMLRewriter` to scan for `<script>` and `<link>` tags in HTML files, uses them as entrypoints for Bun's bundler, generates an optimized bundle for the JavaScript/TypeScript/TSX/JSX and CSS files, and serves the result.

View File

@@ -262,6 +262,93 @@ Then, reference TailwindCSS in your HTML via `<link>` tag, `@import` in CSS, or
<Info>Only one of those are necessary, not all three.</Info>
## Inline environment variables
Bun can replace `process.env.*` references in your JavaScript and TypeScript with their actual values at build time. This is useful for injecting configuration like API URLs or feature flags into your frontend code.
### Dev server (runtime)
To inline environment variables when using `bun ./index.html`, configure the `env` option in your `bunfig.toml`:
```toml title="bunfig.toml" icon="settings"
[serve.static]
env = "PUBLIC_*" # only inline env vars starting with PUBLIC_ (recommended)
# env = "inline" # inline all environment variables
# env = "disable" # disable env var replacement (default)
```
<Note>
This only works with literal `process.env.FOO` references, not `import.meta.env` or indirect access like `const env =
process.env; env.FOO`.
If an environment variable is not set, you may see runtime errors like `ReferenceError: process
is not defined` in the browser.
</Note>
Then run the dev server:
```bash terminal icon="terminal"
PUBLIC_API_URL=https://api.example.com bun ./index.html
```
### Build for production
When building static HTML for production, use the `env` option to inline environment variables:
<Tabs>
<Tab title="CLI">
```bash terminal icon="terminal"
# Inline all environment variables
bun build ./index.html --outdir=dist --env=inline
# Only inline env vars with a specific prefix (recommended)
bun build ./index.html --outdir=dist --env=PUBLIC_*
```
</Tab>
<Tab title="API">
```ts title="build.ts" icon="/icons/typescript.svg"
// Inline all environment variables
await Bun.build({
entrypoints: ["./index.html"],
outdir: "./dist",
env: "inline", // [!code highlight]
});
// Only inline env vars with a specific prefix (recommended)
await Bun.build({
entrypoints: ["./index.html"],
outdir: "./dist",
env: "PUBLIC_*", // [!code highlight]
});
```
</Tab>
</Tabs>
### Example
Given this source file:
```ts title="app.ts" icon="/icons/typescript.svg"
const apiUrl = process.env.PUBLIC_API_URL;
console.log(`API URL: ${apiUrl}`);
```
And running with `PUBLIC_API_URL=https://api.example.com`:
```bash terminal icon="terminal"
PUBLIC_API_URL=https://api.example.com bun build ./index.html --outdir=dist --env=PUBLIC_*
```
The bundled output will contain:
```js title="dist/app.js" icon="/icons/javascript.svg"
const apiUrl = "https://api.example.com";
console.log(`API URL: ${apiUrl}`);
```
## Echo console logs from browser to terminal
Bun's dev server supports streaming console logs from the browser to the terminal.

View File

@@ -9,18 +9,42 @@ In Bun, `fetch` supports sending requests through an HTTP or HTTPS proxy. This i
```ts proxy.ts icon="/icons/typescript.svg"
await fetch("https://example.com", {
// The URL of the proxy server
proxy: "https://usertitle:password@proxy.example.com:8080",
proxy: "https://username:password@proxy.example.com:8080",
});
```
---
The `proxy` option is a URL string that specifies the proxy server. It can include the username and password if the proxy requires authentication. It can be `http://` or `https://`.
The `proxy` option can be a URL string or an object with `url` and optional `headers`. The URL can include the username and password if the proxy requires authentication. It can be `http://` or `https://`.
---
## Custom proxy headers
To send custom headers to the proxy server (useful for proxy authentication tokens, custom routing, etc.), use the object format:
```ts proxy-headers.ts icon="/icons/typescript.svg"
await fetch("https://example.com", {
proxy: {
url: "https://proxy.example.com:8080",
headers: {
"Proxy-Authorization": "Bearer my-token",
"X-Proxy-Region": "us-east-1",
},
},
});
```
The `headers` property accepts a plain object or a `Headers` instance. These headers are sent directly to the proxy server in `CONNECT` requests (for HTTPS targets) or in the proxy request (for HTTP targets).
If you provide a `Proxy-Authorization` header, it will override any credentials specified in the proxy URL.
---
## Environment variables
You can also set the `$HTTP_PROXY` or `$HTTPS_PROXY` environment variable to the proxy URL. This is useful when you want to use the same proxy for all requests.
```sh terminal icon="terminal"
HTTPS_PROXY=https://usertitle:password@proxy.example.com:8080 bun run index.ts
HTTPS_PROXY=https://username:password@proxy.example.com:8080 bun run index.ts
```

View File

@@ -76,7 +76,7 @@ declare module "bun:test" {
You should now be able to use Testing Library in your tests
```ts matchers.d.ts icon="/icons/typescript.svg"
```tsx myComponent.test.tsx icon="/icons/typescript.svg"
import { test, expect } from "bun:test";
import { screen, render } from "@testing-library/react";
import { MyComponent } from "./myComponent";

View File

@@ -107,7 +107,9 @@ Bun supports the following loaders:
### `telemetry`
The `telemetry` field permit to enable/disable the analytics records. Bun records bundle timings (so we can answer with data, "is Bun getting faster?") and feature usage (e.g., "are people actually using macros?"). The request body size is about 60 bytes, so it's not a lot of data. By default the telemetry is enabled. Equivalent of `DO_NOT_TRACK` env variable.
The `telemetry` field is used to enable/disable analytics. By default, telemetry is enabled. This is equivalent to the `DO_NOT_TRACK` environment variable.
Currently we do not collect telemetry and this setting is only used for enabling/disabling anonymous crash reports, but in the future we plan to collect information like which Bun APIs are used most or how long `bun build` takes.
```toml title="bunfig.toml" icon="settings"
telemetry = false

View File

@@ -39,18 +39,19 @@ const text = await proc.stdout.text();
console.log(text); // "const input = "hello world".repeat(400); ..."
```
| Value | Description |
| ------------------------ | ------------------------------------------------ |
| `null` | **Default.** Provide no input to the subprocess |
| `"pipe"` | Return a `FileSink` for fast incremental writing |
| `"inherit"` | Inherit the `stdin` of the parent process |
| `Bun.file()` | Read from the specified file |
| `TypedArray \| DataView` | Use a binary buffer as input |
| `Response` | Use the response `body` as input |
| `Request` | Use the request `body` as input |
| `ReadableStream` | Use a readable stream as input |
| `Blob` | Use a blob as input |
| `number` | Read from the file with a given file descriptor |
| Value | Description |
| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------ |
| `null` | **Default.** Provide no input to the subprocess |
| `"pipe"` | Return a `FileSink` for fast incremental writing |
| `"inherit"` | Inherit the `stdin` of the parent process |
| `"pty"` | Use a pseudo-terminal (PTY). Child sees `process.stdin.isTTY === true`. Falls back to `"pipe"` on Windows. Not supported with `spawnSync`. |
| `Bun.file()` | Read from the specified file |
| `TypedArray \| DataView` | Use a binary buffer as input |
| `Response` | Use the response `body` as input |
| `Request` | Use the request `body` as input |
| `ReadableStream` | Use a readable stream as input |
| `Blob` | Use a blob as input |
| `number` | Read from the file with a given file descriptor |
The `"pipe"` option lets incrementally write to the subprocess's input stream from the parent process.
@@ -105,13 +106,121 @@ console.log(text); // => "1.3.3\n"
Configure the output stream by passing one of the following values to `stdout/stderr`:
| Value | Description |
| ------------ | --------------------------------------------------------------------------------------------------- |
| `"pipe"` | **Default for `stdout`.** Pipe the output to a `ReadableStream` on the returned `Subprocess` object |
| `"inherit"` | **Default for `stderr`.** Inherit from the parent process |
| `"ignore"` | Discard the output |
| `Bun.file()` | Write to the specified file |
| `number` | Write to the file with the given file descriptor |
| Value | Description |
| ------------ | ------------------------------------------------------------------------------------------------------------------------------------------- |
| `"pipe"` | **Default for `stdout`.** Pipe the output to a `ReadableStream` on the returned `Subprocess` object |
| `"inherit"` | **Default for `stderr`.** Inherit from the parent process |
| `"ignore"` | Discard the output |
| `"pty"` | Use a pseudo-terminal (PTY). Child sees `process.stdout.isTTY === true`. Falls back to `"pipe"` on Windows. Not supported with `spawnSync`. |
| `Bun.file()` | Write to the specified file |
| `number` | Write to the file with the given file descriptor |
## Pseudo-terminal (PTY)
Use `"pty"` to spawn a process with a pseudo-terminal, making the child process believe it's running in an interactive terminal. This causes `process.stdout.isTTY` to be `true` in the child, which is useful for:
- Getting colored output from CLI tools that detect TTY
- Running interactive programs that require a terminal
- Testing terminal-dependent behavior
### Basic usage
```ts
const proc = Bun.spawn(["ls", "--color=auto"], {
stdout: "pty",
});
// The child process sees process.stdout.isTTY === true
const output = await proc.stdout.text();
console.log(output); // includes ANSI color codes
```
### Checking isTTY in child process
```ts
const proc = Bun.spawn(["bun", "-e", "console.log('isTTY:', process.stdout.isTTY)"], {
stdout: "pty",
});
const output = await proc.stdout.text();
console.log(output); // "isTTY: true"
```
### Multiple PTY streams
You can use PTY for stdin, stdout, and/or stderr. When multiple streams use PTY, they share the same underlying pseudo-terminal:
```ts
const code = `
console.log("stdout.isTTY:", process.stdout.isTTY);
console.log("stdin.isTTY:", process.stdin.isTTY);
console.log("stderr.isTTY:", process.stderr.isTTY);
`;
const proc = Bun.spawn(["bun", "-e", code], {
stdin: "pty",
stdout: "pty",
stderr: "pty",
});
const output = await proc.stdout.text();
// stdout.isTTY: true
// stdin.isTTY: true
// stderr.isTTY: true
```
### Custom terminal dimensions
Specify terminal width and height using the object syntax:
```ts
const code = `
console.log("columns:", process.stdout.columns);
console.log("rows:", process.stdout.rows);
`;
const proc = Bun.spawn(["bun", "-e", code], {
stdout: {
type: "pty",
width: 120, // columns
height: 40, // rows
},
});
const output = await proc.stdout.text();
// columns: 120
// rows: 40
```
### Getting colored output from git, grep, etc.
Many CLI tools detect whether they're running in a TTY and only emit colors when they are:
```ts
// Without PTY - no colors
const noColor = Bun.spawn(["git", "status"], { stdout: "pipe" });
console.log(await noColor.stdout.text()); // plain text
// With PTY - colors enabled
const withColor = Bun.spawn(["git", "status"], { stdout: "pty" });
console.log(await withColor.stdout.text()); // includes ANSI color codes
```
### Platform support
| Platform | PTY Support |
| -------- | -------------------------------------------- |
| macOS | ✅ Full support |
| Linux | ✅ Full support |
| Windows | ⚠️ Falls back to `"pipe"` (no TTY semantics) |
On Windows, `"pty"` silently falls back to `"pipe"` behavior. The child process will see `process.stdout.isTTY` as `undefined`. This allows cross-platform code to work without errors, though TTY-dependent features won't work on Windows.
### Limitations
- **Not supported with `spawnSync`**: PTY requires asynchronous I/O. Using `"pty"` with `Bun.spawnSync()` will throw an error.
- **Line endings**: PTY converts `\n` to `\r\n` on output (standard terminal behavior).
- **No dynamic resize**: Terminal dimensions are set at spawn time and cannot be changed after.
## Exit handling
@@ -413,6 +522,7 @@ namespace SpawnOptions {
| "pipe"
| "inherit"
| "ignore"
| "pty" // use a pseudo-terminal (macOS/Linux only, falls back to "pipe" on Windows, not supported with spawnSync)
| null // equivalent to "ignore"
| undefined // to use default
| BunFile
@@ -423,6 +533,7 @@ namespace SpawnOptions {
| "pipe"
| "inherit"
| "ignore"
| "pty" // use a pseudo-terminal (macOS/Linux only, falls back to "pipe" on Windows, not supported with spawnSync)
| null // equivalent to "ignore"
| undefined // to use default
| BunFile

View File

@@ -51,7 +51,7 @@ const response = await fetch("http://example.com", {
### Proxying requests
To proxy a request, pass an object with the `proxy` property set to a URL.
To proxy a request, pass an object with the `proxy` property set to a URL string:
```ts
const response = await fetch("http://example.com", {
@@ -59,6 +59,22 @@ const response = await fetch("http://example.com", {
});
```
You can also use an object format to send custom headers to the proxy server:
```ts
const response = await fetch("http://example.com", {
proxy: {
url: "http://proxy.com",
headers: {
"Proxy-Authorization": "Bearer my-token",
"X-Custom-Proxy-Header": "value",
},
},
});
```
The `headers` are sent directly to the proxy in `CONNECT` requests (for HTTPS targets) or in the proxy request (for HTTP targets). If you provide a `Proxy-Authorization` header, it overrides any credentials in the proxy URL.
### Custom headers
To set custom headers, pass an object with the `headers` property set to an object.

View File

@@ -87,11 +87,11 @@
"node:test:cp": "bun ./scripts/fetch-node-test.ts ",
"clean:zig": "rm -rf build/debug/cache/zig build/debug/CMakeCache.txt 'build/debug/*.o' .zig-cache zig-out || true",
"machine:linux:ubuntu": "./scripts/machine.mjs ssh --cloud=aws --arch=x64 --instance-type c7i.2xlarge --os=linux --distro=ubuntu --release=25.04",
"machine:linux:debian": "./scripts/machine.mjs ssh --cloud=aws --arch=x64 --instance-type c7i.2xlarge --os=linux --distro=debian --release=12",
"machine:linux:debian": "./scripts/machine.mjs ssh --cloud=aws --arch=x64 --instance-type c7i.2xlarge --os=linux --distro=debian --release=13",
"machine:linux:alpine": "./scripts/machine.mjs ssh --cloud=aws --arch=x64 --instance-type c7i.2xlarge --os=linux --distro=alpine --release=3.22",
"machine:linux:amazonlinux": "./scripts/machine.mjs ssh --cloud=aws --arch=x64 --instance-type c7i.2xlarge --os=linux --distro=amazonlinux --release=2023",
"machine:windows:2019": "./scripts/machine.mjs ssh --cloud=aws --arch=x64 --instance-type c7i.2xlarge --os=windows --release=2019",
"machine:freebsd": "./scripts/machine.mjs ssh --cloud=aws --arch=x64 --instance-type c7i.large --os=freebsd --release=14.3",
"machine:freebsd": "./scripts/machine.mjs ssh --cloud=aws --arch=x64 --instance-type c7i.2xlarge --os=freebsd --release=14.3",
"sync-webkit-source": "bun ./scripts/sync-webkit-source.ts"
}
}

View File

@@ -1,14 +1,15 @@
{
"lockfileVersion": 1,
"configVersion": 0,
"workspaces": {
"": {
"name": "bun-inspector-protocol",
"dependencies": {
"ws": "^8.13.0",
"ws": "^8.18.3",
},
},
},
"packages": {
"ws": ["ws@8.13.0", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA=="],
"ws": ["ws@8.18.3", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg=="],
}
}

View File

@@ -5,7 +5,7 @@
"build": "bun build --target=node --outfile=index.js --minify-syntax ./index.ts --external=ws"
},
"dependencies": {
"ws": "^8.13.0"
"ws": "^8.18.3"
},
"main": "./index.js",
"type": "module",

File diff suppressed because it is too large Load Diff

View File

@@ -15,5 +15,8 @@
"build-layer": "bun scripts/build-layer.ts",
"publish-layer": "bun scripts/publish-layer.ts",
"format": "prettier --write ."
},
"overrides": {
"braces": "^3.0.3"
}
}

View File

@@ -1740,7 +1740,6 @@ declare module "bun" {
* @default "esm"
*/
format?: /**
* ECMAScript Module format
*/
| "esm"
@@ -5336,6 +5335,7 @@ declare module "bun" {
| "pipe"
| "inherit"
| "ignore"
| "pty"
| null // equivalent to "ignore"
| undefined // to use default
| BunFile
@@ -5349,6 +5349,7 @@ declare module "bun" {
| "pipe"
| "inherit"
| "ignore"
| "pty"
| null // equivalent to "ignore"
| undefined // to use default
| BunFile
@@ -5406,14 +5407,16 @@ declare module "bun" {
* - `"ignore"`, `null`, `undefined`: The process will have no standard input (default)
* - `"pipe"`: The process will have a new {@link FileSink} for standard input
* - `"inherit"`: The process will inherit the standard input of the current process
* - `"pty"`: The process will use a pseudo-terminal (PTY). The child will see `process.stdin.isTTY === true`. Falls back to `"pipe"` on Windows. Not supported with `spawnSync`.
* - `ArrayBufferView`, `Blob`, `Bun.file()`, `Response`, `Request`: The process will read from buffer/stream.
* - `number`: The process will read from the file descriptor
*
* For stdout and stdin you may pass:
* For stdout and stderr you may pass:
*
* - `"pipe"`, `undefined`: The process will have a {@link ReadableStream} for standard output/error
* - `"ignore"`, `null`: The process will have no standard output/error
* - `"inherit"`: The process will inherit the standard output/error of the current process
* - `"pty"`: The process will use a pseudo-terminal (PTY). The child will see `process.stdout.isTTY === true` / `process.stderr.isTTY === true`. Falls back to `"pipe"` on Windows. Not supported with `spawnSync`.
* - `ArrayBufferView`: The process write to the preallocated buffer. Not implemented.
* - `number`: The process will write to the file descriptor
*
@@ -5428,6 +5431,7 @@ declare module "bun" {
* - `"ignore"`, `null`, `undefined`: The process will have no standard input
* - `"pipe"`: The process will have a new {@link FileSink} for standard input
* - `"inherit"`: The process will inherit the standard input of the current process
* - `"pty"`: The process will use a pseudo-terminal (PTY). The child will see `process.stdin.isTTY === true`. Falls back to `"pipe"` on Windows. Not supported with `spawnSync`.
* - `ArrayBufferView`, `Blob`: The process will read from the buffer
* - `number`: The process will read from the file descriptor
*
@@ -5440,6 +5444,7 @@ declare module "bun" {
* - `"pipe"`, `undefined`: The process will have a {@link ReadableStream} for standard output/error
* - `"ignore"`, `null`: The process will have no standard output/error
* - `"inherit"`: The process will inherit the standard output/error of the current process
* - `"pty"`: The process will use a pseudo-terminal (PTY). The child will see `process.stdout.isTTY === true`. Falls back to `"pipe"` on Windows. Not supported with `spawnSync`.
* - `ArrayBufferView`: The process write to the preallocated buffer. Not implemented.
* - `number`: The process will write to the file descriptor
*
@@ -5452,6 +5457,7 @@ declare module "bun" {
* - `"pipe"`, `undefined`: The process will have a {@link ReadableStream} for standard output/error
* - `"ignore"`, `null`: The process will have no standard output/error
* - `"inherit"`: The process will inherit the standard output/error of the current process
* - `"pty"`: The process will use a pseudo-terminal (PTY). The child will see `process.stderr.isTTY === true`. Falls back to `"pipe"` on Windows. Not supported with `spawnSync`.
* - `ArrayBufferView`: The process write to the preallocated buffer. Not implemented.
* - `number`: The process will write to the file descriptor
*

View File

@@ -1920,14 +1920,44 @@ interface BunFetchRequestInit extends RequestInit {
* Override http_proxy or HTTPS_PROXY
* This is a custom property that is not part of the Fetch API specification.
*
* Can be a string URL or an object with `url` and optional `headers`.
*
* @example
* ```js
* // String format
* const response = await fetch("http://example.com", {
* proxy: "https://username:password@127.0.0.1:8080"
* });
*
* // Object format with custom headers sent to the proxy
* const response = await fetch("http://example.com", {
* proxy: {
* url: "https://127.0.0.1:8080",
* headers: {
* "Proxy-Authorization": "Bearer token",
* "X-Custom-Proxy-Header": "value"
* }
* }
* });
* ```
*
* If a `Proxy-Authorization` header is provided in `proxy.headers`, it takes
* precedence over credentials parsed from the proxy URL.
*/
proxy?: string;
proxy?:
| string
| {
/**
* The proxy URL
*/
url: string;
/**
* Custom headers to send to the proxy server.
* These headers are sent in the CONNECT request (for HTTPS targets)
* or in the proxy request (for HTTP targets).
*/
headers?: Bun.HeadersInit;
};
/**
* Override the default S3 options

View File

@@ -100,8 +100,8 @@ declare module "bun" {
declare namespace WebAssembly {
interface ValueTypeMap extends Bun.WebAssembly.ValueTypeMap {}
interface GlobalDescriptor<T extends keyof ValueTypeMap = keyof ValueTypeMap>
extends Bun.WebAssembly.GlobalDescriptor<T> {}
interface GlobalDescriptor<T extends keyof ValueTypeMap = keyof ValueTypeMap> extends Bun.WebAssembly
.GlobalDescriptor<T> {}
interface MemoryDescriptor extends Bun.WebAssembly.MemoryDescriptor {}
interface ModuleExportDescriptor extends Bun.WebAssembly.ModuleExportDescriptor {}
interface ModuleImportDescriptor extends Bun.WebAssembly.ModuleImportDescriptor {}

View File

@@ -213,6 +213,16 @@ namespace uWS {
emitSoon = std::string_view(data.data(), chunkSize(state) - 2);
shouldEmit = true;
}
// Validate that the chunk terminator is \r\n to prevent request smuggling
// The last 2 bytes of the chunk must be exactly \r\n
// Note: chunkSize always includes +2 for the terminator (added in consumeHexNumber),
// and chunks with size 0 (chunkSize == 2) are handled earlier at line 190.
// Therefore chunkSize >= 3 here, so no underflow is possible.
size_t terminatorOffset = chunkSize(state) - 2;
if (data[terminatorOffset] != '\r' || data[terminatorOffset + 1] != '\n') {
state = STATE_IS_ERROR;
return std::nullopt;
}
data.remove_prefix(chunkSize(state));
state = STATE_IS_CHUNKED;
if (shouldEmit) {

View File

@@ -1,8 +1,13 @@
{
"lockfileVersion": 1,
"configVersion": 0,
"workspaces": {
"": {
"name": "mock-debug",
"name": "bun-vscode",
"dependencies": {
"glob": "^13.0.0",
"ws": "^8.18.3",
},
"devDependencies": {
"@types/bun": "^1.1.10",
"@types/vscode": "^1.60.0",
@@ -25,58 +30,86 @@
},
"../bun-inspector-protocol": {
"name": "bun-inspector-protocol",
"version": "0.0.1",
"version": "0.0.2",
"dependencies": {
"ws": "^8.13.0",
"ws": "^8.18.3",
},
},
},
"packages": {
"@azure/abort-controller": ["@azure/abort-controller@2.1.2", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-nBrLsEWm4J2u5LpAPjxADTlq3trDgVZZXHNKabeXZtpq3d3AbN/KGO82R87rdDz5/lYB024rtEf10/q0urNgsA=="],
"@azure/core-auth": ["@azure/core-auth@1.10.1", "", { "dependencies": { "@azure/abort-controller": "^2.1.2", "@azure/core-util": "^1.13.0", "tslib": "^2.6.2" } }, "sha512-ykRMW8PjVAn+RS6ww5cmK9U2CyH9p4Q88YJwvUslfuMmN98w/2rdGRLPqJYObapBCdzBVeDgYWdJnFPFb7qzpg=="],
"@azure/core-client": ["@azure/core-client@1.10.1", "", { "dependencies": { "@azure/abort-controller": "^2.1.2", "@azure/core-auth": "^1.10.0", "@azure/core-rest-pipeline": "^1.22.0", "@azure/core-tracing": "^1.3.0", "@azure/core-util": "^1.13.0", "@azure/logger": "^1.3.0", "tslib": "^2.6.2" } }, "sha512-Nh5PhEOeY6PrnxNPsEHRr9eimxLwgLlpmguQaHKBinFYA/RU9+kOYVOQqOrTsCL+KSxrLLl1gD8Dk5BFW/7l/w=="],
"@azure/core-rest-pipeline": ["@azure/core-rest-pipeline@1.22.2", "", { "dependencies": { "@azure/abort-controller": "^2.1.2", "@azure/core-auth": "^1.10.0", "@azure/core-tracing": "^1.3.0", "@azure/core-util": "^1.13.0", "@azure/logger": "^1.3.0", "@typespec/ts-http-runtime": "^0.3.0", "tslib": "^2.6.2" } }, "sha512-MzHym+wOi8CLUlKCQu12de0nwcq9k9Kuv43j4Wa++CsCpJwps2eeBQwD2Bu8snkxTtDKDx4GwjuR9E8yC8LNrg=="],
"@azure/core-tracing": ["@azure/core-tracing@1.3.1", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-9MWKevR7Hz8kNzzPLfX4EAtGM2b8mr50HPDBvio96bURP/9C+HjdH3sBlLSNNrvRAr5/k/svoH457gB5IKpmwQ=="],
"@azure/core-util": ["@azure/core-util@1.13.1", "", { "dependencies": { "@azure/abort-controller": "^2.1.2", "@typespec/ts-http-runtime": "^0.3.0", "tslib": "^2.6.2" } }, "sha512-XPArKLzsvl0Hf0CaGyKHUyVgF7oDnhKoP85Xv6M4StF/1AhfORhZudHtOyf2s+FcbuQ9dPRAjB8J2KvRRMUK2A=="],
"@azure/identity": ["@azure/identity@4.13.0", "", { "dependencies": { "@azure/abort-controller": "^2.0.0", "@azure/core-auth": "^1.9.0", "@azure/core-client": "^1.9.2", "@azure/core-rest-pipeline": "^1.17.0", "@azure/core-tracing": "^1.0.0", "@azure/core-util": "^1.11.0", "@azure/logger": "^1.0.0", "@azure/msal-browser": "^4.2.0", "@azure/msal-node": "^3.5.0", "open": "^10.1.0", "tslib": "^2.2.0" } }, "sha512-uWC0fssc+hs1TGGVkkghiaFkkS7NkTxfnCH+Hdg+yTehTpMcehpok4PgUKKdyCH+9ldu6FhiHRv84Ntqj1vVcw=="],
"@azure/logger": ["@azure/logger@1.3.0", "", { "dependencies": { "@typespec/ts-http-runtime": "^0.3.0", "tslib": "^2.6.2" } }, "sha512-fCqPIfOcLE+CGqGPd66c8bZpwAji98tZ4JI9i/mlTNTlsIWslCfpg48s/ypyLxZTump5sypjrKn2/kY7q8oAbA=="],
"@azure/msal-browser": ["@azure/msal-browser@4.26.2", "", { "dependencies": { "@azure/msal-common": "15.13.2" } }, "sha512-F2U1mEAFsYGC5xzo1KuWc/Sy3CRglU9Ql46cDUx8x/Y3KnAIr1QAq96cIKCk/ZfnVxlvprXWRjNKoEpgLJXLhg=="],
"@azure/msal-common": ["@azure/msal-common@15.13.2", "", {}, "sha512-cNwUoCk3FF8VQ7Ln/MdcJVIv3sF73/OT86cRH81ECsydh7F4CNfIo2OAx6Cegtg8Yv75x4506wN4q+Emo6erOA=="],
"@azure/msal-node": ["@azure/msal-node@3.8.3", "", { "dependencies": { "@azure/msal-common": "15.13.2", "jsonwebtoken": "^9.0.0", "uuid": "^8.3.0" } }, "sha512-Ul7A4gwmaHzYWj2Z5xBDly/W8JSC1vnKgJ898zPMZr0oSf1ah0tiL15sytjycU/PMhDZAlkWtEL1+MzNMU6uww=="],
"@bcoe/v8-coverage": ["@bcoe/v8-coverage@0.2.3", "", {}, "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw=="],
"@esbuild/android-arm": ["@esbuild/android-arm@0.19.2", "", { "os": "android", "cpu": "arm" }, "sha512-tM8yLeYVe7pRyAu9VMi/Q7aunpLwD139EY1S99xbQkT4/q2qa6eA4ige/WJQYdJ8GBL1K33pPFhPfPdJ/WzT8Q=="],
"@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.19.12", "", { "os": "aix", "cpu": "ppc64" }, "sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA=="],
"@esbuild/android-arm64": ["@esbuild/android-arm64@0.19.2", "", { "os": "android", "cpu": "arm64" }, "sha512-lsB65vAbe90I/Qe10OjkmrdxSX4UJDjosDgb8sZUKcg3oefEuW2OT2Vozz8ef7wrJbMcmhvCC+hciF8jY/uAkw=="],
"@esbuild/android-arm": ["@esbuild/android-arm@0.19.12", "", { "os": "android", "cpu": "arm" }, "sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w=="],
"@esbuild/android-x64": ["@esbuild/android-x64@0.19.2", "", { "os": "android", "cpu": "x64" }, "sha512-qK/TpmHt2M/Hg82WXHRc/W/2SGo/l1thtDHZWqFq7oi24AjZ4O/CpPSu6ZuYKFkEgmZlFoa7CooAyYmuvnaG8w=="],
"@esbuild/android-arm64": ["@esbuild/android-arm64@0.19.12", "", { "os": "android", "cpu": "arm64" }, "sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA=="],
"@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.19.2", "", { "os": "darwin", "cpu": "arm64" }, "sha512-Ora8JokrvrzEPEpZO18ZYXkH4asCdc1DLdcVy8TGf5eWtPO1Ie4WroEJzwI52ZGtpODy3+m0a2yEX9l+KUn0tA=="],
"@esbuild/android-x64": ["@esbuild/android-x64@0.19.12", "", { "os": "android", "cpu": "x64" }, "sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew=="],
"@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.19.2", "", { "os": "darwin", "cpu": "x64" }, "sha512-tP+B5UuIbbFMj2hQaUr6EALlHOIOmlLM2FK7jeFBobPy2ERdohI4Ka6ZFjZ1ZYsrHE/hZimGuU90jusRE0pwDw=="],
"@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.19.12", "", { "os": "darwin", "cpu": "arm64" }, "sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g=="],
"@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.19.2", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-YbPY2kc0acfzL1VPVK6EnAlig4f+l8xmq36OZkU0jzBVHcOTyQDhnKQaLzZudNJQyymd9OqQezeaBgkTGdTGeQ=="],
"@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.19.12", "", { "os": "darwin", "cpu": "x64" }, "sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A=="],
"@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.19.2", "", { "os": "freebsd", "cpu": "x64" }, "sha512-nSO5uZT2clM6hosjWHAsS15hLrwCvIWx+b2e3lZ3MwbYSaXwvfO528OF+dLjas1g3bZonciivI8qKR/Hm7IWGw=="],
"@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.19.12", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA=="],
"@esbuild/linux-arm": ["@esbuild/linux-arm@0.19.2", "", { "os": "linux", "cpu": "arm" }, "sha512-Odalh8hICg7SOD7XCj0YLpYCEc+6mkoq63UnExDCiRA2wXEmGlK5JVrW50vZR9Qz4qkvqnHcpH+OFEggO3PgTg=="],
"@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.19.12", "", { "os": "freebsd", "cpu": "x64" }, "sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg=="],
"@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.19.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-ig2P7GeG//zWlU0AggA3pV1h5gdix0MA3wgB+NsnBXViwiGgY77fuN9Wr5uoCrs2YzaYfogXgsWZbm+HGr09xg=="],
"@esbuild/linux-arm": ["@esbuild/linux-arm@0.19.12", "", { "os": "linux", "cpu": "arm" }, "sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w=="],
"@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.19.2", "", { "os": "linux", "cpu": "ia32" }, "sha512-mLfp0ziRPOLSTek0Gd9T5B8AtzKAkoZE70fneiiyPlSnUKKI4lp+mGEnQXcQEHLJAcIYDPSyBvsUbKUG2ri/XQ=="],
"@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.19.12", "", { "os": "linux", "cpu": "arm64" }, "sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA=="],
"@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.19.2", "", { "os": "linux", "cpu": "none" }, "sha512-hn28+JNDTxxCpnYjdDYVMNTR3SKavyLlCHHkufHV91fkewpIyQchS1d8wSbmXhs1fiYDpNww8KTFlJ1dHsxeSw=="],
"@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.19.12", "", { "os": "linux", "cpu": "ia32" }, "sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA=="],
"@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.19.2", "", { "os": "linux", "cpu": "none" }, "sha512-KbXaC0Sejt7vD2fEgPoIKb6nxkfYW9OmFUK9XQE4//PvGIxNIfPk1NmlHmMg6f25x57rpmEFrn1OotASYIAaTg=="],
"@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.19.12", "", { "os": "linux", "cpu": "none" }, "sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA=="],
"@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.19.2", "", { "os": "linux", "cpu": "ppc64" }, "sha512-dJ0kE8KTqbiHtA3Fc/zn7lCd7pqVr4JcT0JqOnbj4LLzYnp+7h8Qi4yjfq42ZlHfhOCM42rBh0EwHYLL6LEzcw=="],
"@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.19.12", "", { "os": "linux", "cpu": "none" }, "sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w=="],
"@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.19.2", "", { "os": "linux", "cpu": "none" }, "sha512-7Z/jKNFufZ/bbu4INqqCN6DDlrmOTmdw6D0gH+6Y7auok2r02Ur661qPuXidPOJ+FSgbEeQnnAGgsVynfLuOEw=="],
"@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.19.12", "", { "os": "linux", "cpu": "ppc64" }, "sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg=="],
"@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.19.2", "", { "os": "linux", "cpu": "s390x" }, "sha512-U+RinR6aXXABFCcAY4gSlv4CL1oOVvSSCdseQmGO66H+XyuQGZIUdhG56SZaDJQcLmrSfRmx5XZOWyCJPRqS7g=="],
"@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.19.12", "", { "os": "linux", "cpu": "none" }, "sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg=="],
"@esbuild/linux-x64": ["@esbuild/linux-x64@0.19.2", "", { "os": "linux", "cpu": "x64" }, "sha512-oxzHTEv6VPm3XXNaHPyUTTte+3wGv7qVQtqaZCrgstI16gCuhNOtBXLEBkBREP57YTd68P0VgDgG73jSD8bwXQ=="],
"@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.19.12", "", { "os": "linux", "cpu": "s390x" }, "sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg=="],
"@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.19.2", "", { "os": "none", "cpu": "x64" }, "sha512-WNa5zZk1XpTTwMDompZmvQLHszDDDN7lYjEHCUmAGB83Bgs20EMs7ICD+oKeT6xt4phV4NDdSi/8OfjPbSbZfQ=="],
"@esbuild/linux-x64": ["@esbuild/linux-x64@0.19.12", "", { "os": "linux", "cpu": "x64" }, "sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg=="],
"@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.19.2", "", { "os": "openbsd", "cpu": "x64" }, "sha512-S6kI1aT3S++Dedb7vxIuUOb3oAxqxk2Rh5rOXOTYnzN8JzW1VzBd+IqPiSpgitu45042SYD3HCoEyhLKQcDFDw=="],
"@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.19.12", "", { "os": "none", "cpu": "x64" }, "sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA=="],
"@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.19.2", "", { "os": "sunos", "cpu": "x64" }, "sha512-VXSSMsmb+Z8LbsQGcBMiM+fYObDNRm8p7tkUDMPG/g4fhFX5DEFmjxIEa3N8Zr96SjsJ1woAhF0DUnS3MF3ARw=="],
"@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.19.12", "", { "os": "openbsd", "cpu": "x64" }, "sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw=="],
"@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.19.2", "", { "os": "win32", "cpu": "arm64" }, "sha512-5NayUlSAyb5PQYFAU9x3bHdsqB88RC3aM9lKDAz4X1mo/EchMIT1Q+pSeBXNgkfNmRecLXA0O8xP+x8V+g/LKg=="],
"@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.19.12", "", { "os": "sunos", "cpu": "x64" }, "sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA=="],
"@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.19.2", "", { "os": "win32", "cpu": "ia32" }, "sha512-47gL/ek1v36iN0wL9L4Q2MFdujR0poLZMJwhO2/N3gA89jgHp4MR8DKCmwYtGNksbfJb9JoTtbkoe6sDhg2QTA=="],
"@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.19.12", "", { "os": "win32", "cpu": "arm64" }, "sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A=="],
"@esbuild/win32-x64": ["@esbuild/win32-x64@0.19.2", "", { "os": "win32", "cpu": "x64" }, "sha512-tcuhV7ncXBqbt/Ybf0IyrMcwVOAPDckMK9rXNHtF17UTK18OKLpg08glminN06pt2WCoALhXdLfSPbVvK/6fxw=="],
"@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.19.12", "", { "os": "win32", "cpu": "ia32" }, "sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ=="],
"@esbuild/win32-x64": ["@esbuild/win32-x64@0.19.12", "", { "os": "win32", "cpu": "x64" }, "sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA=="],
"@isaacs/balanced-match": ["@isaacs/balanced-match@4.0.1", "", {}, "sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ=="],
"@isaacs/brace-expansion": ["@isaacs/brace-expansion@5.0.0", "", { "dependencies": { "@isaacs/balanced-match": "^4.0.1" } }, "sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA=="],
"@isaacs/cliui": ["@isaacs/cliui@8.0.2", "", { "dependencies": { "string-width": "^5.1.2", "string-width-cjs": "npm:string-width@^4.2.0", "strip-ansi": "^7.0.1", "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", "wrap-ansi": "^8.1.0", "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" } }, "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA=="],
@@ -84,41 +117,63 @@
"@jridgewell/resolve-uri": ["@jridgewell/resolve-uri@3.1.2", "", {}, "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw=="],
"@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.0", "", {}, "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ=="],
"@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.5", "", {}, "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og=="],
"@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.25", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ=="],
"@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="],
"@pkgjs/parseargs": ["@pkgjs/parseargs@0.11.0", "", {}, "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg=="],
"@types/bun": ["@types/bun@1.1.10", "", { "dependencies": { "bun-types": "1.1.29" } }, "sha512-76KYVSwrHwr9zsnk6oLXOGs9KvyBg3U066GLO4rk6JZk1ypEPGCUDZ5yOiESyIHWs9cx9iC8r01utYN32XdmgA=="],
"@types/bun": ["@types/bun@1.3.2", "", { "dependencies": { "bun-types": "1.3.2" } }, "sha512-t15P7k5UIgHKkxwnMNkJbWlh/617rkDGEdSsDbu+qNHTaz9SKf7aC8fiIlUdD5RPpH6GEkP0cK7WlvmrEBRtWg=="],
"@types/istanbul-lib-coverage": ["@types/istanbul-lib-coverage@2.0.6", "", {}, "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w=="],
"@types/mocha": ["@types/mocha@10.0.8", "", {}, "sha512-HfMcUmy9hTMJh66VNcmeC9iVErIZJli2bszuXc6julh5YGuRb/W5OnkHjwLNYdFlMis0sY3If5SEAp+PktdJjw=="],
"@types/mocha": ["@types/mocha@10.0.10", "", {}, "sha512-xPyYSz1cMPnJQhl0CLMH68j3gprKZaTjG3s5Vi+fDgx+uhG9NOXwbVt52eFS8ECyXhyKcjDLCBEqBExKuiZb7Q=="],
"@types/node": ["@types/node@20.12.14", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-scnD59RpYD91xngrQQLGkE+6UrHUPzeKZWhhjBSa3HSkwjbQc38+q3RoIVEwxQGRw3M+j5hpNAM+lgV3cVormg=="],
"@types/node": ["@types/node@24.10.1", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-GNWcUTRBgIRJD5zj+Tq0fKOJ5XZajIiBroOF0yvj2bSU1WvNdYS/dn9UxwsujGW4JX06dnHyjV2y9rRaybH0iQ=="],
"@types/vscode": ["@types/vscode@1.81.0", "", {}, "sha512-YIaCwpT+O2E7WOMq0eCgBEABE++SX3Yl/O02GoMIF2DO3qAtvw7m6BXFYsxnc6XyzwZgh6/s/UG78LSSombl2w=="],
"@types/react": ["@types/react@19.2.6", "", { "dependencies": { "csstype": "^3.2.2" } }, "sha512-p/jUvulfgU7oKtj6Xpk8cA2Y1xKTtICGpJYeJXz2YVO2UcvjQgeRMLDGfDeqeRW2Ta+0QNFwcc8X3GH8SxZz6w=="],
"@types/ws": ["@types/ws@8.5.12", "", { "dependencies": { "@types/node": "*" } }, "sha512-3tPRkv1EtkDpzlgyKyI8pGsGZAGPEaXeu0DOj5DI25Ja91bdAYddYHbADRYVrZMRbfW+1l5YwXVDKohDJNQxkQ=="],
"@types/vscode": ["@types/vscode@1.106.1", "", {}, "sha512-R/HV8u2h8CAddSbX8cjpdd7B8/GnE4UjgjpuGuHcbp1xV6yh4OeqU4L1pKjlwujCrSFS0MOpwJAIs/NexMB1fQ=="],
"@vscode/debugadapter": ["@vscode/debugadapter@1.61.0", "", { "dependencies": { "@vscode/debugprotocol": "1.61.0" } }, "sha512-VDGLUFDVAdnftUebZe4uQCIFUbJ7rTc2Grps4D/CXl+qyzTZSQLv5VADEOZ6kBYG4SvlnMLql5vPQ0G6XvUCvQ=="],
"@typespec/ts-http-runtime": ["@typespec/ts-http-runtime@0.3.2", "", { "dependencies": { "http-proxy-agent": "^7.0.0", "https-proxy-agent": "^7.0.0", "tslib": "^2.6.2" } }, "sha512-IlqQ/Gv22xUC1r/WQm4StLkYQmaaTsXAhUVsNE0+xiyf0yRFiH5++q78U3bw6bLKDCTmh0uqKB9eG9+Bt75Dkg=="],
"@vscode/debugadapter-testsupport": ["@vscode/debugadapter-testsupport@1.61.0", "", { "dependencies": { "@vscode/debugprotocol": "1.61.0" } }, "sha512-M/8aNX1aFvupd+SP0NLEVLKUK9y52BuCK5vKO2gzdpSoRUR2fR8oFbGkTie+/p2Yrcswnuf7hFx0xWkV9avRdg=="],
"@vscode/debugadapter": ["@vscode/debugadapter@1.68.0", "", { "dependencies": { "@vscode/debugprotocol": "1.68.0" } }, "sha512-D6gk5Fw2y4FV8oYmltoXpj+VAZexxJFopN/mcZ6YcgzQE9dgq2L45Aj3GLxScJOD6GeLILcxJIaA8l3v11esGg=="],
"@vscode/debugprotocol": ["@vscode/debugprotocol@1.61.0", "", {}, "sha512-K/kF27jIStVFqlmUaGc2u+Dj8IR7YdEiSqShWr7MWhDudqpAW7uu7XMwoFwjpuC9LSaVwJMIX7EFC5OJ/RmnDQ=="],
"@vscode/debugadapter-testsupport": ["@vscode/debugadapter-testsupport@1.68.0", "", { "dependencies": { "@vscode/debugprotocol": "1.68.0" } }, "sha512-UpbaPsCGMKyjIvJFtqFKDD1MVvME50xuOtRBPrqY1WdhAOLjWQN7FcKEoHv3X85twfNL21jW2M54FYwEdEQv4Q=="],
"@vscode/debugprotocol": ["@vscode/debugprotocol@1.68.0", "", {}, "sha512-2J27dysaXmvnfuhFGhfeuxfHRXunqNPxtBoR3koiTOA9rdxWNDTa1zIFLCFMSHJ9MPTPKFcBeblsyaCJCIlQxg=="],
"@vscode/test-cli": ["@vscode/test-cli@0.0.10", "", { "dependencies": { "@types/mocha": "^10.0.2", "c8": "^9.1.0", "chokidar": "^3.5.3", "enhanced-resolve": "^5.15.0", "glob": "^10.3.10", "minimatch": "^9.0.3", "mocha": "^10.2.0", "supports-color": "^9.4.0", "yargs": "^17.7.2" }, "bin": { "vscode-test": "out/bin.mjs" } }, "sha512-B0mMH4ia+MOOtwNiLi79XhA+MLmUItIC8FckEuKrVAVriIuSWjt7vv4+bF8qVFiNFe4QRfzPaIZk39FZGWEwHA=="],
"@vscode/test-electron": ["@vscode/test-electron@2.4.1", "", { "dependencies": { "http-proxy-agent": "^7.0.2", "https-proxy-agent": "^7.0.5", "jszip": "^3.10.1", "ora": "^7.0.1", "semver": "^7.6.2" } }, "sha512-Gc6EdaLANdktQ1t+zozoBVRynfIsMKMc94Svu1QreOBC8y76x4tvaK32TljrLi1LI2+PK58sDVbL7ALdqf3VRQ=="],
"@vscode/test-electron": ["@vscode/test-electron@2.5.2", "", { "dependencies": { "http-proxy-agent": "^7.0.2", "https-proxy-agent": "^7.0.5", "jszip": "^3.10.1", "ora": "^8.1.0", "semver": "^7.6.2" } }, "sha512-8ukpxv4wYe0iWMRQU18jhzJOHkeGKbnw7xWRX3Zw1WJA4cEKbHcmmLPdPrPtL6rhDcrlCZN+xKRpv09n4gRHYg=="],
"@vscode/vsce": ["@vscode/vsce@2.21.0", "", { "dependencies": { "azure-devops-node-api": "^11.0.1", "chalk": "^2.4.2", "cheerio": "^1.0.0-rc.9", "commander": "^6.2.1", "glob": "^7.0.6", "hosted-git-info": "^4.0.2", "jsonc-parser": "^3.2.0", "leven": "^3.1.0", "markdown-it": "^12.3.2", "mime": "^1.3.4", "minimatch": "^3.0.3", "parse-semver": "^1.1.1", "read": "^1.0.7", "semver": "^7.5.2", "tmp": "^0.2.1", "typed-rest-client": "^1.8.4", "url-join": "^4.0.1", "xml2js": "^0.5.0", "yauzl": "^2.3.1", "yazl": "^2.2.2" }, "optionalDependencies": { "keytar": "^7.7.0" }, "bin": { "vsce": "vsce" } }, "sha512-KuxYqScqUY/duJbkj9eE2tN2X/WJoGAy54hHtxT3ZBkM6IzrOg7H7CXGUPBxNlmqku2w/cAjOUSrgIHlzz0mbA=="],
"@vscode/vsce": ["@vscode/vsce@2.32.0", "", { "dependencies": { "@azure/identity": "^4.1.0", "@vscode/vsce-sign": "^2.0.0", "azure-devops-node-api": "^12.5.0", "chalk": "^2.4.2", "cheerio": "^1.0.0-rc.9", "cockatiel": "^3.1.2", "commander": "^6.2.1", "form-data": "^4.0.0", "glob": "^7.0.6", "hosted-git-info": "^4.0.2", "jsonc-parser": "^3.2.0", "leven": "^3.1.0", "markdown-it": "^12.3.2", "mime": "^1.3.4", "minimatch": "^3.0.3", "parse-semver": "^1.1.1", "read": "^1.0.7", "semver": "^7.5.2", "tmp": "^0.2.1", "typed-rest-client": "^1.8.4", "url-join": "^4.0.1", "xml2js": "^0.5.0", "yauzl": "^2.3.1", "yazl": "^2.2.2" }, "optionalDependencies": { "keytar": "^7.7.0" }, "bin": { "vsce": "vsce" } }, "sha512-3EFJfsgrSftIqt3EtdRcAygy/OJ3hstyI1cDmIgkU9CFZW5C+3djr6mfosndCUqcVYuyjmxOK1xmFp/Bq7+NIg=="],
"agent-base": ["agent-base@7.1.1", "", { "dependencies": { "debug": "^4.3.4" } }, "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA=="],
"@vscode/vsce-sign": ["@vscode/vsce-sign@2.0.9", "", { "optionalDependencies": { "@vscode/vsce-sign-alpine-arm64": "2.0.6", "@vscode/vsce-sign-alpine-x64": "2.0.6", "@vscode/vsce-sign-darwin-arm64": "2.0.6", "@vscode/vsce-sign-darwin-x64": "2.0.6", "@vscode/vsce-sign-linux-arm": "2.0.6", "@vscode/vsce-sign-linux-arm64": "2.0.6", "@vscode/vsce-sign-linux-x64": "2.0.6", "@vscode/vsce-sign-win32-arm64": "2.0.6", "@vscode/vsce-sign-win32-x64": "2.0.6" } }, "sha512-8IvaRvtFyzUnGGl3f5+1Cnor3LqaUWvhaUjAYO8Y39OUYlOf3cRd+dowuQYLpZcP3uwSG+mURwjEBOSq4SOJ0g=="],
"@vscode/vsce-sign-alpine-arm64": ["@vscode/vsce-sign-alpine-arm64@2.0.6", "", { "os": "none", "cpu": "arm64" }, "sha512-wKkJBsvKF+f0GfsUuGT0tSW0kZL87QggEiqNqK6/8hvqsXvpx8OsTEc3mnE1kejkh5r+qUyQ7PtF8jZYN0mo8Q=="],
"@vscode/vsce-sign-alpine-x64": ["@vscode/vsce-sign-alpine-x64@2.0.6", "", { "os": "none", "cpu": "x64" }, "sha512-YoAGlmdK39vKi9jA18i4ufBbd95OqGJxRvF3n6ZbCyziwy3O+JgOpIUPxv5tjeO6gQfx29qBivQ8ZZTUF2Ba0w=="],
"@vscode/vsce-sign-darwin-arm64": ["@vscode/vsce-sign-darwin-arm64@2.0.6", "", { "os": "darwin", "cpu": "arm64" }, "sha512-5HMHaJRIQuozm/XQIiJiA0W9uhdblwwl2ZNDSSAeXGO9YhB9MH5C4KIHOmvyjUnKy4UCuiP43VKpIxW1VWP4tQ=="],
"@vscode/vsce-sign-darwin-x64": ["@vscode/vsce-sign-darwin-x64@2.0.6", "", { "os": "darwin", "cpu": "x64" }, "sha512-25GsUbTAiNfHSuRItoQafXOIpxlYj+IXb4/qarrXu7kmbH94jlm5sdWSCKrrREs8+GsXF1b+l3OB7VJy5jsykw=="],
"@vscode/vsce-sign-linux-arm": ["@vscode/vsce-sign-linux-arm@2.0.6", "", { "os": "linux", "cpu": "arm" }, "sha512-UndEc2Xlq4HsuMPnwu7420uqceXjs4yb5W8E2/UkaHBB9OWCwMd3/bRe/1eLe3D8kPpxzcaeTyXiK3RdzS/1CA=="],
"@vscode/vsce-sign-linux-arm64": ["@vscode/vsce-sign-linux-arm64@2.0.6", "", { "os": "linux", "cpu": "arm64" }, "sha512-cfb1qK7lygtMa4NUl2582nP7aliLYuDEVpAbXJMkDq1qE+olIw/es+C8j1LJwvcRq1I2yWGtSn3EkDp9Dq5FdA=="],
"@vscode/vsce-sign-linux-x64": ["@vscode/vsce-sign-linux-x64@2.0.6", "", { "os": "linux", "cpu": "x64" }, "sha512-/olerl1A4sOqdP+hjvJ1sbQjKN07Y3DVnxO4gnbn/ahtQvFrdhUi0G1VsZXDNjfqmXw57DmPi5ASnj/8PGZhAA=="],
"@vscode/vsce-sign-win32-arm64": ["@vscode/vsce-sign-win32-arm64@2.0.6", "", { "os": "win32", "cpu": "arm64" }, "sha512-ivM/MiGIY0PJNZBoGtlRBM/xDpwbdlCWomUWuLmIxbi1Cxe/1nooYrEQoaHD8ojVRgzdQEUzMsRbyF5cJJgYOg=="],
"@vscode/vsce-sign-win32-x64": ["@vscode/vsce-sign-win32-x64@2.0.6", "", { "os": "win32", "cpu": "x64" }, "sha512-mgth9Kvze+u8CruYMmhHw6Zgy3GRX2S+Ed5oSokDEK5vPEwGGKnmuXua9tmFhomeAnhgJnL4DCna3TiNuGrBTQ=="],
"agent-base": ["agent-base@7.1.4", "", {}, "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ=="],
"ansi-colors": ["ansi-colors@4.1.3", "", {}, "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw=="],
"ansi-regex": ["ansi-regex@6.1.0", "", {}, "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA=="],
"ansi-regex": ["ansi-regex@6.2.2", "", {}, "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg=="],
"ansi-styles": ["ansi-styles@3.2.1", "", { "dependencies": { "color-convert": "^1.9.0" } }, "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA=="],
@@ -126,7 +181,9 @@
"argparse": ["argparse@2.0.1", "", {}, "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="],
"azure-devops-node-api": ["azure-devops-node-api@11.2.0", "", { "dependencies": { "tunnel": "0.0.6", "typed-rest-client": "^1.8.4" } }, "sha512-XdiGPhrpaT5J8wdERRKs5g8E0Zy1pvOYTli7z9E8nmOn3YGp4FhtjhrOyFmX/8veWCwdI69mCHKJw6l+4J/bHA=="],
"asynckit": ["asynckit@0.4.0", "", {}, "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="],
"azure-devops-node-api": ["azure-devops-node-api@12.5.0", "", { "dependencies": { "tunnel": "0.0.6", "typed-rest-client": "^1.8.4" } }, "sha512-R5eFskGvOm3U/GzeAuxRkUsAl0hrAwGgWn6zAd2KrZmrEhWZVqLew4OOupbQlXUuojUzpGtq62SmdhJ06N88og=="],
"balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="],
@@ -134,35 +191,41 @@
"binary-extensions": ["binary-extensions@2.3.0", "", {}, "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw=="],
"bl": ["bl@5.1.0", "", { "dependencies": { "buffer": "^6.0.3", "inherits": "^2.0.4", "readable-stream": "^3.4.0" } }, "sha512-tv1ZJHLfTDnXE6tMHv73YgSJaWR2AFuPwMntBe7XL/GBFHnT0CLnsHMogfk5+GzCDC5ZWarSCYaIGATZt9dNsQ=="],
"bl": ["bl@4.1.0", "", { "dependencies": { "buffer": "^5.5.0", "inherits": "^2.0.4", "readable-stream": "^3.4.0" } }, "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w=="],
"boolbase": ["boolbase@1.0.0", "", {}, "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww=="],
"brace-expansion": ["brace-expansion@2.0.1", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA=="],
"brace-expansion": ["brace-expansion@2.0.2", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ=="],
"braces": ["braces@3.0.3", "", { "dependencies": { "fill-range": "^7.1.1" } }, "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA=="],
"browser-stdout": ["browser-stdout@1.3.1", "", {}, "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw=="],
"buffer": ["buffer@6.0.3", "", { "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.2.1" } }, "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA=="],
"buffer": ["buffer@5.7.1", "", { "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.1.13" } }, "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ=="],
"buffer-crc32": ["buffer-crc32@0.2.13", "", {}, "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ=="],
"buffer-equal-constant-time": ["buffer-equal-constant-time@1.0.1", "", {}, "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA=="],
"bun-debug-adapter-protocol": ["bun-debug-adapter-protocol@workspace:../bun-debug-adapter-protocol"],
"bun-inspector-protocol": ["bun-inspector-protocol@workspace:../bun-inspector-protocol"],
"bun-types": ["bun-types@1.1.29", "", { "dependencies": { "@types/node": "~20.12.8", "@types/ws": "~8.5.10" } }, "sha512-En3/TzSPMPyl5UlUB1MHzHpcrZDakTm7mS203eLoX1fBoEa3PW+aSS8GAqVJ7Is/m34Z5ogL+ECniLY0uDaCPw=="],
"bun-types": ["bun-types@1.3.2", "", { "dependencies": { "@types/node": "*" }, "peerDependencies": { "@types/react": "^19" } }, "sha512-i/Gln4tbzKNuxP70OWhJRZz1MRfvqExowP7U6JKoI8cntFrtxg7RJK3jvz7wQW54UuvNC8tbKHHri5fy74FVqg=="],
"bundle-name": ["bundle-name@4.1.0", "", { "dependencies": { "run-applescript": "^7.0.0" } }, "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q=="],
"c8": ["c8@9.1.0", "", { "dependencies": { "@bcoe/v8-coverage": "^0.2.3", "@istanbuljs/schema": "^0.1.3", "find-up": "^5.0.0", "foreground-child": "^3.1.1", "istanbul-lib-coverage": "^3.2.0", "istanbul-lib-report": "^3.0.1", "istanbul-reports": "^3.1.6", "test-exclude": "^6.0.0", "v8-to-istanbul": "^9.0.0", "yargs": "^17.7.2", "yargs-parser": "^21.1.1" }, "bin": { "c8": "bin/c8.js" } }, "sha512-mBWcT5iqNir1zIkzSPyI3NCR9EZCVI3WUD+AVO17MVWTSFNyUueXE82qTeampNtTr+ilN/5Ua3j24LgbCKjDVg=="],
"call-bind": ["call-bind@1.0.2", "", { "dependencies": { "function-bind": "^1.1.1", "get-intrinsic": "^1.0.2" } }, "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA=="],
"call-bind-apply-helpers": ["call-bind-apply-helpers@1.0.2", "", { "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2" } }, "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ=="],
"call-bound": ["call-bound@1.0.4", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.2", "get-intrinsic": "^1.3.0" } }, "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg=="],
"camelcase": ["camelcase@6.3.0", "", {}, "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA=="],
"chalk": ["chalk@2.4.2", "", { "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", "supports-color": "^5.3.0" } }, "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ=="],
"cheerio": ["cheerio@1.0.0-rc.12", "", { "dependencies": { "cheerio-select": "^2.1.0", "dom-serializer": "^2.0.0", "domhandler": "^5.0.3", "domutils": "^3.0.1", "htmlparser2": "^8.0.1", "parse5": "^7.0.0", "parse5-htmlparser2-tree-adapter": "^7.0.0" } }, "sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q=="],
"cheerio": ["cheerio@1.1.2", "", { "dependencies": { "cheerio-select": "^2.1.0", "dom-serializer": "^2.0.0", "domhandler": "^5.0.3", "domutils": "^3.2.2", "encoding-sniffer": "^0.2.1", "htmlparser2": "^10.0.0", "parse5": "^7.3.0", "parse5-htmlparser2-tree-adapter": "^7.1.0", "parse5-parser-stream": "^7.1.2", "undici": "^7.12.0", "whatwg-mimetype": "^4.0.0" } }, "sha512-IkxPpb5rS/d1IiLbHMgfPuS0FgiWTtFIm/Nj+2woXDLTZ7fOT2eqzgYbdMlLweqlHbsZjxEChoVK+7iph7jyQg=="],
"cheerio-select": ["cheerio-select@2.1.0", "", { "dependencies": { "boolbase": "^1.0.0", "css-select": "^5.1.0", "css-what": "^6.1.0", "domelementtype": "^2.3.0", "domhandler": "^5.0.3", "domutils": "^3.0.1" } }, "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g=="],
@@ -170,16 +233,20 @@
"chownr": ["chownr@1.1.4", "", {}, "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg=="],
"cli-cursor": ["cli-cursor@4.0.0", "", { "dependencies": { "restore-cursor": "^4.0.0" } }, "sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg=="],
"cli-cursor": ["cli-cursor@5.0.0", "", { "dependencies": { "restore-cursor": "^5.0.0" } }, "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw=="],
"cli-spinners": ["cli-spinners@2.9.2", "", {}, "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg=="],
"cliui": ["cliui@8.0.1", "", { "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.1", "wrap-ansi": "^7.0.0" } }, "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ=="],
"cockatiel": ["cockatiel@3.2.1", "", {}, "sha512-gfrHV6ZPkquExvMh9IOkKsBzNDk6sDuZ6DdBGUBkvFnTCqCxzpuq48RySgP0AnaqQkw2zynOFj9yly6T1Q2G5Q=="],
"color-convert": ["color-convert@1.9.3", "", { "dependencies": { "color-name": "1.1.3" } }, "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg=="],
"color-name": ["color-name@1.1.3", "", {}, "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw=="],
"combined-stream": ["combined-stream@1.0.8", "", { "dependencies": { "delayed-stream": "~1.0.0" } }, "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg=="],
"commander": ["commander@6.2.1", "", {}, "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA=="],
"concat-map": ["concat-map@0.0.1", "", {}, "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="],
@@ -188,13 +255,15 @@
"core-util-is": ["core-util-is@1.0.3", "", {}, "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ=="],
"cross-spawn": ["cross-spawn@7.0.3", "", { "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w=="],
"cross-spawn": ["cross-spawn@7.0.6", "", { "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA=="],
"css-select": ["css-select@5.1.0", "", { "dependencies": { "boolbase": "^1.0.0", "css-what": "^6.1.0", "domhandler": "^5.0.2", "domutils": "^3.0.1", "nth-check": "^2.0.1" } }, "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg=="],
"css-select": ["css-select@5.2.2", "", { "dependencies": { "boolbase": "^1.0.0", "css-what": "^6.1.0", "domhandler": "^5.0.2", "domutils": "^3.0.1", "nth-check": "^2.0.1" } }, "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw=="],
"css-what": ["css-what@6.1.0", "", {}, "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw=="],
"css-what": ["css-what@6.2.2", "", {}, "sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA=="],
"debug": ["debug@4.3.7", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ=="],
"csstype": ["csstype@3.2.3", "", {}, "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ=="],
"debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="],
"decamelize": ["decamelize@4.0.0", "", {}, "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ=="],
@@ -202,7 +271,15 @@
"deep-extend": ["deep-extend@0.6.0", "", {}, "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA=="],
"detect-libc": ["detect-libc@2.0.2", "", {}, "sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw=="],
"default-browser": ["default-browser@5.4.0", "", { "dependencies": { "bundle-name": "^4.1.0", "default-browser-id": "^5.0.0" } }, "sha512-XDuvSq38Hr1MdN47EDvYtx3U0MTqpCEn+F6ft8z2vYDzMrvQhVp0ui9oQdqW3MvK3vqUETglt1tVGgjLuJ5izg=="],
"default-browser-id": ["default-browser-id@5.0.1", "", {}, "sha512-x1VCxdX4t+8wVfd1so/9w+vQ4vx7lKd2Qp5tDRutErwmR85OgmfX7RlLRMWafRMY7hbEiXIbudNrjOAPa/hL8Q=="],
"define-lazy-prop": ["define-lazy-prop@3.0.0", "", {}, "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg=="],
"delayed-stream": ["delayed-stream@1.0.0", "", {}, "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ=="],
"detect-libc": ["detect-libc@2.1.2", "", {}, "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ=="],
"diff": ["diff@5.2.0", "", {}, "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A=="],
@@ -212,19 +289,33 @@
"domhandler": ["domhandler@5.0.3", "", { "dependencies": { "domelementtype": "^2.3.0" } }, "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w=="],
"domutils": ["domutils@3.1.0", "", { "dependencies": { "dom-serializer": "^2.0.0", "domelementtype": "^2.3.0", "domhandler": "^5.0.3" } }, "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA=="],
"domutils": ["domutils@3.2.2", "", { "dependencies": { "dom-serializer": "^2.0.0", "domelementtype": "^2.3.0", "domhandler": "^5.0.3" } }, "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw=="],
"dunder-proto": ["dunder-proto@1.0.1", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.1", "es-errors": "^1.3.0", "gopd": "^1.2.0" } }, "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A=="],
"eastasianwidth": ["eastasianwidth@0.2.0", "", {}, "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA=="],
"ecdsa-sig-formatter": ["ecdsa-sig-formatter@1.0.11", "", { "dependencies": { "safe-buffer": "^5.0.1" } }, "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ=="],
"emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="],
"end-of-stream": ["end-of-stream@1.4.4", "", { "dependencies": { "once": "^1.4.0" } }, "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q=="],
"encoding-sniffer": ["encoding-sniffer@0.2.1", "", { "dependencies": { "iconv-lite": "^0.6.3", "whatwg-encoding": "^3.1.1" } }, "sha512-5gvq20T6vfpekVtqrYQsSCFZ1wEg5+wW0/QaZMWkFr6BqD3NfKs0rLCx4rrVlSWJeZb5NBJgVLswK/w2MWU+Gw=="],
"enhanced-resolve": ["enhanced-resolve@5.17.1", "", { "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.2.0" } }, "sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg=="],
"end-of-stream": ["end-of-stream@1.4.5", "", { "dependencies": { "once": "^1.4.0" } }, "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg=="],
"enhanced-resolve": ["enhanced-resolve@5.18.3", "", { "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.2.0" } }, "sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww=="],
"entities": ["entities@2.1.0", "", {}, "sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w=="],
"esbuild": ["esbuild@0.19.2", "", { "optionalDependencies": { "@esbuild/android-arm": "0.19.2", "@esbuild/android-arm64": "0.19.2", "@esbuild/android-x64": "0.19.2", "@esbuild/darwin-arm64": "0.19.2", "@esbuild/darwin-x64": "0.19.2", "@esbuild/freebsd-arm64": "0.19.2", "@esbuild/freebsd-x64": "0.19.2", "@esbuild/linux-arm": "0.19.2", "@esbuild/linux-arm64": "0.19.2", "@esbuild/linux-ia32": "0.19.2", "@esbuild/linux-loong64": "0.19.2", "@esbuild/linux-mips64el": "0.19.2", "@esbuild/linux-ppc64": "0.19.2", "@esbuild/linux-riscv64": "0.19.2", "@esbuild/linux-s390x": "0.19.2", "@esbuild/linux-x64": "0.19.2", "@esbuild/netbsd-x64": "0.19.2", "@esbuild/openbsd-x64": "0.19.2", "@esbuild/sunos-x64": "0.19.2", "@esbuild/win32-arm64": "0.19.2", "@esbuild/win32-ia32": "0.19.2", "@esbuild/win32-x64": "0.19.2" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-G6hPax8UbFakEj3hWO0Vs52LQ8k3lnBhxZWomUJDxfz3rZTLqF5k/FCzuNdLx2RbpBiQQF9H9onlDDH1lZsnjg=="],
"es-define-property": ["es-define-property@1.0.1", "", {}, "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g=="],
"es-errors": ["es-errors@1.3.0", "", {}, "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw=="],
"es-object-atoms": ["es-object-atoms@1.1.1", "", { "dependencies": { "es-errors": "^1.3.0" } }, "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA=="],
"es-set-tostringtag": ["es-set-tostringtag@2.1.0", "", { "dependencies": { "es-errors": "^1.3.0", "get-intrinsic": "^1.2.6", "has-tostringtag": "^1.0.2", "hasown": "^2.0.2" } }, "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA=="],
"esbuild": ["esbuild@0.19.12", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.19.12", "@esbuild/android-arm": "0.19.12", "@esbuild/android-arm64": "0.19.12", "@esbuild/android-x64": "0.19.12", "@esbuild/darwin-arm64": "0.19.12", "@esbuild/darwin-x64": "0.19.12", "@esbuild/freebsd-arm64": "0.19.12", "@esbuild/freebsd-x64": "0.19.12", "@esbuild/linux-arm": "0.19.12", "@esbuild/linux-arm64": "0.19.12", "@esbuild/linux-ia32": "0.19.12", "@esbuild/linux-loong64": "0.19.12", "@esbuild/linux-mips64el": "0.19.12", "@esbuild/linux-ppc64": "0.19.12", "@esbuild/linux-riscv64": "0.19.12", "@esbuild/linux-s390x": "0.19.12", "@esbuild/linux-x64": "0.19.12", "@esbuild/netbsd-x64": "0.19.12", "@esbuild/openbsd-x64": "0.19.12", "@esbuild/sunos-x64": "0.19.12", "@esbuild/win32-arm64": "0.19.12", "@esbuild/win32-ia32": "0.19.12", "@esbuild/win32-x64": "0.19.12" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg=="],
"escalade": ["escalade@3.2.0", "", {}, "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA=="],
@@ -240,7 +331,9 @@
"flat": ["flat@5.0.2", "", { "bin": { "flat": "cli.js" } }, "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ=="],
"foreground-child": ["foreground-child@3.3.0", "", { "dependencies": { "cross-spawn": "^7.0.0", "signal-exit": "^4.0.1" } }, "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg=="],
"foreground-child": ["foreground-child@3.3.1", "", { "dependencies": { "cross-spawn": "^7.0.6", "signal-exit": "^4.0.1" } }, "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw=="],
"form-data": ["form-data@4.0.5", "", { "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", "es-set-tostringtag": "^2.1.0", "hasown": "^2.0.2", "mime-types": "^2.1.12" } }, "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w=="],
"fs-constants": ["fs-constants@1.0.0", "", {}, "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow=="],
@@ -248,27 +341,33 @@
"fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="],
"function-bind": ["function-bind@1.1.1", "", {}, "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="],
"function-bind": ["function-bind@1.1.2", "", {}, "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="],
"get-caller-file": ["get-caller-file@2.0.5", "", {}, "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg=="],
"get-intrinsic": ["get-intrinsic@1.2.1", "", { "dependencies": { "function-bind": "^1.1.1", "has": "^1.0.3", "has-proto": "^1.0.1", "has-symbols": "^1.0.3" } }, "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw=="],
"get-east-asian-width": ["get-east-asian-width@1.4.0", "", {}, "sha512-QZjmEOC+IT1uk6Rx0sX22V6uHWVwbdbxf1faPqJ1QhLdGgsRGCZoyaQBm/piRdJy/D2um6hM1UP7ZEeQ4EkP+Q=="],
"get-intrinsic": ["get-intrinsic@1.3.0", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.2", "es-define-property": "^1.0.1", "es-errors": "^1.3.0", "es-object-atoms": "^1.1.1", "function-bind": "^1.1.2", "get-proto": "^1.0.1", "gopd": "^1.2.0", "has-symbols": "^1.1.0", "hasown": "^2.0.2", "math-intrinsics": "^1.1.0" } }, "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ=="],
"get-proto": ["get-proto@1.0.1", "", { "dependencies": { "dunder-proto": "^1.0.1", "es-object-atoms": "^1.0.0" } }, "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g=="],
"github-from-package": ["github-from-package@0.0.0", "", {}, "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw=="],
"glob": ["glob@10.4.5", "", { "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^3.1.2", "minimatch": "^9.0.4", "minipass": "^7.1.2", "package-json-from-dist": "^1.0.0", "path-scurry": "^1.11.1" }, "bin": { "glob": "dist/esm/bin.mjs" } }, "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg=="],
"glob": ["glob@13.0.0", "", { "dependencies": { "minimatch": "^10.1.1", "minipass": "^7.1.2", "path-scurry": "^2.0.0" } }, "sha512-tvZgpqk6fz4BaNZ66ZsRaZnbHvP/jG3uKJvAZOwEVUL4RTA5nJeeLYfyN9/VA8NX/V3IBG+hkeuGpKjvELkVhA=="],
"glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="],
"graceful-fs": ["graceful-fs@4.2.11", "", {}, "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="],
"gopd": ["gopd@1.2.0", "", {}, "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg=="],
"has": ["has@1.0.3", "", { "dependencies": { "function-bind": "^1.1.1" } }, "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw=="],
"graceful-fs": ["graceful-fs@4.2.11", "", {}, "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="],
"has-flag": ["has-flag@4.0.0", "", {}, "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="],
"has-proto": ["has-proto@1.0.1", "", {}, "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg=="],
"has-symbols": ["has-symbols@1.1.0", "", {}, "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ=="],
"has-symbols": ["has-symbols@1.0.3", "", {}, "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A=="],
"has-tostringtag": ["has-tostringtag@1.0.2", "", { "dependencies": { "has-symbols": "^1.0.3" } }, "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw=="],
"hasown": ["hasown@2.0.2", "", { "dependencies": { "function-bind": "^1.1.2" } }, "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ=="],
"he": ["he@1.2.0", "", { "bin": { "he": "bin/he" } }, "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw=="],
@@ -276,11 +375,13 @@
"html-escaper": ["html-escaper@2.0.2", "", {}, "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg=="],
"htmlparser2": ["htmlparser2@8.0.2", "", { "dependencies": { "domelementtype": "^2.3.0", "domhandler": "^5.0.3", "domutils": "^3.0.1", "entities": "^4.4.0" } }, "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA=="],
"htmlparser2": ["htmlparser2@10.0.0", "", { "dependencies": { "domelementtype": "^2.3.0", "domhandler": "^5.0.3", "domutils": "^3.2.1", "entities": "^6.0.0" } }, "sha512-TwAZM+zE5Tq3lrEHvOlvwgj1XLWQCtaaibSN11Q+gGBAS7Y1uZSWwXXRe4iF6OXnaq1riyQAPFOBtYc77Mxq0g=="],
"http-proxy-agent": ["http-proxy-agent@7.0.2", "", { "dependencies": { "agent-base": "^7.1.0", "debug": "^4.3.4" } }, "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig=="],
"https-proxy-agent": ["https-proxy-agent@7.0.5", "", { "dependencies": { "agent-base": "^7.0.2", "debug": "4" } }, "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw=="],
"https-proxy-agent": ["https-proxy-agent@7.0.6", "", { "dependencies": { "agent-base": "^7.1.2", "debug": "4" } }, "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw=="],
"iconv-lite": ["iconv-lite@0.6.3", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw=="],
"ieee754": ["ieee754@1.2.1", "", {}, "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="],
@@ -294,19 +395,25 @@
"is-binary-path": ["is-binary-path@2.1.0", "", { "dependencies": { "binary-extensions": "^2.0.0" } }, "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw=="],
"is-docker": ["is-docker@3.0.0", "", { "bin": { "is-docker": "cli.js" } }, "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ=="],
"is-extglob": ["is-extglob@2.1.1", "", {}, "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ=="],
"is-fullwidth-code-point": ["is-fullwidth-code-point@3.0.0", "", {}, "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="],
"is-glob": ["is-glob@4.0.3", "", { "dependencies": { "is-extglob": "^2.1.1" } }, "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg=="],
"is-inside-container": ["is-inside-container@1.0.0", "", { "dependencies": { "is-docker": "^3.0.0" }, "bin": { "is-inside-container": "cli.js" } }, "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA=="],
"is-interactive": ["is-interactive@2.0.0", "", {}, "sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ=="],
"is-number": ["is-number@7.0.0", "", {}, "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng=="],
"is-plain-obj": ["is-plain-obj@2.1.0", "", {}, "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA=="],
"is-unicode-supported": ["is-unicode-supported@1.3.0", "", {}, "sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ=="],
"is-unicode-supported": ["is-unicode-supported@2.1.0", "", {}, "sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ=="],
"is-wsl": ["is-wsl@3.1.0", "", { "dependencies": { "is-inside-container": "^1.0.0" } }, "sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw=="],
"isarray": ["isarray@1.0.0", "", {}, "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ=="],
@@ -316,16 +423,22 @@
"istanbul-lib-report": ["istanbul-lib-report@3.0.1", "", { "dependencies": { "istanbul-lib-coverage": "^3.0.0", "make-dir": "^4.0.0", "supports-color": "^7.1.0" } }, "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw=="],
"istanbul-reports": ["istanbul-reports@3.1.7", "", { "dependencies": { "html-escaper": "^2.0.0", "istanbul-lib-report": "^3.0.0" } }, "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g=="],
"istanbul-reports": ["istanbul-reports@3.2.0", "", { "dependencies": { "html-escaper": "^2.0.0", "istanbul-lib-report": "^3.0.0" } }, "sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA=="],
"jackspeak": ["jackspeak@3.4.3", "", { "dependencies": { "@isaacs/cliui": "^8.0.2" }, "optionalDependencies": { "@pkgjs/parseargs": "^0.11.0" } }, "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw=="],
"js-yaml": ["js-yaml@4.1.0", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA=="],
"js-yaml": ["js-yaml@4.1.1", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA=="],
"jsonc-parser": ["jsonc-parser@3.2.0", "", {}, "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w=="],
"jsonc-parser": ["jsonc-parser@3.3.1", "", {}, "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ=="],
"jsonwebtoken": ["jsonwebtoken@9.0.2", "", { "dependencies": { "jws": "^3.2.2", "lodash.includes": "^4.3.0", "lodash.isboolean": "^3.0.3", "lodash.isinteger": "^4.0.4", "lodash.isnumber": "^3.0.3", "lodash.isplainobject": "^4.0.6", "lodash.isstring": "^4.0.1", "lodash.once": "^4.0.0", "ms": "^2.1.1", "semver": "^7.5.4" } }, "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ=="],
"jszip": ["jszip@3.10.1", "", { "dependencies": { "lie": "~3.3.0", "pako": "~1.0.2", "readable-stream": "~2.3.6", "setimmediate": "^1.0.5" } }, "sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g=="],
"jwa": ["jwa@1.4.2", "", { "dependencies": { "buffer-equal-constant-time": "^1.0.1", "ecdsa-sig-formatter": "1.0.11", "safe-buffer": "^5.0.1" } }, "sha512-eeH5JO+21J78qMvTIDdBXidBd6nG2kZjg5Ohz/1fpa28Z4CcsWUzJ1ZZyFq/3z3N17aZy+ZuBoHljASbL1WfOw=="],
"jws": ["jws@3.2.2", "", { "dependencies": { "jwa": "^1.4.1", "safe-buffer": "^5.0.1" } }, "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA=="],
"keytar": ["keytar@7.9.0", "", { "dependencies": { "node-addon-api": "^4.3.0", "prebuild-install": "^7.0.1" } }, "sha512-VPD8mtVtm5JNtA2AErl6Chp06JBfy7diFQ7TQQhdpWOl6MrCRB+eRbvAZUsbGQS9kiMq0coJsy0W0vHpDCkWsQ=="],
"leven": ["leven@3.1.0", "", {}, "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A=="],
@@ -336,6 +449,20 @@
"locate-path": ["locate-path@6.0.0", "", { "dependencies": { "p-locate": "^5.0.0" } }, "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw=="],
"lodash.includes": ["lodash.includes@4.3.0", "", {}, "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w=="],
"lodash.isboolean": ["lodash.isboolean@3.0.3", "", {}, "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg=="],
"lodash.isinteger": ["lodash.isinteger@4.0.4", "", {}, "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA=="],
"lodash.isnumber": ["lodash.isnumber@3.0.3", "", {}, "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw=="],
"lodash.isplainobject": ["lodash.isplainobject@4.0.6", "", {}, "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA=="],
"lodash.isstring": ["lodash.isstring@4.0.1", "", {}, "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw=="],
"lodash.once": ["lodash.once@4.1.1", "", {}, "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg=="],
"log-symbols": ["log-symbols@4.1.0", "", { "dependencies": { "chalk": "^4.1.0", "is-unicode-supported": "^0.1.0" } }, "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg=="],
"lru-cache": ["lru-cache@6.0.0", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA=="],
@@ -344,11 +471,17 @@
"markdown-it": ["markdown-it@12.3.2", "", { "dependencies": { "argparse": "^2.0.1", "entities": "~2.1.0", "linkify-it": "^3.0.1", "mdurl": "^1.0.1", "uc.micro": "^1.0.5" }, "bin": { "markdown-it": "bin/markdown-it.js" } }, "sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg=="],
"math-intrinsics": ["math-intrinsics@1.1.0", "", {}, "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g=="],
"mdurl": ["mdurl@1.0.1", "", {}, "sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g=="],
"mime": ["mime@1.6.0", "", { "bin": { "mime": "cli.js" } }, "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg=="],
"mimic-fn": ["mimic-fn@2.1.0", "", {}, "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg=="],
"mime-db": ["mime-db@1.52.0", "", {}, "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="],
"mime-types": ["mime-types@2.1.35", "", { "dependencies": { "mime-db": "1.52.0" } }, "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw=="],
"mimic-function": ["mimic-function@5.0.1", "", {}, "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA=="],
"mimic-response": ["mimic-response@3.1.0", "", {}, "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ=="],
@@ -360,15 +493,15 @@
"mkdirp-classic": ["mkdirp-classic@0.5.3", "", {}, "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A=="],
"mocha": ["mocha@10.7.3", "", { "dependencies": { "ansi-colors": "^4.1.3", "browser-stdout": "^1.3.1", "chokidar": "^3.5.3", "debug": "^4.3.5", "diff": "^5.2.0", "escape-string-regexp": "^4.0.0", "find-up": "^5.0.0", "glob": "^8.1.0", "he": "^1.2.0", "js-yaml": "^4.1.0", "log-symbols": "^4.1.0", "minimatch": "^5.1.6", "ms": "^2.1.3", "serialize-javascript": "^6.0.2", "strip-json-comments": "^3.1.1", "supports-color": "^8.1.1", "workerpool": "^6.5.1", "yargs": "^16.2.0", "yargs-parser": "^20.2.9", "yargs-unparser": "^2.0.0" }, "bin": { "mocha": "bin/mocha.js", "_mocha": "bin/_mocha" } }, "sha512-uQWxAu44wwiACGqjbPYmjo7Lg8sFrS3dQe7PP2FQI+woptP4vZXSMcfMyFL/e1yFEeEpV4RtyTpZROOKmxis+A=="],
"mocha": ["mocha@10.8.2", "", { "dependencies": { "ansi-colors": "^4.1.3", "browser-stdout": "^1.3.1", "chokidar": "^3.5.3", "debug": "^4.3.5", "diff": "^5.2.0", "escape-string-regexp": "^4.0.0", "find-up": "^5.0.0", "glob": "^8.1.0", "he": "^1.2.0", "js-yaml": "^4.1.0", "log-symbols": "^4.1.0", "minimatch": "^5.1.6", "ms": "^2.1.3", "serialize-javascript": "^6.0.2", "strip-json-comments": "^3.1.1", "supports-color": "^8.1.1", "workerpool": "^6.5.1", "yargs": "^16.2.0", "yargs-parser": "^20.2.9", "yargs-unparser": "^2.0.0" }, "bin": { "mocha": "bin/mocha.js", "_mocha": "bin/_mocha" } }, "sha512-VZlYo/WE8t1tstuRmqgeyBgCbJc/lEdopaa+axcKzTBJ+UIdlAB9XnmvTCAH4pwR4ElNInaedhEBmZD8iCSVEg=="],
"ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="],
"mute-stream": ["mute-stream@0.0.8", "", {}, "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA=="],
"napi-build-utils": ["napi-build-utils@1.0.2", "", {}, "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg=="],
"napi-build-utils": ["napi-build-utils@2.0.0", "", {}, "sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA=="],
"node-abi": ["node-abi@3.47.0", "", { "dependencies": { "semver": "^7.3.5" } }, "sha512-2s6B2CWZM//kPgwnuI0KrYwNjfdByE25zvAaEpq9IH4zcNsarH8Ihu/UuX6XMPEogDAxkuUFeZn60pXNHAqn3A=="],
"node-abi": ["node-abi@3.85.0", "", { "dependencies": { "semver": "^7.3.5" } }, "sha512-zsFhmbkAzwhTft6nd3VxcG0cvJsT70rL+BIGHWVq5fi6MwGrHwzqKaxXE+Hl2GmnGItnDKPPkO5/LQqjVkIdFg=="],
"node-addon-api": ["node-addon-api@4.3.0", "", {}, "sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ=="],
@@ -376,27 +509,31 @@
"nth-check": ["nth-check@2.1.1", "", { "dependencies": { "boolbase": "^1.0.0" } }, "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w=="],
"object-inspect": ["object-inspect@1.12.3", "", {}, "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g=="],
"object-inspect": ["object-inspect@1.13.4", "", {}, "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew=="],
"once": ["once@1.4.0", "", { "dependencies": { "wrappy": "1" } }, "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w=="],
"onetime": ["onetime@5.1.2", "", { "dependencies": { "mimic-fn": "^2.1.0" } }, "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg=="],
"onetime": ["onetime@7.0.0", "", { "dependencies": { "mimic-function": "^5.0.0" } }, "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ=="],
"ora": ["ora@7.0.1", "", { "dependencies": { "chalk": "^5.3.0", "cli-cursor": "^4.0.0", "cli-spinners": "^2.9.0", "is-interactive": "^2.0.0", "is-unicode-supported": "^1.3.0", "log-symbols": "^5.1.0", "stdin-discarder": "^0.1.0", "string-width": "^6.1.0", "strip-ansi": "^7.1.0" } }, "sha512-0TUxTiFJWv+JnjWm4o9yvuskpEJLXTcng8MJuKd+SzAzp2o+OP3HWqNhB4OdJRt1Vsd9/mR0oyaEYlOnL7XIRw=="],
"open": ["open@10.2.0", "", { "dependencies": { "default-browser": "^5.2.1", "define-lazy-prop": "^3.0.0", "is-inside-container": "^1.0.0", "wsl-utils": "^0.1.0" } }, "sha512-YgBpdJHPyQ2UE5x+hlSXcnejzAvD0b22U2OuAP+8OnlJT+PjWPxtgmGqKKc+RgTM63U9gN0YzrYc71R2WT/hTA=="],
"ora": ["ora@8.2.0", "", { "dependencies": { "chalk": "^5.3.0", "cli-cursor": "^5.0.0", "cli-spinners": "^2.9.2", "is-interactive": "^2.0.0", "is-unicode-supported": "^2.0.0", "log-symbols": "^6.0.0", "stdin-discarder": "^0.2.2", "string-width": "^7.2.0", "strip-ansi": "^7.1.0" } }, "sha512-weP+BZ8MVNnlCm8c0Qdc1WSWq4Qn7I+9CJGm7Qali6g44e/PUzbjNqJX5NJ9ljlNMosfJvg1fKEGILklK9cwnw=="],
"p-limit": ["p-limit@3.1.0", "", { "dependencies": { "yocto-queue": "^0.1.0" } }, "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ=="],
"p-locate": ["p-locate@5.0.0", "", { "dependencies": { "p-limit": "^3.0.2" } }, "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw=="],
"package-json-from-dist": ["package-json-from-dist@1.0.0", "", {}, "sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw=="],
"package-json-from-dist": ["package-json-from-dist@1.0.1", "", {}, "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw=="],
"pako": ["pako@1.0.11", "", {}, "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw=="],
"parse-semver": ["parse-semver@1.1.1", "", { "dependencies": { "semver": "^5.1.0" } }, "sha512-Eg1OuNntBMH0ojvEKSrvDSnwLmvVuUOSdylH/pSCPNMIspLlweJyIWXCE+k/5hm3cj/EBUYwmWkjhBALNP4LXQ=="],
"parse5": ["parse5@7.1.2", "", { "dependencies": { "entities": "^4.4.0" } }, "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw=="],
"parse5": ["parse5@7.3.0", "", { "dependencies": { "entities": "^6.0.0" } }, "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw=="],
"parse5-htmlparser2-tree-adapter": ["parse5-htmlparser2-tree-adapter@7.0.0", "", { "dependencies": { "domhandler": "^5.0.2", "parse5": "^7.0.0" } }, "sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g=="],
"parse5-htmlparser2-tree-adapter": ["parse5-htmlparser2-tree-adapter@7.1.0", "", { "dependencies": { "domhandler": "^5.0.3", "parse5": "^7.0.0" } }, "sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g=="],
"parse5-parser-stream": ["parse5-parser-stream@7.1.2", "", { "dependencies": { "parse5": "^7.0.0" } }, "sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow=="],
"path-exists": ["path-exists@4.0.0", "", {}, "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w=="],
@@ -404,19 +541,19 @@
"path-key": ["path-key@3.1.1", "", {}, "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="],
"path-scurry": ["path-scurry@1.11.1", "", { "dependencies": { "lru-cache": "^10.2.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" } }, "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA=="],
"path-scurry": ["path-scurry@2.0.1", "", { "dependencies": { "lru-cache": "^11.0.0", "minipass": "^7.1.2" } }, "sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA=="],
"pend": ["pend@1.2.0", "", {}, "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg=="],
"picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="],
"prebuild-install": ["prebuild-install@7.1.1", "", { "dependencies": { "detect-libc": "^2.0.0", "expand-template": "^2.0.3", "github-from-package": "0.0.0", "minimist": "^1.2.3", "mkdirp-classic": "^0.5.3", "napi-build-utils": "^1.0.1", "node-abi": "^3.3.0", "pump": "^3.0.0", "rc": "^1.2.7", "simple-get": "^4.0.0", "tar-fs": "^2.0.0", "tunnel-agent": "^0.6.0" }, "bin": { "prebuild-install": "bin.js" } }, "sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw=="],
"prebuild-install": ["prebuild-install@7.1.3", "", { "dependencies": { "detect-libc": "^2.0.0", "expand-template": "^2.0.3", "github-from-package": "0.0.0", "minimist": "^1.2.3", "mkdirp-classic": "^0.5.3", "napi-build-utils": "^2.0.0", "node-abi": "^3.3.0", "pump": "^3.0.0", "rc": "^1.2.7", "simple-get": "^4.0.0", "tar-fs": "^2.0.0", "tunnel-agent": "^0.6.0" }, "bin": { "prebuild-install": "bin.js" } }, "sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug=="],
"process-nextick-args": ["process-nextick-args@2.0.1", "", {}, "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="],
"pump": ["pump@3.0.0", "", { "dependencies": { "end-of-stream": "^1.1.0", "once": "^1.3.1" } }, "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww=="],
"pump": ["pump@3.0.3", "", { "dependencies": { "end-of-stream": "^1.1.0", "once": "^1.3.1" } }, "sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA=="],
"qs": ["qs@6.11.2", "", { "dependencies": { "side-channel": "^1.0.4" } }, "sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA=="],
"qs": ["qs@6.14.0", "", { "dependencies": { "side-channel": "^1.1.0" } }, "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w=="],
"randombytes": ["randombytes@2.1.0", "", { "dependencies": { "safe-buffer": "^5.1.0" } }, "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ=="],
@@ -430,15 +567,17 @@
"require-directory": ["require-directory@2.1.1", "", {}, "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q=="],
"restore-cursor": ["restore-cursor@4.0.0", "", { "dependencies": { "onetime": "^5.1.0", "signal-exit": "^3.0.2" } }, "sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg=="],
"restore-cursor": ["restore-cursor@5.1.0", "", { "dependencies": { "onetime": "^7.0.0", "signal-exit": "^4.1.0" } }, "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA=="],
"rimraf": ["rimraf@3.0.2", "", { "dependencies": { "glob": "^7.1.3" }, "bin": { "rimraf": "bin.js" } }, "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA=="],
"run-applescript": ["run-applescript@7.1.0", "", {}, "sha512-DPe5pVFaAsinSaV6QjQ6gdiedWDcRCbUuiQfQa2wmWV7+xC9bGulGI8+TdRmoFkAPaBXk8CrAbnlY2ISniJ47Q=="],
"safe-buffer": ["safe-buffer@5.1.2", "", {}, "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="],
"sax": ["sax@1.2.4", "", {}, "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw=="],
"safer-buffer": ["safer-buffer@2.1.2", "", {}, "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="],
"semver": ["semver@7.5.4", "", { "dependencies": { "lru-cache": "^6.0.0" }, "bin": { "semver": "bin/semver.js" } }, "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA=="],
"sax": ["sax@1.4.3", "", {}, "sha512-yqYn1JhPczigF94DMS+shiDMjDowYO6y9+wB/4WgO0Y19jWYk0lQ4tuG5KI7kj4FTp1wxPj5IFfcrz/s1c3jjQ=="],
"semver": ["semver@7.7.3", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q=="],
"serialize-javascript": ["serialize-javascript@6.0.2", "", { "dependencies": { "randombytes": "^2.1.0" } }, "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g=="],
@@ -448,7 +587,13 @@
"shebang-regex": ["shebang-regex@3.0.0", "", {}, "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="],
"side-channel": ["side-channel@1.0.4", "", { "dependencies": { "call-bind": "^1.0.0", "get-intrinsic": "^1.0.2", "object-inspect": "^1.9.0" } }, "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw=="],
"side-channel": ["side-channel@1.1.0", "", { "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.3", "side-channel-list": "^1.0.0", "side-channel-map": "^1.0.1", "side-channel-weakmap": "^1.0.2" } }, "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw=="],
"side-channel-list": ["side-channel-list@1.0.0", "", { "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.3" } }, "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA=="],
"side-channel-map": ["side-channel-map@1.0.1", "", { "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.5", "object-inspect": "^1.13.3" } }, "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA=="],
"side-channel-weakmap": ["side-channel-weakmap@1.0.2", "", { "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.5", "object-inspect": "^1.13.3", "side-channel-map": "^1.0.1" } }, "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A=="],
"signal-exit": ["signal-exit@4.1.0", "", {}, "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw=="],
@@ -456,9 +601,9 @@
"simple-get": ["simple-get@4.0.1", "", { "dependencies": { "decompress-response": "^6.0.0", "once": "^1.3.1", "simple-concat": "^1.0.0" } }, "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA=="],
"source-map-js": ["source-map-js@1.0.2", "", {}, "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw=="],
"source-map-js": ["source-map-js@1.2.1", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="],
"stdin-discarder": ["stdin-discarder@0.1.0", "", { "dependencies": { "bl": "^5.0.0" } }, "sha512-xhV7w8S+bUwlPTb4bAOUQhv8/cSS5offJuX8GQGq32ONF0ZtDWKfkdomM3HMRA+LhX6um/FZ0COqlwsjD53LeQ=="],
"stdin-discarder": ["stdin-discarder@0.2.2", "", {}, "sha512-UhDfHmA92YAlNnCfhmq0VeNL5bDbiZGg7sZ2IvPsXubGkiNa9EC+tUTsjBRsYUAz87btI6/1wf4XoVvQ3uRnmQ=="],
"string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="],
@@ -466,7 +611,7 @@
"string_decoder": ["string_decoder@1.1.1", "", { "dependencies": { "safe-buffer": "~5.1.0" } }, "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg=="],
"strip-ansi": ["strip-ansi@7.1.0", "", { "dependencies": { "ansi-regex": "^6.0.1" } }, "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ=="],
"strip-ansi": ["strip-ansi@7.1.2", "", { "dependencies": { "ansi-regex": "^6.0.1" } }, "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA=="],
"strip-ansi-cjs": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="],
@@ -474,38 +619,48 @@
"supports-color": ["supports-color@9.4.0", "", {}, "sha512-VL+lNrEoIXww1coLPOmiEmK/0sGigko5COxI09KzHc2VJXJsQ37UaQ+8quuxjDeA7+KnLGTWRyOXSLLR2Wb4jw=="],
"tapable": ["tapable@2.2.1", "", {}, "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ=="],
"tapable": ["tapable@2.3.0", "", {}, "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg=="],
"tar-fs": ["tar-fs@2.1.1", "", { "dependencies": { "chownr": "^1.1.1", "mkdirp-classic": "^0.5.2", "pump": "^3.0.0", "tar-stream": "^2.1.4" } }, "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng=="],
"tar-fs": ["tar-fs@2.1.4", "", { "dependencies": { "chownr": "^1.1.1", "mkdirp-classic": "^0.5.2", "pump": "^3.0.0", "tar-stream": "^2.1.4" } }, "sha512-mDAjwmZdh7LTT6pNleZ05Yt65HC3E+NiQzl672vQG38jIrehtJk/J3mNwIg+vShQPcLF/LV7CMnDW6vjj6sfYQ=="],
"tar-stream": ["tar-stream@2.2.0", "", { "dependencies": { "bl": "^4.0.3", "end-of-stream": "^1.4.1", "fs-constants": "^1.0.0", "inherits": "^2.0.3", "readable-stream": "^3.1.1" } }, "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ=="],
"test-exclude": ["test-exclude@6.0.0", "", { "dependencies": { "@istanbuljs/schema": "^0.1.2", "glob": "^7.1.4", "minimatch": "^3.0.4" } }, "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w=="],
"tmp": ["tmp@0.2.1", "", { "dependencies": { "rimraf": "^3.0.0" } }, "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ=="],
"tmp": ["tmp@0.2.5", "", {}, "sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow=="],
"to-regex-range": ["to-regex-range@5.0.1", "", { "dependencies": { "is-number": "^7.0.0" } }, "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ=="],
"tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
"tunnel": ["tunnel@0.0.6", "", {}, "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg=="],
"tunnel-agent": ["tunnel-agent@0.6.0", "", { "dependencies": { "safe-buffer": "^5.0.1" } }, "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w=="],
"typed-rest-client": ["typed-rest-client@1.8.11", "", { "dependencies": { "qs": "^6.9.1", "tunnel": "0.0.6", "underscore": "^1.12.1" } }, "sha512-5UvfMpd1oelmUPRbbaVnq+rHP7ng2cE4qoQkQeAqxRL6PklkxsM0g32/HL0yfvruK6ojQ5x8EE+HF4YV6DtuCA=="],
"typescript": ["typescript@5.2.2", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w=="],
"typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="],
"uc.micro": ["uc.micro@1.0.6", "", {}, "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA=="],
"underscore": ["underscore@1.13.6", "", {}, "sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A=="],
"underscore": ["underscore@1.13.7", "", {}, "sha512-GMXzWtsc57XAtguZgaQViUOzs0KTkk8ojr3/xAxXLITqf/3EMwxC0inyETfDFjH/Krbhuep0HNbbjI9i/q3F3g=="],
"undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="],
"undici": ["undici@7.16.0", "", {}, "sha512-QEg3HPMll0o3t2ourKwOeUAZ159Kn9mx5pnzHRQO8+Wixmh88YdZRiIwat0iNzNNXn0yoEtXJqFpyW7eM8BV7g=="],
"undici-types": ["undici-types@7.16.0", "", {}, "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw=="],
"url-join": ["url-join@4.0.1", "", {}, "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA=="],
"util-deprecate": ["util-deprecate@1.0.2", "", {}, "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="],
"uuid": ["uuid@8.3.2", "", { "bin": { "uuid": "dist/bin/uuid" } }, "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg=="],
"v8-to-istanbul": ["v8-to-istanbul@9.3.0", "", { "dependencies": { "@jridgewell/trace-mapping": "^0.3.12", "@types/istanbul-lib-coverage": "^2.0.1", "convert-source-map": "^2.0.0" } }, "sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA=="],
"whatwg-encoding": ["whatwg-encoding@3.1.1", "", { "dependencies": { "iconv-lite": "0.6.3" } }, "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ=="],
"whatwg-mimetype": ["whatwg-mimetype@4.0.0", "", {}, "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg=="],
"which": ["which@2.0.2", "", { "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "./bin/node-which" } }, "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA=="],
"workerpool": ["workerpool@6.5.1", "", {}, "sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA=="],
@@ -516,7 +671,9 @@
"wrappy": ["wrappy@1.0.2", "", {}, "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="],
"ws": ["ws@8.13.0", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA=="],
"ws": ["ws@8.18.3", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg=="],
"wsl-utils": ["wsl-utils@0.1.0", "", { "dependencies": { "is-wsl": "^3.1.0" } }, "sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw=="],
"xml2js": ["xml2js@0.5.0", "", { "dependencies": { "sax": ">=0.6.0", "xmlbuilder": "~11.0.0" } }, "sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA=="],
@@ -542,11 +699,11 @@
"@isaacs/cliui/wrap-ansi": ["wrap-ansi@8.1.0", "", { "dependencies": { "ansi-styles": "^6.1.0", "string-width": "^5.0.1", "strip-ansi": "^7.0.1" } }, "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ=="],
"@vscode/test-electron/semver": ["semver@7.6.3", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A=="],
"@vscode/test-cli/glob": ["glob@10.5.0", "", { "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^3.1.2", "minimatch": "^9.0.4", "minipass": "^7.1.2", "package-json-from-dist": "^1.0.0", "path-scurry": "^1.11.1" }, "bin": { "glob": "dist/esm/bin.mjs" } }, "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg=="],
"@vscode/vsce/glob": ["glob@7.2.3", "", { "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^3.1.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" } }, "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q=="],
"@vscode/vsce/minimatch": ["minimatch@3.0.8", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-6FsRAQsxQ61mw+qP1ZzbL9Bc78x2p5OqNgNpnoAFLTrX8n5Kxph0CsnhmKKNXTWjXqU5L0pGPR7hYk+XWZr60Q=="],
"@vscode/vsce/minimatch": ["minimatch@3.1.2", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw=="],
"bl/readable-stream": ["readable-stream@3.6.2", "", { "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } }, "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA=="],
@@ -558,7 +715,9 @@
"dom-serializer/entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="],
"htmlparser2/entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="],
"glob/minimatch": ["minimatch@10.1.1", "", { "dependencies": { "@isaacs/brace-expansion": "^5.0.0" } }, "sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ=="],
"htmlparser2/entities": ["entities@6.0.1", "", {}, "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g=="],
"istanbul-lib-report/supports-color": ["supports-color@7.2.0", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw=="],
@@ -566,8 +725,6 @@
"log-symbols/is-unicode-supported": ["is-unicode-supported@0.1.0", "", {}, "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw=="],
"make-dir/semver": ["semver@7.6.3", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A=="],
"mocha/glob": ["glob@8.1.0", "", { "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^5.0.1", "once": "^1.3.0" } }, "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ=="],
"mocha/minimatch": ["minimatch@5.1.6", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g=="],
@@ -578,42 +735,32 @@
"mocha/yargs-parser": ["yargs-parser@20.2.9", "", {}, "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w=="],
"ora/chalk": ["chalk@5.3.0", "", {}, "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w=="],
"ora/chalk": ["chalk@5.6.2", "", {}, "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA=="],
"ora/log-symbols": ["log-symbols@5.1.0", "", { "dependencies": { "chalk": "^5.0.0", "is-unicode-supported": "^1.1.0" } }, "sha512-l0x2DvrW294C9uDCoQe1VSU4gf529FkSZ6leBl4TiqZH/e+0R7hSfHQBNut2mNygDgHwvYHfFLn6Oxb3VWj2rA=="],
"ora/log-symbols": ["log-symbols@6.0.0", "", { "dependencies": { "chalk": "^5.3.0", "is-unicode-supported": "^1.3.0" } }, "sha512-i24m8rpwhmPIS4zscNzK6MSEhk0DUWa/8iYQWxhffV8jkI4Phvs3F+quL5xvS0gdQR0FyTCMMH33Y78dDTzzIw=="],
"ora/string-width": ["string-width@6.1.0", "", { "dependencies": { "eastasianwidth": "^0.2.0", "emoji-regex": "^10.2.1", "strip-ansi": "^7.0.1" } }, "sha512-k01swCJAgQmuADB0YIc+7TuatfNvTBVOoaUWJjTB9R4VJzR5vNWzf5t42ESVZFPS8xTySF7CAdV4t/aaIm3UnQ=="],
"ora/string-width": ["string-width@7.2.0", "", { "dependencies": { "emoji-regex": "^10.3.0", "get-east-asian-width": "^1.0.0", "strip-ansi": "^7.1.0" } }, "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ=="],
"parse-semver/semver": ["semver@5.7.2", "", { "bin": { "semver": "bin/semver" } }, "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g=="],
"parse5/entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="],
"parse5/entities": ["entities@6.0.1", "", {}, "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g=="],
"path-scurry/lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="],
"randombytes/safe-buffer": ["safe-buffer@5.2.1", "", {}, "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="],
"path-scurry/lru-cache": ["lru-cache@11.2.2", "", {}, "sha512-F9ODfyqML2coTIsQpSkRHnLSZMtkU8Q+mSfcaIyKwy58u+8k5nvAYeiNhsyMARvzNcXJ9QfWVrcPsC9e9rAxtg=="],
"rc/strip-json-comments": ["strip-json-comments@2.0.1", "", {}, "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ=="],
"restore-cursor/signal-exit": ["signal-exit@3.0.7", "", {}, "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="],
"rimraf/glob": ["glob@7.2.3", "", { "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^3.1.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" } }, "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q=="],
"string-width/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="],
"string-width-cjs/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="],
"strip-ansi-cjs/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="],
"tar-stream/bl": ["bl@4.1.0", "", { "dependencies": { "buffer": "^5.5.0", "inherits": "^2.0.4", "readable-stream": "^3.4.0" } }, "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w=="],
"tar-stream/readable-stream": ["readable-stream@3.6.2", "", { "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } }, "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA=="],
"test-exclude/glob": ["glob@7.2.3", "", { "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^3.1.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" } }, "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q=="],
"test-exclude/minimatch": ["minimatch@3.1.2", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw=="],
"tunnel-agent/safe-buffer": ["safe-buffer@5.2.1", "", {}, "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="],
"wrap-ansi/ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="],
"wrap-ansi/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="],
@@ -624,13 +771,11 @@
"@isaacs/cliui/string-width/emoji-regex": ["emoji-regex@9.2.2", "", {}, "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg=="],
"@isaacs/cliui/wrap-ansi/ansi-styles": ["ansi-styles@6.2.1", "", {}, "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug=="],
"@isaacs/cliui/wrap-ansi/ansi-styles": ["ansi-styles@6.2.3", "", {}, "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg=="],
"@vscode/vsce/glob/minimatch": ["minimatch@3.1.2", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw=="],
"@vscode/test-cli/glob/path-scurry": ["path-scurry@1.11.1", "", { "dependencies": { "lru-cache": "^10.2.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" } }, "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA=="],
"@vscode/vsce/minimatch/brace-expansion": ["brace-expansion@1.1.11", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA=="],
"bl/readable-stream/string_decoder": ["string_decoder@1.3.0", "", { "dependencies": { "safe-buffer": "~5.2.0" } }, "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA=="],
"@vscode/vsce/minimatch/brace-expansion": ["brace-expansion@1.1.12", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg=="],
"chalk/supports-color/has-flag": ["has-flag@3.0.0", "", {}, "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw=="],
@@ -642,19 +787,15 @@
"mocha/yargs/cliui": ["cliui@7.0.4", "", { "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.0", "wrap-ansi": "^7.0.0" } }, "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ=="],
"ora/string-width/emoji-regex": ["emoji-regex@10.4.0", "", {}, "sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw=="],
"ora/log-symbols/is-unicode-supported": ["is-unicode-supported@1.3.0", "", {}, "sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ=="],
"rimraf/glob/minimatch": ["minimatch@3.1.2", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw=="],
"ora/string-width/emoji-regex": ["emoji-regex@10.6.0", "", {}, "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A=="],
"string-width-cjs/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="],
"string-width/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="],
"tar-stream/bl/buffer": ["buffer@5.7.1", "", { "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.1.13" } }, "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ=="],
"tar-stream/readable-stream/string_decoder": ["string_decoder@1.3.0", "", { "dependencies": { "safe-buffer": "~5.2.0" } }, "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA=="],
"test-exclude/minimatch/brace-expansion": ["brace-expansion@1.1.11", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA=="],
"test-exclude/minimatch/brace-expansion": ["brace-expansion@1.1.12", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg=="],
"wrap-ansi-cjs/ansi-styles/color-convert": ["color-convert@2.0.1", "", { "dependencies": { "color-name": "~1.1.4" } }, "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ=="],
@@ -664,18 +805,12 @@
"wrap-ansi/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="],
"@vscode/vsce/glob/minimatch/brace-expansion": ["brace-expansion@1.1.11", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA=="],
"bl/readable-stream/string_decoder/safe-buffer": ["safe-buffer@5.2.1", "", {}, "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="],
"@vscode/test-cli/glob/path-scurry/lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="],
"log-symbols/chalk/ansi-styles/color-convert": ["color-convert@2.0.1", "", { "dependencies": { "color-name": "~1.1.4" } }, "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ=="],
"mocha/yargs/cliui/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="],
"rimraf/glob/minimatch/brace-expansion": ["brace-expansion@1.1.11", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA=="],
"tar-stream/readable-stream/string_decoder/safe-buffer": ["safe-buffer@5.2.1", "", {}, "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="],
"wrap-ansi-cjs/ansi-styles/color-convert/color-name": ["color-name@1.1.4", "", {}, "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="],
"wrap-ansi/ansi-styles/color-convert/color-name": ["color-name@1.1.4", "", {}, "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="],

View File

@@ -1,11 +1,14 @@
{
"lockfileVersion": 1,
"configVersion": 0,
"workspaces": {
"": {
"name": "example",
"dependencies": {
"axios": "^1.7.7",
"axios": "^1.13.2",
"body-parser": "^2.2.0",
"elysia": "^0.6.3",
"express": "^4.18.2",
"express": "^4.21.2",
"mime": "^3.0.0",
"mime-db": "^1.52.0",
"react": "^0.0.0-experimental-380f5d67-20241113",
@@ -20,42 +23,37 @@
"peerDependencies": {
"typescript": "^5.0.0",
},
"optionalPeers": [
"typescript",
],
},
},
"trustedDependencies": [
"mime",
],
"packages": {
"@jridgewell/gen-mapping": ["@jridgewell/gen-mapping@0.3.5", "", { "dependencies": { "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg=="],
"@jridgewell/gen-mapping": ["@jridgewell/gen-mapping@0.3.13", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA=="],
"@jridgewell/resolve-uri": ["@jridgewell/resolve-uri@3.1.2", "", {}, "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw=="],
"@jridgewell/set-array": ["@jridgewell/set-array@1.2.1", "", {}, "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A=="],
"@jridgewell/source-map": ["@jridgewell/source-map@0.3.11", "", { "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25" } }, "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA=="],
"@jridgewell/source-map": ["@jridgewell/source-map@0.3.6", "", { "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25" } }, "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ=="],
"@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.5", "", {}, "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og=="],
"@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.0", "", {}, "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ=="],
"@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.25", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ=="],
"@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="],
"@sinclair/typebox": ["@sinclair/typebox@0.30.4", "", {}, "sha512-wFuuDR+O1OAE2GL0q68h1Ty00RE6Ihcixr55A6TU5RCvOUHnwJw9LGuDVg9NxDiAp7m/YJpa+UaOuLAz0ziyOQ=="],
"@types/bun": ["@types/bun@1.1.13", "", { "dependencies": { "bun-types": "1.1.34" } }, "sha512-KmQxSBgVWCl6RSuerlLGZlIWfdxkKqat0nxN61+qu4y1KDn0Ll3j7v1Pl8GnaL3a/U6GGWVTJh75ap62kR1E8Q=="],
"@types/bun": ["@types/bun@1.3.2", "", { "dependencies": { "bun-types": "1.3.2" } }, "sha512-t15P7k5UIgHKkxwnMNkJbWlh/617rkDGEdSsDbu+qNHTaz9SKf7aC8fiIlUdD5RPpH6GEkP0cK7WlvmrEBRtWg=="],
"@types/eslint": ["@types/eslint@9.6.1", "", { "dependencies": { "@types/estree": "*", "@types/json-schema": "*" } }, "sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag=="],
"@types/eslint-scope": ["@types/eslint-scope@3.7.7", "", { "dependencies": { "@types/eslint": "*", "@types/estree": "*" } }, "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg=="],
"@types/estree": ["@types/estree@1.0.6", "", {}, "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw=="],
"@types/estree": ["@types/estree@1.0.8", "", {}, "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w=="],
"@types/json-schema": ["@types/json-schema@7.0.15", "", {}, "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA=="],
"@types/node": ["@types/node@20.12.14", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-scnD59RpYD91xngrQQLGkE+6UrHUPzeKZWhhjBSa3HSkwjbQc38+q3RoIVEwxQGRw3M+j5hpNAM+lgV3cVormg=="],
"@types/node": ["@types/node@24.10.1", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-GNWcUTRBgIRJD5zj+Tq0fKOJ5XZajIiBroOF0yvj2bSU1WvNdYS/dn9UxwsujGW4JX06dnHyjV2y9rRaybH0iQ=="],
"@types/ws": ["@types/ws@8.5.13", "", { "dependencies": { "@types/node": "*" } }, "sha512-osM/gWBTPKgHV8XkTunnegTRIsvF6owmf5w+JtAfOw472dptdm0dlGv4xCt6GwQRcC2XVOvvRE/0bAoQcL2QkA=="],
"@types/react": ["@types/react@19.2.6", "", { "dependencies": { "csstype": "^3.2.2" } }, "sha512-p/jUvulfgU7oKtj6Xpk8cA2Y1xKTtICGpJYeJXz2YVO2UcvjQgeRMLDGfDeqeRW2Ta+0QNFwcc8X3GH8SxZz6w=="],
"@webassemblyjs/ast": ["@webassemblyjs/ast@1.14.1", "", { "dependencies": { "@webassemblyjs/helper-numbers": "1.13.2", "@webassemblyjs/helper-wasm-bytecode": "1.13.2" } }, "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ=="],
@@ -93,33 +91,41 @@
"accepts": ["accepts@1.3.8", "", { "dependencies": { "mime-types": "~2.1.34", "negotiator": "0.6.3" } }, "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw=="],
"acorn": ["acorn@8.14.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA=="],
"acorn": ["acorn@8.15.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg=="],
"acorn-loose": ["acorn-loose@8.4.0", "", { "dependencies": { "acorn": "^8.11.0" } }, "sha512-M0EUka6rb+QC4l9Z3T0nJEzNOO7JcoJlYMrBlyBCiFSXRyxjLKayd4TbQs2FDRWQU1h9FR7QVNHt+PEaoNL5rQ=="],
"acorn-import-phases": ["acorn-import-phases@1.0.4", "", { "peerDependencies": { "acorn": "^8.14.0" } }, "sha512-wKmbr/DDiIXzEOiWrTTUcDm24kQ2vGfZQvM2fwg2vXqR5uW6aapr7ObPtj1th32b9u90/Pf4AItvdTh42fBmVQ=="],
"ajv": ["ajv@6.12.6", "", { "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" } }, "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g=="],
"acorn-loose": ["acorn-loose@8.5.2", "", { "dependencies": { "acorn": "^8.15.0" } }, "sha512-PPvV6g8UGMGgjrMu+n/f9E/tCSkNQ2Y97eFvuVdJfG11+xdIeDcLyNdC8SHcrHbRqkfwLASdplyR6B6sKM1U4A=="],
"ajv-keywords": ["ajv-keywords@3.5.2", "", { "peerDependencies": { "ajv": "^6.9.1" } }, "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ=="],
"ajv": ["ajv@8.17.1", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2" } }, "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g=="],
"ajv-formats": ["ajv-formats@2.1.1", "", { "dependencies": { "ajv": "^8.0.0" } }, "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA=="],
"ajv-keywords": ["ajv-keywords@5.1.0", "", { "dependencies": { "fast-deep-equal": "^3.1.3" }, "peerDependencies": { "ajv": "^8.8.2" } }, "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw=="],
"array-flatten": ["array-flatten@1.1.1", "", {}, "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg=="],
"asynckit": ["asynckit@0.4.0", "", {}, "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="],
"axios": ["axios@1.7.7", "", { "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.0", "proxy-from-env": "^1.1.0" } }, "sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q=="],
"axios": ["axios@1.13.2", "", { "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.4", "proxy-from-env": "^1.1.0" } }, "sha512-VPk9ebNqPcy5lRGuSlKx752IlDatOjT9paPlm8A7yOuW2Fbvp4X3JznJtT4f0GzGLLiWE9W8onz51SqLYwzGaA=="],
"body-parser": ["body-parser@1.20.1", "", { "dependencies": { "bytes": "3.1.2", "content-type": "~1.0.4", "debug": "2.6.9", "depd": "2.0.0", "destroy": "1.2.0", "http-errors": "2.0.0", "iconv-lite": "0.4.24", "on-finished": "2.4.1", "qs": "6.11.0", "raw-body": "2.5.1", "type-is": "~1.6.18", "unpipe": "1.0.0" } }, "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw=="],
"baseline-browser-mapping": ["baseline-browser-mapping@2.8.29", "", { "bin": { "baseline-browser-mapping": "dist/cli.js" } }, "sha512-sXdt2elaVnhpDNRDz+1BDx1JQoJRuNk7oVlAlbGiFkLikHCAQiccexF/9e91zVi6RCgqspl04aP+6Cnl9zRLrA=="],
"browserslist": ["browserslist@4.24.2", "", { "dependencies": { "caniuse-lite": "^1.0.30001669", "electron-to-chromium": "^1.5.41", "node-releases": "^2.0.18", "update-browserslist-db": "^1.1.1" }, "bin": { "browserslist": "cli.js" } }, "sha512-ZIc+Q62revdMcqC6aChtW4jz3My3klmCO1fEmINZY/8J3EpBg5/A/D0AKmBveUh6pgoeycoMkVMko84tuYS+Gg=="],
"body-parser": ["body-parser@2.2.0", "", { "dependencies": { "bytes": "^3.1.2", "content-type": "^1.0.5", "debug": "^4.4.0", "http-errors": "^2.0.0", "iconv-lite": "^0.6.3", "on-finished": "^2.4.1", "qs": "^6.14.0", "raw-body": "^3.0.0", "type-is": "^2.0.0" } }, "sha512-02qvAaxv8tp7fBa/mw1ga98OGm+eCbqzJOKoRt70sLmfEEi+jyBYVTDGfCL/k06/4EMk/z01gCe7HoCH/f2LTg=="],
"browserslist": ["browserslist@4.28.0", "", { "dependencies": { "baseline-browser-mapping": "^2.8.25", "caniuse-lite": "^1.0.30001754", "electron-to-chromium": "^1.5.249", "node-releases": "^2.0.27", "update-browserslist-db": "^1.1.4" }, "bin": { "browserslist": "cli.js" } }, "sha512-tbydkR/CxfMwelN0vwdP/pLkDwyAASZ+VfWm4EOwlB6SWhx1sYnWLqo8N5j0rAzPfzfRaxt0mM/4wPU/Su84RQ=="],
"buffer-from": ["buffer-from@1.1.2", "", {}, "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ=="],
"bun-types": ["bun-types@1.1.34", "", { "dependencies": { "@types/node": "~20.12.8", "@types/ws": "~8.5.10" } }, "sha512-br5QygTEL/TwB4uQOb96Ky22j4Gq2WxWH/8Oqv20fk5HagwKXo/akB+LiYgSfzexCt6kkcUaVm+bKiPl71xPvw=="],
"bun-types": ["bun-types@1.3.2", "", { "dependencies": { "@types/node": "*" }, "peerDependencies": { "@types/react": "^19" } }, "sha512-i/Gln4tbzKNuxP70OWhJRZz1MRfvqExowP7U6JKoI8cntFrtxg7RJK3jvz7wQW54UuvNC8tbKHHri5fy74FVqg=="],
"bytes": ["bytes@3.1.2", "", {}, "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg=="],
"call-bind": ["call-bind@1.0.2", "", { "dependencies": { "function-bind": "^1.1.1", "get-intrinsic": "^1.0.2" } }, "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA=="],
"call-bind-apply-helpers": ["call-bind-apply-helpers@1.0.2", "", { "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2" } }, "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ=="],
"caniuse-lite": ["caniuse-lite@1.0.30001680", "", {}, "sha512-rPQy70G6AGUMnbwS1z6Xg+RkHYPAi18ihs47GH0jcxIG7wArmPgY3XbS2sRdBbxJljp3thdT8BIqv9ccCypiPA=="],
"call-bound": ["call-bound@1.0.4", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.2", "get-intrinsic": "^1.3.0" } }, "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg=="],
"caniuse-lite": ["caniuse-lite@1.0.30001756", "", {}, "sha512-4HnCNKbMLkLdhJz3TToeVWHSnfJvPaq6vu/eRP0Ahub/07n484XHhBF5AJoSGHdVrS8tKFauUQz8Bp9P7LVx7A=="],
"chrome-trace-event": ["chrome-trace-event@1.0.4", "", {}, "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ=="],
@@ -131,11 +137,13 @@
"content-type": ["content-type@1.0.5", "", {}, "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA=="],
"cookie": ["cookie@0.5.0", "", {}, "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw=="],
"cookie": ["cookie@0.7.1", "", {}, "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w=="],
"cookie-signature": ["cookie-signature@1.0.6", "", {}, "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ=="],
"debug": ["debug@2.6.9", "", { "dependencies": { "ms": "2.0.0" } }, "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="],
"csstype": ["csstype@3.2.3", "", {}, "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ=="],
"debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="],
"delayed-stream": ["delayed-stream@1.0.0", "", {}, "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ=="],
@@ -143,17 +151,27 @@
"destroy": ["destroy@1.2.0", "", {}, "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg=="],
"dunder-proto": ["dunder-proto@1.0.1", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.1", "es-errors": "^1.3.0", "gopd": "^1.2.0" } }, "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A=="],
"ee-first": ["ee-first@1.1.1", "", {}, "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="],
"electron-to-chromium": ["electron-to-chromium@1.5.58", "", {}, "sha512-al2l4r+24ZFL7WzyPTlyD0fC33LLzvxqLCwurtBibVPghRGO9hSTl+tis8t1kD7biPiH/en4U0I7o/nQbYeoVA=="],
"electron-to-chromium": ["electron-to-chromium@1.5.258", "", {}, "sha512-rHUggNV5jKQ0sSdWwlaRDkFc3/rRJIVnOSe9yR4zrR07m3ZxhP4N27Hlg8VeJGGYgFTxK5NqDmWI4DSH72vIJg=="],
"elysia": ["elysia@0.6.3", "", { "dependencies": { "@sinclair/typebox": "^0.30.4", "fast-querystring": "^1.1.2", "memoirist": "0.1.4", "openapi-types": "^12.1.3" }, "peerDependencies": { "typescript": ">= 5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-LhdH476fotAQuEUpnLdn8fAzwo3ZmwHVrYzQhujo+x+OpmMXGMJXT7L7/Ct+b5wwR2txP5xCxI1A0suxhRxgIQ=="],
"elysia": ["elysia@0.6.24", "", { "dependencies": { "@sinclair/typebox": "^0.30.4", "fast-querystring": "^1.1.2", "memoirist": "0.1.4", "mergician": "^1.1.0", "openapi-types": "^12.1.3" }, "peerDependencies": { "typescript": ">= 5.0.0" }, "optionalPeers": ["typescript"] }, "sha512-qaN8b816tSecNIsgNwFCMOMlayOaChme9i/VHxCRZyPTgtdAAnrYDZaUQfatyt1jcHUdkf3IT4ny5GuS7NB26w=="],
"encodeurl": ["encodeurl@1.0.2", "", {}, "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w=="],
"encodeurl": ["encodeurl@2.0.0", "", {}, "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg=="],
"enhanced-resolve": ["enhanced-resolve@5.17.1", "", { "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.2.0" } }, "sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg=="],
"enhanced-resolve": ["enhanced-resolve@5.18.3", "", { "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.2.0" } }, "sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww=="],
"es-module-lexer": ["es-module-lexer@1.5.4", "", {}, "sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw=="],
"es-define-property": ["es-define-property@1.0.1", "", {}, "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g=="],
"es-errors": ["es-errors@1.3.0", "", {}, "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw=="],
"es-module-lexer": ["es-module-lexer@1.7.0", "", {}, "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA=="],
"es-object-atoms": ["es-object-atoms@1.1.1", "", { "dependencies": { "es-errors": "^1.3.0" } }, "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA=="],
"es-set-tostringtag": ["es-set-tostringtag@2.1.0", "", { "dependencies": { "es-errors": "^1.3.0", "get-intrinsic": "^1.2.6", "has-tostringtag": "^1.0.2", "hasown": "^2.0.2" } }, "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA=="],
"escalade": ["escalade@3.2.0", "", {}, "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA=="],
@@ -169,45 +187,49 @@
"events": ["events@3.3.0", "", {}, "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q=="],
"express": ["express@4.18.2", "", { "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", "body-parser": "1.20.1", "content-disposition": "0.5.4", "content-type": "~1.0.4", "cookie": "0.5.0", "cookie-signature": "1.0.6", "debug": "2.6.9", "depd": "2.0.0", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "etag": "~1.8.1", "finalhandler": "1.2.0", "fresh": "0.5.2", "http-errors": "2.0.0", "merge-descriptors": "1.0.1", "methods": "~1.1.2", "on-finished": "2.4.1", "parseurl": "~1.3.3", "path-to-regexp": "0.1.7", "proxy-addr": "~2.0.7", "qs": "6.11.0", "range-parser": "~1.2.1", "safe-buffer": "5.2.1", "send": "0.18.0", "serve-static": "1.15.0", "setprototypeof": "1.2.0", "statuses": "2.0.1", "type-is": "~1.6.18", "utils-merge": "1.0.1", "vary": "~1.1.2" } }, "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ=="],
"express": ["express@4.21.2", "", { "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", "body-parser": "1.20.3", "content-disposition": "0.5.4", "content-type": "~1.0.4", "cookie": "0.7.1", "cookie-signature": "1.0.6", "debug": "2.6.9", "depd": "2.0.0", "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "etag": "~1.8.1", "finalhandler": "1.3.1", "fresh": "0.5.2", "http-errors": "2.0.0", "merge-descriptors": "1.0.3", "methods": "~1.1.2", "on-finished": "2.4.1", "parseurl": "~1.3.3", "path-to-regexp": "0.1.12", "proxy-addr": "~2.0.7", "qs": "6.13.0", "range-parser": "~1.2.1", "safe-buffer": "5.2.1", "send": "0.19.0", "serve-static": "1.16.2", "setprototypeof": "1.2.0", "statuses": "2.0.1", "type-is": "~1.6.18", "utils-merge": "1.0.1", "vary": "~1.1.2" } }, "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA=="],
"fast-decode-uri-component": ["fast-decode-uri-component@1.0.1", "", {}, "sha512-WKgKWg5eUxvRZGwW8FvfbaH7AXSh2cL+3j5fMGzUMCxWBJ3dV3a7Wz8y2f/uQ0e3B6WmodD3oS54jTQ9HVTIIg=="],
"fast-deep-equal": ["fast-deep-equal@3.1.3", "", {}, "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="],
"fast-json-stable-stringify": ["fast-json-stable-stringify@2.1.0", "", {}, "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="],
"fast-querystring": ["fast-querystring@1.1.2", "", { "dependencies": { "fast-decode-uri-component": "^1.0.1" } }, "sha512-g6KuKWmFXc0fID8WWH0jit4g0AGBoJhCkJMb1RmbsSEUNvQ+ZC8D6CUZ+GtF8nMzSPXnhiePyyqqipzNNEnHjg=="],
"finalhandler": ["finalhandler@1.2.0", "", { "dependencies": { "debug": "2.6.9", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "on-finished": "2.4.1", "parseurl": "~1.3.3", "statuses": "2.0.1", "unpipe": "~1.0.0" } }, "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg=="],
"fast-uri": ["fast-uri@3.1.0", "", {}, "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA=="],
"follow-redirects": ["follow-redirects@1.15.9", "", {}, "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ=="],
"finalhandler": ["finalhandler@1.3.1", "", { "dependencies": { "debug": "2.6.9", "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "on-finished": "2.4.1", "parseurl": "~1.3.3", "statuses": "2.0.1", "unpipe": "~1.0.0" } }, "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ=="],
"form-data": ["form-data@4.0.1", "", { "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", "mime-types": "^2.1.12" } }, "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw=="],
"follow-redirects": ["follow-redirects@1.15.11", "", {}, "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ=="],
"form-data": ["form-data@4.0.5", "", { "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", "es-set-tostringtag": "^2.1.0", "hasown": "^2.0.2", "mime-types": "^2.1.12" } }, "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w=="],
"forwarded": ["forwarded@0.2.0", "", {}, "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow=="],
"fresh": ["fresh@0.5.2", "", {}, "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q=="],
"function-bind": ["function-bind@1.1.1", "", {}, "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="],
"function-bind": ["function-bind@1.1.2", "", {}, "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="],
"get-intrinsic": ["get-intrinsic@1.2.1", "", { "dependencies": { "function-bind": "^1.1.1", "has": "^1.0.3", "has-proto": "^1.0.1", "has-symbols": "^1.0.3" } }, "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw=="],
"get-intrinsic": ["get-intrinsic@1.3.0", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.2", "es-define-property": "^1.0.1", "es-errors": "^1.3.0", "es-object-atoms": "^1.1.1", "function-bind": "^1.1.2", "get-proto": "^1.0.1", "gopd": "^1.2.0", "has-symbols": "^1.1.0", "hasown": "^2.0.2", "math-intrinsics": "^1.1.0" } }, "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ=="],
"get-proto": ["get-proto@1.0.1", "", { "dependencies": { "dunder-proto": "^1.0.1", "es-object-atoms": "^1.0.0" } }, "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g=="],
"glob-to-regexp": ["glob-to-regexp@0.4.1", "", {}, "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw=="],
"graceful-fs": ["graceful-fs@4.2.11", "", {}, "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="],
"gopd": ["gopd@1.2.0", "", {}, "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg=="],
"has": ["has@1.0.3", "", { "dependencies": { "function-bind": "^1.1.1" } }, "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw=="],
"graceful-fs": ["graceful-fs@4.2.11", "", {}, "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="],
"has-flag": ["has-flag@4.0.0", "", {}, "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="],
"has-proto": ["has-proto@1.0.1", "", {}, "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg=="],
"has-symbols": ["has-symbols@1.1.0", "", {}, "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ=="],
"has-symbols": ["has-symbols@1.0.3", "", {}, "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A=="],
"has-tostringtag": ["has-tostringtag@1.0.2", "", { "dependencies": { "has-symbols": "^1.0.3" } }, "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw=="],
"hasown": ["hasown@2.0.2", "", { "dependencies": { "function-bind": "^1.1.2" } }, "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ=="],
"http-errors": ["http-errors@2.0.0", "", { "dependencies": { "depd": "2.0.0", "inherits": "2.0.4", "setprototypeof": "1.2.0", "statuses": "2.0.1", "toidentifier": "1.0.1" } }, "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ=="],
"iconv-lite": ["iconv-lite@0.4.24", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3" } }, "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA=="],
"iconv-lite": ["iconv-lite@0.6.3", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw=="],
"inherits": ["inherits@2.0.4", "", {}, "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="],
@@ -215,37 +237,47 @@
"jest-worker": ["jest-worker@27.5.1", "", { "dependencies": { "@types/node": "*", "merge-stream": "^2.0.0", "supports-color": "^8.0.0" } }, "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg=="],
"js-tokens": ["js-tokens@4.0.0", "", {}, "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="],
"json-parse-even-better-errors": ["json-parse-even-better-errors@2.3.1", "", {}, "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w=="],
"json-schema-traverse": ["json-schema-traverse@0.4.1", "", {}, "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="],
"json-schema-traverse": ["json-schema-traverse@1.0.0", "", {}, "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="],
"loader-runner": ["loader-runner@4.3.0", "", {}, "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg=="],
"loader-runner": ["loader-runner@4.3.1", "", {}, "sha512-IWqP2SCPhyVFTBtRcgMHdzlf9ul25NwaFx4wCEH/KjAXuuHY4yNjvPXsBokp8jCB936PyWRaPKUNh8NvylLp2Q=="],
"media-typer": ["media-typer@0.3.0", "", {}, "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ=="],
"loose-envify": ["loose-envify@1.4.0", "", { "dependencies": { "js-tokens": "^3.0.0 || ^4.0.0" }, "bin": { "loose-envify": "cli.js" } }, "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q=="],
"math-intrinsics": ["math-intrinsics@1.1.0", "", {}, "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g=="],
"media-typer": ["media-typer@1.1.0", "", {}, "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw=="],
"memoirist": ["memoirist@0.1.4", "", {}, "sha512-D6GbPSqO2nUVOmm7VZjJc5tC60pkOVUPzLwkKl1vCiYP+2b1cG8N9q1O3P0JmNM68u8vsgefPbxRUCSGxSXD+g=="],
"merge-descriptors": ["merge-descriptors@1.0.1", "", {}, "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w=="],
"merge-descriptors": ["merge-descriptors@1.0.3", "", {}, "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ=="],
"merge-stream": ["merge-stream@2.0.0", "", {}, "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w=="],
"mergician": ["mergician@1.1.0", "", {}, "sha512-FXbxzU6BBhGkV8XtUr8Sk015ZRaAALviit8Lle6OEgd1udX8wlu6tBeUMLGQGdz1MfHpAVNNQkXowyDnJuhXpA=="],
"methods": ["methods@1.1.2", "", {}, "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w=="],
"mime": ["mime@3.0.0", "", { "bin": { "mime": "cli.js" } }, "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A=="],
"mime-db": ["mime-db@1.52.0", "", {}, "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="],
"mime-db": ["mime-db@1.54.0", "", {}, "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ=="],
"mime-types": ["mime-types@2.1.35", "", { "dependencies": { "mime-db": "1.52.0" } }, "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw=="],
"ms": ["ms@2.0.0", "", {}, "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="],
"ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="],
"negotiator": ["negotiator@0.6.3", "", {}, "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg=="],
"neo-async": ["neo-async@2.6.2", "", {}, "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw=="],
"node-releases": ["node-releases@2.0.18", "", {}, "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g=="],
"node-releases": ["node-releases@2.0.27", "", {}, "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA=="],
"object-inspect": ["object-inspect@1.12.3", "", {}, "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g=="],
"object-assign": ["object-assign@4.1.1", "", {}, "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg=="],
"object-inspect": ["object-inspect@1.13.4", "", {}, "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew=="],
"on-finished": ["on-finished@2.4.1", "", { "dependencies": { "ee-first": "1.1.1" } }, "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg=="],
@@ -253,51 +285,61 @@
"parseurl": ["parseurl@1.3.3", "", {}, "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ=="],
"path-to-regexp": ["path-to-regexp@0.1.7", "", {}, "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ=="],
"path-to-regexp": ["path-to-regexp@0.1.12", "", {}, "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ=="],
"picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="],
"prop-types": ["prop-types@15.8.1", "", { "dependencies": { "loose-envify": "^1.4.0", "object-assign": "^4.1.1", "react-is": "^16.13.1" } }, "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg=="],
"proxy-addr": ["proxy-addr@2.0.7", "", { "dependencies": { "forwarded": "0.2.0", "ipaddr.js": "1.9.1" } }, "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg=="],
"proxy-from-env": ["proxy-from-env@1.1.0", "", {}, "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="],
"punycode": ["punycode@2.3.1", "", {}, "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg=="],
"qs": ["qs@6.11.0", "", { "dependencies": { "side-channel": "^1.0.4" } }, "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q=="],
"qs": ["qs@6.14.0", "", { "dependencies": { "side-channel": "^1.1.0" } }, "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w=="],
"randombytes": ["randombytes@2.1.0", "", { "dependencies": { "safe-buffer": "^5.1.0" } }, "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ=="],
"range-parser": ["range-parser@1.2.1", "", {}, "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg=="],
"raw-body": ["raw-body@2.5.1", "", { "dependencies": { "bytes": "3.1.2", "http-errors": "2.0.0", "iconv-lite": "0.4.24", "unpipe": "1.0.0" } }, "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig=="],
"raw-body": ["raw-body@3.0.1", "", { "dependencies": { "bytes": "3.1.2", "http-errors": "2.0.0", "iconv-lite": "0.7.0", "unpipe": "1.0.0" } }, "sha512-9G8cA+tuMS75+6G/TzW8OtLzmBDMo8p1JRxN5AZ+LAp8uxGA8V8GZm4GQ4/N5QNQEnLmg6SS7wyuSmbKepiKqA=="],
"react": ["react@0.0.0-experimental-380f5d67-20241113", "", {}, "sha512-QquU1j1TmZR+KgGSFvWTlOuwLvGrA8ldUJean+gT0nYIhSJ1ZkdXJQFnFRWqxoc74C7SY1o4NMz0yJxpUBoQ2w=="],
"react": ["react@0.0.0-fec00a869", "", { "dependencies": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1", "prop-types": "^15.6.2", "scheduler": "0.0.0-fec00a869" } }, "sha512-FaS3ViFU4ag7cuhDHQgGK3DAdWaD8YFXzEbO/Qzz33Si7VEzRRdnyoegFwg7VkEKxR6CvCVP6revi9Tm3Gq+WQ=="],
"react-dom": ["react-dom@0.0.0-experimental-380f5d67-20241113", "", { "dependencies": { "scheduler": "0.0.0-experimental-380f5d67-20241113" }, "peerDependencies": { "react": "0.0.0-experimental-380f5d67-20241113" } }, "sha512-1ok9k5rAF7YuTveNefkPOvZHHuh5RLnCc5DU7sT7IL3i2K+LZmlsbSdlylMevjt9OzovxWQdsk04Fd4GKVCBWg=="],
"react-dom": ["react-dom@0.0.0-fec00a869", "", { "dependencies": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1", "prop-types": "^15.6.2", "scheduler": "0.0.0-fec00a869" }, "peerDependencies": { "react": "0.0.0-fec00a869" } }, "sha512-atB5i2HgCvbvhtGXq9oaX/BCL2AFZjnccougU8S9eulRFNQbNrfGNwIcj04PRo3XU1ZsBw5syL/5l596UaolKA=="],
"react-refresh": ["react-refresh@0.0.0-experimental-380f5d67-20241113", "", {}, "sha512-PwTxoYh02oTSdM2DLV8r3ZzHwObVDIsS05fxNcajIZe+/kIFTWThmXYJpGMljzjIs0wwScVkMONU6URTRPQvHA=="],
"react-is": ["react-is@16.13.1", "", {}, "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="],
"react-refresh": ["react-refresh@0.0.0-f77c7b9d7", "", {}, "sha512-mErwv0xcQz2sYnCJPaQ93D23Irnrfo5c+wG2k2KAgWOvFfqXPQdIUZ1j9S+gKYQI2kqgd0fdTJchEJydqroyJw=="],
"react-server-dom-bun": ["react-server-dom-bun@0.0.0-experimental-603e6108-20241029", "", { "dependencies": { "neo-async": "^2.6.1" } }, "sha512-FfteCHlOgJSnDJRatgIkIU74jQQ9M1+fH2e6kfY9Sibu8FAWEUjgApKQPDfiXgjrkY7w0ITQu0b2FezC0eGzCw=="],
"react-server-dom-webpack": ["react-server-dom-webpack@0.0.0-experimental-380f5d67-20241113", "", { "dependencies": { "acorn-loose": "^8.3.0", "neo-async": "^2.6.1", "webpack-sources": "^3.2.0" }, "peerDependencies": { "react": "0.0.0-experimental-380f5d67-20241113", "react-dom": "0.0.0-experimental-380f5d67-20241113", "webpack": "^5.59.0" } }, "sha512-hUluisy+9Srvrju5yS+qBOIAX82E+MRYOmoTNbV0kUsTi964ZZFLBzuruASAyUbbP1OhtFl0DwBxYN+UT0yUFQ=="],
"react-server-dom-webpack": ["react-server-dom-webpack@0.0.0-experimental-ff628334-20250205", "", { "dependencies": { "acorn-loose": "^8.3.0", "neo-async": "^2.6.1", "webpack-sources": "^3.2.0" }, "peerDependencies": { "react": "0.0.0-experimental-ff628334-20250205", "react-dom": "0.0.0-experimental-ff628334-20250205", "webpack": "^5.59.0" } }, "sha512-aYqTnSs+yYJJ+ihrTH5Cg48ipXYVFbyARcC6h3sfK6pc0/VxSqQ1sdbzOcG1WHaFDIeuonoAJ4zbRGb/8IUmJA=="],
"require-from-string": ["require-from-string@2.0.2", "", {}, "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw=="],
"safe-buffer": ["safe-buffer@5.2.1", "", {}, "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="],
"safer-buffer": ["safer-buffer@2.1.2", "", {}, "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="],
"scheduler": ["scheduler@0.0.0-experimental-380f5d67-20241113", "", {}, "sha512-UtSmlBSHar7hQvCXiozfIryfUFCL58+mqjrZONnLD06xdTlfgLrTcI5gS3Xo/RnNhUziLPV0DsinpI3a+q7Yzg=="],
"scheduler": ["scheduler@0.0.0-fec00a869", "", { "dependencies": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1" } }, "sha512-0U25jnyBP6dRPYwaVW4WMYB0jJSYlrIHFmIuXv27X+KIHJr7vyE9gcFTqZ61NQTuxYLYepAHnUs4KgQEUDlI+g=="],
"schema-utils": ["schema-utils@3.3.0", "", { "dependencies": { "@types/json-schema": "^7.0.8", "ajv": "^6.12.5", "ajv-keywords": "^3.5.2" } }, "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg=="],
"schema-utils": ["schema-utils@4.3.3", "", { "dependencies": { "@types/json-schema": "^7.0.9", "ajv": "^8.9.0", "ajv-formats": "^2.1.1", "ajv-keywords": "^5.1.0" } }, "sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA=="],
"send": ["send@0.18.0", "", { "dependencies": { "debug": "2.6.9", "depd": "2.0.0", "destroy": "1.2.0", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "etag": "~1.8.1", "fresh": "0.5.2", "http-errors": "2.0.0", "mime": "1.6.0", "ms": "2.1.3", "on-finished": "2.4.1", "range-parser": "~1.2.1", "statuses": "2.0.1" } }, "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg=="],
"send": ["send@0.19.0", "", { "dependencies": { "debug": "2.6.9", "depd": "2.0.0", "destroy": "1.2.0", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "etag": "~1.8.1", "fresh": "0.5.2", "http-errors": "2.0.0", "mime": "1.6.0", "ms": "2.1.3", "on-finished": "2.4.1", "range-parser": "~1.2.1", "statuses": "2.0.1" } }, "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw=="],
"serialize-javascript": ["serialize-javascript@6.0.2", "", { "dependencies": { "randombytes": "^2.1.0" } }, "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g=="],
"serve-static": ["serve-static@1.15.0", "", { "dependencies": { "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "parseurl": "~1.3.3", "send": "0.18.0" } }, "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g=="],
"serve-static": ["serve-static@1.16.2", "", { "dependencies": { "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "parseurl": "~1.3.3", "send": "0.19.0" } }, "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw=="],
"setprototypeof": ["setprototypeof@1.2.0", "", {}, "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="],
"side-channel": ["side-channel@1.0.4", "", { "dependencies": { "call-bind": "^1.0.0", "get-intrinsic": "^1.0.2", "object-inspect": "^1.9.0" } }, "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw=="],
"side-channel": ["side-channel@1.1.0", "", { "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.3", "side-channel-list": "^1.0.0", "side-channel-map": "^1.0.1", "side-channel-weakmap": "^1.0.2" } }, "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw=="],
"side-channel-list": ["side-channel-list@1.0.0", "", { "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.3" } }, "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA=="],
"side-channel-map": ["side-channel-map@1.0.1", "", { "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.5", "object-inspect": "^1.13.3" } }, "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA=="],
"side-channel-weakmap": ["side-channel-weakmap@1.0.2", "", { "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.5", "object-inspect": "^1.13.3", "side-channel-map": "^1.0.1" } }, "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A=="],
"source-map": ["source-map@0.6.1", "", {}, "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="],
@@ -307,38 +349,68 @@
"supports-color": ["supports-color@8.1.1", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q=="],
"tapable": ["tapable@2.2.1", "", {}, "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ=="],
"tapable": ["tapable@2.3.0", "", {}, "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg=="],
"terser": ["terser@5.36.0", "", { "dependencies": { "@jridgewell/source-map": "^0.3.3", "acorn": "^8.8.2", "commander": "^2.20.0", "source-map-support": "~0.5.20" }, "bin": { "terser": "bin/terser" } }, "sha512-IYV9eNMuFAV4THUspIRXkLakHnV6XO7FEdtKjf/mDyrnqUg9LnlOn6/RwRvM9SZjR4GUq8Nk8zj67FzVARr74w=="],
"terser": ["terser@5.44.1", "", { "dependencies": { "@jridgewell/source-map": "^0.3.3", "acorn": "^8.15.0", "commander": "^2.20.0", "source-map-support": "~0.5.20" }, "bin": { "terser": "bin/terser" } }, "sha512-t/R3R/n0MSwnnazuPpPNVO60LX0SKL45pyl9YlvxIdkH0Of7D5qM2EVe+yASRIlY5pZ73nclYJfNANGWPwFDZw=="],
"terser-webpack-plugin": ["terser-webpack-plugin@5.3.10", "", { "dependencies": { "@jridgewell/trace-mapping": "^0.3.20", "jest-worker": "^27.4.5", "schema-utils": "^3.1.1", "serialize-javascript": "^6.0.1", "terser": "^5.26.0" }, "peerDependencies": { "webpack": "^5.1.0" } }, "sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w=="],
"terser-webpack-plugin": ["terser-webpack-plugin@5.3.14", "", { "dependencies": { "@jridgewell/trace-mapping": "^0.3.25", "jest-worker": "^27.4.5", "schema-utils": "^4.3.0", "serialize-javascript": "^6.0.2", "terser": "^5.31.1" }, "peerDependencies": { "webpack": "^5.1.0" } }, "sha512-vkZjpUjb6OMS7dhV+tILUW6BhpDR7P2L/aQSAv+Uwk+m8KATX9EccViHTJR2qDtACKPIYndLGCyl3FMo+r2LMw=="],
"toidentifier": ["toidentifier@1.0.1", "", {}, "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA=="],
"type-is": ["type-is@1.6.18", "", { "dependencies": { "media-typer": "0.3.0", "mime-types": "~2.1.24" } }, "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g=="],
"type-is": ["type-is@2.0.1", "", { "dependencies": { "content-type": "^1.0.5", "media-typer": "^1.1.0", "mime-types": "^3.0.0" } }, "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw=="],
"undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="],
"typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="],
"undici-types": ["undici-types@7.16.0", "", {}, "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw=="],
"unpipe": ["unpipe@1.0.0", "", {}, "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ=="],
"update-browserslist-db": ["update-browserslist-db@1.1.1", "", { "dependencies": { "escalade": "^3.2.0", "picocolors": "^1.1.0" }, "peerDependencies": { "browserslist": ">= 4.21.0" }, "bin": { "update-browserslist-db": "cli.js" } }, "sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A=="],
"uri-js": ["uri-js@4.4.1", "", { "dependencies": { "punycode": "^2.1.0" } }, "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg=="],
"update-browserslist-db": ["update-browserslist-db@1.1.4", "", { "dependencies": { "escalade": "^3.2.0", "picocolors": "^1.1.1" }, "peerDependencies": { "browserslist": ">= 4.21.0" }, "bin": { "update-browserslist-db": "cli.js" } }, "sha512-q0SPT4xyU84saUX+tomz1WLkxUbuaJnR1xWt17M7fJtEJigJeWUNGUqrauFXsHnqev9y9JTRGwk13tFBuKby4A=="],
"utils-merge": ["utils-merge@1.0.1", "", {}, "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA=="],
"vary": ["vary@1.1.2", "", {}, "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg=="],
"watchpack": ["watchpack@2.4.2", "", { "dependencies": { "glob-to-regexp": "^0.4.1", "graceful-fs": "^4.1.2" } }, "sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw=="],
"watchpack": ["watchpack@2.4.4", "", { "dependencies": { "glob-to-regexp": "^0.4.1", "graceful-fs": "^4.1.2" } }, "sha512-c5EGNOiyxxV5qmTtAB7rbiXxi1ooX1pQKMLX/MIabJjRA0SJBQOjKF+KSVfHkr9U1cADPon0mRiVe/riyaiDUA=="],
"webpack": ["webpack@5.96.1", "", { "dependencies": { "@types/eslint-scope": "^3.7.7", "@types/estree": "^1.0.6", "@webassemblyjs/ast": "^1.12.1", "@webassemblyjs/wasm-edit": "^1.12.1", "@webassemblyjs/wasm-parser": "^1.12.1", "acorn": "^8.14.0", "browserslist": "^4.24.0", "chrome-trace-event": "^1.0.2", "enhanced-resolve": "^5.17.1", "es-module-lexer": "^1.2.1", "eslint-scope": "5.1.1", "events": "^3.2.0", "glob-to-regexp": "^0.4.1", "graceful-fs": "^4.2.11", "json-parse-even-better-errors": "^2.3.1", "loader-runner": "^4.2.0", "mime-types": "^2.1.27", "neo-async": "^2.6.2", "schema-utils": "^3.2.0", "tapable": "^2.1.1", "terser-webpack-plugin": "^5.3.10", "watchpack": "^2.4.1", "webpack-sources": "^3.2.3" }, "bin": { "webpack": "bin/webpack.js" } }, "sha512-l2LlBSvVZGhL4ZrPwyr8+37AunkcYj5qh8o6u2/2rzoPc8gxFJkLj1WxNgooi9pnoc06jh0BjuXnamM4qlujZA=="],
"webpack": ["webpack@5.103.0", "", { "dependencies": { "@types/eslint-scope": "^3.7.7", "@types/estree": "^1.0.8", "@types/json-schema": "^7.0.15", "@webassemblyjs/ast": "^1.14.1", "@webassemblyjs/wasm-edit": "^1.14.1", "@webassemblyjs/wasm-parser": "^1.14.1", "acorn": "^8.15.0", "acorn-import-phases": "^1.0.3", "browserslist": "^4.26.3", "chrome-trace-event": "^1.0.2", "enhanced-resolve": "^5.17.3", "es-module-lexer": "^1.2.1", "eslint-scope": "5.1.1", "events": "^3.2.0", "glob-to-regexp": "^0.4.1", "graceful-fs": "^4.2.11", "json-parse-even-better-errors": "^2.3.1", "loader-runner": "^4.3.1", "mime-types": "^2.1.27", "neo-async": "^2.6.2", "schema-utils": "^4.3.3", "tapable": "^2.3.0", "terser-webpack-plugin": "^5.3.11", "watchpack": "^2.4.4", "webpack-sources": "^3.3.3" }, "bin": { "webpack": "bin/webpack.js" } }, "sha512-HU1JOuV1OavsZ+mfigY0j8d1TgQgbZ6M+J75zDkpEAwYeXjWSqrGJtgnPblJjd/mAyTNQ7ygw0MiKOn6etz8yw=="],
"webpack-sources": ["webpack-sources@3.2.3", "", {}, "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w=="],
"webpack-sources": ["webpack-sources@3.3.3", "", {}, "sha512-yd1RBzSGanHkitROoPFd6qsrxt+oFhg/129YzheDGqeustzX0vTZJZsSsQjVQC4yzBQ56K55XU8gaNCtIzOnTg=="],
"esrecurse/estraverse": ["estraverse@5.3.0", "", {}, "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA=="],
"express/body-parser": ["body-parser@1.20.3", "", { "dependencies": { "bytes": "3.1.2", "content-type": "~1.0.5", "debug": "2.6.9", "depd": "2.0.0", "destroy": "1.2.0", "http-errors": "2.0.0", "iconv-lite": "0.4.24", "on-finished": "2.4.1", "qs": "6.13.0", "raw-body": "2.5.2", "type-is": "~1.6.18", "unpipe": "1.0.0" } }, "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g=="],
"express/debug": ["debug@2.6.9", "", { "dependencies": { "ms": "2.0.0" } }, "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="],
"express/qs": ["qs@6.13.0", "", { "dependencies": { "side-channel": "^1.0.6" } }, "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg=="],
"express/type-is": ["type-is@1.6.18", "", { "dependencies": { "media-typer": "0.3.0", "mime-types": "~2.1.24" } }, "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g=="],
"finalhandler/debug": ["debug@2.6.9", "", { "dependencies": { "ms": "2.0.0" } }, "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="],
"mime-types/mime-db": ["mime-db@1.52.0", "", {}, "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="],
"raw-body/iconv-lite": ["iconv-lite@0.7.0", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-cf6L2Ds3h57VVmkZe+Pn+5APsT7FpqJtEhhieDCvrE2MK5Qk9MyffgQyuxQTm6BChfeZNtcOLHp9IcWRVcIcBQ=="],
"send/debug": ["debug@2.6.9", "", { "dependencies": { "ms": "2.0.0" } }, "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="],
"send/encodeurl": ["encodeurl@1.0.2", "", {}, "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w=="],
"send/mime": ["mime@1.6.0", "", { "bin": { "mime": "cli.js" } }, "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg=="],
"send/ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="],
"type-is/mime-types": ["mime-types@3.0.1", "", { "dependencies": { "mime-db": "^1.54.0" } }, "sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA=="],
"express/body-parser/iconv-lite": ["iconv-lite@0.4.24", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3" } }, "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA=="],
"express/body-parser/raw-body": ["raw-body@2.5.2", "", { "dependencies": { "bytes": "3.1.2", "http-errors": "2.0.0", "iconv-lite": "0.4.24", "unpipe": "1.0.0" } }, "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA=="],
"express/debug/ms": ["ms@2.0.0", "", {}, "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="],
"express/type-is/media-typer": ["media-typer@0.3.0", "", {}, "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ=="],
"finalhandler/debug/ms": ["ms@2.0.0", "", {}, "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="],
"send/debug/ms": ["ms@2.0.0", "", {}, "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="],
}
}

View File

@@ -2,9 +2,10 @@
"private": true,
"name": "example",
"dependencies": {
"axios": "^1.7.7",
"axios": "^1.13.2",
"body-parser": "^2.2.0",
"elysia": "^0.6.3",
"express": "^4.18.2",
"express": "^4.21.2",
"mime": "^3.0.0",
"mime-db": "^1.52.0",
"react": "^0.0.0-experimental-380f5d67-20241113",

View File

@@ -378,5 +378,9 @@
"workspaces": [
"../bun-debug-adapter-protocol",
"../bun-inspector-protocol"
]
],
"overrides": {
"glob": "^13.0.0",
"ws": "^8.18.3"
}
}

View File

@@ -1,5 +1,5 @@
#!/bin/sh
# Version: 20
# Version: 21
# A script that installs the dependencies needed to build and test Bun.
# This should work on macOS and Linux with a POSIX shell.
@@ -192,7 +192,7 @@ download_file() {
file_tmp_dir="$(create_tmp_directory)"
file_tmp_path="$file_tmp_dir/$(basename "$file_url")"
fetch "$file_url" >"$file_tmp_path"
fetch "$file_url" > "$file_tmp_path"
grant_to_user "$file_tmp_path"
print "$file_tmp_path"
@@ -204,14 +204,14 @@ download_and_verify_file() {
hash="$2"
path=$(download_file "$file_url")
execute sh -c 'echo "'"$hash $path"'" | sha256sum -c' >/dev/null 2>&1
execute sh -c 'echo "'"$hash $path"'" | sha256sum -c -' >/dev/null 2>&1
print "$path"
}
append_to_profile() {
content="$1"
profiles=".profile .zprofile .bash_profile .bashrc .zshrc"
profiles=".profile .zprofile .bash_profile .bashrc .zshrc .cshrc"
for profile in $profiles; do
for profile_path in "$current_home/$profile" "$home/$profile"; do
if [ "$ci" = "1" ] || [ -f "$profile_path" ]; then
@@ -275,12 +275,15 @@ check_operating_system() {
os="$("$uname" -s)"
case "$os" in
Linux*)
Linux)
os="linux"
;;
Darwin*)
Darwin)
os="darwin"
;;
FreeBSD)
os="freebsd"
;;
*)
error "Unsupported operating system: $os"
;;
@@ -343,6 +346,11 @@ check_operating_system() {
;;
esac
;;
freebsd)
. /etc/os-release
distro="$ID"
release="$VERSION_ID"
;;
esac
if [ -n "$distro" ]; then
@@ -426,6 +434,9 @@ check_package_manager() {
error "No package manager found. (apt, dnf, yum, apk)"
fi
;;
freebsd)
pm="pkg"
;;
esac
print "Package manager: $pm"
@@ -438,6 +449,13 @@ check_package_manager() {
apk)
package_manager update
;;
pkg)
# may need to switch betwen 'latest' and 'quarterly' depending on which repo www/chromium is in. check https://www.freshports.org/www/chromium/.
# mkdir -p /usr/local/etc/pkg/repos
# echo 'FreeBSD: { url: "pkg+http://pkg.FreeBSD.org/${ABI}/quarterly" }' > /usr/local/etc/pkg/repos/FreeBSD.conf
export ASSUME_ALWAYS_YES=yes
package_manager update -f
;;
esac
}
@@ -478,6 +496,9 @@ check_user() {
}
check_ulimit() {
if ! [ "$os" = "linux" ]; then
return
fi
if ! [ "$ci" = "1" ]; then
return
fi
@@ -588,6 +609,9 @@ package_manager() {
brew)
execute_as_user brew "$@"
;;
pkg)
execute_sudo pkg "$@"
;;
*)
error "Unsupported package manager: $pm"
;;
@@ -645,6 +669,9 @@ install_packages() {
--no-progress \
"$@"
;;
pkg)
package_manager install "$@"
;;
*)
error "Unsupported package manager: $pm"
;;
@@ -688,13 +715,57 @@ install_common_software() {
apt-transport-https \
software-properties-common
fi
# https://packages.debian.org
# https://packages.ubuntu.com
install_packages \
bash \
ca-certificates \
curl \
htop \
gnupg \
git \
unzip \
wget \
libc6-dbg
;;
dnf)
# https://packages.fedoraproject.org
install_packages \
bash \
ca-certificates \
curl \
htop \
gnupg \
git \
unzip \
wget \
dnf-plugins-core
;;
apk)
# https://pkgs.alpinelinux.org/packages
install_packages \
bash \
ca-certificates \
curl \
htop \
gnupg \
git \
unzip \
wget \
;;
pkg)
# https://www.freshports.org
install_packages \
shells/bash \
ftp/curl \
sysutils/htop \
security/gnupg \
devel/git \
archivers/unzip \
ftp/wget \
editors/vim \
sysutils/neofetch \
;;
esac
case "$distro" in
@@ -718,16 +789,6 @@ install_common_software() {
execute "$crb" enable
fi
install_packages \
bash \
ca-certificates \
curl \
htop \
gnupg \
git \
unzip \
wget
install_rosetta
install_nodejs
install_bun
@@ -755,6 +816,9 @@ install_nodejs() {
linux)
nodejs_platform="linux"
;;
freebsd)
nodejs_platform="freebsd"
;;
*)
error "Unsupported OS for Node.js download: $os"
;;
@@ -773,6 +837,12 @@ install_nodejs() {
;;
esac
if [ "$os" = "freebsd" ]; then
# TODO: use nodejs_version_exact
install_packages "www/node$(nodejs_version)" "www/npm-node$(nodejs_version)"
return
fi
case "$abi" in
musl)
nodejs_mirror="https://bun-nodejs-release.s3.us-west-1.amazonaws.com"
@@ -862,6 +932,10 @@ install_nodejs() {
}
install_nodejs_headers() {
if [ "$os" = "freebsd" ]; then
return
fi
nodejs_version="$(nodejs_version_exact)"
nodejs_headers_tar="$(download_file "https://nodejs.org/download/release/v$nodejs_version/node-v$nodejs_version-headers.tar.gz")"
nodejs_headers_dir="$(dirname "$nodejs_headers_tar")"
@@ -876,6 +950,10 @@ install_nodejs_headers() {
}
setup_node_gyp_cache() {
if [ "$os" = "freebsd" ]; then
return
fi
nodejs_version="$1"
headers_source="$2"
@@ -914,6 +992,11 @@ bun_version_exact() {
}
install_bun() {
if [ "$os" = "freebsd" ]; then
# TODO: need to complete bun bootstrap for for this work
return
fi
install_packages unzip
case "$pm" in
@@ -965,6 +1048,9 @@ install_cmake() {
--skip-license \
--prefix=/usr
;;
freebsd-pkg)
install_packages devel/cmake
;;
esac
}
@@ -1027,19 +1113,34 @@ install_build_essentials() {
;;
esac
install_packages \
make \
python3 \
libtool \
ruby \
perl
case "$os" in
linux)
install_packages \
make \
python3 \
libtool \
ruby \
perl \
;;
freebsd)
install_packages \
devel/ninja \
devel/pkgconf \
lang/go \
devel/gmake \
lang/python3 \
devel/libtool \
lang/ruby33 \
perl5 \
;;
esac
install_cmake
install_llvm
install_osxcross
install_gcc
install_sccache
install_rust
install_sccache
install_docker
}
@@ -1073,11 +1174,17 @@ install_llvm() {
"llvm$(llvm_version)-dev" # Ensures llvm-symbolizer is installed
;;
esac
case "$os" in
freebsd)
# TODO: use llvm_version_exact
install_packages "devel/llvm$(llvm_version)"
;;
esac
}
install_gcc() {
if ! [ "$os" = "linux" ] || ! [ "$distro" = "ubuntu" ] || [ -z "$gcc_version" ]
then
if ! [ "$os" = "linux" ] || ! [ "$distro" = "ubuntu" ] || [ -z "$gcc_version" ]; then
return
fi
@@ -1150,6 +1257,18 @@ install_gcc() {
}
install_sccache() {
case "$os" in
linux)
;;
freebsd)
cargo install sccache --locked --version 0.12.0
return
;;
*)
error "Unsupported platform: $os"
;;
esac
# Alright, look, this function is cobbled together but it's only as cobbled
# together as this whole script is.
#
@@ -1177,12 +1296,17 @@ install_sccache() {
}
install_rust() {
case "$pm" in
apk)
case "$distro" in
alpine)
install_packages \
rust \
cargo
;;
freebsd)
install_packages lang/rust
create_directory "$HOME/.cargo/bin"
append_to_path "$HOME/.cargo/bin"
;;
*)
rust_home="/opt/rust"
create_directory "$rust_home"
@@ -1212,6 +1336,11 @@ install_docker() {
package_manager install docker --cask
fi
;;
pkg)
install_packages \
sysutils/docker \
sysutils/docker-compose \
;;
*)
case "$distro-$release" in
amzn-2 | amzn-1)
@@ -1306,10 +1435,17 @@ install_tailscale() {
execute_as_user go install tailscale.com/cmd/tailscale{,d}@latest
append_to_path "$home/go/bin"
;;
freebsd)
install_packages security/tailscale
;;
esac
}
install_fuse_python() {
if ! [ "$os" = "linux" ]; then
return
fi
# only linux needs this
case "$pm" in
apk)
@@ -1339,7 +1475,7 @@ install_fuse_python() {
}
create_buildkite_user() {
if ! [ "$ci" = "1" ] || ! [ "$os" = "linux" ]; then
if ! [ "$ci" = "1" ]; then
return
fi
@@ -1368,6 +1504,14 @@ create_buildkite_user() {
--home "$home" \
--disabled-password
;;
freebsd)
execute_sudo pw group add -n "$group"
execute_sudo pw user add \
-n "$user" \
-g "$group" \
-s "$(require sh)" \
-d "$home" \
;;
*)
execute_sudo useradd "$user" \
--system \
@@ -1421,7 +1565,7 @@ install_buildkite() {
return
fi
buildkite_version="3.87.0"
buildkite_version="3.114.0"
case "$arch" in
aarch64)
buildkite_arch="arm64"
@@ -1518,6 +1662,10 @@ install_chromium() {
xorg-x11-fonts-Type1 \
xorg-x11-utils
;;
pkg)
install_packages \
www/chromium \
;;
esac
case "$distro" in
@@ -1529,28 +1677,46 @@ install_chromium() {
}
install_age() {
# we only use this to encrypt core dumps, which we only have on Linux
age_version="1.2.1"
case "$os" in
linux)
age_tarball=""
case "$arch" in
x64)
age_tarball="$(download_and_verify_file https://github.com/FiloSottile/age/releases/download/v1.2.1/age-v1.2.1-linux-amd64.tar.gz 7df45a6cc87d4da11cc03a539a7470c15b1041ab2b396af088fe9990f7c79d50)"
age_arch="amd64"
age_hash="7df45a6cc87d4da11cc03a539a7470c15b1041ab2b396af088fe9990f7c79d50"
;;
aarch64)
age_tarball="$(download_and_verify_file https://github.com/FiloSottile/age/releases/download/v1.2.1/age-v1.2.1-linux-arm64.tar.gz 57fd79a7ece5fe501f351b9dd51a82fbee1ea8db65a8839db17f5c080245e99f)"
age_arch="arm64"
age_hash="57fd79a7ece5fe501f351b9dd51a82fbee1ea8db65a8839db17f5c080245e99f"
;;
*)
error "Unsupported platform: $os-$arch"
;;
esac
age_extract_dir="$(create_tmp_directory)"
execute tar -C "$age_extract_dir" -zxf "$age_tarball" age/age
move_to_bin "$age_extract_dir/age/age"
;;
freebsd)
case "$arch" in
x64)
age_arch="amd64"
age_hash="943a7510a9973a1e589b913a70228aa1361a63cde39e3ed581435a4d4802df29"
;;
*)
error "Unsupported platform: $os-$arch"
;;
esac
;;
*)
error "Unsupported platform: $os-$arch"
;;
esac
age_tarball="$(download_and_verify_file https://github.com/FiloSottile/age/releases/download/v$age_version/age-v$age_version-$os-$age_arch.tar.gz "$age_hash")"
age_extract_dir="$(create_tmp_directory)"
execute tar -C "$age_extract_dir" -zxf "$age_tarball" age/age
move_to_bin "$age_extract_dir/age/age"
}
configure_core_dumps() {
# we only have core dumps on Linux
case "$os" in
linux)
# set up a directory that the test runner will look in after running tests
@@ -1600,7 +1766,7 @@ ensure_no_tmpfs() {
if ! [ "$os" = "linux" ]; then
return
fi
if ! [ "$distro" = "ubuntu" ]; then
if ! ( [ "$distro" = "ubuntu" ] || [ "$distro" = "debian" ] ); then
return
fi

View File

@@ -712,7 +712,7 @@ write_files:
HostKey /etc/ssh/ssh_host_ed25519_key
SyslogFacility AUTHPRIV
PermitRootLogin yes
AuthorizedKeysFile .ssh/authorized_keys
AuthorizedKeysFile %h/.ssh/authorized_keys
PasswordAuthentication no
ChallengeResponseAuthentication no
GSSAPIAuthentication yes
@@ -883,8 +883,7 @@ function getSshKeys() {
const sshFiles = readdirSync(sshPath, { withFileTypes: true, encoding: "utf-8" });
const publicPaths = sshFiles
.filter(entry => entry.isFile() && entry.name.endsWith(".pub"))
.map(({ name }) => join(sshPath, name))
.filter(path => !readFile(path, { cache: true }).startsWith("ssh-ed25519"));
.map(({ name }) => join(sshPath, name));
sshKeys.push(
...publicPaths.map(publicPath => ({
@@ -960,10 +959,11 @@ async function getGithubOrgSshKeys(organization) {
* @returns {Promise<void>}
*/
async function spawnScp(options) {
const { hostname, port, username, identityPaths, password, source, destination, retries = 10 } = options;
const { hostname, port, username, identityPaths, password, source, destination, retries = 3 } = options;
await waitForPort({ hostname, port: port || 22 });
const command = ["scp", "-o", "StrictHostKeyChecking=no"];
command.push("-O"); // use SCP instead of SFTP
if (!password) {
command.push("-o", "BatchMode=yes");
}
@@ -1228,7 +1228,6 @@ async function main() {
};
let { detached, bootstrap, ci, os, arch, distro, release, features } = options;
if (os === "freebsd") bootstrap = false;
let name = `${os}-${arch}-${(release || "").replace(/\./g, "")}`;

View File

@@ -2842,7 +2842,7 @@ export function printEnvironment() {
if (isCI) {
startGroup("Environment", () => {
for (const [key, value] of Object.entries(process.env)) {
for (const [key, value] of Object.entries(process.env).toSorted()) {
console.log(`${key}:`, value);
}
});
@@ -2986,6 +2986,9 @@ const emojiMap = {
gear: ["⚙️", "gear"],
clipboard: ["📋", "clipboard"],
rocket: ["🚀", "rocket"],
freebsd: ["😈", "freebsd"],
openbsd: ["🐡", "openbsd"],
netbsd: ["🚩", "netbsd"],
};
/**

View File

@@ -51,6 +51,7 @@ pub const Features = struct {
pub var tls_server: usize = 0;
pub var http_server: usize = 0;
pub var https_server: usize = 0;
pub var http_client_proxy: usize = 0;
/// Set right before JSC::initialize is called
pub var jsc: usize = 0;
/// Set when bake.DevServer is initialized
@@ -88,10 +89,13 @@ pub const Features = struct {
pub var yarn_migration: usize = 0;
pub var pnpm_migration: usize = 0;
pub var yaml_parse: usize = 0;
pub var cpu_profile: usize = 0;
pub var heap_snapshot: usize = 0;
comptime {
@export(&napi_module_register, .{ .name = "Bun__napi_module_register_count" });
@export(&process_dlopen, .{ .name = "Bun__process_dlopen_count" });
@export(&heap_snapshot, .{ .name = "Bun__Feature__heap_snapshot" });
}
pub fn formatter() Formatter {

View File

@@ -280,6 +280,7 @@ pub const Run = struct {
.dir = cpu_prof_opts.dir,
};
CPUProfiler.startCPUProfiler(vm.jsc_vm);
bun.analytics.Features.cpu_profile += 1;
}
this.addConditionalGlobals();

View File

@@ -1425,6 +1425,7 @@ pub const Formatter = struct {
o, // o
O, // O
c, // c
j, // j
};
fn writeWithFormatting(
@@ -1466,6 +1467,7 @@ pub const Formatter = struct {
'O' => .O,
'd', 'i' => .i,
'c' => .c,
'j' => .j,
'%' => {
// print up to and including the first %
const end = slice[0..i];
@@ -1625,6 +1627,16 @@ pub const Formatter = struct {
.c => {
// TODO: Implement %c
},
.j => {
// JSON.stringify the value
var str = bun.String.empty;
defer str.deref();
try next_value.jsonStringify(global, 0, &str);
this.addForNewLine(str.length());
writer.print("{f}", .{str});
},
}
if (this.remaining_values.len == 0) break;
},

View File

@@ -3512,8 +3512,7 @@ pub const IPCInstanceUnion = union(enum) {
/// IPC is put in this "enabled but not started" state when IPC is detected
/// but the client JavaScript has not yet done `.on("message")`
waiting: struct {
// TODO: rename to `fd`
info: bun.FD,
fd: bun.FD,
mode: IPC.Mode,
},
initialized: *IPCInstance,
@@ -3586,9 +3585,9 @@ pub const IPCInstance = struct {
pub const Handlers = IPC.NewIPCHandler(IPCInstance);
};
pub fn initIPCInstance(this: *VirtualMachine, info: bun.FD, mode: IPC.Mode) void {
IPC.log("initIPCInstance {f}", .{info});
this.ipc = .{ .waiting = .{ .info = info, .mode = mode } };
pub fn initIPCInstance(this: *VirtualMachine, fd: bun.FD, mode: IPC.Mode) void {
IPC.log("initIPCInstance {f}", .{fd});
this.ipc = .{ .waiting = .{ .fd = fd, .mode = mode } };
}
pub fn getIPCInstance(this: *VirtualMachine) ?*IPCInstance {
@@ -3596,7 +3595,7 @@ pub fn getIPCInstance(this: *VirtualMachine) ?*IPCInstance {
if (this.ipc.? != .waiting) return this.ipc.?.initialized;
const opts = this.ipc.?.waiting;
IPC.log("getIPCInstance {f}", .{opts.info});
IPC.log("getIPCInstance {f}", .{opts.fd});
this.event_loop.ensureWaker();
@@ -3615,7 +3614,7 @@ pub fn getIPCInstance(this: *VirtualMachine) ?*IPCInstance {
instance.data = .init(opts.mode, .{ .virtual_machine = instance }, .uninitialized);
const socket = IPC.Socket.fromFd(context, opts.info, IPC.SendQueue, &instance.data, null, true) orelse {
const socket = IPC.Socket.fromFd(context, opts.fd, IPC.SendQueue, &instance.data, null, true) orelse {
instance.deinit();
this.ipc = null;
Output.warn("Unable to start IPC socket", .{});
@@ -3637,10 +3636,10 @@ pub fn getIPCInstance(this: *VirtualMachine) ?*IPCInstance {
this.ipc = .{ .initialized = instance };
instance.data.windowsConfigureClient(opts.info) catch {
instance.data.windowsConfigureClient(opts.fd) catch {
instance.deinit();
this.ipc = null;
Output.warn("Unable to start IPC pipe '{f}'", .{opts.info});
Output.warn("Unable to start IPC pipe '{f}'", .{opts.fd});
return null;
};

View File

@@ -946,13 +946,8 @@ pub fn indexOfLine(globalThis: *jsc.JSGlobalObject, callframe: *jsc.CallFrame) b
var offset: usize = 0;
if (arguments.len > 1) {
offset = @as(
usize,
@intCast(@max(
arguments[1].to(u32),
0,
)),
);
const offset_value = try arguments[1].coerce(i64, globalThis);
offset = @intCast(@max(offset_value, 0));
}
const bytes = buffer.byteSlice();
@@ -1217,11 +1212,19 @@ pub fn mmapFile(globalThis: *jsc.JSGlobalObject, callframe: *jsc.CallFrame) bun.
}
if (try opts.get(globalThis, "size")) |value| {
map_size = @as(usize, @intCast(value.toInt64()));
const size_value = try value.coerceToInt64(globalThis);
if (size_value < 0) {
return globalThis.throwInvalidArguments("size must be a non-negative integer", .{});
}
map_size = @intCast(size_value);
}
if (try opts.get(globalThis, "offset")) |value| {
offset = @as(usize, @intCast(value.toInt64()));
const offset_value = try value.coerceToInt64(globalThis);
if (offset_value < 0) {
return globalThis.throwInvalidArguments("offset must be a non-negative integer", .{});
}
offset = @intCast(offset_value);
offset = std.mem.alignBackwardAnyAlign(usize, offset, std.heap.pageSize());
}
}

View File

@@ -225,23 +225,26 @@ static void* JSVALUE_TO_PTR(EncodedJSValue val) {
return 0;
if (JSCELL_IS_TYPED_ARRAY(val)) {
return JSVALUE_TO_TYPED_ARRAY_VECTOR(val);
return JSVALUE_TO_TYPED_ARRAY_VECTOR(val);
}
if (JSVALUE_IS_INT32(val)) {
return (void*)(uintptr_t)JSVALUE_TO_INT32(val);
}
// Assume the JSValue is a double
val.asInt64 -= DoubleEncodeOffset;
size_t ptr = (size_t)val.asDouble;
return (void*)ptr;
return (void*)(uintptr_t)val.asDouble;
}
static EncodedJSValue PTR_TO_JSVALUE(void* ptr) {
EncodedJSValue val;
if (ptr == 0)
{
val.asInt64 = TagValueNull;
return val;
if (ptr == 0) {
val.asInt64 = TagValueNull;
return val;
}
val.asDouble = (double)(size_t)ptr;
val.asDouble = (double)(uintptr_t)ptr;
val.asInt64 += DoubleEncodeOffset;
return val;
}

View File

@@ -1171,9 +1171,15 @@ pub const JSBundler = struct {
extern fn JSBundlerPlugin__tombstone(*Plugin) void;
extern fn JSBundlerPlugin__runOnEndCallbacks(*Plugin, jsc.JSValue, jsc.JSValue, jsc.JSValue) jsc.JSValue;
pub fn runOnEndCallbacks(this: *Plugin, globalThis: *jsc.JSGlobalObject, build_promise: *jsc.JSPromise, build_result: jsc.JSValue, rejection: jsc.JSValue) JSError!jsc.JSValue {
pub fn runOnEndCallbacks(this: *Plugin, globalThis: *jsc.JSGlobalObject, build_promise: *jsc.JSPromise, build_result: jsc.JSValue, rejection: bun.JSError!jsc.JSValue) bun.JSError!jsc.JSValue {
jsc.markBinding(@src());
const rejection_value = rejection catch |err| switch (err) {
error.OutOfMemory => globalThis.createOutOfMemoryError(),
error.JSError => globalThis.takeError(err),
error.JSTerminated => return error.JSTerminated,
};
var scope: jsc.CatchScope = undefined;
scope.init(globalThis, @src());
defer scope.deinit();
@@ -1182,7 +1188,7 @@ pub const JSBundler = struct {
this,
build_promise.asValue(globalThis),
build_result,
rejection,
rejection_value,
);
try scope.returnIfException();

View File

@@ -635,6 +635,16 @@ pub fn spawnMaybeSync(
.stdout_maxbuf = subprocess.stdout_maxbuf,
};
if (comptime Environment.isPosix) {
log("After subprocess init: stdout state={s}, stdin FD={?d}, stdout FD={?d}", .{
@tagName(subprocess.stdout),
if (spawned.stdin) |fd| fd.native() else null,
if (spawned.stdout) |fd| fd.native() else null,
});
} else {
log("After subprocess init: stdout state={s}", .{@tagName(subprocess.stdout)});
}
subprocess.process.setExitHandler(subprocess);
promise_for_stream.ensureStillAlive();
@@ -997,7 +1007,7 @@ pub fn appendEnvpFromJS(globalThis: *jsc.JSGlobalObject, object: *jsc.JSObject,
}
}
const log = Output.scoped(.Subprocess, .hidden);
const log = Output.scoped(.spawn_bindings, .hidden);
extern "C" const BUN_DEFAULT_PATH_FOR_SPAWN: [*:0]const u8;
const IPC = @import("../../ipc.zig");

View File

@@ -1004,6 +1004,13 @@ pub const PosixSpawnOptions = struct {
pipe: bun.FileDescriptor,
// TODO: remove this entry, it doesn't seem to be used
dup2: struct { out: bun.jsc.Subprocess.StdioKind, to: bun.jsc.Subprocess.StdioKind },
/// Pseudo-terminal with optional window size configuration
pty: PtyConfig,
pub const PtyConfig = struct {
width: u16 = 80,
height: u16 = 24,
};
};
pub fn deinit(_: *const PosixSpawnOptions) void {
@@ -1104,15 +1111,21 @@ pub const PosixSpawnResult = struct {
extra_pipes: std.array_list.Managed(bun.FileDescriptor) = std.array_list.Managed(bun.FileDescriptor).init(bun.default_allocator),
memfds: [3]bool = .{ false, false, false },
/// PTY master file descriptor if PTY was requested for any stdio.
/// The child process has the slave side; parent uses this for I/O.
pty_master: ?bun.FileDescriptor = null,
// ESRCH can happen when requesting the pidfd
has_exited: bool = false,
pub fn close(this: *WindowsSpawnResult) void {
pub fn close(this: *PosixSpawnResult) void {
if (this.pty_master) |fd| {
fd.close();
this.pty_master = null;
}
for (this.extra_pipes.items) |fd| {
fd.close();
}
this.extra_pipes.clearAndFree();
}
@@ -1301,6 +1314,38 @@ pub fn spawnProcessPosix(
var dup_stdout_to_stderr: bool = false;
// Check if any stdio uses PTY and create a single PTY pair if needed
var pty_slave: ?bun.FileDescriptor = null;
var pty_master: ?bun.FileDescriptor = null;
for (stdio_options) |opt| {
if (opt == .pty) {
// Create PTY pair with the configured window size
const winsize = bun.sys.WinSize{
.ws_col = opt.pty.width,
.ws_row = opt.pty.height,
};
const pty_pair = try bun.sys.openpty(&winsize).unwrap();
pty_master = pty_pair.master;
pty_slave = pty_pair.slave;
log("PTY created: master={d}, slave={d}", .{ pty_pair.master.native(), pty_pair.slave.native() });
// Track for cleanup
try to_close_at_end.append(pty_pair.slave);
try to_close_on_error.append(pty_pair.master);
// Set master to non-blocking for async operations
if (!options.sync) {
try bun.sys.setNonblocking(pty_pair.master).unwrap();
}
spawned.pty_master = pty_pair.master;
break;
}
}
for (0..3) |i| {
const stdio = stdios[i];
const fileno = bun.FD.fromNative(@intCast(i));
@@ -1417,6 +1462,29 @@ pub fn spawnProcessPosix(
try actions.dup2(fd, fileno);
stdio.* = fd;
},
.pty => {
// Use the slave side of the PTY for this stdio
// The PTY pair was already created above
const slave = pty_slave.?;
try actions.dup2(slave, fileno);
// The parent gets the master side for I/O.
// Each stdio gets its own dup'd FD so they can register with epoll independently.
// stderr is ignored if stdout already has PTY (they share the same stream).
if (i == 2 and stdio_options[1] == .pty) {
// stdout is also PTY, stderr becomes ignore (user reads both from stdout)
stdio.* = null;
log("PTY stderr: ignored (stdout has PTY)", .{});
} else {
// dup() the master FD so each stdio has its own FD for epoll
const duped = try bun.sys.dup(pty_master.?).unwrap();
if (!options.sync) {
try bun.sys.setNonblocking(duped).unwrap();
}
try to_close_on_error.append(duped);
stdio.* = duped;
log("PTY {s}: duped master={d}", .{ if (i == 0) "stdin" else if (i == 1) "stdout" else "stderr", duped.native() });
}
},
}
}
@@ -1463,6 +1531,19 @@ pub fn spawnProcessPosix(
try extra_fds.append(fd);
},
.pty => {
// Use existing PTY slave (should have been created from primary stdio)
if (pty_slave) |slave| {
try actions.dup2(slave, fileno);
// dup() the master FD so each extra_fd has its own FD for epoll
const duped = try bun.sys.dup(pty_master.?).unwrap();
if (!options.sync) {
try bun.sys.setNonblocking(duped).unwrap();
}
try to_close_on_error.append(duped);
try extra_fds.append(duped);
}
},
}
}
@@ -1494,6 +1575,13 @@ pub fn spawnProcessPosix(
spawned.extra_pipes = extra_fds;
extra_fds = std.array_list.Managed(bun.FileDescriptor).init(bun.default_allocator);
// Parent uses dup()'d copies of the PTY master for stdio/extra_fds;
// the original master FD is no longer needed and should be closed
// to avoid leaking one FD per PTY spawn.
if (pty_master) |fd| {
fd.close();
}
if (comptime Environment.isLinux) {
// If it's spawnSync and we want to block the entire thread
// don't even bother with pidfd. It's not necessary.

View File

@@ -14,6 +14,16 @@ pub const Stdio = union(enum) {
pipe,
ipc,
readable_stream: jsc.WebCore.ReadableStream,
/// Pseudo-terminal: creates a PTY master/slave pair for the spawned process.
/// The child gets the slave side, parent gets the master side for I/O.
pty: PtyOptions,
pub const PtyOptions = struct {
/// Terminal width in columns (default: 80)
width: u16 = 80,
/// Terminal height in rows (default: 24)
height: u16 = 24,
};
const log = bun.sys.syslog;
@@ -192,6 +202,7 @@ pub const Stdio = union(enum) {
.path => |pathlike| .{ .path = pathlike.slice() },
.inherit => .{ .inherit = {} },
.ignore => .{ .ignore = {} },
.pty => |pty_opts| .{ .pty = .{ .width = pty_opts.width, .height = pty_opts.height } },
},
};
}
@@ -244,6 +255,7 @@ pub const Stdio = union(enum) {
.path => |pathlike| .{ .path = pathlike.slice() },
.inherit => .{ .inherit = {} },
.ignore => .{ .ignore = {} },
.pty => .{ .buffer = bun.handleOom(bun.default_allocator.create(uv.Pipe)) }, // PTY falls back to pipe on Windows
.memfd => @panic("This should never happen"),
},
@@ -346,8 +358,18 @@ pub const Stdio = union(enum) {
out_stdio.* = Stdio{ .pipe = {} };
} else if (str.eqlComptime("ipc")) {
out_stdio.* = Stdio{ .ipc = {} };
} else if (str.eqlComptime("pty")) {
if (is_sync) {
return globalThis.throwInvalidArguments("PTY is not supported with spawnSync", .{});
}
// On Windows, PTY falls back to pipe (no real PTY support)
if (comptime Environment.isWindows) {
out_stdio.* = Stdio{ .pipe = {} };
} else {
out_stdio.* = Stdio{ .pty = .{} };
}
} else {
return globalThis.throwInvalidArguments("stdio must be an array of 'inherit', 'pipe', 'ignore', Bun.file(pathOrFd), number, or null", .{});
return globalThis.throwInvalidArguments("stdio must be an array of 'inherit', 'pipe', 'ignore', 'pty', Bun.file(pathOrFd), number, or null", .{});
}
return;
} else if (value.isNumber()) {
@@ -436,7 +458,56 @@ pub const Stdio = union(enum) {
return;
}
return globalThis.throwInvalidArguments("stdio must be an array of 'inherit', 'ignore', or null", .{});
// Check for PTY object: { type: "pty", width?: number, height?: number }
if (value.isObject()) {
if (try value.getTruthy(globalThis, "type")) |type_val| {
if (type_val.isString()) {
const type_str = try type_val.getZigString(globalThis);
if (type_str.eqlComptime("pty")) {
if (is_sync) {
return globalThis.throwInvalidArguments("PTY is not supported with spawnSync", .{});
}
// On Windows, PTY falls back to pipe (no real PTY support)
if (comptime Environment.isWindows) {
out_stdio.* = Stdio{ .pipe = {} };
return;
}
var pty_opts: PtyOptions = .{};
if (try value.get(globalThis, "width")) |width_val| {
if (!width_val.isUndefinedOrNull()) {
if (!width_val.isNumber()) {
return globalThis.throwInvalidArguments("PTY width must be a number", .{});
}
const width = width_val.toInt32();
if (width <= 0 or width > std.math.maxInt(u16)) {
return globalThis.throwInvalidArguments("PTY width must be a positive integer <= 65535", .{});
}
pty_opts.width = @intCast(width);
}
}
if (try value.get(globalThis, "height")) |height_val| {
if (!height_val.isUndefinedOrNull()) {
if (!height_val.isNumber()) {
return globalThis.throwInvalidArguments("PTY height must be a number", .{});
}
const height = height_val.toInt32();
if (height <= 0 or height > std.math.maxInt(u16)) {
return globalThis.throwInvalidArguments("PTY height must be a positive integer <= 65535", .{});
}
pty_opts.height = @intCast(height);
}
}
out_stdio.* = Stdio{ .pty = pty_opts };
return;
}
}
}
}
return globalThis.throwInvalidArguments("stdio must be an array of 'inherit', 'pipe', 'ignore', 'pty', Bun.file(pathOrFd), number, or null", .{});
}
pub fn extractBlob(stdio: *Stdio, globalThis: *jsc.JSGlobalObject, blob: jsc.WebCore.Blob.Any, i: i32) bun.JSError!void {

View File

@@ -282,6 +282,7 @@ pub fn getStdin(this: *Subprocess, globalThis: *JSGlobalObject) bun.JSError!JSVa
}
pub fn getStdout(this: *Subprocess, globalThis: *JSGlobalObject) bun.JSError!JSValue {
log("getStdout: subprocess={*}, stdout ptr={*}, stdout state={s}", .{ this, &this.stdout, @tagName(this.stdout) });
this.observable_getters.insert(.stdout);
// NOTE: ownership of internal buffers is transferred to the JSValue, which
// gets cached on JSSubprocess (created via bindgen). This makes it

View File

@@ -1,3 +1,5 @@
const log = Output.scoped(.Readable, .hidden);
pub const Readable = union(enum) {
fd: bun.FileDescriptor,
memfd: bun.FileDescriptor,
@@ -57,7 +59,8 @@ pub const Readable = union(enum) {
}
}
return switch (stdio) {
log("Readable.init: stdio={s}, result={?d}, subprocess={*}, stdout state={s}", .{ @tagName(stdio), if (comptime Environment.isPosix) (if (result) |r| r.native() else null) else @as(?c_int, null), process, @tagName(process.stdout) });
const readable = switch (stdio) {
.inherit => Readable{ .inherit = {} },
.ignore, .ipc, .path => Readable{ .ignore = {} },
.fd => |fd| if (Environment.isPosix) Readable{ .fd = result.? } else Readable{ .fd = fd },
@@ -67,10 +70,22 @@ pub const Readable = union(enum) {
.array_buffer, .blob => Output.panic("TODO: implement ArrayBuffer & Blob support in Stdio readable", .{}),
.capture => Output.panic("TODO: implement capture support in Stdio readable", .{}),
.readable_stream => Readable{ .ignore = {} }, // ReadableStream is handled separately
.pty => if (Environment.isPosix and result == null) blk: {
// When stdout and stderr both use PTY, they share the same master FD.
// stderr's result will be null - ignore it since stdout handles reading.
log("PTY with null result -> ignore", .{});
break :blk Readable{ .ignore = {} };
} else blk: {
log("PTY with result -> creating pipe reader", .{});
break :blk Readable{ .pipe = PipeReader.createForPty(event_loop, process, result, max_size) }; // PTY master - use read() not recv()
},
};
log("Readable.init returning: {s}", .{@tagName(readable)});
return readable;
}
pub fn onClose(this: *Readable, _: ?bun.sys.Error) void {
pub fn onClose(this: *Readable, err: ?bun.sys.Error) void {
log("onClose called, current state={s}, err={?s}", .{ @tagName(this.*), if (err) |e| @tagName(e.getErrno()) else null });
this.* = .closed;
}
@@ -116,6 +131,7 @@ pub const Readable = union(enum) {
pub fn toJS(this: *Readable, globalThis: *jsc.JSGlobalObject, exited: bool) bun.JSError!JSValue {
_ = exited; // autofix
log("Readable.toJS: this={*}, state={s}", .{ this, @tagName(this.*) });
switch (this.*) {
// should only be reachable when the entire output is buffered.
.memfd => return this.toBufferedValue(globalThis),
@@ -139,6 +155,7 @@ pub const Readable = union(enum) {
return jsc.WebCore.ReadableStream.fromOwnedSlice(globalThis, own, 0);
},
else => {
log("Readable.toJS returning undefined for state={s}", .{@tagName(this.*)});
return .js_undefined;
},
}

View File

@@ -14,6 +14,8 @@ state: union(enum) {
err: bun.sys.Error,
} = .{ .pending = {} },
stdio_result: StdioResult,
/// True if this is a PTY master (character device, not socket - use read() not recv())
is_pty: bool = false,
pub const IOReader = bun.io.BufferedReader;
pub const Poll = IOReader;
@@ -34,12 +36,21 @@ pub fn detach(this: *PipeReader) void {
}
pub fn create(event_loop: *jsc.EventLoop, process: *Subprocess, result: StdioResult, limit: ?*MaxBuf) *PipeReader {
return createWithOptions(event_loop, process, result, limit, false);
}
pub fn createForPty(event_loop: *jsc.EventLoop, process: *Subprocess, result: StdioResult, limit: ?*MaxBuf) *PipeReader {
return createWithOptions(event_loop, process, result, limit, true);
}
fn createWithOptions(event_loop: *jsc.EventLoop, process: *Subprocess, result: StdioResult, limit: ?*MaxBuf, is_pty: bool) *PipeReader {
var this = bun.new(PipeReader, .{
.ref_count = .init(),
.process = process,
.reader = IOReader.init(@This()),
.event_loop = event_loop,
.stdio_result = result,
.is_pty = is_pty,
});
MaxBuf.addToPipereader(limit, &this.reader.maxbuf);
if (Environment.isWindows) {
@@ -63,6 +74,13 @@ pub fn start(this: *PipeReader, process: *Subprocess, event_loop: *jsc.EventLoop
return this.reader.startWithCurrentPipe();
}
// Set PTY flag BEFORE start() so that onError can check it during registerPoll()
if (comptime Environment.isPosix) {
if (this.is_pty) {
this.reader.flags.is_pty = true;
}
}
switch (this.reader.start(this.stdio_result.?, true)) {
.err => |err| {
return .{ .err = err };
@@ -70,8 +88,11 @@ pub fn start(this: *PipeReader, process: *Subprocess, event_loop: *jsc.EventLoop
.result => {
if (comptime Environment.isPosix) {
const poll = this.reader.handle.poll;
poll.flags.insert(.socket);
this.reader.flags.socket = true;
// PTY is a character device, not a socket - use read() not recv()
if (!this.is_pty) {
poll.flags.insert(.socket);
this.reader.flags.socket = true;
}
this.reader.flags.nonblocking = true;
this.reader.flags.pollable = true;
poll.flags.insert(.nonblocking);
@@ -167,6 +188,13 @@ pub fn toBuffer(this: *PipeReader, globalThis: *jsc.JSGlobalObject) jsc.JSValue
}
pub fn onReaderError(this: *PipeReader, err: bun.sys.Error) void {
// For PTY, EIO is expected when the child exits (slave side closes).
// Treat it as a normal EOF, not an error.
if (this.is_pty and err.getErrno() == .IO) {
this.onReaderDone();
return;
}
if (this.state == .done) {
bun.default_allocator.free(this.state.done);
}

View File

@@ -153,6 +153,10 @@ pub const Writable = union(enum) {
.ipc, .capture => {
return Writable{ .ignore = {} };
},
.pty => {
// PTY stdin is not supported on Windows; return ignore
return Writable{ .ignore = {} };
},
}
}
@@ -228,6 +232,30 @@ pub const Writable = union(enum) {
.ipc, .capture => {
return Writable{ .ignore = {} };
},
.pty => {
// PTY uses pipe-like semantics, but with the PTY master fd
const pipe = jsc.WebCore.FileSink.create(event_loop, result.?);
switch (pipe.writer.start(pipe.fd, true)) {
.result => {},
.err => {
pipe.deref();
return error.UnexpectedCreatingStdin;
},
}
// PTY master is a character device, NOT a socket
// Do NOT set .socket flag - PTY uses write() not send()
subprocess.weak_file_sink_stdin_ptr = pipe;
subprocess.ref();
subprocess.flags.has_stdin_destructor_called = false;
subprocess.flags.deref_on_stdin_destroyed = true;
return Writable{
.pipe = pipe,
};
},
}
}

View File

@@ -1360,7 +1360,7 @@ pub const FFI = struct {
const num = ptr.asPtrAddress();
if (num > 0)
function.symbol_from_dynamic_library = @as(*anyopaque, @ptrFromInt(num));
} else {
} else if (ptr.isHeapBigInt()) {
const num = ptr.toUInt64NoTruncate();
if (num > 0) {
function.symbol_from_dynamic_library = @as(*anyopaque, @ptrFromInt(num));

View File

@@ -0,0 +1,39 @@
#pragma once
#include <concepts>
#include <tuple>
#include <type_traits>
#include <utility>
namespace Bun::Algo::Tuple {
namespace detail {
template<typename Tuple, typename Func, std::size_t... Is>
requires(
std::invocable<Func, std::integral_constant<std::size_t, Is>,
decltype(std::get<Is>(std::declval<Tuple>()))>
&& ...)
void forEachIndexedImpl(Tuple&& t, Func&& f, std::index_sequence<Is...>)
{
(f(std::integral_constant<std::size_t, Is> {}, std::get<Is>(std::forward<Tuple>(t))), ...);
}
} // namespace detail
/// @brief Iterates over tuple elements, invoking a callback with each element and its index.
///
/// @see WTF::apply if you do not need the index.
///
/// @tparam Tuple A tuple-like type (std::tuple, std::pair, std::array)
/// @tparam Func Callable with signature `void(std::size_t index, ElementType element)`
template<typename Tuple, typename Func>
void forEachIndexed(Tuple&& t, Func&& f)
{
detail::forEachIndexedImpl(
std::forward<Tuple>(t),
std::forward<Func>(f),
std::make_index_sequence<std::tuple_size_v<std::decay_t<Tuple>>> {});
}
} // namespace Bun::Algo::Tuple

View File

@@ -48,6 +48,8 @@
#include <netdb.h>
#endif
extern "C" size_t Bun__Feature__heap_snapshot;
BUN_DECLARE_HOST_FUNCTION(Bun__DNS__lookup);
BUN_DECLARE_HOST_FUNCTION(Bun__DNS__resolve);
BUN_DECLARE_HOST_FUNCTION(Bun__DNS__resolveSrv);
@@ -598,6 +600,8 @@ JSC_DEFINE_HOST_FUNCTION(functionGenerateHeapSnapshot, (JSC::JSGlobalObject * gl
auto& heapProfiler = *vm.heapProfiler();
heapProfiler.clearSnapshots();
Bun__Feature__heap_snapshot += 1;
JSValue arg0 = callFrame->argument(0);
auto throwScope = DECLARE_THROW_SCOPE(vm);
bool useV8 = false;

View File

@@ -680,10 +680,10 @@ String functionName(JSC::VM& vm, JSC::JSGlobalObject* lexicalGlobalObject, JSC::
return functionName;
}
String functionName(JSC::VM& vm, JSC::JSGlobalObject* lexicalGlobalObject, const JSC::StackFrame& frame, bool isInFinalizer, unsigned int* flags)
String functionName(JSC::VM& vm, JSC::JSGlobalObject* lexicalGlobalObject, const JSC::StackFrame& frame, FinalizerSafety finalizerSafety, unsigned int* flags)
{
bool isConstructor = false;
if (isInFinalizer) {
if (finalizerSafety == FinalizerSafety::MustNotTriggerGC) {
if (auto* callee = frame.callee()) {
if (auto* object = callee->getObject()) {
@@ -763,8 +763,7 @@ String functionName(JSC::VM& vm, JSC::JSGlobalObject* lexicalGlobalObject, const
isConstructor = true;
}
// We cannot run this in FinalizeUnconditionally, as we cannot call getters there
if (!isInFinalizer) {
if (finalizerSafety == FinalizerSafety::NotInFinalizer) {
auto codeType = codeblock->codeType();
switch (codeType) {
case JSC::CodeType::FunctionCode:

View File

@@ -220,6 +220,11 @@ String sourceURL(JSC::VM& vm, const JSC::StackFrame& frame);
String sourceURL(JSC::StackVisitor& visitor);
String sourceURL(JSC::VM& vm, JSC::JSFunction* function);
enum class FinalizerSafety {
NotInFinalizer,
MustNotTriggerGC,
};
class FunctionNameFlags {
public:
static constexpr unsigned None = 0;
@@ -232,6 +237,6 @@ public:
String functionName(JSC::VM& vm, JSC::CodeBlock* codeBlock);
String functionName(JSC::VM& vm, JSC::JSGlobalObject* lexicalGlobalObject, JSC::JSObject* callee);
String functionName(JSC::VM& vm, JSC::JSGlobalObject* lexicalGlobalObject, const JSC::StackFrame& frame, bool isInFinalizer, unsigned int* flags);
String functionName(JSC::VM& vm, JSC::JSGlobalObject* lexicalGlobalObject, const JSC::StackFrame& frame, FinalizerSafety, unsigned int* flags);
}

View File

@@ -100,16 +100,6 @@ pub inline fn BOOLEAN_TO_JSVALUE(arg_val: @"bool") EncodedJSValue {
res.asInt64 = @as(i64, @bitCast(@as(c_longlong, if (@as(c_int, @intFromBool(val)) != 0) (@as(c_int, 2) | @as(c_int, 4)) | @as(c_int, 1) else (@as(c_int, 2) | @as(c_int, 4)) | @as(c_int, 0))));
return res;
}
pub inline fn PTR_TO_JSVALUE(arg_ptr: ?*anyopaque) EncodedJSValue {
const ptr = arg_ptr;
var val: EncodedJSValue = undefined;
val.asInt64 = @as(i64, @intCast(@intFromPtr(ptr))) + (@as(c_longlong, 1) << @as(@import("std").math.Log2Int(c_longlong), @intCast(49)));
return val;
}
pub inline fn JSVALUE_TO_PTR(arg_val: EncodedJSValue) ?*anyopaque {
const val = arg_val;
return @as(?*anyopaque, @ptrFromInt(val.asInt64 - (@as(c_longlong, 1) << @as(@import("std").math.Log2Int(c_longlong), @intCast(49)))));
}
pub inline fn JSVALUE_TO_INT32(arg_val: EncodedJSValue) i32 {
const val = arg_val;
return @as(i32, @bitCast(@as(c_int, @truncate(val.asInt64))));

View File

@@ -250,7 +250,7 @@ WTF::String formatStackTrace(
}
}
WTF::String functionName = Zig::functionName(vm, globalObjectForFrame, frame, !errorInstance, &flags);
WTF::String functionName = Zig::functionName(vm, globalObjectForFrame, frame, errorInstance ? Zig::FinalizerSafety::NotInFinalizer : Zig::FinalizerSafety::MustNotTriggerGC, &flags);
OrdinalNumber originalLine = {};
OrdinalNumber originalColumn = {};
OrdinalNumber displayLine = {};

View File

@@ -1741,6 +1741,16 @@ JSC::EncodedJSValue jsBufferToStringFromBytes(JSGlobalObject* lexicalGlobalObjec
return Bun::ERR::STRING_TOO_LONG(scope, lexicalGlobalObject);
}
// Check encoding-specific output size limits
// For hex, output is 2x input size
if (encoding == BufferEncodingType::hex && bytes.size() > WTF::String::MaxLength / 2) {
return Bun::ERR::STRING_TOO_LONG(scope, lexicalGlobalObject);
}
// For base64, output is ceil(input * 4 / 3)
if ((encoding == BufferEncodingType::base64 || encoding == BufferEncodingType::base64url) && bytes.size() > (WTF::String::MaxLength / 4) * 3) {
return Bun::ERR::STRING_TOO_LONG(scope, lexicalGlobalObject);
}
switch (encoding) {
case WebCore::BufferEncodingType::buffer: {
auto* buffer = createUninitializedBuffer(lexicalGlobalObject, bytes.size());
@@ -1985,12 +1995,15 @@ static JSC::EncodedJSValue jsBufferPrototypeFunction_SliceWithEncoding(JSC::JSGl
template<BufferEncodingType encoding>
static JSC::EncodedJSValue jsBufferPrototypeFunction_writeEncodingBody(JSC::VM& vm, JSC::JSGlobalObject* lexicalGlobalObject, JSArrayBufferView* castedThis, JSString* str, JSValue offsetValue, JSValue lengthValue)
{
size_t byteLength = castedThis->byteLength();
auto scope = DECLARE_THROW_SCOPE(vm);
double offset;
double length;
double length = 0;
bool lengthWasUndefined = lengthValue.isUndefined();
// Convert offset and length to numbers BEFORE caching byteLength,
// as toNumber can call arbitrary JS (via Symbol.toPrimitive) which
// could detach the buffer or cause GC.
if (offsetValue.isUndefined()) {
offset = 0;
} else if (offsetValue.isNumber()) {
@@ -1999,23 +2012,52 @@ static JSC::EncodedJSValue jsBufferPrototypeFunction_writeEncodingBody(JSC::VM&
offset = offsetValue.toNumber(lexicalGlobalObject);
RETURN_IF_EXCEPTION(scope, {});
}
if (lengthValue.isUndefined()) {
length = byteLength - offset;
} else if (lengthValue.isNumber()) {
length = lengthValue.asNumber();
} else {
length = lengthValue.toNumber(lexicalGlobalObject);
RETURN_IF_EXCEPTION(scope, {});
if (!lengthWasUndefined) {
if (lengthValue.isNumber()) {
length = lengthValue.asNumber();
} else {
length = lengthValue.toNumber(lexicalGlobalObject);
RETURN_IF_EXCEPTION(scope, {});
}
}
if (offset < 0 || offset > byteLength) {
// Re-check if detached after potential JS execution
if (castedThis->isDetached()) [[unlikely]] {
throwTypeError(lexicalGlobalObject, scope, "ArrayBufferView is detached"_s);
return {};
}
// Now safe to cache byteLength after all JS calls
size_t byteLength = castedThis->byteLength();
// Node.js JS wrapper checks: if (offset < 0 || offset > this.byteLength)
// When offset is NaN, both comparisons return false, so no error is thrown.
// We need to match this behavior exactly.
bool offsetWasNaN = std::isnan(offset);
if (!offsetWasNaN && (offset < 0 || offset > byteLength)) {
return Bun::ERR::BUFFER_OUT_OF_BOUNDS(scope, lexicalGlobalObject, "offset");
}
if (length < 0 || length > byteLength - offset) {
return Bun::ERR::BUFFER_OUT_OF_BOUNDS(scope, lexicalGlobalObject, "length");
// Convert NaN offset to 0 for actual use (matching V8's IntegerValue behavior)
size_t safeOffset = offsetWasNaN ? 0 : static_cast<size_t>(offset);
// Calculate max_length
size_t maxLength;
if (lengthWasUndefined) {
maxLength = byteLength - safeOffset;
} else {
// Node.js JS wrapper checks: if (length < 0 || length > this.byteLength - offset)
// When offset is NaN, (byteLength - offset) is NaN, so (length > NaN) is false.
// This means the check passes even for large lengths when offset is NaN.
if (!offsetWasNaN && (length < 0 || length > byteLength - offset)) {
return Bun::ERR::BUFFER_OUT_OF_BOUNDS(scope, lexicalGlobalObject, "length");
}
// Convert NaN length to 0, negative to 0 (for NaN offset case)
int64_t intLength = (std::isnan(length) || length < 0) ? 0 : static_cast<int64_t>(length);
// Clamp to available buffer space
maxLength = std::min(byteLength - safeOffset, static_cast<size_t>(intLength));
}
RELEASE_AND_RETURN(scope, writeToBuffer(lexicalGlobalObject, castedThis, str, offset, length, encoding));
RELEASE_AND_RETURN(scope, writeToBuffer(lexicalGlobalObject, castedThis, str, safeOffset, maxLength, encoding));
}
template<BufferEncodingType encoding>

View File

@@ -380,6 +380,9 @@ public:
if (auto* moduleNamespaceObject = tryJSDynamicCast<JSModuleNamespaceObject*>(target)) {
moduleNamespaceObject->overrideExportValue(moduleNamespaceObject->globalObject(), this->spyIdentifier, implValue);
}
} else if (auto index = parseIndex(this->spyIdentifier)) {
// Use putDirectIndex for numeric property keys (e.g., spyOn(arr, 0))
target->putDirectIndex(globalObject(), *index, implValue, this->spyAttributes, PutDirectIndexLikePutDirect);
} else {
target->putDirect(this->vm(), this->spyIdentifier, implValue, this->spyAttributes);
}
@@ -1528,6 +1531,9 @@ BUN_DEFINE_HOST_FUNCTION(JSMock__jsSpyOn, (JSC::JSGlobalObject * lexicalGlobalOb
if (JSModuleNamespaceObject* moduleNamespaceObject = tryJSDynamicCast<JSModuleNamespaceObject*>(object)) {
moduleNamespaceObject->overrideExportValue(globalObject, propertyKey, mock);
mock->spyAttributes |= JSMockFunction::SpyAttributeESModuleNamespace;
} else if (auto index = parseIndex(propertyKey)) {
// Use putDirectIndex for numeric property keys (e.g., spyOn(arr, 0))
object->putDirectIndex(globalObject, *index, mock, attributes, PutDirectIndexLikePutDirect);
} else {
object->putDirect(vm, propertyKey, mock, attributes);
}
@@ -1544,6 +1550,9 @@ BUN_DEFINE_HOST_FUNCTION(JSMock__jsSpyOn, (JSC::JSGlobalObject * lexicalGlobalOb
if (JSModuleNamespaceObject* moduleNamespaceObject = tryJSDynamicCast<JSModuleNamespaceObject*>(object)) {
moduleNamespaceObject->overrideExportValue(globalObject, propertyKey, mock);
mock->spyAttributes |= JSMockFunction::SpyAttributeESModuleNamespace;
} else if (auto index = parseIndex(propertyKey)) {
// For indexed properties, set the mock directly instead of wrapping in GetterSetter
object->putDirectIndex(globalObject, *index, mock, attributes, PutDirectIndexLikePutDirect);
} else {
object->putDirectAccessor(globalObject, propertyKey, JSC::GetterSetter::create(vm, globalObject, mock, mock), attributes);
}

View File

@@ -285,7 +285,19 @@ pub const JSPromise = opaque {
}
}
const err = value catch |err| globalThis.takeException(err);
const err = value catch |err| switch (err) {
// We can't use globalThis.takeException() because it throws out of
// memory error when we instead need to take the exception.
error.OutOfMemory => globalThis.createOutOfMemoryError(),
error.JSTerminated => return,
else => err: {
const exception = globalThis.tryTakeException() orelse {
@panic("A JavaScript exception was thrown, but it was cleared before it could be read.");
};
break :err exception.toError() orelse exception;
},
};
bun.cpp.JSC__JSPromise__reject(this, globalThis, err) catch return error.JSTerminated;
}

View File

@@ -1156,10 +1156,11 @@ pub const JSValue = enum(i64) {
return JSC__JSValue__bigIntSum(globalObject, a, b);
}
extern fn JSC__JSValue__toUInt64NoTruncate(this: JSValue) u64;
/// Value must be either `isHeapBigInt` or `isNumber`
pub fn toUInt64NoTruncate(this: JSValue) u64 {
return JSC__JSValue__toUInt64NoTruncate(this);
}
extern fn JSC__JSValue__toUInt64NoTruncate(this: JSValue) u64;
/// Deprecated: replace with 'toBunString'
pub fn getZigString(this: JSValue, global: *JSGlobalObject) bun.JSError!ZigString {

View File

@@ -24,7 +24,7 @@ JS_EXPORT_PRIVATE JSWrappingFunction* JSWrappingFunction::create(
Zig::NativeFunctionPtr functionPointer,
JSC::JSValue wrappedFnValue)
{
JSC::JSFunction* wrappedFn = jsCast<JSC::JSFunction*>(wrappedFnValue.asCell());
JSC::JSObject* wrappedFn = wrappedFnValue.getObject();
ASSERT(wrappedFn != nullptr);
auto nameStr = symbolName->tag == BunStringTag::Empty ? WTF::emptyString() : symbolName->toWTFString();
@@ -75,9 +75,9 @@ extern "C" JSC::EncodedJSValue Bun__JSWrappingFunction__getWrappedFunction(
Zig::GlobalObject* globalObject)
{
JSC::JSValue thisValue = JSC::JSValue::decode(thisValueEncoded);
JSWrappingFunction* thisObject = jsCast<JSWrappingFunction*>(thisValue.asCell());
JSWrappingFunction* thisObject = jsDynamicCast<JSWrappingFunction*>(thisValue.asCell());
if (thisObject != nullptr) {
JSC::JSFunction* wrappedFn = thisObject->m_wrappedFn.get();
JSC::JSObject* wrappedFn = thisObject->m_wrappedFn.get();
return JSC::JSValue::encode(wrappedFn);
}
return {};

View File

@@ -59,7 +59,7 @@ public:
}
private:
JSWrappingFunction(JSC::VM& vm, JSC::NativeExecutable* native, JSC::JSGlobalObject* globalObject, JSC::Structure* structure, JSC::JSFunction* wrappedFn)
JSWrappingFunction(JSC::VM& vm, JSC::NativeExecutable* native, JSC::JSGlobalObject* globalObject, JSC::Structure* structure, JSC::JSObject* wrappedFn)
: Base(vm, native, globalObject, structure)
, m_wrappedFn(wrappedFn, JSC::WriteBarrierEarlyInit)
{
@@ -69,7 +69,7 @@ private:
DECLARE_VISIT_CHILDREN;
JSC::WriteBarrier<JSC::JSFunction> m_wrappedFn;
JSC::WriteBarrier<JSC::JSObject> m_wrappedFn;
};
}

View File

@@ -166,7 +166,7 @@ String URLDecomposition::port() const
}
// Outer optional is whether we could parse at all. Inner optional is "no port specified".
static std::optional<std::optional<uint16_t>> parsePort(StringView string, StringView protocol)
std::optional<std::optional<uint16_t>> URLDecomposition::parsePort(StringView string, StringView protocol)
{
// https://url.spec.whatwg.org/#port-state with state override given.
uint32_t port { 0 };

View File

@@ -35,6 +35,10 @@ namespace WebCore {
class URLDecomposition {
public:
// Parse a port string with optional protocol for default port detection
// Returns nullopt on parse error, or optional<uint16_t> (nullopt means empty/default port)
static std::optional<std::optional<uint16_t>> parsePort(StringView port, StringView protocol);
String origin() const;
WEBCORE_EXPORT String protocol() const;

View File

@@ -1,3 +1,4 @@
#include "Algo/Tuple.h"
#include "root.h"
#include "JSDOMURL.h"
@@ -20,6 +21,7 @@
#include "JSCloseEvent.h"
#include "JSErrorEvent.h"
#include "JSMessageEvent.h"
#include <tuple>
namespace Bun {
@@ -31,44 +33,27 @@ JSC::JSValue createUndiciInternalBinding(Zig::GlobalObject* globalObject)
{
auto& vm = JSC::getVM(globalObject);
auto* obj = constructEmptyObject(globalObject, globalObject->objectPrototype(), 11);
obj->putDirectIndex(
globalObject, 0,
globalObject->JSResponseConstructor());
obj->putDirectIndex(
globalObject, 1,
globalObject->JSRequestConstructor());
obj->putDirectIndex(
globalObject, 2,
WebCore::JSFetchHeaders::getConstructor(vm, globalObject));
obj->putDirectIndex(
globalObject, 3,
WebCore::JSDOMFormData::getConstructor(vm, globalObject));
obj->putDirectIndex(
globalObject, 4,
globalObject->JSDOMFileConstructor());
obj->putDirectIndex(
globalObject, 5,
JSDOMURL::getConstructor(vm, globalObject));
obj->putDirectIndex(
globalObject, 6,
JSAbortSignal::getConstructor(vm, globalObject));
obj->putDirectIndex(
globalObject, 7,
JSURLSearchParams::getConstructor(vm, globalObject));
obj->putDirectIndex(
globalObject, 8,
JSWebSocket::getConstructor(vm, globalObject));
obj->putDirectIndex(
globalObject, 9,
JSCloseEvent::getConstructor(vm, globalObject));
obj->putDirectIndex(
globalObject, 10,
JSErrorEvent::getConstructor(vm, globalObject));
obj->putDirectIndex(
globalObject, 11,
auto fields = std::make_tuple(
globalObject->JSResponseConstructor(),
globalObject->JSRequestConstructor(),
WebCore::JSFetchHeaders::getConstructor(vm, globalObject),
WebCore::JSDOMFormData::getConstructor(vm, globalObject),
globalObject->JSDOMFileConstructor(),
JSDOMURL::getConstructor(vm, globalObject),
JSAbortSignal::getConstructor(vm, globalObject),
JSURLSearchParams::getConstructor(vm, globalObject),
JSWebSocket::getConstructor(vm, globalObject),
JSCloseEvent::getConstructor(vm, globalObject),
JSErrorEvent::getConstructor(vm, globalObject),
JSMessageEvent::getConstructor(vm, globalObject));
auto* obj = constructEmptyObject(globalObject, globalObject->objectPrototype(),
std::tuple_size_v<decltype(fields)>);
Bun::Algo::Tuple::forEachIndexed(std::move(fields), [&](std::size_t index, auto&& field) {
obj->putDirectIndex(globalObject, index, field);
});
return obj;
}

View File

@@ -1,3 +1,4 @@
#pragma once
namespace Bun {

View File

@@ -63,13 +63,14 @@ enum PopulateStackTraceFlags {
#define SYNTAX_ERROR_CODE 4
static void populateStackFrameMetadata(JSC::VM& vm, JSC::JSGlobalObject* globalObject, const JSC::StackFrame& stackFrame, ZigStackFrame& frame)
{
using Zig::FinalizerSafety;
static void populateStackFrameMetadata(JSC::VM& vm, JSC::JSGlobalObject* globalObject, const JSC::StackFrame& stackFrame, ZigStackFrame& frame, FinalizerSafety finalizerSafety)
{
if (stackFrame.isWasmFrame()) {
frame.code_type = ZigStackFrameCodeWasm;
auto name = Zig::functionName(vm, globalObject, stackFrame, false, nullptr);
auto name = Zig::functionName(vm, globalObject, stackFrame, finalizerSafety, nullptr);
if (!name.isEmpty()) {
frame.function_name = Bun::toStringRef(name);
}
@@ -109,18 +110,19 @@ static void populateStackFrameMetadata(JSC::VM& vm, JSC::JSGlobalObject* globalO
}
}
auto calleeCell = stackFrame.callee();
if (!calleeCell)
return;
JSC::JSObject* callee = calleeCell->getObject();
if (!callee)
return;
WTF::String functionName = Zig::functionName(vm, globalObject, callee);
if (!functionName.isEmpty()) {
frame.function_name = Bun::toStringRef(functionName);
WTF::String functionName;
if (finalizerSafety == FinalizerSafety::MustNotTriggerGC) {
// Use the safe overload that avoids property access
functionName = Zig::functionName(vm, globalObject, stackFrame, finalizerSafety, nullptr);
} else {
// Use the richer callee-based path
if (auto calleeCell = stackFrame.callee()) {
if (auto* callee = calleeCell->getObject())
functionName = Zig::functionName(vm, globalObject, callee);
}
}
if (!functionName.isEmpty())
frame.function_name = Bun::toStringRef(functionName);
frame.is_async = stackFrame.isAsyncFrame();
}
@@ -223,10 +225,10 @@ static void populateStackFramePosition(const JSC::StackFrame& stackFrame, BunStr
}
static void populateStackFrame(JSC::VM& vm, ZigStackTrace& trace, const JSC::StackFrame& stackFrame,
ZigStackFrame& frame, bool is_top, JSC::SourceProvider** referenced_source_provider, JSC::JSGlobalObject* globalObject, PopulateStackTraceFlags flags)
ZigStackFrame& frame, bool is_top, JSC::SourceProvider** referenced_source_provider, JSC::JSGlobalObject* globalObject, PopulateStackTraceFlags flags, FinalizerSafety finalizerSafety)
{
if (flags == PopulateStackTraceFlags::OnlyPosition) {
populateStackFrameMetadata(vm, globalObject, stackFrame, frame);
populateStackFrameMetadata(vm, globalObject, stackFrame, frame, finalizerSafety);
populateStackFramePosition(stackFrame, nullptr,
nullptr,
0, frame.position, referenced_source_provider, flags);
@@ -419,7 +421,7 @@ public:
}
};
static void populateStackTrace(JSC::VM& vm, const WTF::Vector<JSC::StackFrame>& frames, ZigStackTrace& trace, JSC::JSGlobalObject* globalObject, PopulateStackTraceFlags flags)
static void populateStackTrace(JSC::VM& vm, const WTF::Vector<JSC::StackFrame>& frames, ZigStackTrace& trace, JSC::JSGlobalObject* globalObject, PopulateStackTraceFlags flags, FinalizerSafety finalizerSafety = FinalizerSafety::NotInFinalizer)
{
if (flags == PopulateStackTraceFlags::OnlyPosition) {
uint8_t frame_i = 0;
@@ -437,7 +439,7 @@ static void populateStackTrace(JSC::VM& vm, const WTF::Vector<JSC::StackFrame>&
ZigStackFrame& frame = trace.frames_ptr[frame_i];
frame.jsc_stack_frame_index = static_cast<int32_t>(stack_frame_i);
populateStackFrame(vm, trace, frames[stack_frame_i], frame, frame_i == 0, &trace.referenced_source_provider, globalObject, flags);
populateStackFrame(vm, trace, frames[stack_frame_i], frame, frame_i == 0, &trace.referenced_source_provider, globalObject, flags, finalizerSafety);
stack_frame_i++;
frame_i++;
}
@@ -449,7 +451,7 @@ static void populateStackTrace(JSC::VM& vm, const WTF::Vector<JSC::StackFrame>&
// so jsc_stack_frame_index is always a valid value here.
ASSERT(frame.jsc_stack_frame_index >= 0);
ASSERT(static_cast<size_t>(frame.jsc_stack_frame_index) < frames.size());
populateStackFrame(vm, trace, frames[frame.jsc_stack_frame_index], frame, i == 0, &trace.referenced_source_provider, globalObject, flags);
populateStackFrame(vm, trace, frames[frame.jsc_stack_frame_index], frame, i == 0, &trace.referenced_source_provider, globalObject, flags, finalizerSafety);
}
}
}
@@ -484,7 +486,7 @@ static void fromErrorInstance(ZigException& except, JSC::JSGlobalObject* global,
populateStackTrace(vm, *stackTrace, except.stack, global, flags);
} else if (err->stackTrace() != nullptr && err->stackTrace()->size() > 0) {
populateStackTrace(vm, *err->stackTrace(), except.stack, global, flags);
populateStackTrace(vm, *err->stackTrace(), except.stack, global, flags, FinalizerSafety::MustNotTriggerGC);
} else {
getFromSourceURL = true;
@@ -886,7 +888,7 @@ extern "C" void ZigException__collectSourceLines(JSC::EncodedJSValue jsException
if (JSC::ErrorInstance* error = JSC::jsDynamicCast<JSC::ErrorInstance*>(value)) {
if (error->stackTrace() != nullptr && error->stackTrace()->size() > 0) {
populateStackTrace(global->vm(), *error->stackTrace(), exception->stack, global, PopulateStackTraceFlags::OnlySourceLines);
populateStackTrace(global->vm(), *error->stackTrace(), exception->stack, global, PopulateStackTraceFlags::OnlySourceLines, FinalizerSafety::MustNotTriggerGC);
}
return;
}

View File

@@ -130,6 +130,7 @@
#include "JSTextDecoderStream.h"
#include "JSTransformStream.h"
#include "JSTransformStreamDefaultController.h"
#include "JSURLPattern.h"
#include "JSURLSearchParams.h"
#include "JSWasmStreamingCompiler.h"
#include "JSWebSocket.h"
@@ -1009,6 +1010,7 @@ WEBCORE_GENERATED_CONSTRUCTOR_GETTER(TextEncoderStream);
WEBCORE_GENERATED_CONSTRUCTOR_GETTER(TextDecoderStream);
WEBCORE_GENERATED_CONSTRUCTOR_GETTER(TransformStream)
WEBCORE_GENERATED_CONSTRUCTOR_GETTER(TransformStreamDefaultController)
WEBCORE_GENERATED_CONSTRUCTOR_GETTER(URLPattern);
WEBCORE_GENERATED_CONSTRUCTOR_GETTER(URLSearchParams);
WEBCORE_GENERATED_CONSTRUCTOR_GETTER(WebSocket);
WEBCORE_GENERATED_CONSTRUCTOR_GETTER(Worker);

View File

@@ -84,6 +84,7 @@
TransformStream TransformStreamConstructorCallback PropertyCallback
TransformStreamDefaultController TransformStreamDefaultControllerConstructorCallback PropertyCallback
URL DOMURLConstructorCallback DontEnum|PropertyCallback
URLPattern URLPatternConstructorCallback PropertyCallback
URLSearchParams URLSearchParamsConstructorCallback DontEnum|PropertyCallback
WebSocket WebSocketConstructorCallback PropertyCallback
Worker WorkerConstructorCallback PropertyCallback

View File

@@ -152,6 +152,8 @@
#include <JavaScriptCore/IntegrityInlines.h>
#endif
extern "C" size_t Bun__Feature__heap_snapshot;
#if OS(DARWIN)
#if ASSERT_ENABLED
#if !__has_feature(address_sanitizer)
@@ -2914,20 +2916,26 @@ JSC::EncodedJSValue JSC__JSModuleLoader__evaluate(JSC::JSGlobalObject* globalObj
}
}
JSC::EncodedJSValue ReadableStream__empty(Zig::GlobalObject* globalObject)
[[ZIG_EXPORT(zero_is_throw)]] JSC::EncodedJSValue ReadableStream__empty(Zig::GlobalObject* globalObject)
{
auto& vm = JSC::getVM(globalObject);
auto scope = DECLARE_THROW_SCOPE(vm);
auto clientData = WebCore::clientData(vm);
auto* function = globalObject->getDirect(vm, clientData->builtinNames().createEmptyReadableStreamPrivateName()).getObject();
return JSValue::encode(JSC::call(globalObject, function, JSC::ArgList(), "ReadableStream.create"_s));
JSValue emptyStream = JSC::call(globalObject, function, JSC::ArgList(), "ReadableStream.create"_s);
RETURN_IF_EXCEPTION(scope, {});
return JSValue::encode(emptyStream);
}
JSC::EncodedJSValue ReadableStream__used(Zig::GlobalObject* globalObject)
[[ZIG_EXPORT(zero_is_throw)]] JSC::EncodedJSValue ReadableStream__used(Zig::GlobalObject* globalObject)
{
auto& vm = JSC::getVM(globalObject);
auto scope = DECLARE_THROW_SCOPE(vm);
auto clientData = WebCore::clientData(vm);
auto* function = globalObject->getDirect(vm, clientData->builtinNames().createUsedReadableStreamPrivateName()).getObject();
return JSValue::encode(JSC::call(globalObject, function, JSC::ArgList(), "ReadableStream.create"_s));
JSValue usedStream = JSC::call(globalObject, function, JSC::ArgList(), "ReadableStream.create"_s);
RETURN_IF_EXCEPTION(scope, {});
return JSValue::encode(usedStream);
}
JSC::EncodedJSValue JSC__JSValue__createRangeError(const ZigString* message, const ZigString* arg1,
@@ -3659,6 +3667,8 @@ JSC::EncodedJSValue JSC__JSGlobalObject__generateHeapSnapshot(JSC::JSGlobalObjec
// JSC::DeferTermination deferScope(vm);
auto scope = DECLARE_THROW_SCOPE(vm);
Bun__Feature__heap_snapshot += 1;
JSC::HeapSnapshotBuilder snapshotBuilder(vm.ensureHeapProfiler());
snapshotBuilder.buildSnapshot();
@@ -5673,7 +5683,15 @@ CPP_DECL JSC::EncodedJSValue WebCore__DOMFormData__createFromURLQuery(JSC::JSGlo
{
Zig::GlobalObject* globalObject = static_cast<Zig::GlobalObject*>(arg0);
// don't need to copy the string because it internally does.
auto formData = DOMFormData::create(globalObject->scriptExecutionContext(), toString(*arg1));
auto str = toString(*arg1);
// toString() in helpers.h returns an empty string when the input exceeds
// String::MaxLength or Bun's synthetic allocation limit. This is the only
// condition under which toString() returns empty for non-empty input.
if (str.isEmpty() && arg1->len > 0) {
auto scope = DECLARE_THROW_SCOPE(globalObject->vm());
return Bun::ERR::STRING_TOO_LONG(scope, globalObject);
}
auto formData = DOMFormData::create(globalObject->scriptExecutionContext(), WTFMove(str));
return JSValue::encode(toJSNewlyCreated(arg0, globalObject, WTFMove(formData)));
}

View File

@@ -2,6 +2,7 @@
#include "root.h"
#include "wtf/text/ASCIILiteral.h"
#include "wtf/SIMDUTF.h"
#include <JavaScriptCore/Error.h>
#include <JavaScriptCore/Exception.h>
@@ -79,12 +80,24 @@ static const WTF::String toString(ZigString str)
}
if (isTaggedUTF8Ptr(str.ptr)) [[unlikely]] {
ASSERT_WITH_MESSAGE(!isTaggedExternalPtr(str.ptr), "UTF8 and external ptr are mutually exclusive. The external will never be freed.");
// Check if the resulting UTF-16 string could possibly exceed the maximum length.
// For valid UTF-8, the number of UTF-16 code units is <= the number of UTF-8 bytes
// (ASCII is 1:1; other code points use multiple UTF-8 bytes per UTF-16 code unit).
// We only need to compute the actual UTF-16 length when the byte length exceeds the limit.
size_t maxLength = std::min(Bun__stringSyntheticAllocationLimit, static_cast<size_t>(WTF::String::MaxLength));
if (str.len > maxLength) [[unlikely]] {
// UTF-8 byte length != UTF-16 length, so use simdutf to calculate the actual UTF-16 length.
size_t utf16Length = simdutf::utf16_length_from_utf8(reinterpret_cast<const char*>(untag(str.ptr)), str.len);
if (utf16Length > maxLength) {
return {};
}
}
return WTF::String::fromUTF8ReplacingInvalidSequences(std::span { untag(str.ptr), str.len });
}
if (isTaggedExternalPtr(str.ptr)) [[unlikely]] {
// This will fail if the string is too long. Let's make it explicit instead of an ASSERT.
if (str.len > Bun__stringSyntheticAllocationLimit) [[unlikely]] {
if (str.len > Bun__stringSyntheticAllocationLimit || str.len > WTF::String::MaxLength) [[unlikely]] {
free_global_string(nullptr, reinterpret_cast<void*>(const_cast<unsigned char*>(untag(str.ptr))), static_cast<unsigned>(str.len));
return {};
}
@@ -95,7 +108,7 @@ static const WTF::String toString(ZigString str)
}
// This will fail if the string is too long. Let's make it explicit instead of an ASSERT.
if (str.len > Bun__stringSyntheticAllocationLimit) [[unlikely]] {
if (str.len > Bun__stringSyntheticAllocationLimit || str.len > WTF::String::MaxLength) [[unlikely]] {
return {};
}
@@ -121,11 +134,19 @@ static const WTF::String toString(ZigString str, StringPointer ptr)
return WTF::String();
}
if (isTaggedUTF8Ptr(str.ptr)) [[unlikely]] {
// Check if the resulting UTF-16 string could possibly exceed the maximum length.
size_t maxLength = std::min(Bun__stringSyntheticAllocationLimit, static_cast<size_t>(WTF::String::MaxLength));
if (ptr.len > maxLength) [[unlikely]] {
size_t utf16Length = simdutf::utf16_length_from_utf8(reinterpret_cast<const char*>(&untag(str.ptr)[ptr.off]), ptr.len);
if (utf16Length > maxLength) {
return {};
}
}
return WTF::String::fromUTF8ReplacingInvalidSequences(std::span { &untag(str.ptr)[ptr.off], ptr.len });
}
// This will fail if the string is too long. Let's make it explicit instead of an ASSERT.
if (str.len > Bun__stringSyntheticAllocationLimit) [[unlikely]] {
if (ptr.len > Bun__stringSyntheticAllocationLimit || ptr.len > WTF::String::MaxLength) [[unlikely]] {
return {};
}
@@ -141,11 +162,19 @@ static const WTF::String toStringCopy(ZigString str, StringPointer ptr)
return WTF::String();
}
if (isTaggedUTF8Ptr(str.ptr)) [[unlikely]] {
// Check if the resulting UTF-16 string could possibly exceed the maximum length.
size_t maxLength = std::min(Bun__stringSyntheticAllocationLimit, static_cast<size_t>(WTF::String::MaxLength));
if (ptr.len > maxLength) [[unlikely]] {
size_t utf16Length = simdutf::utf16_length_from_utf8(reinterpret_cast<const char*>(&untag(str.ptr)[ptr.off]), ptr.len);
if (utf16Length > maxLength) {
return {};
}
}
return WTF::String::fromUTF8ReplacingInvalidSequences(std::span { &untag(str.ptr)[ptr.off], ptr.len });
}
// This will fail if the string is too long. Let's make it explicit instead of an ASSERT.
if (str.len > Bun__stringSyntheticAllocationLimit) [[unlikely]] {
if (ptr.len > Bun__stringSyntheticAllocationLimit || ptr.len > WTF::String::MaxLength) [[unlikely]] {
return {};
}
@@ -161,6 +190,14 @@ static const WTF::String toStringCopy(ZigString str)
return WTF::String();
}
if (isTaggedUTF8Ptr(str.ptr)) [[unlikely]] {
// Check if the resulting UTF-16 string could possibly exceed the maximum length.
size_t maxLength = std::min(Bun__stringSyntheticAllocationLimit, static_cast<size_t>(WTF::String::MaxLength));
if (str.len > maxLength) [[unlikely]] {
size_t utf16Length = simdutf::utf16_length_from_utf8(reinterpret_cast<const char*>(untag(str.ptr)), str.len);
if (utf16Length > maxLength) {
return {};
}
}
return WTF::String::fromUTF8ReplacingInvalidSequences(std::span { untag(str.ptr), str.len });
}
@@ -188,6 +225,14 @@ static void appendToBuilder(ZigString str, WTF::StringBuilder& builder)
return;
}
if (isTaggedUTF8Ptr(str.ptr)) [[unlikely]] {
// Check if the resulting UTF-16 string could possibly exceed the maximum length.
size_t maxLength = std::min(Bun__stringSyntheticAllocationLimit, static_cast<size_t>(WTF::String::MaxLength));
if (str.len > maxLength) [[unlikely]] {
size_t utf16Length = simdutf::utf16_length_from_utf8(reinterpret_cast<const char*>(untag(str.ptr)), str.len);
if (utf16Length > maxLength) {
return;
}
}
WTF::String converted = WTF::String::fromUTF8ReplacingInvalidSequences(std::span { untag(str.ptr), str.len });
builder.append(converted);
return;

View File

@@ -81,6 +81,7 @@ public:
std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForDOMFormData;
std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForDOMFormDataIterator;
std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForDOMURL;
std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForURLPattern;
std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForURLSearchParams;
std::unique_ptr<GCClient::IsoSubspace> m_clientSubspaceForURLSearchParamsIterator;

View File

@@ -860,11 +860,12 @@ enum class DOMConstructorID : uint16_t {
Cookie,
CookieMap,
EventEmitter,
URLPattern,
};
static constexpr unsigned numberOfDOMConstructorsBase = 848;
static constexpr unsigned bunExtraConstructors = 3;
static constexpr unsigned bunExtraConstructors = 4;
static constexpr unsigned numberOfDOMConstructors = numberOfDOMConstructorsBase + bunExtraConstructors;

View File

@@ -938,6 +938,7 @@ public:
// std::unique_ptr<IsoSubspace> m_subspaceForDOMFormData;
// std::unique_ptr<IsoSubspace> m_subspaceForDOMFormDataIterator;
std::unique_ptr<IsoSubspace> m_subspaceForDOMURL;
std::unique_ptr<IsoSubspace> m_subspaceForURLPattern;
std::unique_ptr<IsoSubspace> m_subspaceForJSSign;
std::unique_ptr<IsoSubspace> m_subspaceForJSVerify;
std::unique_ptr<IsoSubspace> m_subspaceForJSHmac;

View File

@@ -0,0 +1,545 @@
/*
This file is part of the WebKit open source project.
This file has been generated by generate-bindings.pl. DO NOT MODIFY!
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "config.h"
#include "JSURLPattern.h"
#include "ActiveDOMObject.h"
#include "ExtendedDOMClientIsoSubspaces.h"
#include "ExtendedDOMIsoSubspaces.h"
#include "JSDOMAttribute.h"
#include "JSDOMBinding.h"
#include "JSDOMConstructor.h"
#include "JSDOMConvertBoolean.h"
#include "JSDOMConvertDictionary.h"
#include "JSDOMConvertInterface.h"
#include "JSDOMConvertNullable.h"
#include "JSDOMConvertOptional.h"
#include "JSDOMConvertStrings.h"
#include "JSDOMConvertUnion.h"
#include "JSDOMExceptionHandling.h"
#include "JSDOMGlobalObject.h"
#include "JSDOMGlobalObjectInlines.h"
#include "JSDOMOperation.h"
#include "JSDOMWrapperCache.h"
#include "JSURLPatternInit.h"
#include "JSURLPatternOptions.h"
#include "JSURLPatternResult.h"
#include "ScriptExecutionContext.h"
#include "WebCoreJSClientData.h"
#include <JavaScriptCore/FunctionPrototype.h>
#include <JavaScriptCore/HeapAnalyzer.h>
#include <JavaScriptCore/JSCInlines.h>
#include <JavaScriptCore/JSDestructibleObjectHeapCellType.h>
#include <JavaScriptCore/SlotVisitorMacros.h>
#include <JavaScriptCore/SubspaceInlines.h>
#include <wtf/GetPtr.h>
#include <wtf/PointerPreparations.h>
#include <wtf/URL.h>
#include <wtf/Variant.h>
#include <wtf/text/MakeString.h>
namespace WebCore {
using namespace JSC;
// Helper to convert from IDL's std::variant to WTF's Variant
static URLPattern::URLPatternInput convertToWTFVariant(std::variant<String, URLPatternInit>&& input)
{
if (std::holds_alternative<String>(input))
return URLPattern::URLPatternInput(std::get<String>(std::move(input)));
return URLPattern::URLPatternInput(std::get<URLPatternInit>(std::move(input)));
}
static std::optional<URLPattern::URLPatternInput> convertToOptionalWTFVariant(std::optional<std::variant<String, URLPatternInit>>&& input)
{
if (!input)
return std::nullopt;
return convertToWTFVariant(std::move(*input));
}
// Functions
static JSC_DECLARE_HOST_FUNCTION(jsURLPatternPrototypeFunction_test);
static JSC_DECLARE_HOST_FUNCTION(jsURLPatternPrototypeFunction_exec);
// Attributes
static JSC_DECLARE_CUSTOM_GETTER(jsURLPatternConstructor);
static JSC_DECLARE_CUSTOM_GETTER(jsURLPattern_protocol);
static JSC_DECLARE_CUSTOM_GETTER(jsURLPattern_username);
static JSC_DECLARE_CUSTOM_GETTER(jsURLPattern_password);
static JSC_DECLARE_CUSTOM_GETTER(jsURLPattern_hostname);
static JSC_DECLARE_CUSTOM_GETTER(jsURLPattern_port);
static JSC_DECLARE_CUSTOM_GETTER(jsURLPattern_pathname);
static JSC_DECLARE_CUSTOM_GETTER(jsURLPattern_search);
static JSC_DECLARE_CUSTOM_GETTER(jsURLPattern_hash);
static JSC_DECLARE_CUSTOM_GETTER(jsURLPattern_hasRegExpGroups);
class JSURLPatternPrototype final : public JSC::JSNonFinalObject {
public:
using Base = JSC::JSNonFinalObject;
static JSURLPatternPrototype* create(JSC::VM& vm, JSDOMGlobalObject* globalObject, JSC::Structure* structure)
{
JSURLPatternPrototype* ptr = new (NotNull, JSC::allocateCell<JSURLPatternPrototype>(vm)) JSURLPatternPrototype(vm, globalObject, structure);
ptr->finishCreation(vm);
return ptr;
}
DECLARE_INFO;
template<typename CellType, JSC::SubspaceAccess>
static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSURLPatternPrototype, Base);
return &vm.plainObjectSpace();
}
static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
{
return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info());
}
private:
JSURLPatternPrototype(JSC::VM& vm, JSC::JSGlobalObject*, JSC::Structure* structure)
: JSC::JSNonFinalObject(vm, structure)
{
}
void finishCreation(JSC::VM&);
};
STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(JSURLPatternPrototype, JSURLPatternPrototype::Base);
using JSURLPatternDOMConstructor = JSDOMConstructor<JSURLPattern>;
static inline EncodedJSValue constructJSURLPattern1(JSGlobalObject* lexicalGlobalObject, CallFrame* callFrame)
{
auto& vm = lexicalGlobalObject->vm();
auto throwScope = DECLARE_THROW_SCOPE(vm);
auto* castedThis = jsCast<JSURLPatternDOMConstructor*>(callFrame->jsCallee());
ASSERT(castedThis);
RefPtr context = castedThis->scriptExecutionContext();
if (!context) [[unlikely]]
return throwConstructorScriptExecutionContextUnavailableError(*lexicalGlobalObject, throwScope, "URLPattern"_s);
EnsureStillAliveScope argument0 = callFrame->uncheckedArgument(0);
auto input = convert<IDLUnion<IDLUSVString, IDLDictionary<URLPatternInit>>>(*lexicalGlobalObject, argument0.value());
RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
EnsureStillAliveScope argument1 = callFrame->uncheckedArgument(1);
auto baseURL = convert<IDLUSVString>(*lexicalGlobalObject, argument1.value());
RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
EnsureStillAliveScope argument2 = callFrame->argument(2);
auto options = convert<IDLDictionary<URLPatternOptions>>(*lexicalGlobalObject, argument2.value());
RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
auto object = URLPattern::create(*context, convertToWTFVariant(WTFMove(input)), WTFMove(baseURL), WTFMove(options));
if constexpr (IsExceptionOr<decltype(object)>)
RETURN_IF_EXCEPTION(throwScope, {});
static_assert(TypeOrExceptionOrUnderlyingType<decltype(object)>::isRef);
auto jsValue = toJSNewlyCreated<IDLInterface<URLPattern>>(*lexicalGlobalObject, *castedThis->globalObject(), throwScope, WTFMove(object));
if constexpr (IsExceptionOr<decltype(object)>)
RETURN_IF_EXCEPTION(throwScope, {});
setSubclassStructureIfNeeded<URLPattern>(lexicalGlobalObject, callFrame, asObject(jsValue));
RETURN_IF_EXCEPTION(throwScope, {});
return JSValue::encode(jsValue);
}
static inline EncodedJSValue constructJSURLPattern2(JSGlobalObject* lexicalGlobalObject, CallFrame* callFrame)
{
auto& vm = lexicalGlobalObject->vm();
auto throwScope = DECLARE_THROW_SCOPE(vm);
auto* castedThis = jsCast<JSURLPatternDOMConstructor*>(callFrame->jsCallee());
ASSERT(castedThis);
RefPtr context = castedThis->scriptExecutionContext();
if (!context) [[unlikely]]
return throwConstructorScriptExecutionContextUnavailableError(*lexicalGlobalObject, throwScope, "URLPattern"_s);
EnsureStillAliveScope argument0 = callFrame->argument(0);
auto input = convert<IDLOptional<IDLUnion<IDLUSVString, IDLDictionary<URLPatternInit>>>>(*lexicalGlobalObject, argument0.value());
RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
EnsureStillAliveScope argument1 = callFrame->argument(1);
auto options = convert<IDLDictionary<URLPatternOptions>>(*lexicalGlobalObject, argument1.value());
RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
auto object = URLPattern::create(*context, convertToOptionalWTFVariant(WTFMove(input)), WTFMove(options));
if constexpr (IsExceptionOr<decltype(object)>)
RETURN_IF_EXCEPTION(throwScope, {});
static_assert(TypeOrExceptionOrUnderlyingType<decltype(object)>::isRef);
auto jsValue = toJSNewlyCreated<IDLInterface<URLPattern>>(*lexicalGlobalObject, *castedThis->globalObject(), throwScope, WTFMove(object));
if constexpr (IsExceptionOr<decltype(object)>)
RETURN_IF_EXCEPTION(throwScope, {});
setSubclassStructureIfNeeded<URLPattern>(lexicalGlobalObject, callFrame, asObject(jsValue));
RETURN_IF_EXCEPTION(throwScope, {});
return JSValue::encode(jsValue);
}
template<> EncodedJSValue JSC_HOST_CALL_ATTRIBUTES JSURLPatternDOMConstructor::construct(JSGlobalObject* lexicalGlobalObject, CallFrame* callFrame)
{
SUPPRESS_UNCOUNTED_LOCAL auto& vm = lexicalGlobalObject->vm();
auto throwScope = DECLARE_THROW_SCOPE(vm);
UNUSED_PARAM(throwScope);
size_t argsCount = std::min<size_t>(3, callFrame->argumentCount());
if (argsCount == 0) {
RELEASE_AND_RETURN(throwScope, (constructJSURLPattern2(lexicalGlobalObject, callFrame)));
}
if (argsCount == 1) {
RELEASE_AND_RETURN(throwScope, (constructJSURLPattern2(lexicalGlobalObject, callFrame)));
}
if (argsCount == 2) {
JSValue distinguishingArg = callFrame->uncheckedArgument(1);
if (distinguishingArg.isUndefined())
RELEASE_AND_RETURN(throwScope, (constructJSURLPattern2(lexicalGlobalObject, callFrame)));
if (distinguishingArg.isUndefinedOrNull())
RELEASE_AND_RETURN(throwScope, (constructJSURLPattern2(lexicalGlobalObject, callFrame)));
if (distinguishingArg.isObject())
RELEASE_AND_RETURN(throwScope, (constructJSURLPattern2(lexicalGlobalObject, callFrame)));
RELEASE_AND_RETURN(throwScope, (constructJSURLPattern1(lexicalGlobalObject, callFrame)));
}
if (argsCount == 3) {
RELEASE_AND_RETURN(throwScope, (constructJSURLPattern1(lexicalGlobalObject, callFrame)));
}
return throwVMTypeError(lexicalGlobalObject, throwScope);
}
JSC_ANNOTATE_HOST_FUNCTION(JSURLPatternConstructorConstruct, JSURLPatternDOMConstructor::construct);
template<> const ClassInfo JSURLPatternDOMConstructor::s_info = { "URLPattern"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSURLPatternDOMConstructor) };
template<> JSValue JSURLPatternDOMConstructor::prototypeForStructure(JSC::VM& vm, const JSDOMGlobalObject& globalObject)
{
UNUSED_PARAM(vm);
return globalObject.functionPrototype();
}
template<> void JSURLPatternDOMConstructor::initializeProperties(VM& vm, JSDOMGlobalObject& globalObject)
{
putDirect(vm, vm.propertyNames->length, jsNumber(0), JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum);
JSString* nameString = jsNontrivialString(vm, "URLPattern"_s);
m_originalName.set(vm, this, nameString);
putDirect(vm, vm.propertyNames->name, nameString, JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum);
putDirect(vm, vm.propertyNames->prototype, JSURLPattern::prototype(vm, globalObject), JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::DontDelete);
}
/* Hash table for prototype */
static const std::array<HashTableValue, 12> JSURLPatternPrototypeTableValues {
HashTableValue { "constructor"_s, static_cast<unsigned>(PropertyAttribute::DontEnum), NoIntrinsic, { HashTableValue::GetterSetterType, jsURLPatternConstructor, 0 } },
HashTableValue { "protocol"_s, JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute, NoIntrinsic, { HashTableValue::GetterSetterType, jsURLPattern_protocol, 0 } },
HashTableValue { "username"_s, JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute, NoIntrinsic, { HashTableValue::GetterSetterType, jsURLPattern_username, 0 } },
HashTableValue { "password"_s, JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute, NoIntrinsic, { HashTableValue::GetterSetterType, jsURLPattern_password, 0 } },
HashTableValue { "hostname"_s, JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute, NoIntrinsic, { HashTableValue::GetterSetterType, jsURLPattern_hostname, 0 } },
HashTableValue { "port"_s, JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute, NoIntrinsic, { HashTableValue::GetterSetterType, jsURLPattern_port, 0 } },
HashTableValue { "pathname"_s, JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute, NoIntrinsic, { HashTableValue::GetterSetterType, jsURLPattern_pathname, 0 } },
HashTableValue { "search"_s, JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute, NoIntrinsic, { HashTableValue::GetterSetterType, jsURLPattern_search, 0 } },
HashTableValue { "hash"_s, JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute, NoIntrinsic, { HashTableValue::GetterSetterType, jsURLPattern_hash, 0 } },
HashTableValue { "hasRegExpGroups"_s, JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute, NoIntrinsic, { HashTableValue::GetterSetterType, jsURLPattern_hasRegExpGroups, 0 } },
HashTableValue { "test"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, jsURLPatternPrototypeFunction_test, 0 } },
HashTableValue { "exec"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function), NoIntrinsic, { HashTableValue::NativeFunctionType, jsURLPatternPrototypeFunction_exec, 0 } },
};
const ClassInfo JSURLPatternPrototype::s_info = { "URLPattern"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSURLPatternPrototype) };
void JSURLPatternPrototype::finishCreation(VM& vm)
{
Base::finishCreation(vm);
reifyStaticProperties(vm, JSURLPattern::info(), JSURLPatternPrototypeTableValues, *this);
JSC_TO_STRING_TAG_WITHOUT_TRANSITION();
}
const ClassInfo JSURLPattern::s_info = { "URLPattern"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSURLPattern) };
JSURLPattern::JSURLPattern(Structure* structure, JSDOMGlobalObject& globalObject, Ref<URLPattern>&& impl)
: JSDOMWrapper<URLPattern>(structure, globalObject, WTFMove(impl))
{
}
JSObject* JSURLPattern::createPrototype(VM& vm, JSDOMGlobalObject& globalObject)
{
auto* structure = JSURLPatternPrototype::createStructure(vm, &globalObject, globalObject.objectPrototype());
structure->setMayBePrototype(true);
return JSURLPatternPrototype::create(vm, &globalObject, structure);
}
JSObject* JSURLPattern::prototype(VM& vm, JSDOMGlobalObject& globalObject)
{
return getDOMPrototype<JSURLPattern>(vm, globalObject);
}
JSValue JSURLPattern::getConstructor(VM& vm, const JSGlobalObject* globalObject)
{
return getDOMConstructor<JSURLPatternDOMConstructor, DOMConstructorID::URLPattern>(vm, *jsCast<const JSDOMGlobalObject*>(globalObject));
}
void JSURLPattern::destroy(JSC::JSCell* cell)
{
SUPPRESS_MEMORY_UNSAFE_CAST JSURLPattern* thisObject = static_cast<JSURLPattern*>(cell);
thisObject->JSURLPattern::~JSURLPattern();
}
JSC_DEFINE_CUSTOM_GETTER(jsURLPatternConstructor, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName))
{
SUPPRESS_UNCOUNTED_LOCAL auto& vm = JSC::getVM(lexicalGlobalObject);
auto throwScope = DECLARE_THROW_SCOPE(vm);
auto* prototype = jsDynamicCast<JSURLPatternPrototype*>(JSValue::decode(thisValue));
if (!prototype) [[unlikely]]
return throwVMTypeError(lexicalGlobalObject, throwScope);
return JSValue::encode(JSURLPattern::getConstructor(vm, prototype->globalObject()));
}
static inline JSValue jsURLPattern_protocolGetter(JSGlobalObject& lexicalGlobalObject, JSURLPattern& thisObject)
{
SUPPRESS_UNCOUNTED_LOCAL auto& vm = JSC::getVM(&lexicalGlobalObject);
auto throwScope = DECLARE_THROW_SCOPE(vm);
SUPPRESS_UNCOUNTED_LOCAL auto& impl = thisObject.wrapped();
RELEASE_AND_RETURN(throwScope, (toJS<IDLUSVString>(lexicalGlobalObject, throwScope, impl.protocol())));
}
JSC_DEFINE_CUSTOM_GETTER(jsURLPattern_protocol, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName))
{
return IDLAttribute<JSURLPattern>::get<jsURLPattern_protocolGetter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName);
}
static inline JSValue jsURLPattern_usernameGetter(JSGlobalObject& lexicalGlobalObject, JSURLPattern& thisObject)
{
SUPPRESS_UNCOUNTED_LOCAL auto& vm = JSC::getVM(&lexicalGlobalObject);
auto throwScope = DECLARE_THROW_SCOPE(vm);
SUPPRESS_UNCOUNTED_LOCAL auto& impl = thisObject.wrapped();
RELEASE_AND_RETURN(throwScope, (toJS<IDLUSVString>(lexicalGlobalObject, throwScope, impl.username())));
}
JSC_DEFINE_CUSTOM_GETTER(jsURLPattern_username, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName))
{
return IDLAttribute<JSURLPattern>::get<jsURLPattern_usernameGetter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName);
}
static inline JSValue jsURLPattern_passwordGetter(JSGlobalObject& lexicalGlobalObject, JSURLPattern& thisObject)
{
SUPPRESS_UNCOUNTED_LOCAL auto& vm = JSC::getVM(&lexicalGlobalObject);
auto throwScope = DECLARE_THROW_SCOPE(vm);
SUPPRESS_UNCOUNTED_LOCAL auto& impl = thisObject.wrapped();
RELEASE_AND_RETURN(throwScope, (toJS<IDLUSVString>(lexicalGlobalObject, throwScope, impl.password())));
}
JSC_DEFINE_CUSTOM_GETTER(jsURLPattern_password, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName))
{
return IDLAttribute<JSURLPattern>::get<jsURLPattern_passwordGetter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName);
}
static inline JSValue jsURLPattern_hostnameGetter(JSGlobalObject& lexicalGlobalObject, JSURLPattern& thisObject)
{
SUPPRESS_UNCOUNTED_LOCAL auto& vm = JSC::getVM(&lexicalGlobalObject);
auto throwScope = DECLARE_THROW_SCOPE(vm);
SUPPRESS_UNCOUNTED_LOCAL auto& impl = thisObject.wrapped();
RELEASE_AND_RETURN(throwScope, (toJS<IDLUSVString>(lexicalGlobalObject, throwScope, impl.hostname())));
}
JSC_DEFINE_CUSTOM_GETTER(jsURLPattern_hostname, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName))
{
return IDLAttribute<JSURLPattern>::get<jsURLPattern_hostnameGetter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName);
}
static inline JSValue jsURLPattern_portGetter(JSGlobalObject& lexicalGlobalObject, JSURLPattern& thisObject)
{
SUPPRESS_UNCOUNTED_LOCAL auto& vm = JSC::getVM(&lexicalGlobalObject);
auto throwScope = DECLARE_THROW_SCOPE(vm);
SUPPRESS_UNCOUNTED_LOCAL auto& impl = thisObject.wrapped();
RELEASE_AND_RETURN(throwScope, (toJS<IDLUSVString>(lexicalGlobalObject, throwScope, impl.port())));
}
JSC_DEFINE_CUSTOM_GETTER(jsURLPattern_port, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName))
{
return IDLAttribute<JSURLPattern>::get<jsURLPattern_portGetter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName);
}
static inline JSValue jsURLPattern_pathnameGetter(JSGlobalObject& lexicalGlobalObject, JSURLPattern& thisObject)
{
SUPPRESS_UNCOUNTED_LOCAL auto& vm = JSC::getVM(&lexicalGlobalObject);
auto throwScope = DECLARE_THROW_SCOPE(vm);
SUPPRESS_UNCOUNTED_LOCAL auto& impl = thisObject.wrapped();
RELEASE_AND_RETURN(throwScope, (toJS<IDLUSVString>(lexicalGlobalObject, throwScope, impl.pathname())));
}
JSC_DEFINE_CUSTOM_GETTER(jsURLPattern_pathname, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName))
{
return IDLAttribute<JSURLPattern>::get<jsURLPattern_pathnameGetter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName);
}
static inline JSValue jsURLPattern_searchGetter(JSGlobalObject& lexicalGlobalObject, JSURLPattern& thisObject)
{
SUPPRESS_UNCOUNTED_LOCAL auto& vm = JSC::getVM(&lexicalGlobalObject);
auto throwScope = DECLARE_THROW_SCOPE(vm);
SUPPRESS_UNCOUNTED_LOCAL auto& impl = thisObject.wrapped();
RELEASE_AND_RETURN(throwScope, (toJS<IDLUSVString>(lexicalGlobalObject, throwScope, impl.search())));
}
JSC_DEFINE_CUSTOM_GETTER(jsURLPattern_search, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName))
{
return IDLAttribute<JSURLPattern>::get<jsURLPattern_searchGetter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName);
}
static inline JSValue jsURLPattern_hashGetter(JSGlobalObject& lexicalGlobalObject, JSURLPattern& thisObject)
{
SUPPRESS_UNCOUNTED_LOCAL auto& vm = JSC::getVM(&lexicalGlobalObject);
auto throwScope = DECLARE_THROW_SCOPE(vm);
SUPPRESS_UNCOUNTED_LOCAL auto& impl = thisObject.wrapped();
RELEASE_AND_RETURN(throwScope, (toJS<IDLUSVString>(lexicalGlobalObject, throwScope, impl.hash())));
}
JSC_DEFINE_CUSTOM_GETTER(jsURLPattern_hash, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName))
{
return IDLAttribute<JSURLPattern>::get<jsURLPattern_hashGetter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName);
}
static inline JSValue jsURLPattern_hasRegExpGroupsGetter(JSGlobalObject& lexicalGlobalObject, JSURLPattern& thisObject)
{
SUPPRESS_UNCOUNTED_LOCAL auto& vm = JSC::getVM(&lexicalGlobalObject);
auto throwScope = DECLARE_THROW_SCOPE(vm);
SUPPRESS_UNCOUNTED_LOCAL auto& impl = thisObject.wrapped();
RELEASE_AND_RETURN(throwScope, (toJS<IDLBoolean>(lexicalGlobalObject, throwScope, impl.hasRegExpGroups())));
}
JSC_DEFINE_CUSTOM_GETTER(jsURLPattern_hasRegExpGroups, (JSGlobalObject * lexicalGlobalObject, EncodedJSValue thisValue, PropertyName attributeName))
{
return IDLAttribute<JSURLPattern>::get<jsURLPattern_hasRegExpGroupsGetter, CastedThisErrorBehavior::Assert>(*lexicalGlobalObject, thisValue, attributeName);
}
static inline JSC::EncodedJSValue jsURLPatternPrototypeFunction_testBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperation<JSURLPattern>::ClassParameter castedThis)
{
auto& vm = JSC::getVM(lexicalGlobalObject);
auto throwScope = DECLARE_THROW_SCOPE(vm);
UNUSED_PARAM(throwScope);
UNUSED_PARAM(callFrame);
auto& impl = castedThis->wrapped();
RefPtr context = jsCast<JSDOMGlobalObject*>(lexicalGlobalObject)->scriptExecutionContext();
if (!context) [[unlikely]]
return JSValue::encode(jsUndefined());
EnsureStillAliveScope argument0 = callFrame->argument(0);
auto input = convert<IDLOptional<IDLUnion<IDLUSVString, IDLDictionary<URLPatternInit>>>>(*lexicalGlobalObject, argument0.value());
RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
EnsureStillAliveScope argument1 = callFrame->argument(1);
auto baseURL = argument1.value().isUndefined() ? String() : convert<IDLUSVString>(*lexicalGlobalObject, argument1.value());
RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
RELEASE_AND_RETURN(throwScope, JSValue::encode(toJS<IDLBoolean>(*lexicalGlobalObject, throwScope, impl.test(*context, convertToOptionalWTFVariant(WTFMove(input)), WTFMove(baseURL)))));
}
JSC_DEFINE_HOST_FUNCTION(jsURLPatternPrototypeFunction_test, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame))
{
return IDLOperation<JSURLPattern>::call<jsURLPatternPrototypeFunction_testBody>(*lexicalGlobalObject, *callFrame, "test");
}
static inline JSC::EncodedJSValue jsURLPatternPrototypeFunction_execBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperation<JSURLPattern>::ClassParameter castedThis)
{
auto& vm = JSC::getVM(lexicalGlobalObject);
auto throwScope = DECLARE_THROW_SCOPE(vm);
UNUSED_PARAM(throwScope);
UNUSED_PARAM(callFrame);
auto& impl = castedThis->wrapped();
RefPtr context = jsCast<JSDOMGlobalObject*>(lexicalGlobalObject)->scriptExecutionContext();
if (!context) [[unlikely]]
return JSValue::encode(jsUndefined());
EnsureStillAliveScope argument0 = callFrame->argument(0);
auto input = convert<IDLOptional<IDLUnion<IDLUSVString, IDLDictionary<URLPatternInit>>>>(*lexicalGlobalObject, argument0.value());
RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
EnsureStillAliveScope argument1 = callFrame->argument(1);
auto baseURL = argument1.value().isUndefined() ? String() : convert<IDLUSVString>(*lexicalGlobalObject, argument1.value());
RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
RELEASE_AND_RETURN(throwScope, JSValue::encode(toJS<IDLNullable<IDLDictionary<URLPatternResult>>>(*lexicalGlobalObject, *castedThis->globalObject(), throwScope, impl.exec(*context, convertToOptionalWTFVariant(WTFMove(input)), WTFMove(baseURL)))));
}
JSC_DEFINE_HOST_FUNCTION(jsURLPatternPrototypeFunction_exec, (JSGlobalObject * lexicalGlobalObject, CallFrame* callFrame))
{
return IDLOperation<JSURLPattern>::call<jsURLPatternPrototypeFunction_execBody>(*lexicalGlobalObject, *callFrame, "exec");
}
JSC::GCClient::IsoSubspace* JSURLPattern::subspaceForImpl(JSC::VM& vm)
{
return WebCore::subspaceForImpl<JSURLPattern, UseCustomHeapCellType::No>(vm, [](auto& spaces) { return spaces.m_clientSubspaceForURLPattern.get(); }, [](auto& spaces, auto&& space) { spaces.m_clientSubspaceForURLPattern = std::forward<decltype(space)>(space); }, [](auto& spaces) { return spaces.m_subspaceForURLPattern.get(); }, [](auto& spaces, auto&& space) { spaces.m_subspaceForURLPattern = std::forward<decltype(space)>(space); });
}
void JSURLPattern::analyzeHeap(JSCell* cell, HeapAnalyzer& analyzer)
{
auto* thisObject = jsCast<JSURLPattern*>(cell);
analyzer.setWrappedObjectForCell(cell, &thisObject->wrapped());
if (RefPtr context = thisObject->scriptExecutionContext())
analyzer.setLabelForCell(cell, makeString("url "_s, context->url().string()));
Base::analyzeHeap(cell, analyzer);
}
bool JSURLPatternOwner::isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown> handle, void*, AbstractSlotVisitor& visitor, ASCIILiteral* reason)
{
UNUSED_PARAM(handle);
UNUSED_PARAM(visitor);
UNUSED_PARAM(reason);
return false;
}
void JSURLPatternOwner::finalize(JSC::Handle<JSC::Unknown> handle, void* context)
{
SUPPRESS_MEMORY_UNSAFE_CAST auto* jsURLPattern = static_cast<JSURLPattern*>(handle.slot()->asCell());
auto& world = *static_cast<DOMWrapperWorld*>(context);
uncacheWrapper(world, jsURLPattern->protectedWrapped().ptr(), jsURLPattern);
}
WTF_ALLOW_UNSAFE_BUFFER_USAGE_BEGIN
#if ENABLE(BINDING_INTEGRITY)
#if PLATFORM(WIN)
#pragma warning(disable : 4483)
extern "C" {
extern void (*const __identifier("??_7URLPattern@WebCore@@6B@")[])();
}
#else
extern "C" {
extern void* _ZTVN7WebCore10URLPatternE[];
}
#endif
template<std::same_as<URLPattern> T>
static inline void verifyVTable(URLPattern* ptr)
{
if constexpr (std::is_polymorphic_v<T>) {
const void* actualVTablePointer = getVTablePointer<T>(ptr);
#if PLATFORM(WIN)
void* expectedVTablePointer = __identifier("??_7URLPattern@WebCore@@6B@");
#else
void* expectedVTablePointer = &_ZTVN7WebCore10URLPatternE[2];
#endif
// If you hit this assertion you either have a use after free bug, or
// URLPattern has subclasses. If URLPattern has subclasses that get passed
// to toJS() we currently require URLPattern you to opt out of binding hardening
// by adding the SkipVTableValidation attribute to the interface IDL definition
RELEASE_ASSERT(actualVTablePointer == expectedVTablePointer);
}
}
#endif
WTF_ALLOW_UNSAFE_BUFFER_USAGE_END
JSC::JSValue toJSNewlyCreated(JSC::JSGlobalObject*, JSDOMGlobalObject* globalObject, Ref<URLPattern>&& impl)
{
#if ENABLE(BINDING_INTEGRITY)
verifyVTable<URLPattern>(impl.ptr());
#endif
return createWrapper<URLPattern>(globalObject, WTFMove(impl));
}
JSC::JSValue toJS(JSC::JSGlobalObject* lexicalGlobalObject, JSDOMGlobalObject* globalObject, URLPattern& impl)
{
return wrap(lexicalGlobalObject, globalObject, impl);
}
URLPattern* JSURLPattern::toWrapped(JSC::VM&, JSC::JSValue value)
{
if (auto* wrapper = jsDynamicCast<JSURLPattern*>(value))
return &wrapper->wrapped();
return nullptr;
}
}

View File

@@ -0,0 +1,96 @@
/*
This file is part of the WebKit open source project.
This file has been generated by generate-bindings.pl. DO NOT MODIFY!
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#pragma once
#include "URLPattern.h"
#include "JSDOMWrapper.h"
#include <wtf/NeverDestroyed.h>
namespace WebCore {
class JSURLPattern : public JSDOMWrapper<URLPattern> {
public:
using Base = JSDOMWrapper<URLPattern>;
static JSURLPattern* create(JSC::Structure* structure, JSDOMGlobalObject* globalObject, Ref<URLPattern>&& impl)
{
SUPPRESS_UNCOUNTED_LOCAL auto& vm = globalObject->vm();
JSURLPattern* ptr = new (NotNull, JSC::allocateCell<JSURLPattern>(vm)) JSURLPattern(structure, *globalObject, WTFMove(impl));
ptr->finishCreation(vm);
return ptr;
}
static JSC::JSObject* createPrototype(JSC::VM&, JSDOMGlobalObject&);
static JSC::JSObject* prototype(JSC::VM&, JSDOMGlobalObject&);
static URLPattern* toWrapped(JSC::VM&, JSC::JSValue);
static void destroy(JSC::JSCell*);
DECLARE_INFO;
static JSC::Structure* createStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::JSValue prototype)
{
return JSC::Structure::create(vm, globalObject, prototype, JSC::TypeInfo(JSC::ObjectType, StructureFlags), info(), JSC::NonArray);
}
static JSC::JSValue getConstructor(JSC::VM&, const JSC::JSGlobalObject*);
template<typename, JSC::SubspaceAccess mode> static JSC::GCClient::IsoSubspace* subspaceFor(JSC::VM& vm)
{
if constexpr (mode == JSC::SubspaceAccess::Concurrently)
return nullptr;
return subspaceForImpl(vm);
}
static JSC::GCClient::IsoSubspace* subspaceForImpl(JSC::VM& vm);
static void analyzeHeap(JSCell*, JSC::HeapAnalyzer&);
protected:
JSURLPattern(JSC::Structure*, JSDOMGlobalObject&, Ref<URLPattern>&&);
DECLARE_DEFAULT_FINISH_CREATION;
};
class JSURLPatternOwner final : public JSC::WeakHandleOwner {
public:
bool isReachableFromOpaqueRoots(JSC::Handle<JSC::Unknown>, void* context, JSC::AbstractSlotVisitor&, ASCIILiteral*) final;
void finalize(JSC::Handle<JSC::Unknown>, void* context) final;
};
inline JSC::WeakHandleOwner* wrapperOwner(DOMWrapperWorld&, URLPattern*)
{
static NeverDestroyed<JSURLPatternOwner> owner;
return &owner.get();
}
inline void* wrapperKey(URLPattern* wrappableObject)
{
return wrappableObject;
}
JSC::JSValue toJS(JSC::JSGlobalObject*, JSDOMGlobalObject*, URLPattern&);
inline JSC::JSValue toJS(JSC::JSGlobalObject* lexicalGlobalObject, JSDOMGlobalObject* globalObject, URLPattern* impl) { return impl ? toJS(lexicalGlobalObject, globalObject, *impl) : JSC::jsNull(); }
JSC::JSValue toJSNewlyCreated(JSC::JSGlobalObject*, JSDOMGlobalObject*, Ref<URLPattern>&&);
ALWAYS_INLINE JSC::JSValue toJSNewlyCreated(JSC::JSGlobalObject* lexicalGlobalObject, JSDOMGlobalObject* globalObject, URLPattern& impl) { return toJSNewlyCreated(lexicalGlobalObject, globalObject, Ref { impl }); }
inline JSC::JSValue toJSNewlyCreated(JSC::JSGlobalObject* lexicalGlobalObject, JSDOMGlobalObject* globalObject, RefPtr<URLPattern>&& impl) { return impl ? toJSNewlyCreated(lexicalGlobalObject, globalObject, impl.releaseNonNull()) : JSC::jsNull(); }
template<> struct JSDOMWrapperConverterTraits<URLPattern> {
using WrapperClass = JSURLPattern;
using ToWrappedReturnType = URLPattern*;
};
} // namespace WebCore

View File

@@ -0,0 +1,200 @@
/*
This file is part of the WebKit open source project.
This file has been generated by generate-bindings.pl. DO NOT MODIFY!
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "config.h"
#include "JSURLPatternInit.h"
#include "JSDOMConvertStrings.h"
#include "JSDOMGlobalObject.h"
#include <JavaScriptCore/JSCInlines.h>
#include <JavaScriptCore/ObjectConstructor.h>
namespace WebCore {
using namespace JSC;
template<> URLPatternInit convertDictionary<URLPatternInit>(JSGlobalObject& lexicalGlobalObject, JSValue value)
{
auto& vm = JSC::getVM(&lexicalGlobalObject);
auto throwScope = DECLARE_THROW_SCOPE(vm);
bool isNullOrUndefined = value.isUndefinedOrNull();
auto* object = isNullOrUndefined ? nullptr : value.getObject();
if (!isNullOrUndefined && !object) [[unlikely]] {
throwTypeError(&lexicalGlobalObject, throwScope);
return {};
}
URLPatternInit result;
JSValue baseURLValue;
if (isNullOrUndefined)
baseURLValue = jsUndefined();
else {
baseURLValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "baseURL"_s));
RETURN_IF_EXCEPTION(throwScope, {});
}
if (!baseURLValue.isUndefined()) {
result.baseURL = convert<IDLUSVString>(lexicalGlobalObject, baseURLValue);
RETURN_IF_EXCEPTION(throwScope, {});
}
JSValue hashValue;
if (isNullOrUndefined)
hashValue = jsUndefined();
else {
hashValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "hash"_s));
RETURN_IF_EXCEPTION(throwScope, {});
}
if (!hashValue.isUndefined()) {
result.hash = convert<IDLUSVString>(lexicalGlobalObject, hashValue);
RETURN_IF_EXCEPTION(throwScope, {});
}
JSValue hostnameValue;
if (isNullOrUndefined)
hostnameValue = jsUndefined();
else {
hostnameValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "hostname"_s));
RETURN_IF_EXCEPTION(throwScope, {});
}
if (!hostnameValue.isUndefined()) {
result.hostname = convert<IDLUSVString>(lexicalGlobalObject, hostnameValue);
RETURN_IF_EXCEPTION(throwScope, {});
}
JSValue passwordValue;
if (isNullOrUndefined)
passwordValue = jsUndefined();
else {
passwordValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "password"_s));
RETURN_IF_EXCEPTION(throwScope, {});
}
if (!passwordValue.isUndefined()) {
result.password = convert<IDLUSVString>(lexicalGlobalObject, passwordValue);
RETURN_IF_EXCEPTION(throwScope, {});
}
JSValue pathnameValue;
if (isNullOrUndefined)
pathnameValue = jsUndefined();
else {
pathnameValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "pathname"_s));
RETURN_IF_EXCEPTION(throwScope, {});
}
if (!pathnameValue.isUndefined()) {
result.pathname = convert<IDLUSVString>(lexicalGlobalObject, pathnameValue);
RETURN_IF_EXCEPTION(throwScope, {});
}
JSValue portValue;
if (isNullOrUndefined)
portValue = jsUndefined();
else {
portValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "port"_s));
RETURN_IF_EXCEPTION(throwScope, {});
}
if (!portValue.isUndefined()) {
result.port = convert<IDLUSVString>(lexicalGlobalObject, portValue);
RETURN_IF_EXCEPTION(throwScope, {});
}
JSValue protocolValue;
if (isNullOrUndefined)
protocolValue = jsUndefined();
else {
protocolValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "protocol"_s));
RETURN_IF_EXCEPTION(throwScope, {});
}
if (!protocolValue.isUndefined()) {
result.protocol = convert<IDLUSVString>(lexicalGlobalObject, protocolValue);
RETURN_IF_EXCEPTION(throwScope, {});
}
JSValue searchValue;
if (isNullOrUndefined)
searchValue = jsUndefined();
else {
searchValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "search"_s));
RETURN_IF_EXCEPTION(throwScope, {});
}
if (!searchValue.isUndefined()) {
result.search = convert<IDLUSVString>(lexicalGlobalObject, searchValue);
RETURN_IF_EXCEPTION(throwScope, {});
}
JSValue usernameValue;
if (isNullOrUndefined)
usernameValue = jsUndefined();
else {
usernameValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "username"_s));
RETURN_IF_EXCEPTION(throwScope, {});
}
if (!usernameValue.isUndefined()) {
result.username = convert<IDLUSVString>(lexicalGlobalObject, usernameValue);
RETURN_IF_EXCEPTION(throwScope, {});
}
return result;
}
JSC::JSObject* convertDictionaryToJS(JSC::JSGlobalObject& lexicalGlobalObject, JSDOMGlobalObject& globalObject, const URLPatternInit& dictionary)
{
auto& vm = JSC::getVM(&lexicalGlobalObject);
auto throwScope = DECLARE_THROW_SCOPE(vm);
auto result = constructEmptyObject(&lexicalGlobalObject, globalObject.objectPrototype());
if (!IDLUSVString::isNullValue(dictionary.baseURL)) {
auto baseURLValue = toJS<IDLUSVString>(lexicalGlobalObject, throwScope, IDLUSVString::extractValueFromNullable(dictionary.baseURL));
RETURN_IF_EXCEPTION(throwScope, {});
result->putDirect(vm, JSC::Identifier::fromString(vm, "baseURL"_s), baseURLValue);
}
if (!IDLUSVString::isNullValue(dictionary.hash)) {
auto hashValue = toJS<IDLUSVString>(lexicalGlobalObject, throwScope, IDLUSVString::extractValueFromNullable(dictionary.hash));
RETURN_IF_EXCEPTION(throwScope, {});
result->putDirect(vm, JSC::Identifier::fromString(vm, "hash"_s), hashValue);
}
if (!IDLUSVString::isNullValue(dictionary.hostname)) {
auto hostnameValue = toJS<IDLUSVString>(lexicalGlobalObject, throwScope, IDLUSVString::extractValueFromNullable(dictionary.hostname));
RETURN_IF_EXCEPTION(throwScope, {});
result->putDirect(vm, JSC::Identifier::fromString(vm, "hostname"_s), hostnameValue);
}
if (!IDLUSVString::isNullValue(dictionary.password)) {
auto passwordValue = toJS<IDLUSVString>(lexicalGlobalObject, throwScope, IDLUSVString::extractValueFromNullable(dictionary.password));
RETURN_IF_EXCEPTION(throwScope, {});
result->putDirect(vm, JSC::Identifier::fromString(vm, "password"_s), passwordValue);
}
if (!IDLUSVString::isNullValue(dictionary.pathname)) {
auto pathnameValue = toJS<IDLUSVString>(lexicalGlobalObject, throwScope, IDLUSVString::extractValueFromNullable(dictionary.pathname));
RETURN_IF_EXCEPTION(throwScope, {});
result->putDirect(vm, JSC::Identifier::fromString(vm, "pathname"_s), pathnameValue);
}
if (!IDLUSVString::isNullValue(dictionary.port)) {
auto portValue = toJS<IDLUSVString>(lexicalGlobalObject, throwScope, IDLUSVString::extractValueFromNullable(dictionary.port));
RETURN_IF_EXCEPTION(throwScope, {});
result->putDirect(vm, JSC::Identifier::fromString(vm, "port"_s), portValue);
}
if (!IDLUSVString::isNullValue(dictionary.protocol)) {
auto protocolValue = toJS<IDLUSVString>(lexicalGlobalObject, throwScope, IDLUSVString::extractValueFromNullable(dictionary.protocol));
RETURN_IF_EXCEPTION(throwScope, {});
result->putDirect(vm, JSC::Identifier::fromString(vm, "protocol"_s), protocolValue);
}
if (!IDLUSVString::isNullValue(dictionary.search)) {
auto searchValue = toJS<IDLUSVString>(lexicalGlobalObject, throwScope, IDLUSVString::extractValueFromNullable(dictionary.search));
RETURN_IF_EXCEPTION(throwScope, {});
result->putDirect(vm, JSC::Identifier::fromString(vm, "search"_s), searchValue);
}
if (!IDLUSVString::isNullValue(dictionary.username)) {
auto usernameValue = toJS<IDLUSVString>(lexicalGlobalObject, throwScope, IDLUSVString::extractValueFromNullable(dictionary.username));
RETURN_IF_EXCEPTION(throwScope, {});
result->putDirect(vm, JSC::Identifier::fromString(vm, "username"_s), usernameValue);
}
return result;
}
} // namespace WebCore

View File

@@ -0,0 +1,32 @@
/*
This file is part of the WebKit open source project.
This file has been generated by generate-bindings.pl. DO NOT MODIFY!
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#pragma once
#include "JSDOMConvertDictionary.h"
#include "URLPatternInit.h"
namespace WebCore {
template<> URLPatternInit convertDictionary<URLPatternInit>(JSC::JSGlobalObject&, JSC::JSValue);
JSC::JSObject* convertDictionaryToJS(JSC::JSGlobalObject&, JSDOMGlobalObject&, const URLPatternInit&);
} // namespace WebCore

View File

@@ -0,0 +1,56 @@
/*
This file is part of the WebKit open source project.
This file has been generated by generate-bindings.pl. DO NOT MODIFY!
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "config.h"
#include "JSURLPatternOptions.h"
#include "JSDOMConvertBoolean.h"
#include <JavaScriptCore/JSCInlines.h>
namespace WebCore {
using namespace JSC;
template<> URLPatternOptions convertDictionary<URLPatternOptions>(JSGlobalObject& lexicalGlobalObject, JSValue value)
{
auto& vm = JSC::getVM(&lexicalGlobalObject);
auto throwScope = DECLARE_THROW_SCOPE(vm);
bool isNullOrUndefined = value.isUndefinedOrNull();
auto* object = isNullOrUndefined ? nullptr : value.getObject();
if (!isNullOrUndefined && !object) [[unlikely]] {
throwTypeError(&lexicalGlobalObject, throwScope);
return {};
}
URLPatternOptions result;
JSValue ignoreCaseValue;
if (isNullOrUndefined)
ignoreCaseValue = jsUndefined();
else {
ignoreCaseValue = object->get(&lexicalGlobalObject, Identifier::fromString(vm, "ignoreCase"_s));
RETURN_IF_EXCEPTION(throwScope, {});
}
if (!ignoreCaseValue.isUndefined()) {
result.ignoreCase = convert<IDLBoolean>(lexicalGlobalObject, ignoreCaseValue);
RETURN_IF_EXCEPTION(throwScope, {});
} else
result.ignoreCase = false;
return result;
}
} // namespace WebCore

View File

@@ -0,0 +1,30 @@
/*
This file is part of the WebKit open source project.
This file has been generated by generate-bindings.pl. DO NOT MODIFY!
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#pragma once
#include "JSDOMConvertDictionary.h"
#include "URLPatternOptions.h"
namespace WebCore {
template<> URLPatternOptions convertDictionary<URLPatternOptions>(JSC::JSGlobalObject&, JSC::JSValue);
} // namespace WebCore

View File

@@ -0,0 +1,175 @@
/*
This file is part of the WebKit open source project.
This file has been generated by generate-bindings.pl. DO NOT MODIFY!
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "config.h"
#include "root.h"
#include "JSURLPatternResult.h"
#include "IDLTypes.h"
#include "JSDOMConvertBase.h"
#include "JSDOMConvertStrings.h"
#include "JSDOMGlobalObject.h"
#include "JSURLPatternInit.h"
#include <JavaScriptCore/JSArray.h>
#include <JavaScriptCore/JSCInlines.h>
#include <JavaScriptCore/ObjectConstructor.h>
namespace WebCore {
using namespace JSC;
// URLPatternResult and URLPatternComponentResult are output-only dictionaries that are
// returned from exec() but never accepted as input from JavaScript. These convertDictionary
// template specializations are required to satisfy template instantiation in the binding
// infrastructure. They intentionally throw TypeErrors to catch any invalid JS→native
// conversion attempts, as these types should never be constructed from JavaScript values.
template<> URLPatternResult convertDictionary<URLPatternResult>(JSGlobalObject& lexicalGlobalObject, JSValue value)
{
auto& vm = JSC::getVM(&lexicalGlobalObject);
auto throwScope = DECLARE_THROW_SCOPE(vm);
UNUSED_PARAM(value);
throwTypeError(&lexicalGlobalObject, throwScope, "URLPatternResult cannot be converted from JavaScript"_s);
return {};
}
template<> URLPatternComponentResult convertDictionary<URLPatternComponentResult>(JSGlobalObject& lexicalGlobalObject, JSValue value)
{
auto& vm = JSC::getVM(&lexicalGlobalObject);
auto throwScope = DECLARE_THROW_SCOPE(vm);
UNUSED_PARAM(value);
throwTypeError(&lexicalGlobalObject, throwScope, "URLPatternComponentResult cannot be converted from JavaScript"_s);
return {};
}
// Helper to convert the groups record to JS
static JSC::JSObject* convertGroupsToJS(JSC::JSGlobalObject& lexicalGlobalObject, JSDOMGlobalObject& globalObject, const URLPatternComponentResult::GroupsRecord& groups)
{
auto& vm = JSC::getVM(&lexicalGlobalObject);
auto throwScope = DECLARE_THROW_SCOPE(vm);
auto result = constructEmptyObject(&lexicalGlobalObject, globalObject.objectPrototype());
for (const auto& pair : groups) {
JSValue jsValue = WTF::switchOn(pair.value, [&](std::monostate) -> JSValue { return jsUndefined(); }, [&](const String& str) -> JSValue { return toJS<IDLUSVString>(lexicalGlobalObject, throwScope, str); });
RETURN_IF_EXCEPTION(throwScope, nullptr);
// Check if the key is an array index
auto identifier = Identifier::fromString(vm, pair.key);
if (auto index = parseIndex(identifier)) {
result->putDirectIndex(&lexicalGlobalObject, index.value(), jsValue);
RETURN_IF_EXCEPTION(throwScope, nullptr);
} else {
result->putDirect(vm, identifier, jsValue);
}
}
return result;
}
// Helper to convert URLPatternInput (variant) to JS
static JSC::JSValue convertURLPatternInputToJS(JSC::JSGlobalObject& lexicalGlobalObject, JSDOMGlobalObject& globalObject, const URLPattern::URLPatternInput& input)
{
auto& vm = JSC::getVM(&lexicalGlobalObject);
auto throwScope = DECLARE_THROW_SCOPE(vm);
return WTF::switchOn(input, [&](const String& str) -> JSValue { return toJS<IDLUSVString>(lexicalGlobalObject, throwScope, str); }, [&](const URLPatternInit& init) -> JSValue { return convertDictionaryToJS(lexicalGlobalObject, globalObject, init); });
}
JSC::JSObject* convertDictionaryToJS(JSC::JSGlobalObject& lexicalGlobalObject, JSDOMGlobalObject& globalObject, const URLPatternComponentResult& dictionary)
{
auto& vm = JSC::getVM(&lexicalGlobalObject);
auto throwScope = DECLARE_THROW_SCOPE(vm);
auto result = constructEmptyObject(&lexicalGlobalObject, globalObject.objectPrototype());
// Output input
auto inputValue = toJS<IDLUSVString>(lexicalGlobalObject, throwScope, dictionary.input);
RETURN_IF_EXCEPTION(throwScope, nullptr);
result->putDirect(vm, Identifier::fromString(vm, "input"_s), inputValue);
// Output groups - record<USVString, (undefined or USVString)>
auto groupsValue = convertGroupsToJS(lexicalGlobalObject, globalObject, dictionary.groups);
RETURN_IF_EXCEPTION(throwScope, nullptr);
result->putDirect(vm, Identifier::fromString(vm, "groups"_s), groupsValue);
return result;
}
JSC::JSObject* convertDictionaryToJS(JSC::JSGlobalObject& lexicalGlobalObject, JSDOMGlobalObject& globalObject, const URLPatternResult& dictionary)
{
auto& vm = JSC::getVM(&lexicalGlobalObject);
auto throwScope = DECLARE_THROW_SCOPE(vm);
auto result = constructEmptyObject(&lexicalGlobalObject, globalObject.objectPrototype());
// Output inputs - sequence<(USVString or URLPatternInit)>
auto inputsArray = JSC::constructEmptyArray(&lexicalGlobalObject, nullptr, dictionary.inputs.size());
RETURN_IF_EXCEPTION(throwScope, nullptr);
for (size_t i = 0; i < dictionary.inputs.size(); ++i) {
auto inputValue = convertURLPatternInputToJS(lexicalGlobalObject, globalObject, dictionary.inputs[i]);
RETURN_IF_EXCEPTION(throwScope, nullptr);
inputsArray->putDirectIndex(&lexicalGlobalObject, i, inputValue);
RETURN_IF_EXCEPTION(throwScope, nullptr);
}
result->putDirect(vm, Identifier::fromString(vm, "inputs"_s), inputsArray);
// Output protocol
auto protocolValue = convertDictionaryToJS(lexicalGlobalObject, globalObject, dictionary.protocol);
RETURN_IF_EXCEPTION(throwScope, nullptr);
result->putDirect(vm, Identifier::fromString(vm, "protocol"_s), protocolValue);
// Output username
auto usernameValue = convertDictionaryToJS(lexicalGlobalObject, globalObject, dictionary.username);
RETURN_IF_EXCEPTION(throwScope, nullptr);
result->putDirect(vm, Identifier::fromString(vm, "username"_s), usernameValue);
// Output password
auto passwordValue = convertDictionaryToJS(lexicalGlobalObject, globalObject, dictionary.password);
RETURN_IF_EXCEPTION(throwScope, nullptr);
result->putDirect(vm, Identifier::fromString(vm, "password"_s), passwordValue);
// Output hostname
auto hostnameValue = convertDictionaryToJS(lexicalGlobalObject, globalObject, dictionary.hostname);
RETURN_IF_EXCEPTION(throwScope, nullptr);
result->putDirect(vm, Identifier::fromString(vm, "hostname"_s), hostnameValue);
// Output port
auto portValue = convertDictionaryToJS(lexicalGlobalObject, globalObject, dictionary.port);
RETURN_IF_EXCEPTION(throwScope, nullptr);
result->putDirect(vm, Identifier::fromString(vm, "port"_s), portValue);
// Output pathname
auto pathnameValue = convertDictionaryToJS(lexicalGlobalObject, globalObject, dictionary.pathname);
RETURN_IF_EXCEPTION(throwScope, nullptr);
result->putDirect(vm, Identifier::fromString(vm, "pathname"_s), pathnameValue);
// Output search
auto searchValue = convertDictionaryToJS(lexicalGlobalObject, globalObject, dictionary.search);
RETURN_IF_EXCEPTION(throwScope, nullptr);
result->putDirect(vm, Identifier::fromString(vm, "search"_s), searchValue);
// Output hash
auto hashValue = convertDictionaryToJS(lexicalGlobalObject, globalObject, dictionary.hash);
RETURN_IF_EXCEPTION(throwScope, nullptr);
result->putDirect(vm, Identifier::fromString(vm, "hash"_s), hashValue);
return result;
}
} // namespace WebCore

View File

@@ -0,0 +1,36 @@
/*
This file is part of the WebKit open source project.
This file has been generated by generate-bindings.pl. DO NOT MODIFY!
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#pragma once
#include "JSDOMConvertDictionary.h"
#include "URLPatternResult.h"
namespace WebCore {
template<> URLPatternResult convertDictionary<URLPatternResult>(JSC::JSGlobalObject&, JSC::JSValue);
JSC::JSObject* convertDictionaryToJS(JSC::JSGlobalObject&, JSDOMGlobalObject&, const URLPatternResult&);
template<> URLPatternComponentResult convertDictionary<URLPatternComponentResult>(JSC::JSGlobalObject&, JSC::JSValue);
JSC::JSObject* convertDictionaryToJS(JSC::JSGlobalObject&, JSDOMGlobalObject&, const URLPatternComponentResult&);
} // namespace WebCore

View File

@@ -0,0 +1,493 @@
/*
* Copyright (C) 2024 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "URLPattern.h"
#include "ExceptionOr.h"
#include "ScriptExecutionContext.h"
#include "URLPatternCanonical.h"
#include "URLPatternConstructorStringParser.h"
#include "URLPatternInit.h"
#include "URLPatternOptions.h"
#include "URLPatternParser.h"
#include "URLPatternResult.h"
#include <JavaScriptCore/RegExp.h>
#include <wtf/RefCounted.h>
#include <wtf/TZoneMallocInlines.h>
#include <wtf/URL.h>
#include <wtf/URLParser.h>
#include <wtf/text/MakeString.h>
#include <wtf/text/StringToIntegerConversion.h>
namespace WebCore {
using namespace JSC;
WTF_MAKE_TZONE_OR_ISO_ALLOCATED_IMPL(URLPattern);
// https://urlpattern.spec.whatwg.org/#process-a-base-url-string
static String processBaseURLString(StringView input, BaseURLStringType type)
{
if (type != BaseURLStringType::Pattern)
return input.toString();
return URLPatternUtilities::escapePatternString(input);
}
// https://urlpattern.spec.whatwg.org/#hostname-pattern-is-an-ipv6-address
static bool isHostnamePatternIPv6(StringView hostname)
{
if (hostname.length() < 2)
return false;
if (hostname[0] == '[')
return true;
if (hostname[0] == '{' && hostname[1] == '[')
return true;
if (hostname[0] == '\\' && hostname[1] == '[')
return true;
return false;
}
URLPattern::URLPattern() = default;
// https://urlpattern.spec.whatwg.org/#process-a-urlpatterninit
static ExceptionOr<URLPatternInit> processInit(URLPatternInit&& init, BaseURLStringType type, String&& protocol = {}, String&& username = {}, String&& password = {}, String&& hostname = {}, String&& port = {}, String&& pathname = {}, String&& search = {}, String&& hash = {})
{
URLPatternInit result { WTFMove(protocol), WTFMove(username), WTFMove(password), WTFMove(hostname), WTFMove(port), WTFMove(pathname), WTFMove(search), WTFMove(hash), {} };
URL baseURL;
if (!init.baseURL.isNull()) {
baseURL = URL(init.baseURL);
if (!baseURL.isValid())
return Exception { ExceptionCode::TypeError, "Invalid baseURL."_s };
if (init.protocol.isNull())
result.protocol = processBaseURLString(baseURL.protocol(), type);
if (type != BaseURLStringType::Pattern
&& init.protocol.isNull()
&& init.hostname.isNull()
&& init.port.isNull()
&& init.username.isNull())
result.username = processBaseURLString(baseURL.user(), type);
if (type != BaseURLStringType::Pattern
&& init.protocol.isNull()
&& init.hostname.isNull()
&& init.port.isNull()
&& init.username.isNull()
&& init.password.isNull())
result.password = processBaseURLString(baseURL.password(), type);
if (init.protocol.isNull()
&& init.hostname.isNull()) {
result.hostname = processBaseURLString(!baseURL.host().isNull() ? baseURL.host() : StringView { emptyString() }, type);
}
if (init.protocol.isNull()
&& init.hostname.isNull()
&& init.port.isNull()) {
auto port = baseURL.port();
result.port = port ? String::number(*port) : emptyString();
}
if (init.protocol.isNull()
&& init.hostname.isNull()
&& init.port.isNull()
&& init.pathname.isNull()) {
result.pathname = processBaseURLString(baseURL.path(), type);
}
if (init.protocol.isNull()
&& init.hostname.isNull()
&& init.port.isNull()
&& init.pathname.isNull()
&& init.search.isNull()) {
result.search = processBaseURLString(baseURL.hasQuery() ? baseURL.query() : StringView { emptyString() }, type);
}
if (init.protocol.isNull()
&& init.hostname.isNull()
&& init.port.isNull()
&& init.pathname.isNull()
&& init.search.isNull()
&& init.hash.isNull()) {
result.hash = processBaseURLString(baseURL.hasFragmentIdentifier() ? baseURL.fragmentIdentifier() : StringView { emptyString() }, type);
}
}
if (!init.protocol.isNull()) {
auto protocolResult = canonicalizeProtocol(init.protocol, type);
if (protocolResult.hasException())
return protocolResult.releaseException();
result.protocol = protocolResult.releaseReturnValue();
}
if (!init.username.isNull())
result.username = canonicalizeUsername(init.username, type);
if (!init.password.isNull())
result.password = canonicalizePassword(init.password, type);
if (!init.hostname.isNull()) {
auto hostResult = canonicalizeHostname(init.hostname, type);
if (hostResult.hasException())
return hostResult.releaseException();
result.hostname = hostResult.releaseReturnValue();
}
if (!init.port.isNull()) {
auto portResult = canonicalizePort(init.port, result.protocol, type);
if (portResult.hasException())
return portResult.releaseException();
result.port = portResult.releaseReturnValue();
}
if (!init.pathname.isNull()) {
result.pathname = init.pathname;
if (!baseURL.isNull() && !baseURL.hasOpaquePath() && !isAbsolutePathname(result.pathname, type)) {
auto baseURLPath = processBaseURLString(baseURL.path(), type);
size_t slashIndex = baseURLPath.reverseFind('/');
if (slashIndex != notFound)
result.pathname = makeString(StringView { baseURLPath }.left(slashIndex + 1), result.pathname);
}
auto pathResult = processPathname(result.pathname, result.protocol, type);
if (pathResult.hasException())
return pathResult.releaseException();
result.pathname = pathResult.releaseReturnValue();
}
if (!init.search.isNull()) {
auto queryResult = canonicalizeSearch(init.search, type);
if (queryResult.hasException())
return queryResult.releaseException();
result.search = queryResult.releaseReturnValue();
}
if (!init.hash.isNull()) {
auto fragmentResult = canonicalizeHash(init.hash, type);
if (fragmentResult.hasException())
return fragmentResult.releaseException();
result.hash = fragmentResult.releaseReturnValue();
}
return result;
}
// https://urlpattern.spec.whatwg.org/#url-pattern-create
ExceptionOr<Ref<URLPattern>> URLPattern::create(ScriptExecutionContext& context, URLPatternInput&& input, String&& baseURL, URLPatternOptions&& options)
{
URLPatternInit init;
if (std::holds_alternative<String>(input) && !std::get<String>(input).isNull()) {
auto maybeInit = URLPatternConstructorStringParser(WTFMove(std::get<String>(input))).parse(context);
if (maybeInit.hasException())
return maybeInit.releaseException();
init = maybeInit.releaseReturnValue();
if (baseURL.isNull() && init.protocol.isEmpty())
return Exception { ExceptionCode::TypeError, "Relative constructor string must have additional baseURL argument."_s };
init.baseURL = WTFMove(baseURL);
} else if (std::holds_alternative<URLPatternInit>(input)) {
if (!baseURL.isNull())
return Exception { ExceptionCode::TypeError, "Constructor with a URLPatternInit should have a null baseURL argument."_s };
init = std::get<URLPatternInit>(input);
}
auto maybeProcessedInit = processInit(WTFMove(init), BaseURLStringType::Pattern);
if (maybeProcessedInit.hasException())
return maybeProcessedInit.releaseException();
auto processedInit = maybeProcessedInit.releaseReturnValue();
if (!processedInit.protocol)
processedInit.protocol = "*"_s;
if (!processedInit.username)
processedInit.username = "*"_s;
if (!processedInit.password)
processedInit.password = "*"_s;
if (!processedInit.hostname)
processedInit.hostname = "*"_s;
if (!processedInit.pathname)
processedInit.pathname = "*"_s;
if (!processedInit.search)
processedInit.search = "*"_s;
if (!processedInit.hash)
processedInit.hash = "*"_s;
if (!processedInit.port)
processedInit.port = "*"_s;
if (auto parsedPort = parseInteger<uint16_t>(processedInit.port, 10, WTF::ParseIntegerWhitespacePolicy::Disallow)) {
if (WTF::URLParser::isSpecialScheme(processedInit.protocol) && isDefaultPortForProtocol(*parsedPort, processedInit.protocol))
processedInit.port = emptyString();
}
Ref result = adoptRef(*new URLPattern);
auto maybeCompileException = result->compileAllComponents(context, WTFMove(processedInit), options);
if (maybeCompileException.hasException())
return maybeCompileException.releaseException();
return result;
}
// https://urlpattern.spec.whatwg.org/#urlpattern-initialize
ExceptionOr<Ref<URLPattern>> URLPattern::create(ScriptExecutionContext& context, std::optional<URLPatternInput>&& input, URLPatternOptions&& options)
{
if (!input)
input = URLPatternInit {};
return create(context, WTFMove(*input), String {}, WTFMove(options));
}
// https://urlpattern.spec.whatwg.org/#build-a-url-pattern-from-a-web-idl-value
ExceptionOr<Ref<URLPattern>> URLPattern::create(ScriptExecutionContext& context, Compatible&& value, const String& baseURL)
{
return switchOn(WTFMove(value), [&](RefPtr<URLPattern>&& pattern) -> ExceptionOr<Ref<URLPattern>> { return pattern.releaseNonNull(); }, [&](URLPatternInit&& init) -> ExceptionOr<Ref<URLPattern>> { return URLPattern::create(context, WTFMove(init), {}, {}); }, [&](String&& string) -> ExceptionOr<Ref<URLPattern>> { return URLPattern::create(context, WTFMove(string), String { baseURL }, {}); });
}
URLPattern::~URLPattern() = default;
// https://urlpattern.spec.whatwg.org/#dom-urlpattern-test
ExceptionOr<bool> URLPattern::test(ScriptExecutionContext& context, std::optional<URLPatternInput>&& input, String&& baseURL) const
{
if (!input)
input = URLPatternInit {};
auto maybeResult = match(context, WTFMove(*input), WTFMove(baseURL));
if (maybeResult.hasException())
return maybeResult.releaseException();
return !!maybeResult.returnValue();
}
// https://urlpattern.spec.whatwg.org/#dom-urlpattern-exec
ExceptionOr<std::optional<URLPatternResult>> URLPattern::exec(ScriptExecutionContext& context, std::optional<URLPatternInput>&& input, String&& baseURL) const
{
if (!input)
input = URLPatternInit {};
return match(context, WTFMove(*input), WTFMove(baseURL));
}
ExceptionOr<void> URLPattern::compileAllComponents(ScriptExecutionContext& context, URLPatternInit&& processedInit, const URLPatternOptions& options)
{
Ref vm = context.vm();
JSC::JSLockHolder lock(vm);
auto maybeProtocolComponent = URLPatternUtilities::URLPatternComponent::compile(vm, processedInit.protocol, EncodingCallbackType::Protocol, URLPatternUtilities::URLPatternStringOptions {});
if (maybeProtocolComponent.hasException())
return maybeProtocolComponent.releaseException();
m_protocolComponent = maybeProtocolComponent.releaseReturnValue();
auto maybeUsernameComponent = URLPatternUtilities::URLPatternComponent::compile(vm, processedInit.username, EncodingCallbackType::Username, URLPatternUtilities::URLPatternStringOptions {});
if (maybeUsernameComponent.hasException())
return maybeUsernameComponent.releaseException();
m_usernameComponent = maybeUsernameComponent.releaseReturnValue();
auto maybePasswordComponent = URLPatternUtilities::URLPatternComponent::compile(vm, processedInit.password, EncodingCallbackType::Password, URLPatternUtilities::URLPatternStringOptions {});
if (maybePasswordComponent.hasException())
return maybePasswordComponent.releaseException();
m_passwordComponent = maybePasswordComponent.releaseReturnValue();
auto hostnameEncodingCallbackType = isHostnamePatternIPv6(processedInit.hostname) ? EncodingCallbackType::IPv6Host : EncodingCallbackType::Host;
auto maybeHostnameComponent = URLPatternUtilities::URLPatternComponent::compile(vm, processedInit.hostname, hostnameEncodingCallbackType, URLPatternUtilities::URLPatternStringOptions { .delimiterCodepoint = "."_s });
if (maybeHostnameComponent.hasException())
return maybeHostnameComponent.releaseException();
m_hostnameComponent = maybeHostnameComponent.releaseReturnValue();
auto maybePortComponent = URLPatternUtilities::URLPatternComponent::compile(vm, processedInit.port, EncodingCallbackType::Port, URLPatternUtilities::URLPatternStringOptions {});
if (maybePortComponent.hasException())
return maybePortComponent.releaseException();
m_portComponent = maybePortComponent.releaseReturnValue();
URLPatternUtilities::URLPatternStringOptions compileOptions { .ignoreCase = options.ignoreCase };
auto maybePathnameComponent = m_protocolComponent.matchSpecialSchemeProtocol(context)
? URLPatternUtilities::URLPatternComponent::compile(vm, processedInit.pathname, EncodingCallbackType::Path, URLPatternUtilities::URLPatternStringOptions { "/"_s, "/"_s, options.ignoreCase })
: URLPatternUtilities::URLPatternComponent::compile(vm, processedInit.pathname, EncodingCallbackType::OpaquePath, compileOptions);
if (maybePathnameComponent.hasException())
return maybePathnameComponent.releaseException();
m_pathnameComponent = maybePathnameComponent.releaseReturnValue();
auto maybeSearchComponent = URLPatternUtilities::URLPatternComponent::compile(vm, processedInit.search, EncodingCallbackType::Search, compileOptions);
if (maybeSearchComponent.hasException())
return maybeSearchComponent.releaseException();
m_searchComponent = maybeSearchComponent.releaseReturnValue();
auto maybeHashComponent = URLPatternUtilities::URLPatternComponent::compile(vm, processedInit.hash, EncodingCallbackType::Hash, compileOptions);
if (maybeHashComponent.hasException())
return maybeHashComponent.releaseException();
m_hashComponent = maybeHashComponent.releaseReturnValue();
return {};
}
static inline void matchHelperAssignInputsFromURL(const URL& input, String& protocol, String& username, String& password, String& hostname, String& port, String& pathname, String& search, String& hash)
{
protocol = input.protocol().toString();
username = input.user();
password = input.password();
hostname = input.host().toString();
port = input.port() ? String::number(*input.port()) : emptyString();
pathname = input.path().toString();
search = input.query().toString();
hash = input.fragmentIdentifier().toString();
}
static inline void matchHelperAssignInputsFromInit(const URLPatternInit& input, String& protocol, String& username, String& password, String& hostname, String& port, String& pathname, String& search, String& hash)
{
protocol = input.protocol;
username = input.username;
password = input.password;
hostname = input.hostname;
port = input.port;
pathname = input.pathname;
search = input.search;
hash = input.hash;
}
// https://urlpattern.spec.whatwg.org/#url-pattern-match
ExceptionOr<std::optional<URLPatternResult>> URLPattern::match(ScriptExecutionContext& context, Variant<URL, URLPatternInput>&& input, String&& baseURLString) const
{
URLPatternResult result;
String protocol, username, password, hostname, port, pathname, search, hash;
if (URL* inputURL = std::get_if<URL>(&input)) {
ASSERT(!inputURL->isEmpty() && inputURL->isValid());
matchHelperAssignInputsFromURL(*inputURL, protocol, username, password, hostname, port, pathname, search, hash);
result.inputs = Vector<URLPatternInput> { String { inputURL->string() } };
} else {
URLPatternInput* inputPattern = std::get_if<URLPatternInput>(&input);
result.inputs.append(*inputPattern);
auto hasError = WTF::switchOn(*inputPattern, [&](const URLPatternInit& value) -> ExceptionOr<bool> {
if (!baseURLString.isNull())
return Exception { ExceptionCode::TypeError, "Base URL string is provided with a URLPatternInit. If URLPatternInit is provided, please use URLPatternInit.baseURL property instead"_s };
URLPatternInit initCopy = value;
auto maybeResult = processInit(WTFMove(initCopy), BaseURLStringType::URL);
if (maybeResult.hasException())
return true;
matchHelperAssignInputsFromInit(maybeResult.releaseReturnValue(), protocol, username, password, hostname, port, pathname, search, hash);
return false; }, [&](const String& value) -> ExceptionOr<bool> {
URL baseURL;
if (!baseURLString.isNull()) {
baseURL = URL { baseURLString };
if (!baseURL.isValid())
return true;
result.inputs.append(baseURLString);
}
URL url { baseURL, value };
if (!url.isValid())
return true;
matchHelperAssignInputsFromURL(url, protocol, username, password, hostname, port, pathname, search, hash);
return false; });
if (hasError.hasException())
return hasError.releaseException();
if (hasError.returnValue())
return { std::nullopt };
}
auto protocolExecResult = m_protocolComponent.componentExec(context, protocol);
if (protocolExecResult.isNull() || protocolExecResult.isUndefined())
return { std::nullopt };
auto* globalObject = context.globalObject();
if (!globalObject)
return { std::nullopt };
result.protocol = m_protocolComponent.createComponentMatchResult(globalObject, WTFMove(protocol), protocolExecResult);
auto usernameExecResult = m_usernameComponent.componentExec(context, username);
if (usernameExecResult.isNull() || usernameExecResult.isUndefined())
return { std::nullopt };
result.username = m_usernameComponent.createComponentMatchResult(globalObject, WTFMove(username), usernameExecResult);
auto passwordExecResult = m_passwordComponent.componentExec(context, password);
if (passwordExecResult.isNull() || passwordExecResult.isUndefined())
return { std::nullopt };
result.password = m_passwordComponent.createComponentMatchResult(globalObject, WTFMove(password), passwordExecResult);
auto hostnameExecResult = m_hostnameComponent.componentExec(context, hostname);
if (hostnameExecResult.isNull() || hostnameExecResult.isUndefined())
return { std::nullopt };
result.hostname = m_hostnameComponent.createComponentMatchResult(globalObject, WTFMove(hostname), hostnameExecResult);
auto pathnameExecResult = m_pathnameComponent.componentExec(context, pathname);
if (pathnameExecResult.isNull() || pathnameExecResult.isUndefined())
return { std::nullopt };
result.pathname = m_pathnameComponent.createComponentMatchResult(globalObject, WTFMove(pathname), pathnameExecResult);
auto portExecResult = m_portComponent.componentExec(context, port);
if (portExecResult.isNull() || portExecResult.isUndefined())
return { std::nullopt };
result.port = m_portComponent.createComponentMatchResult(globalObject, WTFMove(port), portExecResult);
auto searchExecResult = m_searchComponent.componentExec(context, search);
if (searchExecResult.isNull() || searchExecResult.isUndefined())
return { std::nullopt };
result.search = m_searchComponent.createComponentMatchResult(globalObject, WTFMove(search), searchExecResult);
auto hashExecResult = m_hashComponent.componentExec(context, hash);
if (hashExecResult.isNull() || hashExecResult.isUndefined())
return { std::nullopt };
result.hash = m_hashComponent.createComponentMatchResult(globalObject, WTFMove(hash), hashExecResult);
return { result };
}
// https://urlpattern.spec.whatwg.org/#url-pattern-has-regexp-groups
bool URLPattern::hasRegExpGroups() const
{
return m_protocolComponent.hasRegexGroupsFromPartList()
|| m_usernameComponent.hasRegexGroupsFromPartList()
|| m_passwordComponent.hasRegexGroupsFromPartList()
|| m_hostnameComponent.hasRegexGroupsFromPartList()
|| m_pathnameComponent.hasRegexGroupsFromPartList()
|| m_portComponent.hasRegexGroupsFromPartList()
|| m_searchComponent.hasRegexGroupsFromPartList()
|| m_hashComponent.hasRegexGroupsFromPartList();
}
}

View File

@@ -0,0 +1,95 @@
/*
* Copyright (C) 2024 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
#include "root.h"
#include "URLPatternComponent.h"
#include "URLPatternInit.h"
#include <wtf/Forward.h>
#include <wtf/Ref.h>
#include <wtf/RefCounted.h>
#include <wtf/RefPtr.h>
#include <wtf/TZoneMalloc.h>
namespace WebCore {
class ScriptExecutionContext;
struct URLPatternOptions;
struct URLPatternResult;
template<typename> class ExceptionOr;
enum class BaseURLStringType : bool { Pattern,
URL };
namespace URLPatternUtilities {
class URLPatternComponent;
}
class URLPattern final : public RefCounted<URLPattern> {
WTF_MAKE_TZONE_OR_ISO_ALLOCATED(URLPattern);
public:
using URLPatternInput = Variant<String, URLPatternInit>;
static ExceptionOr<Ref<URLPattern>> create(ScriptExecutionContext&, URLPatternInput&&, String&& baseURL, URLPatternOptions&&);
static ExceptionOr<Ref<URLPattern>> create(ScriptExecutionContext&, std::optional<URLPatternInput>&&, URLPatternOptions&&);
using Compatible = Variant<String, URLPatternInit, RefPtr<URLPattern>>;
static ExceptionOr<Ref<URLPattern>> create(ScriptExecutionContext&, Compatible&&, const String&);
~URLPattern();
ExceptionOr<bool> test(ScriptExecutionContext&, std::optional<URLPatternInput>&&, String&& baseURL) const;
ExceptionOr<std::optional<URLPatternResult>> exec(ScriptExecutionContext&, std::optional<URLPatternInput>&&, String&& baseURL) const;
const String& protocol() const { return m_protocolComponent.patternString(); }
const String& username() const { return m_usernameComponent.patternString(); }
const String& password() const { return m_passwordComponent.patternString(); }
const String& hostname() const { return m_hostnameComponent.patternString(); }
const String& port() const { return m_portComponent.patternString(); }
const String& pathname() const { return m_pathnameComponent.patternString(); }
const String& search() const { return m_searchComponent.patternString(); }
const String& hash() const { return m_hashComponent.patternString(); }
bool hasRegExpGroups() const;
private:
URLPattern();
ExceptionOr<void> compileAllComponents(ScriptExecutionContext&, URLPatternInit&&, const URLPatternOptions&);
ExceptionOr<std::optional<URLPatternResult>> match(ScriptExecutionContext&, Variant<URL, URLPatternInput>&&, String&& baseURLString) const;
URLPatternUtilities::URLPatternComponent m_protocolComponent;
URLPatternUtilities::URLPatternComponent m_usernameComponent;
URLPatternUtilities::URLPatternComponent m_passwordComponent;
URLPatternUtilities::URLPatternComponent m_hostnameComponent;
URLPatternUtilities::URLPatternComponent m_pathnameComponent;
URLPatternUtilities::URLPatternComponent m_portComponent;
URLPatternUtilities::URLPatternComponent m_searchComponent;
URLPatternUtilities::URLPatternComponent m_hashComponent;
};
}

View File

@@ -0,0 +1,54 @@
/*
* Copyright (C) 2024 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Apple Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
// https://urlpattern.spec.whatwg.org/#urlpattern
typedef (USVString or URLPatternInit) URLPatternInput;
[
EnabledBySetting=URLPatternAPIEnabled,
Exposed=(Window,Worker)
] interface URLPattern {
[CallWith=CurrentScriptExecutionContext] constructor(URLPatternInput input, USVString baseURL, optional URLPatternOptions options);
[CallWith=CurrentScriptExecutionContext] constructor(optional URLPatternInput input, optional URLPatternOptions options);
[CallWith=CurrentScriptExecutionContext] boolean test(optional URLPatternInput input, optional USVString baseURL);
[CallWith=CurrentScriptExecutionContext] URLPatternResult? exec(optional URLPatternInput input, optional USVString baseURL);
readonly attribute USVString protocol;
readonly attribute USVString username;
readonly attribute USVString password;
readonly attribute USVString hostname;
readonly attribute USVString port;
readonly attribute USVString pathname;
readonly attribute USVString search;
readonly attribute USVString hash;
readonly attribute boolean hasRegExpGroups;
};

View File

@@ -0,0 +1,289 @@
/*
* Copyright (C) 2024 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "URLPatternCanonical.h"
#include "ExceptionOr.h"
#include "URLDecomposition.h"
#include "URLPattern.h"
#include <wtf/URL.h>
#include <wtf/URLParser.h>
#include <wtf/text/MakeString.h>
namespace WebCore {
static constexpr auto dummyURLCharacters { "https://w/"_s };
static bool isValidIPv6HostCodePoint(auto codepoint)
{
static constexpr std::array validSpecialCodepoints { '[', ']', ':' };
return isASCIIHexDigit(codepoint) || std::find(validSpecialCodepoints.begin(), validSpecialCodepoints.end(), codepoint) != validSpecialCodepoints.end();
}
// https://urlpattern.spec.whatwg.org/#is-an-absolute-pathname
bool isAbsolutePathname(StringView input, BaseURLStringType inputType)
{
if (input.isEmpty())
return false;
if (input[0] == '/')
return true;
if (inputType == BaseURLStringType::URL)
return false;
if (input.length() < 2)
return false;
if (input.startsWith("\\/"_s))
return true;
if (input.startsWith("{/"_s))
return true;
return false;
}
// https://urlpattern.spec.whatwg.org/#canonicalize-a-protocol, combined with https://urlpattern.spec.whatwg.org/#process-protocol-for-init
ExceptionOr<String> canonicalizeProtocol(StringView value, BaseURLStringType valueType)
{
if (value.isEmpty())
return value.toString();
auto strippedValue = value.endsWith(':') ? value.left(value.length() - 1) : value;
if (valueType == BaseURLStringType::Pattern)
return strippedValue.toString();
URL dummyURL(makeString(strippedValue, "://w/"_s));
if (!dummyURL.isValid())
return Exception { ExceptionCode::TypeError, "Invalid input to canonicalize a URL protocol string."_s };
return dummyURL.protocol().toString();
}
// https://urlpattern.spec.whatwg.org/#canonicalize-a-username, combined with https://urlpattern.spec.whatwg.org/#process-username-for-init
String canonicalizeUsername(StringView value, BaseURLStringType valueType)
{
if (value.isEmpty())
return value.toString();
if (valueType == BaseURLStringType::Pattern)
return value.toString();
URL dummyURL(dummyURLCharacters);
dummyURL.setUser(value);
return dummyURL.encodedUser().toString();
}
// https://urlpattern.spec.whatwg.org/#canonicalize-a-password, combined with https://urlpattern.spec.whatwg.org/#process-password-for-init
String canonicalizePassword(StringView value, BaseURLStringType valueType)
{
if (value.isEmpty())
return value.toString();
if (valueType == BaseURLStringType::Pattern)
return value.toString();
URL dummyURL(dummyURLCharacters);
dummyURL.setPassword(value);
return dummyURL.encodedPassword().toString();
}
// https://urlpattern.spec.whatwg.org/#canonicalize-a-hostname, combined with https://urlpattern.spec.whatwg.org/#process-hostname-for-init
ExceptionOr<String> canonicalizeHostname(StringView value, BaseURLStringType valueType)
{
if (value.isEmpty())
return value.toString();
if (valueType == BaseURLStringType::Pattern)
return value.toString();
URL dummyURL(dummyURLCharacters);
if (!dummyURL.setHost(value))
return Exception { ExceptionCode::TypeError, "Invalid input to canonicalize a URL host string."_s };
return dummyURL.host().toString();
}
// https://urlpattern.spec.whatwg.org/#canonicalize-an-ipv6-hostname
ExceptionOr<String> canonicalizeIPv6Hostname(StringView value, BaseURLStringType valueType)
{
if (valueType == BaseURLStringType::Pattern)
return value.toString();
StringBuilder result;
result.reserveCapacity(value.length());
for (auto codepoint : value.codePoints()) {
if (!isValidIPv6HostCodePoint(codepoint))
return Exception { ExceptionCode::TypeError, "Invalid input to canonicalize a URL IPv6 host string."_s };
result.append(toASCIILower(codepoint));
}
return String { result.toString() };
}
// https://urlpattern.spec.whatwg.org/#canonicalize-a-port, combined with https://urlpattern.spec.whatwg.org/#process-port-for-init
ExceptionOr<String> canonicalizePort(StringView portValue, StringView protocolValue, BaseURLStringType portValueType)
{
if (portValue.isEmpty())
return portValue.toString();
if (portValueType == BaseURLStringType::Pattern)
return portValue.toString();
auto maybePort = URLDecomposition::parsePort(portValue, protocolValue);
if (!maybePort)
return Exception { ExceptionCode::TypeError, "Invalid input to canonicalize a URL port string."_s };
auto maybePortNumber = *maybePort;
if (!maybePortNumber)
return String { emptyString() };
return String::number(*maybePortNumber);
}
// https://urlpattern.spec.whatwg.org/#canonicalize-an-opaque-pathname
ExceptionOr<String> canonicalizeOpaquePathname(StringView value)
{
if (value.isEmpty())
return value.toString();
URL dummyURL(makeString("a:"_s, value));
if (!dummyURL.isValid())
return Exception { ExceptionCode::TypeError, "Invalid input to canonicalize a URL opaque path string."_s };
return dummyURL.path().toString();
}
// https://urlpattern.spec.whatwg.org/#canonicalize-a-pathname
ExceptionOr<String> canonicalizePathname(StringView pathnameValue)
{
if (pathnameValue.isEmpty())
return pathnameValue.toString();
bool hasLeadingSlash = pathnameValue[0] == '/';
String maybeAddSlashPrefix = hasLeadingSlash ? pathnameValue.toString() : makeString("/-"_s, pathnameValue);
// FIXME: Set state override to State::PathStart after URLParser supports state override.
URL dummyURL(dummyURLCharacters);
dummyURL.setPath(maybeAddSlashPrefix);
ASSERT(dummyURL.isValid());
auto result = dummyURL.path();
if (!hasLeadingSlash)
result = result.substring(2);
return result.toString();
}
// https://urlpattern.spec.whatwg.org/#process-pathname-for-init
ExceptionOr<String> processPathname(StringView pathnameValue, const StringView protocolValue, BaseURLStringType pathnameValueType)
{
if (pathnameValue.isEmpty())
return pathnameValue.toString();
if (pathnameValueType == BaseURLStringType::Pattern)
return pathnameValue.toString();
if (WTF::URLParser::isSpecialScheme(protocolValue) || protocolValue.isEmpty())
return canonicalizePathname(pathnameValue);
return canonicalizeOpaquePathname(pathnameValue);
}
// https://urlpattern.spec.whatwg.org/#canonicalize-a-search, combined with https://urlpattern.spec.whatwg.org/#process-search-for-init
ExceptionOr<String> canonicalizeSearch(StringView value, BaseURLStringType valueType)
{
if (value.isEmpty())
return value.toString();
auto strippedValue = value[0] == '?' ? value.substring(1) : value;
if (valueType == BaseURLStringType::Pattern)
return strippedValue.toString();
URL dummyURL(dummyURLCharacters);
dummyURL.setQuery(strippedValue);
ASSERT(dummyURL.isValid());
return dummyURL.query().toString();
}
// https://urlpattern.spec.whatwg.org/#canonicalize-a-hash, combined with https://urlpattern.spec.whatwg.org/#process-hash-for-init
ExceptionOr<String> canonicalizeHash(StringView value, BaseURLStringType valueType)
{
if (value.isEmpty())
return value.toString();
auto strippedValue = value[0] == '#' ? value.substring(1) : value;
if (valueType == BaseURLStringType::Pattern)
return strippedValue.toString();
URL dummyURL(dummyURLCharacters);
dummyURL.setFragmentIdentifier(strippedValue);
ASSERT(dummyURL.isValid());
return dummyURL.fragmentIdentifier().toString();
}
ExceptionOr<String> callEncodingCallback(EncodingCallbackType type, StringView input)
{
switch (type) {
case EncodingCallbackType::Protocol:
return canonicalizeProtocol(input, BaseURLStringType::URL);
case EncodingCallbackType::Username:
return canonicalizeUsername(input, BaseURLStringType::URL);
case EncodingCallbackType::Password:
return canonicalizePassword(input, BaseURLStringType::URL);
case EncodingCallbackType::Host:
return canonicalizeHostname(input, BaseURLStringType::URL);
case EncodingCallbackType::IPv6Host:
return canonicalizeIPv6Hostname(input, BaseURLStringType::URL);
case EncodingCallbackType::Port:
return canonicalizePort(input, {}, BaseURLStringType::URL);
case EncodingCallbackType::Path:
return canonicalizePathname(input);
case EncodingCallbackType::OpaquePath:
return canonicalizeOpaquePathname(input);
case EncodingCallbackType::Search:
return canonicalizeSearch(input, BaseURLStringType::URL);
case EncodingCallbackType::Hash:
return canonicalizeHash(input, BaseURLStringType::URL);
default:
ASSERT_NOT_REACHED();
return Exception { ExceptionCode::TypeError, "Invalid input type for encoding callback."_s };
}
}
}

View File

@@ -0,0 +1,60 @@
/*
* Copyright (C) 2024 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
#include <wtf/text/StringView.h>
#include <wtf/text/WTFString.h>
namespace WebCore {
template<typename> class ExceptionOr;
enum class BaseURLStringType : bool;
enum class EncodingCallbackType : uint8_t { Protocol,
Username,
Password,
Host,
IPv6Host,
Port,
Path,
OpaquePath,
Search,
Hash };
bool isAbsolutePathname(StringView input, BaseURLStringType inputType);
ExceptionOr<String> canonicalizeProtocol(StringView, BaseURLStringType valueType);
String canonicalizeUsername(StringView value, BaseURLStringType valueType);
String canonicalizePassword(StringView value, BaseURLStringType valueType);
ExceptionOr<String> canonicalizeHostname(StringView value, BaseURLStringType valueType);
ExceptionOr<String> canonicalizeIPv6Hostname(StringView value, BaseURLStringType valueType);
ExceptionOr<String> canonicalizePort(StringView portValue, StringView protocolValue, BaseURLStringType portValueType);
ExceptionOr<String> processPathname(StringView pathnameValue, const StringView protocolValue, BaseURLStringType pathnameValueType);
ExceptionOr<String> canonicalizePathname(StringView pathnameValue);
ExceptionOr<String> canonicalizeOpaquePathname(StringView value);
ExceptionOr<String> canonicalizeSearch(StringView value, BaseURLStringType valueType);
ExceptionOr<String> canonicalizeHash(StringView value, BaseURLStringType valueType);
ExceptionOr<String> callEncodingCallback(EncodingCallbackType, StringView input);
}

View File

@@ -0,0 +1,146 @@
/*
* Copyright (C) 2024 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "URLPatternComponent.h"
#include "ExceptionOr.h"
#include "ScriptExecutionContext.h"
#include "URLPatternCanonical.h"
#include "URLPatternParser.h"
#include "URLPatternResult.h"
#include <JavaScriptCore/JSCJSValue.h>
#include <JavaScriptCore/JSString.h>
#include <JavaScriptCore/RegExpObject.h>
#include <ranges>
namespace WebCore {
using namespace JSC;
namespace URLPatternUtilities {
URLPatternComponent::URLPatternComponent(String&& patternString, JSC::Strong<JSC::RegExp>&& regex, Vector<String>&& groupNameList, bool hasRegexpGroupsFromPartsList)
: m_patternString(WTFMove(patternString))
, m_regularExpression(WTFMove(regex))
, m_groupNameList(WTFMove(groupNameList))
, m_hasRegexGroupsFromPartList(hasRegexpGroupsFromPartsList)
{
}
// https://urlpattern.spec.whatwg.org/#compile-a-component
ExceptionOr<URLPatternComponent> URLPatternComponent::compile(Ref<JSC::VM> vm, StringView input, EncodingCallbackType type, const URLPatternStringOptions& options)
{
auto maybePartList = URLPatternParser::parse(input, options, type);
if (maybePartList.hasException())
return maybePartList.releaseException();
Vector<Part> partList = maybePartList.releaseReturnValue();
auto [regularExpressionString, nameList] = generateRegexAndNameList(partList, options);
OptionSet<JSC::Yarr::Flags> flags = { JSC::Yarr::Flags::UnicodeSets };
if (options.ignoreCase)
flags.add(JSC::Yarr::Flags::IgnoreCase);
JSC::RegExp* regularExpression = JSC::RegExp::create(vm, regularExpressionString, flags);
if (!regularExpression->isValid())
return Exception { ExceptionCode::TypeError, "Unable to create RegExp object regular expression from provided URLPattern string."_s };
String patternString = generatePatternString(partList, options);
bool hasRegexGroups = partList.containsIf([](auto& part) {
return part.type == PartType::Regexp;
});
return URLPatternComponent { WTFMove(patternString), JSC::Strong<JSC::RegExp> { vm, regularExpression }, WTFMove(nameList), hasRegexGroups };
}
// https://urlpattern.spec.whatwg.org/#protocol-component-matches-a-special-scheme
bool URLPatternComponent::matchSpecialSchemeProtocol(ScriptExecutionContext& context) const
{
Ref vm = context.vm();
JSC::JSLockHolder lock(vm);
static constexpr std::array specialSchemeList { "ftp"_s, "file"_s, "http"_s, "https"_s, "ws"_s, "wss"_s };
auto contextObject = context.globalObject();
if (!contextObject)
return false;
auto protocolRegex = JSC::RegExpObject::create(vm, contextObject->regExpStructure(), m_regularExpression.get(), true);
auto isSchemeMatch = std::ranges::find_if(specialSchemeList, [context = Ref { context }, &vm, &protocolRegex](const String& scheme) {
auto maybeMatch = protocolRegex->exec(context->globalObject(), JSC::jsString(vm, scheme));
return !maybeMatch.isNull();
});
return isSchemeMatch != specialSchemeList.end();
}
JSC::JSValue URLPatternComponent::componentExec(ScriptExecutionContext& context, StringView comparedString) const
{
Ref vm = context.vm();
JSC::JSLockHolder lock(vm);
auto throwScope = DECLARE_THROW_SCOPE(vm);
auto contextObject = context.globalObject();
if (!contextObject) {
throwTypeError(contextObject, throwScope, "URLPattern execution requires a valid execution context"_s);
return {};
}
auto regex = JSC::RegExpObject::create(vm, contextObject->regExpStructure(), m_regularExpression.get(), true);
return regex->exec(contextObject, JSC::jsString(vm, comparedString));
}
// https://urlpattern.spec.whatwg.org/#create-a-component-match-result
URLPatternComponentResult URLPatternComponent::createComponentMatchResult(JSC::JSGlobalObject* globalObject, String&& input, const JSC::JSValue& execResult) const
{
URLPatternComponentResult::GroupsRecord groups;
Ref vm = globalObject->vm();
auto throwScope = DECLARE_THROW_SCOPE(vm);
auto lengthValue = execResult.get(globalObject, vm->propertyNames->length);
RETURN_IF_EXCEPTION(throwScope, {});
auto length = lengthValue.toIntegerOrInfinity(globalObject);
RETURN_IF_EXCEPTION(throwScope, {});
ASSERT(length >= 0 && std::isfinite(length));
for (unsigned index = 1; index < length; ++index) {
auto match = execResult.get(globalObject, index);
RETURN_IF_EXCEPTION(throwScope, {});
Variant<std::monostate, String> value;
if (!match.isNull() && !match.isUndefined()) {
value = match.toWTFString(globalObject);
RETURN_IF_EXCEPTION(throwScope, {});
}
size_t groupIndex = index - 1;
String groupName = groupIndex < m_groupNameList.size() ? m_groupNameList[groupIndex] : emptyString();
groups.append(URLPatternComponentResult::NameMatchPair { WTFMove(groupName), WTFMove(value) });
}
return URLPatternComponentResult { !input.isEmpty() ? WTFMove(input) : emptyString(), WTFMove(groups) };
}
}
}

View File

@@ -0,0 +1,67 @@
/*
* Copyright (C) 2024 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
#include <JavaScriptCore/Strong.h>
#include <JavaScriptCore/StrongInlines.h>
namespace JSC {
class RegExp;
class VM;
class JSValue;
}
namespace WebCore {
class ScriptExecutionContext;
struct URLPatternComponentResult;
enum class EncodingCallbackType : uint8_t;
template<typename> class ExceptionOr;
namespace URLPatternUtilities {
struct URLPatternStringOptions;
class URLPatternComponent {
public:
static ExceptionOr<URLPatternComponent> compile(Ref<JSC::VM>, StringView, EncodingCallbackType, const URLPatternStringOptions&);
const String& patternString() const { return m_patternString; }
bool hasRegexGroupsFromPartList() const { return m_hasRegexGroupsFromPartList; }
bool matchSpecialSchemeProtocol(ScriptExecutionContext&) const;
JSC::JSValue componentExec(ScriptExecutionContext&, StringView) const;
URLPatternComponentResult createComponentMatchResult(JSC::JSGlobalObject*, String&& input, const JSC::JSValue& execResult) const;
URLPatternComponent() = default;
private:
URLPatternComponent(String&&, JSC::Strong<JSC::RegExp>&&, Vector<String>&&, bool);
String m_patternString;
JSC::Strong<JSC::RegExp> m_regularExpression;
Vector<String> m_groupNameList;
bool m_hasRegexGroupsFromPartList { false };
};
}
}

View File

@@ -0,0 +1,368 @@
/*
* Copyright (C) 2024 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "URLPatternConstructorStringParser.h"
#include "ExceptionOr.h"
#include "URLPatternCanonical.h"
#include "URLPatternComponent.h"
#include "URLPatternInit.h"
#include "URLPatternParser.h"
#include "URLPatternTokenizer.h"
namespace WebCore {
using namespace JSC;
URLPatternConstructorStringParser::URLPatternConstructorStringParser(String&& input)
: m_input(WTFMove(input))
{
}
// https://urlpattern.spec.whatwg.org/#rewind
void URLPatternConstructorStringParser::rewind()
{
m_tokenIndex = m_componentStart;
m_tokenIncrement = 0;
}
// https://urlpattern.spec.whatwg.org/#get-a-safe-token
const URLPatternUtilities::Token& URLPatternConstructorStringParser::getSafeToken(size_t index) const
{
if (index < m_tokenList.size())
return m_tokenList[index];
ASSERT(m_tokenList.last().type == URLPatternUtilities::TokenType::End);
return m_tokenList.last();
}
// https://urlpattern.spec.whatwg.org/#is-a-non-special-pattern-char
bool URLPatternConstructorStringParser::isNonSpecialPatternCharacter(size_t index, char value) const
{
auto token = getSafeToken(index);
return token.value.length() == 1 && token.value[0] == value
&& (token.type == URLPatternUtilities::TokenType::Char
|| token.type == URLPatternUtilities::TokenType::EscapedChar
|| token.type == URLPatternUtilities::TokenType::InvalidChar);
}
// https://urlpattern.spec.whatwg.org/#is-a-search-prefix
bool URLPatternConstructorStringParser::isSearchPrefix() const
{
if (isNonSpecialPatternCharacter(m_tokenIndex, '?'))
return true;
if (m_tokenList[m_tokenIndex].value != "?"_s)
return false;
if (m_tokenIndex == 0)
return true;
size_t previousIndex = m_tokenIndex - 1;
auto previousToken = getSafeToken(previousIndex);
if (previousToken.type == URLPatternUtilities::TokenType::Name
|| previousToken.type == URLPatternUtilities::TokenType::Regexp
|| previousToken.type == URLPatternUtilities::TokenType::Close
|| previousToken.type == URLPatternUtilities::TokenType::Asterisk) {
return false;
}
return true;
}
// https://urlpattern.spec.whatwg.org/#next-is-authority-slashes
bool URLPatternConstructorStringParser::isAuthoritySlashesNext() const
{
if (!isNonSpecialPatternCharacter(m_tokenIndex + 1, '/'))
return false;
if (!isNonSpecialPatternCharacter(m_tokenIndex + 2, '/'))
return false;
return true;
}
// https://urlpattern.spec.whatwg.org/#make-a-component-string
String URLPatternConstructorStringParser::makeComponentString() const
{
const auto& token = m_tokenList[m_tokenIndex];
auto componentStartToken = getSafeToken(m_componentStart);
auto componentStartIndex = *componentStartToken.index;
return m_input.substring(componentStartIndex, *token.index - componentStartIndex).toString();
}
static inline void setInitComponentFromState(URLPatternInit& init, URLPatternConstructorStringParserState state, String&& componentString)
{
switch (state) {
case URLPatternConstructorStringParserState::Protocol:
init.protocol = WTFMove(componentString);
break;
case URLPatternConstructorStringParserState::Username:
init.username = WTFMove(componentString);
break;
case URLPatternConstructorStringParserState::Password:
init.password = WTFMove(componentString);
break;
case URLPatternConstructorStringParserState::Hostname:
init.hostname = WTFMove(componentString);
break;
case URLPatternConstructorStringParserState::Port:
init.port = WTFMove(componentString);
break;
case URLPatternConstructorStringParserState::Pathname:
init.pathname = WTFMove(componentString);
break;
case URLPatternConstructorStringParserState::Search:
init.search = WTFMove(componentString);
break;
case URLPatternConstructorStringParserState::Hash:
init.hash = WTFMove(componentString);
break;
default:
break;
}
}
// https://urlpattern.spec.whatwg.org/#compute-protocol-matches-a-special-scheme-flag
ExceptionOr<void> URLPatternConstructorStringParser::computeProtocolMatchSpecialSchemeFlag(ScriptExecutionContext& context)
{
Ref vm = context.vm();
JSC::JSLockHolder lock(vm);
auto maybeProtocolComponent = URLPatternUtilities::URLPatternComponent::compile(vm, makeComponentString(), EncodingCallbackType::Protocol, URLPatternUtilities::URLPatternStringOptions {});
if (maybeProtocolComponent.hasException())
return maybeProtocolComponent.releaseException();
auto protocolComponent = maybeProtocolComponent.releaseReturnValue();
m_protocolMatchesSpecialSchemeFlag = protocolComponent.matchSpecialSchemeProtocol(context);
return {};
}
// https://urlpattern.spec.whatwg.org/#change-state
void URLPatternConstructorStringParser::changeState(URLPatternConstructorStringParserState newState, size_t skip)
{
if (m_state != URLPatternConstructorStringParserState::Init
&& m_state != URLPatternConstructorStringParserState::Authority
&& m_state != URLPatternConstructorStringParserState::Done)
setInitComponentFromState(m_result, m_state, makeComponentString());
if (m_state != URLPatternConstructorStringParserState::Init && newState != URLPatternConstructorStringParserState::Done) {
// Set init's hostname to empty if conditions are met.
static constexpr std::array validStateConditionsForEmptyHostname { URLPatternConstructorStringParserState::Protocol, URLPatternConstructorStringParserState::Authority, URLPatternConstructorStringParserState::Username, URLPatternConstructorStringParserState::Password };
static constexpr std::array validNewStateConditionsForEmptyHostname { URLPatternConstructorStringParserState::Port, URLPatternConstructorStringParserState::Pathname, URLPatternConstructorStringParserState::Search, URLPatternConstructorStringParserState::Hash };
if (std::ranges::find(validStateConditionsForEmptyHostname, m_state) != validStateConditionsForEmptyHostname.end()
&& std::ranges::find(validNewStateConditionsForEmptyHostname, newState) != validNewStateConditionsForEmptyHostname.end()
&& m_result.hostname.isNull()) {
m_result.hostname = emptyString();
}
// Set init's pathname to empty if conditions are met.
static constexpr std::array validStateConditionsForEmptyPathname { URLPatternConstructorStringParserState::Protocol, URLPatternConstructorStringParserState::Authority, URLPatternConstructorStringParserState::Username, URLPatternConstructorStringParserState::Password, URLPatternConstructorStringParserState::Hostname, URLPatternConstructorStringParserState::Port };
static constexpr std::array validNewStateConditionsForEmptyPathname { URLPatternConstructorStringParserState::Search, URLPatternConstructorStringParserState::Hash };
if (std::ranges::find(validStateConditionsForEmptyPathname, m_state) != validStateConditionsForEmptyPathname.end()
&& std::ranges::find(validNewStateConditionsForEmptyPathname, newState) != validNewStateConditionsForEmptyPathname.end()
&& m_result.pathname.isNull()) {
m_result.pathname = m_protocolMatchesSpecialSchemeFlag ? "/"_s : emptyString();
}
// Set init's search to empty if conditions are met.
static constexpr std::array validStateConditionsForEmptySearch { URLPatternConstructorStringParserState::Protocol, URLPatternConstructorStringParserState::Authority, URLPatternConstructorStringParserState::Username, URLPatternConstructorStringParserState::Password, URLPatternConstructorStringParserState::Hostname, URLPatternConstructorStringParserState::Port, URLPatternConstructorStringParserState::Pathname };
if (std::ranges::find(validStateConditionsForEmptySearch, m_state) != validStateConditionsForEmptySearch.end()
&& newState == URLPatternConstructorStringParserState::Hash
&& m_result.search.isNull()) {
m_result.search = emptyString();
}
}
m_state = newState;
m_tokenIndex += skip;
m_componentStart = m_tokenIndex;
m_tokenIncrement = 0;
}
void URLPatternConstructorStringParser::updateState(ScriptExecutionContext& context)
{
switch (m_state) {
case URLPatternConstructorStringParserState::Init:
// Look for protocol prefix.
if (isNonSpecialPatternCharacter(m_tokenIndex, ':')) {
rewind();
m_state = URLPatternConstructorStringParserState::Protocol;
}
break;
case URLPatternConstructorStringParserState::Protocol:
// Look for protocol prefix.
if (isNonSpecialPatternCharacter(m_tokenIndex, ':')) {
auto maybeMatchesSpecialSchemeProtocol = computeProtocolMatchSpecialSchemeFlag(context);
if (maybeMatchesSpecialSchemeProtocol.hasException())
break; // FIXME: Return exceptions.
auto nextState = URLPatternConstructorStringParserState::Pathname;
auto skip = 1;
if (isAuthoritySlashesNext()) {
nextState = URLPatternConstructorStringParserState::Authority;
skip = 3;
} else if (m_protocolMatchesSpecialSchemeFlag)
nextState = URLPatternConstructorStringParserState::Authority;
changeState(nextState, skip);
}
break;
case URLPatternConstructorStringParserState::Authority:
// Look for identity terminator.
if (isNonSpecialPatternCharacter(m_tokenIndex, '@')) {
rewind();
m_state = URLPatternConstructorStringParserState::Username;
} else if (isNonSpecialPatternCharacter(m_tokenIndex, '/') || isSearchPrefix() || isNonSpecialPatternCharacter(m_tokenIndex, '#')) { // Look for pathname start, search prefix or hash prefix.
rewind();
m_state = URLPatternConstructorStringParserState::Hostname;
}
break;
case URLPatternConstructorStringParserState::Username:
// Look for password prefix.
if (isNonSpecialPatternCharacter(m_tokenIndex, ':'))
changeState(URLPatternConstructorStringParserState::Password, 1);
// Look for identity terminator.
else if (isNonSpecialPatternCharacter(m_tokenIndex, '@'))
changeState(URLPatternConstructorStringParserState::Hostname, 1);
break;
case URLPatternConstructorStringParserState::Password:
// Look for identity terminator.
if (isNonSpecialPatternCharacter(m_tokenIndex, '@'))
changeState(URLPatternConstructorStringParserState::Hostname, 1);
break;
case URLPatternConstructorStringParserState::Hostname:
// Look for an IPv6 open.
if (isNonSpecialPatternCharacter(m_tokenIndex, '['))
++m_hostnameIPv6BracketDepth;
// Look for an IPv6 close.
else if (isNonSpecialPatternCharacter(m_tokenIndex, ']') && m_hostnameIPv6BracketDepth > 0)
--m_hostnameIPv6BracketDepth;
// Look for port prefix.
else if (isNonSpecialPatternCharacter(m_tokenIndex, ':') && !m_hostnameIPv6BracketDepth)
changeState(URLPatternConstructorStringParserState::Port, 1);
// Look for pathname start.
else if (isNonSpecialPatternCharacter(m_tokenIndex, '/'))
changeState(URLPatternConstructorStringParserState::Pathname, 0);
// Look for search prefix.
else if (isSearchPrefix())
changeState(URLPatternConstructorStringParserState::Search, 1);
// Look for hash prefix.
else if (isNonSpecialPatternCharacter(m_tokenIndex, '#'))
changeState(URLPatternConstructorStringParserState::Hash, 1);
break;
case URLPatternConstructorStringParserState::Port:
// Look for pathname start.
if (isNonSpecialPatternCharacter(m_tokenIndex, '/'))
changeState(URLPatternConstructorStringParserState::Pathname, 0);
else if (isSearchPrefix())
changeState(URLPatternConstructorStringParserState::Search, 1);
// Look for hash prefix.
else if (isNonSpecialPatternCharacter(m_tokenIndex, '#'))
changeState(URLPatternConstructorStringParserState::Hash, 1);
break;
case URLPatternConstructorStringParserState::Pathname:
if (isSearchPrefix())
changeState(URLPatternConstructorStringParserState::Search, 1);
// Look for hash prefix.
else if (isNonSpecialPatternCharacter(m_tokenIndex, '#'))
changeState(URLPatternConstructorStringParserState::Hash, 1);
break;
case URLPatternConstructorStringParserState::Search:
// Look for hash prefix.
if (isNonSpecialPatternCharacter(m_tokenIndex, '#'))
changeState(URLPatternConstructorStringParserState::Hash, 1);
break;
case URLPatternConstructorStringParserState::Hash:
break;
case URLPatternConstructorStringParserState::Done:
ASSERT_NOT_REACHED();
break;
default:
break;
}
}
void URLPatternConstructorStringParser::performParse(ScriptExecutionContext& context)
{
while (m_tokenIndex < m_tokenList.size()) {
m_tokenIncrement = 1;
if (m_tokenList[m_tokenIndex].type == URLPatternUtilities::TokenType::End) {
if (m_state == URLPatternConstructorStringParserState::Init) {
rewind();
if (isNonSpecialPatternCharacter(m_tokenIndex, '#'))
changeState(URLPatternConstructorStringParserState::Hash, 1);
else if (isSearchPrefix())
changeState(URLPatternConstructorStringParserState::Search, 1);
else
changeState(URLPatternConstructorStringParserState::Pathname, 0);
m_tokenIndex += m_tokenIncrement;
continue;
}
if (m_state == URLPatternConstructorStringParserState::Authority) {
rewind();
m_state = URLPatternConstructorStringParserState::Hostname;
m_tokenIndex += m_tokenIncrement;
continue;
}
changeState(URLPatternConstructorStringParserState::Done, 0);
break;
}
if (m_tokenList[m_tokenIndex].type == URLPatternUtilities::TokenType::Open) {
++m_groupDepth;
++m_tokenIndex;
continue;
}
if (m_groupDepth) {
if (m_tokenList[m_tokenIndex].type == URLPatternUtilities::TokenType::Close)
--m_groupDepth;
else {
m_tokenIndex += m_tokenIncrement;
continue;
}
}
updateState(context);
m_tokenIndex += m_tokenIncrement;
}
if (!m_result.hostname.isNull() && m_result.port.isNull())
m_result.port = emptyString();
}
// https://urlpattern.spec.whatwg.org/#parse-a-constructor-string
ExceptionOr<URLPatternInit> URLPatternConstructorStringParser::parse(ScriptExecutionContext& context)
{
auto maybeTokenList = URLPatternUtilities::Tokenizer(m_input, URLPatternUtilities::TokenizePolicy::Lenient).tokenize();
if (maybeTokenList.hasException())
return maybeTokenList.releaseException();
m_tokenList = maybeTokenList.releaseReturnValue();
performParse(context);
return URLPatternInit { m_result };
}
}

View File

@@ -0,0 +1,85 @@
/*
* Copyright (C) 2024 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
#include "ScriptExecutionContext.h"
#include "URLPatternInit.h"
namespace WebCore {
template<typename> class ExceptionOr;
enum class EncodingCallbackType : uint8_t;
namespace URLPatternUtilities {
struct Token;
enum class TokenType : uint8_t;
struct URLPatternStringOptions;
struct URLPatternInit;
}
enum class URLPatternConstructorStringParserState : uint8_t { Init,
Protocol,
Authority,
Username,
Password,
Hostname,
Port,
Pathname,
Search,
Hash,
Done };
class URLPatternConstructorStringParser {
public:
explicit URLPatternConstructorStringParser(String&& input);
ExceptionOr<URLPatternInit> parse(ScriptExecutionContext&);
private:
void performParse(ScriptExecutionContext&);
void rewind();
const URLPatternUtilities::Token& getSafeToken(size_t index) const;
bool isNonSpecialPatternCharacter(size_t index, char value) const;
bool isSearchPrefix() const;
bool isAuthoritySlashesNext() const;
String makeComponentString() const;
void changeState(URLPatternConstructorStringParserState, size_t skip);
void updateState(ScriptExecutionContext&);
ExceptionOr<void> computeProtocolMatchSpecialSchemeFlag(ScriptExecutionContext&);
StringView m_input;
Vector<URLPatternUtilities::Token> m_tokenList;
URLPatternInit m_result;
size_t m_componentStart { 0 };
size_t m_tokenIndex { 0 };
size_t m_tokenIncrement { 1 };
size_t m_groupDepth { 0 };
int m_hostnameIPv6BracketDepth { 0 };
bool m_protocolMatchesSpecialSchemeFlag { false };
URLPatternConstructorStringParserState m_state { URLPatternConstructorStringParserState::Init };
};
}

View File

@@ -0,0 +1,44 @@
/*
* Copyright (C) 2024 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
#include <wtf/text/WTFString.h>
namespace WebCore {
struct URLPatternInit {
String protocol;
String username;
String password;
String hostname;
String port;
String pathname;
String search;
String hash;
String baseURL;
};
}

View File

@@ -0,0 +1,41 @@
/*
* Copyright (C) 2024 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
// https://urlpattern.spec.whatwg.org/#dictdef-urlpatterninit
[
JSGenerateToJSObject,
JSGenerateToNativeObject
] dictionary URLPatternInit {
USVString protocol;
USVString username;
USVString password;
USVString hostname;
USVString port;
USVString pathname;
USVString search;
USVString hash;
USVString baseURL;
};

View File

@@ -0,0 +1,34 @@
/*
* Copyright (C) 2024 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
namespace WebCore {
struct URLPatternOptions {
bool ignoreCase { false };
};
}

View File

@@ -0,0 +1,30 @@
/*
* Copyright (C) 2024 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
// https://urlpattern.spec.whatwg.org/#dictdef-urlpatternoptions
dictionary URLPatternOptions {
boolean ignoreCase = false;
};

View File

@@ -0,0 +1,553 @@
/*
* Copyright (C) 2024 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "URLPatternParser.h"
#include "ExceptionOr.h"
#include "URLPatternCanonical.h"
#include "URLPatternTokenizer.h"
#include <ranges>
#include <wtf/text/MakeString.h>
namespace WebCore {
namespace URLPatternUtilities {
URLPatternParser::URLPatternParser(EncodingCallbackType type, String&& segmentWildcardRegexp)
: m_callbackType(type)
, m_segmentWildcardRegexp(WTFMove(segmentWildcardRegexp))
{
}
ExceptionOr<void> URLPatternParser::performParse(const URLPatternStringOptions& options)
{
ExceptionOr<void> maybeFunctionException;
while (m_index < m_tokenList.size()) {
auto charToken = tryToConsumeToken(TokenType::Char);
auto nameToken = tryToConsumeToken(TokenType::Name);
auto regexOrWildcardToken = tryToConsumeRegexOrWildcardToken(nameToken);
if (!nameToken.isNull() || !regexOrWildcardToken.isNull()) {
String prefix;
if (!charToken.isNull())
prefix = charToken.value.toString();
if (!prefix.isEmpty() && prefix != options.prefixCodepoint)
m_pendingFixedValue.append(std::exchange(prefix, {}));
maybeFunctionException = maybeAddPartFromPendingFixedValue();
if (maybeFunctionException.hasException())
return maybeFunctionException.releaseException();
auto modifierToken = tryToConsumeModifierToken();
maybeFunctionException = addPart(WTFMove(prefix), nameToken, regexOrWildcardToken, {}, modifierToken);
if (maybeFunctionException.hasException())
return maybeFunctionException.releaseException();
continue;
}
auto fixedToken = charToken;
if (fixedToken.isNull())
fixedToken = tryToConsumeToken(TokenType::EscapedChar);
if (!fixedToken.isNull()) {
m_pendingFixedValue.append(WTFMove(fixedToken.value));
continue;
}
auto openToken = tryToConsumeToken(TokenType::Open);
if (!openToken.isNull()) {
String prefix = consumeText();
nameToken = tryToConsumeToken(TokenType::Name);
regexOrWildcardToken = tryToConsumeRegexOrWildcardToken(nameToken);
String suffix = consumeText();
auto maybeCloseError = consumeRequiredToken(TokenType::Close);
if (maybeCloseError.hasException())
return maybeCloseError.releaseException();
auto modifierToken = tryToConsumeModifierToken();
maybeFunctionException = addPart(WTFMove(prefix), nameToken, regexOrWildcardToken, WTFMove(suffix), modifierToken);
if (maybeFunctionException.hasException())
return maybeFunctionException.releaseException();
continue;
}
maybeFunctionException = maybeAddPartFromPendingFixedValue();
if (maybeFunctionException.hasException())
return maybeFunctionException.releaseException();
auto maybeSyntaxError = consumeRequiredToken(TokenType::End);
if (maybeSyntaxError.hasException())
return maybeSyntaxError.releaseException();
}
return {};
}
// https://urlpattern.spec.whatwg.org/#try-to-consume-a-token
Token URLPatternParser::tryToConsumeToken(TokenType type)
{
if (m_index >= m_tokenList.size())
return {};
auto& nextToken = m_tokenList[m_index];
if (nextToken.type != type)
return {};
++m_index;
return nextToken;
}
// https://urlpattern.spec.whatwg.org/#try-to-consume-a-regexp-or-wildcard-token
Token URLPatternParser::tryToConsumeRegexOrWildcardToken(const Token& token)
{
auto tokenResult = tryToConsumeToken(TokenType::Regexp);
if (tokenResult.isNull() && token.isNull())
tokenResult = tryToConsumeToken(TokenType::Asterisk);
return tokenResult;
}
// https://urlpattern.spec.whatwg.org/#try-to-consume-a-modifier-token
Token URLPatternParser::tryToConsumeModifierToken()
{
auto token = tryToConsumeToken(TokenType::OtherModifier);
if (!token.isNull())
return token;
return tryToConsumeToken(TokenType::Asterisk);
}
// https://urlpattern.spec.whatwg.org/#consume-text
String URLPatternParser::consumeText()
{
StringBuilder result;
while (true) {
auto consumedToken = tryToConsumeToken(TokenType::Char);
if (consumedToken.isNull())
consumedToken = tryToConsumeToken(TokenType::EscapedChar);
if (consumedToken.isNull())
break;
result.append(consumedToken.value);
}
return result.toString();
}
// https://urlpattern.spec.whatwg.org/#consume-a-required-token
ExceptionOr<Token> URLPatternParser::consumeRequiredToken(TokenType type)
{
auto result = tryToConsumeToken(type);
if (result.isNull())
return Exception { ExceptionCode::TypeError, "Null token was produced when consuming a required token."_s };
return result;
}
// https://urlpattern.spec.whatwg.org/#maybe-add-a-part-from-the-pending-fixed-value
ExceptionOr<void> URLPatternParser::maybeAddPartFromPendingFixedValue()
{
if (m_pendingFixedValue.isEmpty())
return {};
auto encodedValue = callEncodingCallback(m_callbackType, m_pendingFixedValue.toString());
m_pendingFixedValue.clear();
if (encodedValue.hasException())
return encodedValue.releaseException();
m_partList.append(Part { .type = PartType::FixedText, .value = encodedValue.releaseReturnValue(), .modifier = Modifier::None });
return {};
}
// https://urlpattern.spec.whatwg.org/#add-a-part
ExceptionOr<void> URLPatternParser::addPart(String&& prefix, const Token& nameToken, const Token& regexpOrWildcardToken, String&& suffix, const Token& modifierToken)
{
Modifier modifier = Modifier::None;
if (!modifierToken.isNull()) {
if (modifierToken.value == "?"_s)
modifier = Modifier::Optional;
else if (modifierToken.value == "*"_s)
modifier = Modifier::ZeroOrMore;
else if (modifierToken.value == "+"_s)
modifier = Modifier::OneOrMore;
}
if (nameToken.isNull() && regexpOrWildcardToken.isNull() && modifier == Modifier::None) {
m_pendingFixedValue.append(WTFMove(prefix));
return {};
}
auto maybeFunctionException = maybeAddPartFromPendingFixedValue();
if (maybeFunctionException.hasException())
return maybeFunctionException.releaseException();
if (nameToken.isNull() && regexpOrWildcardToken.isNull()) {
ASSERT(suffix.isEmpty());
if (prefix.isEmpty())
return {};
auto encodedValue = callEncodingCallback(m_callbackType, WTFMove(prefix));
if (encodedValue.hasException())
return encodedValue.releaseException();
m_partList.append(Part { .type = PartType::FixedText, .value = encodedValue.releaseReturnValue(), .modifier = modifier });
return {};
}
String regexValue;
if (regexpOrWildcardToken.isNull())
regexValue = m_segmentWildcardRegexp;
else if (regexpOrWildcardToken.type == TokenType::Asterisk)
regexValue = ".*"_s;
else
regexValue = regexpOrWildcardToken.value.toString();
PartType type = PartType::Regexp;
if (regexValue == m_segmentWildcardRegexp) {
type = PartType::SegmentWildcard;
regexValue = {};
} else if (regexValue == ".*"_s) {
type = PartType::FullWildcard;
regexValue = {};
}
String name;
if (!nameToken.isNull())
name = nameToken.value.toString();
else if (!regexpOrWildcardToken.isNull()) {
name = String::number(m_nextNumericName);
++m_nextNumericName;
}
if (isDuplicateName(name))
return Exception { ExceptionCode::TypeError, "Duplicate name token produced when adding to parser part list."_s };
auto encodedPrefix = callEncodingCallback(m_callbackType, WTFMove(prefix));
if (encodedPrefix.hasException())
return encodedPrefix.releaseException();
auto encodedSuffix = callEncodingCallback(m_callbackType, WTFMove(suffix));
if (encodedSuffix.hasException())
return encodedSuffix.releaseException();
m_partList.append(Part { type, WTFMove(regexValue), modifier, WTFMove(name), encodedPrefix.releaseReturnValue(), encodedSuffix.releaseReturnValue() });
return {};
}
// https://urlpattern.spec.whatwg.org/#is-a-duplicate-name
bool URLPatternParser::isDuplicateName(StringView name) const
{
return m_partList.containsIf([&](auto& part) {
return part.name == name;
});
}
// https://urlpattern.spec.whatwg.org/#parse-a-pattern-string
ExceptionOr<Vector<Part>> URLPatternParser::parse(StringView patternStringInput, const URLPatternStringOptions& options, EncodingCallbackType type)
{
URLPatternParser tokenParser { type, generateSegmentWildcardRegexp(options) };
auto maybeParserTokenList = Tokenizer(patternStringInput, TokenizePolicy::Strict).tokenize();
if (maybeParserTokenList.hasException())
return maybeParserTokenList.releaseException();
tokenParser.setTokenList(maybeParserTokenList.releaseReturnValue());
auto maybePerformParseError = tokenParser.performParse(options);
if (maybePerformParseError.hasException())
return maybePerformParseError.releaseException();
return tokenParser.takePartList();
}
// https://urlpattern.spec.whatwg.org/#generate-a-segment-wildcard-regexp
String generateSegmentWildcardRegexp(const URLPatternStringOptions& options)
{
return makeString("[^"_s, escapeRegexString(options.delimiterCodepoint), "]+?"_s);
}
template<typename CharacterType>
static String escapeRegexStringForCharacters(std::span<const CharacterType> characters)
{
static constexpr auto regexEscapeCharacters = std::to_array<const CharacterType>({ '.', '+', '*', '?', '^', '$', '{', '}', '(', ')', '[', ']', '|', '/', '\\' }); // NOLINT
StringBuilder result;
result.reserveCapacity(characters.size());
for (auto character : characters) {
if (std::ranges::find(regexEscapeCharacters, character) != regexEscapeCharacters.end())
result.append('\\');
result.append(character);
}
return result.toString();
}
// https://urlpattern.spec.whatwg.org/#escape-a-regexp-string
String escapeRegexString(StringView input)
{
// FIXME: Ensure input only contains ASCII based on spec after the parser (or tokenizer) knows to filter non-ASCII input.
if (input.is8Bit())
return escapeRegexStringForCharacters(input.span8());
return escapeRegexStringForCharacters(input.span16());
}
// https://urlpattern.spec.whatwg.org/#convert-a-modifier-to-a-string
ASCIILiteral convertModifierToString(Modifier modifier)
{
switch (modifier) {
case Modifier::ZeroOrMore:
return "*"_s;
case Modifier::Optional:
return "?"_s;
case Modifier::OneOrMore:
return "+"_s;
default:
return {};
}
}
// https://urlpattern.spec.whatwg.org/#generate-a-regular-expression-and-name-list
std::pair<String, Vector<String>> generateRegexAndNameList(const Vector<Part>& partList, const URLPatternStringOptions& options)
{
StringBuilder result;
result.append('^');
Vector<String> nameList;
for (auto& part : partList) {
if (part.type == PartType::FixedText) {
if (part.modifier == Modifier::None)
result.append(escapeRegexString(part.value));
else
result.append("(?:"_s, escapeRegexString(part.value), ')', convertModifierToString(part.modifier));
continue;
}
ASSERT(!part.name.isEmpty());
nameList.append(part.name);
String regexpValue;
if (part.type == PartType::SegmentWildcard)
regexpValue = generateSegmentWildcardRegexp(options);
else if (part.type == PartType::FullWildcard)
regexpValue = ".*"_s;
else
regexpValue = part.value;
if (part.prefix.isEmpty() && part.suffix.isEmpty()) {
if (part.modifier == Modifier::None || part.modifier == Modifier::Optional)
result.append('(', regexpValue, ')', convertModifierToString(part.modifier));
else
result.append("((?:"_s, regexpValue, ')', convertModifierToString(part.modifier), ')');
continue;
}
if (part.modifier == Modifier::None || part.modifier == Modifier::Optional) {
result.append("(?:"_s, escapeRegexString(part.prefix), '(', regexpValue, ')', escapeRegexString(part.suffix), ')', convertModifierToString(part.modifier));
continue;
}
ASSERT(part.modifier == Modifier::ZeroOrMore || part.modifier == Modifier::OneOrMore);
ASSERT(!part.prefix.isEmpty() || !part.suffix.isEmpty());
result.append("(?:"_s,
escapeRegexString(part.prefix),
"((?:"_s,
regexpValue,
")(?:"_s,
escapeRegexString(part.suffix),
escapeRegexString(part.prefix),
"(?:"_s,
regexpValue,
"))*)"_s,
escapeRegexString(part.suffix),
')');
if (part.modifier == Modifier::ZeroOrMore)
result.append('?');
}
result.append('$');
return { result.toString(), WTFMove(nameList) };
}
// https://urlpattern.spec.whatwg.org/#generate-a-pattern-string
String generatePatternString(const Vector<Part>& partList, const URLPatternStringOptions& options)
{
StringBuilder result;
for (size_t index = 0; index < partList.size(); ++index) {
auto& part = partList[index];
std::optional<Part> previousPart;
if (index > 0)
previousPart = partList[index - 1];
std::optional<Part> nextPart;
if (index < partList.size() - 1)
nextPart = partList[index + 1];
if (part.type == PartType::FixedText) {
if (part.modifier == Modifier::None) {
result.append(escapePatternString(part.value));
continue;
}
result.append('{', escapePatternString(part.value), '}', convertModifierToString(part.modifier));
continue;
}
bool hasCustomName = !part.name.isEmpty() && !isASCIIDigit(part.name[0]);
bool needsGrouping = !part.suffix.isEmpty() || (!part.prefix.isEmpty() && part.prefix != options.prefixCodepoint);
if (!needsGrouping && hasCustomName
&& part.type == PartType::SegmentWildcard && part.modifier == Modifier::None
&& nextPart && nextPart->prefix.isEmpty() && nextPart->suffix.isEmpty()) {
if (nextPart->type == PartType::FixedText) {
if (!nextPart->value.isEmpty())
needsGrouping = isValidNameCodepoint(*StringView(nextPart->value).codePoints().begin(), IsFirst::No);
} else
needsGrouping = !nextPart->name.isEmpty() && isASCIIDigit(nextPart->name[0]);
}
if (!needsGrouping && part.prefix.isEmpty() && previousPart && previousPart->type == PartType::FixedText && !previousPart->value.isEmpty()) {
if (options.prefixCodepoint.length() == 1
&& options.prefixCodepoint.startsWith(*StringView(previousPart->value).codePoints().codePointAt(previousPart->value.length() - 1)))
needsGrouping = true;
}
ASSERT(!part.name.isEmpty());
if (needsGrouping)
result.append('{');
result.append(escapePatternString(part.prefix));
if (hasCustomName)
result.append(':', part.name);
if (part.type == PartType::Regexp)
result.append('(', part.value, ')');
else if (part.type == PartType::SegmentWildcard && !hasCustomName)
result.append('(', generateSegmentWildcardRegexp(options), ')');
else if (part.type == PartType::FullWildcard) {
if (!hasCustomName
&& (!previousPart || previousPart->type == PartType::FixedText || previousPart->modifier != Modifier::None
|| needsGrouping || !part.prefix.isEmpty()))
result.append('*');
else
result.append("(.*)"_s);
}
if (part.type == PartType::SegmentWildcard && hasCustomName && !part.suffix.isEmpty() && isValidNameCodepoint(*StringView(part.suffix).codePoints().begin(), IsFirst::Yes))
result.append('\\');
result.append(escapePatternString(part.suffix));
if (needsGrouping)
result.append('}');
result.append(convertModifierToString(part.modifier));
}
return result.toString();
}
template<typename CharacterType>
static String escapePatternStringForCharacters(std::span<const CharacterType> characters)
{
static constexpr auto escapeCharacters = std::to_array<const CharacterType>({ '+', '*', '?', ':', '(', ')', '\\', '{', '}' }); // NOLINT
StringBuilder result;
result.reserveCapacity(characters.size());
for (auto character : characters) {
if (std::ranges::find(escapeCharacters, character) != escapeCharacters.end())
result.append('\\');
result.append(character);
}
return result.toString();
}
// https://urlpattern.spec.whatwg.org/#escape-a-pattern-string
String escapePatternString(StringView input)
{
// FIXME: Ensure input only contains ASCII based on spec after the parser (or tokenizer) knows to filter non-ASCII input.
if (input.is8Bit())
return escapePatternStringForCharacters(input.span8());
return escapePatternStringForCharacters(input.span16());
}
// https://urlpattern.spec.whatwg.org/#is-a-valid-name-code-point
bool isValidNameCodepoint(char16_t codepoint, URLPatternUtilities::IsFirst first)
{
if (first == URLPatternUtilities::IsFirst::Yes)
return u_hasBinaryProperty(codepoint, UCHAR_ID_START) || codepoint == '_' || codepoint == '$';
return u_hasBinaryProperty(codepoint, UCHAR_ID_CONTINUE) || codepoint == '_' || codepoint == '$' || codepoint == 0x200c || codepoint == 0x200d;
}
} // namespace URLPatternUtilities
} // namespace WebCore

View File

@@ -0,0 +1,110 @@
/*
* Copyright (C) 2024 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
#include "URLPatternTokenizer.h"
#include <wtf/text/StringBuilder.h>
#include <wtf/text/WTFString.h>
namespace WebCore {
enum class EncodingCallbackType : uint8_t;
template<typename> class ExceptionOr;
namespace URLPatternUtilities {
struct Token;
enum class TokenType : uint8_t;
enum class PartType : uint8_t { FixedText,
Regexp,
SegmentWildcard,
FullWildcard };
enum class Modifier : uint8_t { None,
Optional,
ZeroOrMore,
OneOrMore };
enum class IsFirst : bool { No,
Yes };
struct Part {
PartType type;
String value;
Modifier modifier;
String name {};
String prefix {};
String suffix {};
};
struct URLPatternStringOptions {
String delimiterCodepoint {};
String prefixCodepoint {};
bool ignoreCase { false };
};
class URLPatternParser {
public:
URLPatternParser(EncodingCallbackType, String&& segmentWildcardRegexp);
ExceptionOr<void> performParse(const URLPatternStringOptions&);
void setTokenList(Vector<Token>&& tokenList) { m_tokenList = WTFMove(tokenList); }
static ExceptionOr<Vector<Part>> parse(StringView, const URLPatternStringOptions&, EncodingCallbackType);
private:
Token tryToConsumeToken(TokenType);
Token tryToConsumeRegexOrWildcardToken(const Token&);
Token tryToConsumeModifierToken();
String consumeText();
ExceptionOr<Token> consumeRequiredToken(TokenType);
ExceptionOr<void> maybeAddPartFromPendingFixedValue();
ExceptionOr<void> addPart(String&& prefix, const Token& nameToken, const Token& regexpOrWildcardToken, String&& suffix, const Token& modifierToken);
bool isDuplicateName(StringView) const;
Vector<Part> takePartList() { return std::exchange(m_partList, {}); }
Vector<Token> m_tokenList;
Vector<Part> m_partList;
EncodingCallbackType m_callbackType;
String m_segmentWildcardRegexp;
StringBuilder m_pendingFixedValue;
size_t m_index { 0 };
int m_nextNumericName { 0 };
};
// FIXME: Consider moving functions to somewhere generic, perhaps refactor Part to its own class.
String generateSegmentWildcardRegexp(const URLPatternStringOptions&);
String escapeRegexString(StringView);
ASCIILiteral convertModifierToString(Modifier);
std::pair<String, Vector<String>> generateRegexAndNameList(const Vector<Part>& partList, const URLPatternStringOptions&);
String generatePatternString(const Vector<Part>& partList, const URLPatternStringOptions&);
String escapePatternString(StringView input);
bool isValidNameCodepoint(char16_t codepoint, URLPatternUtilities::IsFirst);
} // namespace URLPatternUtilities
} // namespace WebCore

View File

@@ -0,0 +1,52 @@
/*
* Copyright (C) 2024 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
#include "URLPattern.h"
namespace WebCore {
struct URLPatternComponentResult {
using NameMatchPair = KeyValuePair<String, Variant<std::monostate, String>>;
using GroupsRecord = Vector<NameMatchPair>;
String input;
GroupsRecord groups;
};
struct URLPatternResult {
Vector<URLPattern::URLPatternInput> inputs;
URLPatternComponentResult protocol;
URLPatternComponentResult username;
URLPatternComponentResult password;
URLPatternComponentResult hostname;
URLPatternComponentResult port;
URLPatternComponentResult pathname;
URLPatternComponentResult search;
URLPatternComponentResult hash;
};
}

View File

@@ -0,0 +1,54 @@
/*
* Copyright (C) 2024 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
// https://urlpattern.spec.whatwg.org/#dictdef-urlpatterncomponentresult
// https://urlpattern.spec.whatwg.org/#dictdef-urlpatternresult
typedef (USVString or URLPatternInit) URLPatternInput;
[
JSGenerateToJSObject,
JSGenerateToNativeObject,
ImplementedAs=URLPatternComponentResult
] dictionary URLPatternComponentResult {
USVString input;
record<USVString, (undefined or USVString)> groups;
};
[
JSGenerateToJSObject,
JSGenerateToNativeObject
] dictionary URLPatternResult {
sequence<URLPatternInput> inputs;
URLPatternComponentResult protocol;
URLPatternComponentResult username;
URLPatternComponentResult password;
URLPatternComponentResult hostname;
URLPatternComponentResult port;
URLPatternComponentResult pathname;
URLPatternComponentResult search;
URLPatternComponentResult hash;
};

View File

@@ -0,0 +1,273 @@
/*
* Copyright (C) 2024 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "URLPatternTokenizer.h"
#include "ExceptionOr.h"
#include "URLPatternParser.h"
#include <unicode/utf16.h>
#include <wtf/text/MakeString.h>
namespace WebCore {
namespace URLPatternUtilities {
bool Token::isNull() const
{
if (!index) {
ASSERT(value.isNull());
return true;
}
return false;
}
// https://urlpattern.spec.whatwg.org/#get-the-next-code-point
void Tokenizer::getNextCodePoint()
{
m_codepoint = m_input[m_nextIndex++];
if (m_input.is8Bit() || !U16_IS_LEAD(m_codepoint) || m_nextIndex >= m_input.length())
return;
auto next = m_input[m_nextIndex];
if (!U16_IS_TRAIL(next))
return;
m_nextIndex++;
m_codepoint = U16_GET_SUPPLEMENTARY(m_codepoint, next);
}
// https://urlpattern.spec.whatwg.org/#seek-and-get-the-next-code-point
void Tokenizer::seekNextCodePoint(size_t index)
{
m_nextIndex = index;
getNextCodePoint();
}
// https://urlpattern.spec.whatwg.org/#add-a-token
void Tokenizer::addToken(TokenType currentType, size_t nextPosition, size_t valuePosition, size_t valueLength)
{
m_tokenList.append(Token { currentType, m_index, m_input.substring(valuePosition, valueLength) });
m_index = nextPosition;
}
// https://urlpattern.spec.whatwg.org/#add-a-token-with-default-length
void Tokenizer::addToken(TokenType currentType, size_t nextPosition, size_t valuePosition)
{
addToken(currentType, nextPosition, valuePosition, nextPosition - valuePosition);
}
// https://urlpattern.spec.whatwg.org/#add-a-token-with-default-position-and-length
void Tokenizer::addToken(TokenType currentType)
{
addToken(currentType, m_nextIndex, m_index);
}
// https://urlpattern.spec.whatwg.org/#process-a-tokenizing-error
ExceptionOr<void> Tokenizer::processTokenizingError(size_t nextPosition, size_t valuePosition, const String& callerErrorInfo)
{
if (m_policy == TokenizePolicy::Strict)
return Exception { ExceptionCode::TypeError, callerErrorInfo };
ASSERT(m_policy == TokenizePolicy::Lenient);
addToken(TokenType::InvalidChar, nextPosition, valuePosition);
return {};
}
Tokenizer::Tokenizer(StringView input, TokenizePolicy tokenizerPolicy)
: m_input(input)
, m_policy(tokenizerPolicy)
{
}
// https://urlpattern.spec.whatwg.org/#tokenize
ExceptionOr<Vector<Token>> Tokenizer::tokenize()
{
ExceptionOr<void> maybeException;
while (m_index < m_input.length()) {
if (m_policy == TokenizePolicy::Strict && maybeException.hasException())
return maybeException.releaseException();
seekNextCodePoint(m_index);
if (m_codepoint == '*') {
addToken(TokenType::Asterisk);
continue;
}
if (m_codepoint == '+' || m_codepoint == '?') {
addToken(TokenType::OtherModifier);
continue;
}
if (m_codepoint == '\\') {
if (m_index == m_input.length() - 1) {
maybeException = processTokenizingError(m_nextIndex, m_index, "No character is provided after escape."_s);
continue;
}
auto escapedIndex = m_nextIndex;
getNextCodePoint();
addToken(TokenType::EscapedChar, m_nextIndex, escapedIndex);
continue;
}
if (m_codepoint == '{') {
addToken(TokenType::Open);
continue;
}
if (m_codepoint == '}') {
addToken(TokenType::Close);
continue;
}
if (m_codepoint == ':') {
auto namePosition = m_nextIndex;
auto nameStart = namePosition;
while (namePosition < m_input.length()) {
seekNextCodePoint(namePosition);
bool isValidCodepoint = isValidNameCodepoint(m_codepoint, namePosition == nameStart ? IsFirst::Yes : IsFirst::No);
if (!isValidCodepoint)
break;
namePosition = m_nextIndex;
}
if (namePosition <= nameStart) {
maybeException = processTokenizingError(nameStart, m_index, makeString("Name position "_s, String::number(namePosition), " is less than name start "_s, String::number(nameStart)));
continue;
}
addToken(TokenType::Name, namePosition, nameStart);
continue;
}
if (m_codepoint == '(') {
int depth = 1;
auto regexPosition = m_nextIndex;
auto regexStart = regexPosition;
bool hasError = false;
while (regexPosition < m_input.length()) {
seekNextCodePoint(regexPosition);
if (!isASCII(m_codepoint)) {
maybeException = processTokenizingError(regexStart, m_index, "Current codepoint is not ascii"_s);
hasError = true;
break;
}
if (regexPosition == regexStart && m_codepoint == '?') {
maybeException = processTokenizingError(regexStart, m_index, "Regex cannot start with modifier."_s);
hasError = true;
break;
}
if (m_codepoint == '\\') {
if (regexPosition == m_input.length() - 1) {
maybeException = processTokenizingError(regexStart, m_index, "No character is provided after escape."_s);
hasError = true;
break;
}
getNextCodePoint();
if (!isASCII(m_codepoint)) {
maybeException = processTokenizingError(regexStart, m_index, "Current codepoint is not ascii"_s);
hasError = true;
break;
}
regexPosition = m_nextIndex;
continue;
}
if (m_codepoint == ')') {
depth = depth - 1;
if (!depth) {
regexPosition = m_nextIndex;
break;
}
}
if (m_codepoint == '(') {
depth = depth + 1;
if (regexPosition == m_input.length() - 1) {
maybeException = processTokenizingError(regexStart, m_index, "No closing token is provided by end of string."_s);
hasError = true;
break;
}
int temporaryPosition = m_nextIndex;
getNextCodePoint();
if (m_codepoint != '?') {
maybeException = processTokenizingError(regexStart, m_index, "Required OtherModifier token is not provided in regex."_s);
hasError = true;
break;
}
m_nextIndex = temporaryPosition;
}
regexPosition = m_nextIndex;
}
if (hasError)
continue;
if (depth) {
maybeException = processTokenizingError(regexStart, m_index, "Current open token does not have a corresponding close token."_s);
continue;
}
auto regexLength = regexPosition - regexStart - 1;
if (!regexLength)
maybeException = processTokenizingError(regexStart, m_index, "Regex length is zero."_s);
addToken(TokenType::Regexp, regexPosition, regexStart, regexLength);
continue;
}
addToken(TokenType::Char);
}
addToken(TokenType::End, m_index, m_index);
return WTFMove(m_tokenList);
}
} // namespace URLPatternUtilities
} // namespace WebCore

Some files were not shown because too many files have changed in this diff Show More