mirror of
https://github.com/oven-sh/bun
synced 2026-02-09 02:18:47 +00:00
Compare commits
165 Commits
nektro-pat
...
fix-node-h
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7b566e2cfc | ||
|
|
6ae4158762 | ||
|
|
8dc95b041a | ||
|
|
211fd4fa06 | ||
|
|
10665821c4 | ||
|
|
a3585ff961 | ||
|
|
2aeff10a85 | ||
|
|
f2c8e63ae1 | ||
|
|
40bfda0f87 | ||
|
|
9888570456 | ||
|
|
a1690cd708 | ||
|
|
e602e2b887 | ||
|
|
eae2d61f12 | ||
|
|
8e246e1e67 | ||
|
|
f30ca39242 | ||
|
|
9f68db4818 | ||
|
|
f1cd5abfaa | ||
|
|
a8a7da3466 | ||
|
|
da9c980d26 | ||
|
|
27cf0d5eaf | ||
|
|
b5cbf16cb8 | ||
|
|
2024fa09d7 | ||
|
|
46b2a58c25 | ||
|
|
d871b2ebdc | ||
|
|
dc51dab7bc | ||
|
|
e39305dd91 | ||
|
|
6e1f1c4da7 | ||
|
|
21a42a0dee | ||
|
|
982083b3e9 | ||
|
|
40e222c43b | ||
|
|
c8634668e7 | ||
|
|
fa9bb75ad3 | ||
|
|
c47e402025 | ||
|
|
a3f48c1d47 | ||
|
|
de048cb474 | ||
|
|
0c5ee31707 | ||
|
|
c820b0c5e1 | ||
|
|
d09e381cbc | ||
|
|
53d631f1bd | ||
|
|
74768449bc | ||
|
|
294adc2269 | ||
|
|
ff97424667 | ||
|
|
cbf8d7cad6 | ||
|
|
0c41951b58 | ||
|
|
50b36696f8 | ||
|
|
de4182f305 | ||
|
|
4214cc0aaa | ||
|
|
d1c77f5061 | ||
|
|
45e01cdaf2 | ||
|
|
2fc19daeec | ||
|
|
60c0b9ab96 | ||
|
|
7f948f9c3e | ||
|
|
66fb9f1097 | ||
|
|
062a5b9bf8 | ||
|
|
5bedf15462 | ||
|
|
d7aee40387 | ||
|
|
26f08fabd7 | ||
|
|
05b48ce57c | ||
|
|
1ed87f4e83 | ||
|
|
b089558674 | ||
|
|
45df1dbba0 | ||
|
|
beb32770f0 | ||
|
|
3eec297282 | ||
|
|
b0b6c979ee | ||
|
|
7d69ac03ec | ||
|
|
d7e08abce8 | ||
|
|
d907942966 | ||
|
|
fe0e737f7b | ||
|
|
8da959df85 | ||
|
|
d7a047a533 | ||
|
|
c260223127 | ||
|
|
e834a80b7b | ||
|
|
7011dd6524 | ||
|
|
cde668b54c | ||
|
|
01db86e915 | ||
|
|
85376147a4 | ||
|
|
d2ecce272c | ||
|
|
7ee0b428d6 | ||
|
|
9482e4c86a | ||
|
|
42276a9500 | ||
|
|
ae8f78c84d | ||
|
|
9636852224 | ||
|
|
5f72715a42 | ||
|
|
c60b5dd4d6 | ||
|
|
42c474a21f | ||
|
|
04078fbf61 | ||
|
|
28ebbb3f20 | ||
|
|
96fa32bcc1 | ||
|
|
b3246b6971 | ||
|
|
0345414ded | ||
|
|
01d214b276 | ||
|
|
fdd181d68d | ||
|
|
5c7df736bf | ||
|
|
29870cb572 | ||
|
|
32223e90e3 | ||
|
|
31198cdbd9 | ||
|
|
971f2b1ed7 | ||
|
|
832cf91e88 | ||
|
|
2e010073aa | ||
|
|
4c93b72906 | ||
|
|
7091fd5791 | ||
|
|
e5edd388a0 | ||
|
|
b887270e25 | ||
|
|
fc0d0ad8d3 | ||
|
|
ddfc8555f7 | ||
|
|
6d0739f7d9 | ||
|
|
fdd750e4b5 | ||
|
|
9a5afe371a | ||
|
|
5123561889 | ||
|
|
ba7f59355f | ||
|
|
a79f92df9e | ||
|
|
8bc88763ec | ||
|
|
4a0e982bb2 | ||
|
|
013fdddc6e | ||
|
|
a9ca465ad0 | ||
|
|
cd4d75ee7b | ||
|
|
aa2e109f5f | ||
|
|
45e3c9da70 | ||
|
|
cee026b87e | ||
|
|
1a68ce05dc | ||
|
|
bf0253df1d | ||
|
|
2e3e6a15e0 | ||
|
|
589fa6274d | ||
|
|
4cf0d39e58 | ||
|
|
a1952c71f7 | ||
|
|
48df26462d | ||
|
|
66cf62c3c4 | ||
|
|
9d6729fef3 | ||
|
|
20144ced54 | ||
|
|
2e6cbd9a4d | ||
|
|
85f49a7a1a | ||
|
|
6ba858dfbb | ||
|
|
7b423d5ff8 | ||
|
|
ae19729a72 | ||
|
|
2d45ae7441 | ||
|
|
e6cb0de539 | ||
|
|
924e50b6e9 | ||
|
|
1d32e78cf4 | ||
|
|
b5bca2d976 | ||
|
|
1acd4039b6 | ||
|
|
438ec5d1eb | ||
|
|
1a9cadf5f4 | ||
|
|
304b471281 | ||
|
|
6028683f87 | ||
|
|
0b58e791b3 | ||
|
|
1570d4f0a7 | ||
|
|
b6b6efc839 | ||
|
|
d502df353c | ||
|
|
7161326baa | ||
|
|
903d6d058c | ||
|
|
96b305389f | ||
|
|
2a74f0d8f4 | ||
|
|
6e99733320 | ||
|
|
94ab3007a4 | ||
|
|
4645c309ca | ||
|
|
852830eb54 | ||
|
|
4840217156 | ||
|
|
78fb3ce64d | ||
|
|
368ddfdd14 | ||
|
|
f9ebabe898 | ||
|
|
60eb2c4ecb | ||
|
|
8a177f6c85 | ||
|
|
5053d0eaaf | ||
|
|
6ec2b98336 | ||
|
|
bae0921ef7 |
@@ -1,12 +1,12 @@
|
||||
ARG LLVM_VERSION="18"
|
||||
ARG REPORTED_LLVM_VERSION="18.1.8"
|
||||
ARG LLVM_VERSION="19"
|
||||
ARG REPORTED_LLVM_VERSION="19.1.7"
|
||||
ARG OLD_BUN_VERSION="1.1.38"
|
||||
ARG DEFAULT_CFLAGS="-mno-omit-leaf-frame-pointer -fno-omit-frame-pointer -ffunction-sections -fdata-sections -faddrsig -fno-unwind-tables -fno-asynchronous-unwind-tables"
|
||||
ARG DEFAULT_CXXFLAGS="-flto=full -fwhole-program-vtables -fforce-emit-vtables"
|
||||
ARG BUILDKITE_AGENT_TAGS="queue=linux,os=linux,arch=${TARGETARCH}"
|
||||
|
||||
FROM --platform=$BUILDPLATFORM ubuntu:20.04 as base-arm64
|
||||
FROM --platform=$BUILDPLATFORM ubuntu:18.04 as base-amd64
|
||||
FROM --platform=$BUILDPLATFORM ubuntu:20.04 as base-amd64
|
||||
FROM base-$TARGETARCH as base
|
||||
|
||||
ARG LLVM_VERSION
|
||||
|
||||
@@ -107,9 +107,9 @@ const buildPlatforms = [
|
||||
{ os: "linux", arch: "aarch64", distro: "amazonlinux", release: "2023", features: ["docker"] },
|
||||
{ os: "linux", arch: "x64", distro: "amazonlinux", release: "2023", features: ["docker"] },
|
||||
{ os: "linux", arch: "x64", baseline: true, distro: "amazonlinux", release: "2023", features: ["docker"] },
|
||||
{ os: "linux", arch: "aarch64", abi: "musl", distro: "alpine", release: "3.20" },
|
||||
{ os: "linux", arch: "x64", abi: "musl", distro: "alpine", release: "3.20" },
|
||||
{ os: "linux", arch: "x64", abi: "musl", baseline: true, distro: "alpine", release: "3.20" },
|
||||
{ os: "linux", arch: "aarch64", abi: "musl", distro: "alpine", release: "3.21" },
|
||||
{ os: "linux", arch: "x64", abi: "musl", distro: "alpine", release: "3.21" },
|
||||
{ os: "linux", arch: "x64", abi: "musl", baseline: true, distro: "alpine", release: "3.21" },
|
||||
{ os: "windows", arch: "x64", release: "2019" },
|
||||
{ os: "windows", arch: "x64", baseline: true, release: "2019" },
|
||||
];
|
||||
@@ -134,9 +134,9 @@ const testPlatforms = [
|
||||
{ os: "linux", arch: "x64", baseline: true, distro: "ubuntu", release: "24.04", tier: "latest" },
|
||||
{ os: "linux", arch: "x64", baseline: true, distro: "ubuntu", release: "22.04", tier: "previous" },
|
||||
{ os: "linux", arch: "x64", baseline: true, distro: "ubuntu", release: "20.04", tier: "oldest" },
|
||||
{ os: "linux", arch: "aarch64", abi: "musl", distro: "alpine", release: "3.20", tier: "latest" },
|
||||
{ os: "linux", arch: "x64", abi: "musl", distro: "alpine", release: "3.20", tier: "latest" },
|
||||
{ os: "linux", arch: "x64", abi: "musl", baseline: true, distro: "alpine", release: "3.20", tier: "latest" },
|
||||
{ os: "linux", arch: "aarch64", abi: "musl", distro: "alpine", release: "3.21", tier: "latest" },
|
||||
{ os: "linux", arch: "x64", abi: "musl", distro: "alpine", release: "3.21", tier: "latest" },
|
||||
{ os: "linux", arch: "x64", abi: "musl", baseline: true, distro: "alpine", release: "3.21", tier: "latest" },
|
||||
{ os: "windows", arch: "x64", release: "2019", tier: "oldest" },
|
||||
{ os: "windows", arch: "x64", release: "2019", baseline: true, tier: "oldest" },
|
||||
];
|
||||
@@ -471,7 +471,7 @@ function getBuildZigStep(platform, options) {
|
||||
cancel_on_build_failing: isMergeQueue(),
|
||||
env: getBuildEnv(platform, options),
|
||||
command: `bun run build:ci --target bun-zig --toolchain ${toolchain}`,
|
||||
timeout_in_minutes: 25,
|
||||
timeout_in_minutes: 35,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -201,6 +201,8 @@ function create_release() {
|
||||
local artifacts=(
|
||||
bun-darwin-aarch64.zip
|
||||
bun-darwin-aarch64-profile.zip
|
||||
bun-darwin-x64.zip
|
||||
bun-darwin-x64-profile.zip
|
||||
bun-linux-aarch64.zip
|
||||
bun-linux-aarch64-profile.zip
|
||||
bun-linux-x64.zip
|
||||
|
||||
4
.github/workflows/clang-format.yml
vendored
4
.github/workflows/clang-format.yml
vendored
@@ -11,8 +11,8 @@ on:
|
||||
|
||||
env:
|
||||
BUN_VERSION: "1.2.0"
|
||||
LLVM_VERSION: "18.1.8"
|
||||
LLVM_VERSION_MAJOR: "18"
|
||||
LLVM_VERSION: "19.1.7"
|
||||
LLVM_VERSION_MAJOR: "19"
|
||||
|
||||
jobs:
|
||||
clang-format:
|
||||
|
||||
4
.github/workflows/clang-tidy.yml
vendored
4
.github/workflows/clang-tidy.yml
vendored
@@ -11,8 +11,8 @@ on:
|
||||
|
||||
env:
|
||||
BUN_VERSION: "1.2.0"
|
||||
LLVM_VERSION: "18.1.8"
|
||||
LLVM_VERSION_MAJOR: "18"
|
||||
LLVM_VERSION: "19.1.7"
|
||||
LLVM_VERSION_MAJOR: "19"
|
||||
|
||||
jobs:
|
||||
clang-tidy:
|
||||
|
||||
1
.github/workflows/run-lint.yml
vendored
1
.github/workflows/run-lint.yml
vendored
@@ -3,7 +3,6 @@ name: Lint
|
||||
permissions:
|
||||
contents: read
|
||||
env:
|
||||
LLVM_VERSION: 16
|
||||
BUN_VERSION: "1.2.0"
|
||||
|
||||
on:
|
||||
|
||||
2
.github/workflows/update-cares.yml
vendored
2
.github/workflows/update-cares.yml
vendored
@@ -89,4 +89,6 @@ jobs:
|
||||
|
||||
Updates c-ares to version ${{ steps.check-version.outputs.tag }}
|
||||
|
||||
Compare: https://github.com/c-ares/c-ares/compare/${{ steps.check-version.outputs.current }}...${{ steps.check-version.outputs.latest }}
|
||||
|
||||
Auto-updated by [this workflow](https://github.com/oven-sh/bun/actions/workflows/update-cares.yml)
|
||||
|
||||
2
.github/workflows/update-libarchive.yml
vendored
2
.github/workflows/update-libarchive.yml
vendored
@@ -89,4 +89,6 @@ jobs:
|
||||
|
||||
Updates libarchive to version ${{ steps.check-version.outputs.tag }}
|
||||
|
||||
Compare: https://github.com/libarchive/libarchive/compare/${{ steps.check-version.outputs.current }}...${{ steps.check-version.outputs.latest }}
|
||||
|
||||
Auto-updated by [this workflow](https://github.com/oven-sh/bun/actions/workflows/update-libarchive.yml)
|
||||
|
||||
2
.github/workflows/update-libdeflate.yml
vendored
2
.github/workflows/update-libdeflate.yml
vendored
@@ -89,4 +89,6 @@ jobs:
|
||||
|
||||
Updates libdeflate to version ${{ steps.check-version.outputs.tag }}
|
||||
|
||||
Compare: https://github.com/ebiggers/libdeflate/compare/${{ steps.check-version.outputs.current }}...${{ steps.check-version.outputs.latest }}
|
||||
|
||||
Auto-updated by [this workflow](https://github.com/oven-sh/bun/actions/workflows/update-libdeflate.yml)
|
||||
|
||||
2
.github/workflows/update-lolhtml.yml
vendored
2
.github/workflows/update-lolhtml.yml
vendored
@@ -89,4 +89,6 @@ jobs:
|
||||
|
||||
Updates lolhtml to version ${{ steps.check-version.outputs.tag }}
|
||||
|
||||
Compare: https://github.com/cloudflare/lol-html/compare/${{ steps.check-version.outputs.current }}...${{ steps.check-version.outputs.latest }}
|
||||
|
||||
Auto-updated by [this workflow](https://github.com/oven-sh/bun/actions/workflows/update-lolhtml.yml)
|
||||
|
||||
2
.github/workflows/update-lshpack.yml
vendored
2
.github/workflows/update-lshpack.yml
vendored
@@ -89,4 +89,6 @@ jobs:
|
||||
|
||||
Updates lshpack to version ${{ steps.check-version.outputs.tag }}
|
||||
|
||||
Compare: https://github.com/litespeedtech/ls-hpack/compare/${{ steps.check-version.outputs.current }}...${{ steps.check-version.outputs.latest }}
|
||||
|
||||
Auto-updated by [this workflow](https://github.com/oven-sh/bun/actions/workflows/update-lshpack.yml)
|
||||
|
||||
82
.github/workflows/update-root-certs.yml
vendored
Normal file
82
.github/workflows/update-root-certs.yml
vendored
Normal file
@@ -0,0 +1,82 @@
|
||||
name: Daily Root Certs Update Check
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: "0 0 * * *" # Runs at 00:00 UTC every day
|
||||
workflow_dispatch: # Allows manual trigger
|
||||
|
||||
jobs:
|
||||
check-and-update:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: write
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Bun
|
||||
uses: oven-sh/setup-bun@v1
|
||||
with:
|
||||
bun-version: latest
|
||||
|
||||
- name: Generate root certs and capture output
|
||||
id: generate-certs
|
||||
run: |
|
||||
cd packages/bun-usockets/
|
||||
OUTPUT=$(bun generate-root-certs.mjs -v)
|
||||
echo "cert_output<<EOF" >> $GITHUB_ENV
|
||||
echo "$OUTPUT" >> $GITHUB_ENV
|
||||
echo "EOF" >> $GITHUB_ENV
|
||||
|
||||
- name: Check for changes and stage files
|
||||
id: check-changes
|
||||
run: |
|
||||
if [[ -n "$(git status --porcelain)" ]]; then
|
||||
echo "Found changes, staging modified files..."
|
||||
git config --global user.name "github-actions[bot]"
|
||||
git config --global user.email "github-actions[bot]@users.noreply.github.com"
|
||||
|
||||
# Get list of modified files and add them
|
||||
git status --porcelain | while read -r status file; do
|
||||
# Remove leading status and whitespace
|
||||
file=$(echo "$file" | sed 's/^.* //')
|
||||
echo "Adding changed file: $file"
|
||||
git add "$file"
|
||||
done
|
||||
|
||||
echo "changes=true" >> $GITHUB_OUTPUT
|
||||
|
||||
# Store the list of changed files
|
||||
CHANGED_FILES=$(git status --porcelain)
|
||||
echo "changed_files<<EOF" >> $GITHUB_ENV
|
||||
echo "$CHANGED_FILES" >> $GITHUB_ENV
|
||||
echo "EOF" >> $GITHUB_ENV
|
||||
else
|
||||
echo "No changes detected"
|
||||
echo "changes=false" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
|
||||
- name: Create Pull Request
|
||||
if: steps.check-changes.outputs.changes == 'true'
|
||||
uses: peter-evans/create-pull-request@v5
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
commit-message: "update(root_certs): Update root certificates $(date +'%Y-%m-%d')"
|
||||
title: "update(root_certs) $(date +'%Y-%m-%d')"
|
||||
body: |
|
||||
Automated root certificates update
|
||||
|
||||
${{ env.cert_output }}
|
||||
|
||||
## Changed Files:
|
||||
```
|
||||
${{ env.changed_files }}
|
||||
```
|
||||
branch: certs/update-root-certs-${{ github.run_number }}
|
||||
base: main
|
||||
delete-branch: true
|
||||
labels:
|
||||
- "automation"
|
||||
- "root-certs"
|
||||
2
.github/workflows/update-sqlite3.yml
vendored
2
.github/workflows/update-sqlite3.yml
vendored
@@ -106,4 +106,6 @@ jobs:
|
||||
|
||||
Updates SQLite to version ${{ steps.check-version.outputs.latest }}
|
||||
|
||||
Compare: https://sqlite.org/src/vdiff?from=${{ steps.check-version.outputs.current }}&to=${{ steps.check-version.outputs.latest }}
|
||||
|
||||
Auto-updated by [this workflow](https://github.com/oven-sh/bun/actions/workflows/update-sqlite3.yml)
|
||||
|
||||
18
.lldbinit
18
.lldbinit
@@ -1,4 +1,16 @@
|
||||
# command script import vendor/zig/tools/lldb_pretty_printers.py
|
||||
command script import vendor/WebKit/Tools/lldb/lldb_webkit.py
|
||||
# Tell LLDB what to do when the debugged process receives SIGPWR: pass it through to the process
|
||||
# (-p), but do not stop the process (-s) or notify the user (-n).
|
||||
#
|
||||
# JSC's garbage collector sends this signal (as configured by Bun WebKit in
|
||||
# Thread::initializePlatformThreading() in ThreadingPOSIX.cpp) to the JS thread to suspend or resume
|
||||
# it. So stopping the process would just create noise when debugging any long-running script.
|
||||
process handle -p true -s false -n false SIGPWR
|
||||
|
||||
# type summary add --summary-string "${var} | inner=${var[0-30]}, source=${var[33-64]}, tag=${var[31-32]}" "unsigned long"
|
||||
command script import misctools/lldb/lldb_pretty_printers.py
|
||||
type category enable zig.lang
|
||||
type category enable zig.std
|
||||
|
||||
command script import misctools/lldb/lldb_webkit.py
|
||||
|
||||
command script delete btjs
|
||||
command alias btjs p {printf("gathering btjs trace...\n");printf("%s\n", (char*)dumpBtjsTrace())}
|
||||
47
.vscode/launch.json
generated
vendored
47
.vscode/launch.json
generated
vendored
@@ -22,7 +22,6 @@
|
||||
},
|
||||
"console": "internalConsole",
|
||||
// Don't pause when the GC runs while the debugger is open.
|
||||
"postRunCommands": ["command source '${workspaceFolder}/misctools/lldb/lldb_commands'"],
|
||||
},
|
||||
{
|
||||
"type": "lldb",
|
||||
@@ -38,7 +37,6 @@
|
||||
},
|
||||
"console": "internalConsole",
|
||||
// Don't pause when the GC runs while the debugger is open.
|
||||
"postRunCommands": ["command source '${workspaceFolder}/misctools/lldb/lldb_commands'"],
|
||||
},
|
||||
{
|
||||
"type": "lldb",
|
||||
@@ -60,7 +58,6 @@
|
||||
},
|
||||
"console": "internalConsole",
|
||||
// Don't pause when the GC runs while the debugger is open.
|
||||
"postRunCommands": ["command source '${workspaceFolder}/misctools/lldb/lldb_commands'"],
|
||||
},
|
||||
{
|
||||
"type": "lldb",
|
||||
@@ -76,7 +73,6 @@
|
||||
},
|
||||
"console": "internalConsole",
|
||||
// Don't pause when the GC runs while the debugger is open.
|
||||
"postRunCommands": ["command source '${workspaceFolder}/misctools/lldb/lldb_commands'"],
|
||||
},
|
||||
{
|
||||
"type": "lldb",
|
||||
@@ -92,7 +88,6 @@
|
||||
},
|
||||
"console": "internalConsole",
|
||||
// Don't pause when the GC runs while the debugger is open.
|
||||
"postRunCommands": ["command source '${workspaceFolder}/misctools/lldb/lldb_commands'"],
|
||||
},
|
||||
{
|
||||
"type": "lldb",
|
||||
@@ -108,7 +103,6 @@
|
||||
},
|
||||
"console": "internalConsole",
|
||||
// Don't pause when the GC runs while the debugger is open.
|
||||
"postRunCommands": ["command source '${workspaceFolder}/misctools/lldb/lldb_commands'"],
|
||||
},
|
||||
{
|
||||
"type": "lldb",
|
||||
@@ -125,7 +119,6 @@
|
||||
},
|
||||
"console": "internalConsole",
|
||||
// Don't pause when the GC runs while the debugger is open.
|
||||
"postRunCommands": ["command source '${workspaceFolder}/misctools/lldb/lldb_commands'"],
|
||||
"serverReadyAction": {
|
||||
"pattern": "https://debug.bun.sh/#localhost:([0-9]+)/",
|
||||
"uriFormat": "https://debug.bun.sh/#ws://localhost:%s/",
|
||||
@@ -147,7 +140,6 @@
|
||||
},
|
||||
"console": "internalConsole",
|
||||
// Don't pause when the GC runs while the debugger is open.
|
||||
"postRunCommands": ["command source '${workspaceFolder}/misctools/lldb/lldb_commands'"],
|
||||
"serverReadyAction": {
|
||||
"pattern": "https://debug.bun.sh/#localhost:([0-9]+)/",
|
||||
"uriFormat": "https://debug.bun.sh/#ws://localhost:%s/",
|
||||
@@ -169,7 +161,6 @@
|
||||
},
|
||||
"console": "internalConsole",
|
||||
// Don't pause when the GC runs while the debugger is open.
|
||||
"postRunCommands": ["command source '${workspaceFolder}/misctools/lldb/lldb_commands'"],
|
||||
},
|
||||
{
|
||||
"type": "lldb",
|
||||
@@ -188,7 +179,6 @@
|
||||
},
|
||||
"console": "internalConsole",
|
||||
// Don't pause when the GC runs while the debugger is open.
|
||||
"postRunCommands": ["command source '${workspaceFolder}/misctools/lldb/lldb_commands'"],
|
||||
},
|
||||
{
|
||||
"type": "lldb",
|
||||
@@ -203,7 +193,6 @@
|
||||
},
|
||||
"console": "internalConsole",
|
||||
// Don't pause when the GC runs while the debugger is open.
|
||||
"postRunCommands": ["command source '${workspaceFolder}/misctools/lldb/lldb_commands'"],
|
||||
},
|
||||
{
|
||||
"type": "lldb",
|
||||
@@ -221,7 +210,6 @@
|
||||
},
|
||||
"console": "internalConsole",
|
||||
// Don't pause when the GC runs while the debugger is open.
|
||||
"postRunCommands": ["command source '${workspaceFolder}/misctools/lldb/lldb_commands'"],
|
||||
},
|
||||
{
|
||||
"type": "lldb",
|
||||
@@ -236,7 +224,6 @@
|
||||
},
|
||||
"console": "internalConsole",
|
||||
// Don't pause when the GC runs while the debugger is open.
|
||||
"postRunCommands": ["command source '${workspaceFolder}/misctools/lldb/lldb_commands'"],
|
||||
},
|
||||
{
|
||||
"type": "lldb",
|
||||
@@ -253,7 +240,6 @@
|
||||
},
|
||||
"console": "internalConsole",
|
||||
// Don't pause when the GC runs while the debugger is open.
|
||||
"postRunCommands": ["command source '${workspaceFolder}/misctools/lldb/lldb_commands'"],
|
||||
"serverReadyAction": {
|
||||
"pattern": "https://debug.bun.sh/#localhost:([0-9]+)/",
|
||||
"uriFormat": "https://debug.bun.sh/#ws://localhost:%s/",
|
||||
@@ -275,7 +261,6 @@
|
||||
},
|
||||
"console": "internalConsole",
|
||||
// Don't pause when the GC runs while the debugger is open.
|
||||
"postRunCommands": ["command source '${workspaceFolder}/misctools/lldb/lldb_commands'"],
|
||||
"serverReadyAction": {
|
||||
"pattern": "https://debug.bun.sh/#localhost:([0-9]+)/",
|
||||
"uriFormat": "https://debug.bun.sh/#ws://localhost:%s/",
|
||||
@@ -297,7 +282,6 @@
|
||||
},
|
||||
"console": "internalConsole",
|
||||
// Don't pause when the GC runs while the debugger is open.
|
||||
"postRunCommands": ["command source '${workspaceFolder}/misctools/lldb/lldb_commands'"],
|
||||
},
|
||||
{
|
||||
"type": "lldb",
|
||||
@@ -313,7 +297,6 @@
|
||||
},
|
||||
"console": "internalConsole",
|
||||
// Don't pause when the GC runs while the debugger is open.
|
||||
"postRunCommands": ["command source '${workspaceFolder}/misctools/lldb/lldb_commands'"],
|
||||
},
|
||||
{
|
||||
"type": "lldb",
|
||||
@@ -329,7 +312,6 @@
|
||||
},
|
||||
"console": "internalConsole",
|
||||
// Don't pause when the GC runs while the debugger is open.
|
||||
"postRunCommands": ["command source '${workspaceFolder}/misctools/lldb/lldb_commands'"],
|
||||
},
|
||||
{
|
||||
"type": "lldb",
|
||||
@@ -345,7 +327,6 @@
|
||||
},
|
||||
"console": "internalConsole",
|
||||
// Don't pause when the GC runs while the debugger is open.
|
||||
"postRunCommands": ["command source '${workspaceFolder}/misctools/lldb/lldb_commands'"],
|
||||
},
|
||||
{
|
||||
"type": "lldb",
|
||||
@@ -361,7 +342,6 @@
|
||||
},
|
||||
"console": "internalConsole",
|
||||
// Don't pause when the GC runs while the debugger is open.
|
||||
"postRunCommands": ["command source '${workspaceFolder}/misctools/lldb/lldb_commands'"],
|
||||
},
|
||||
{
|
||||
"type": "lldb",
|
||||
@@ -378,7 +358,6 @@
|
||||
},
|
||||
"console": "internalConsole",
|
||||
// Don't pause when the GC runs while the debugger is open.
|
||||
"postRunCommands": ["command source '${workspaceFolder}/misctools/lldb/lldb_commands'"],
|
||||
"serverReadyAction": {
|
||||
"pattern": "https://debug.bun.sh/#localhost:([0-9]+)/",
|
||||
"uriFormat": "https://debug.bun.sh/#ws://localhost:%s/",
|
||||
@@ -400,7 +379,6 @@
|
||||
},
|
||||
"console": "internalConsole",
|
||||
// Don't pause when the GC runs while the debugger is open.
|
||||
"postRunCommands": ["command source '${workspaceFolder}/misctools/lldb/lldb_commands'"],
|
||||
"serverReadyAction": {
|
||||
"pattern": "https://debug.bun.sh/#localhost:([0-9]+)/",
|
||||
"uriFormat": "https://debug.bun.sh/#ws://localhost:%s/",
|
||||
@@ -421,7 +399,6 @@
|
||||
},
|
||||
"console": "internalConsole",
|
||||
// Don't pause when the GC runs while the debugger is open.
|
||||
"postRunCommands": ["command source '${workspaceFolder}/misctools/lldb/lldb_commands'"],
|
||||
},
|
||||
// bun test [*]
|
||||
{
|
||||
@@ -437,7 +414,6 @@
|
||||
},
|
||||
"console": "internalConsole",
|
||||
// Don't pause when the GC runs while the debugger is open.
|
||||
"postRunCommands": ["command source '${workspaceFolder}/misctools/lldb/lldb_commands'"],
|
||||
},
|
||||
{
|
||||
"type": "lldb",
|
||||
@@ -452,7 +428,6 @@
|
||||
},
|
||||
"console": "internalConsole",
|
||||
// Don't pause when the GC runs while the debugger is open.
|
||||
"postRunCommands": ["command source '${workspaceFolder}/misctools/lldb/lldb_commands'"],
|
||||
},
|
||||
{
|
||||
"type": "lldb",
|
||||
@@ -468,7 +443,6 @@
|
||||
},
|
||||
"console": "internalConsole",
|
||||
// Don't pause when the GC runs while the debugger is open.
|
||||
"postRunCommands": ["command source '${workspaceFolder}/misctools/lldb/lldb_commands'"],
|
||||
"serverReadyAction": {
|
||||
"pattern": "https://debug.bun.sh/#localhost:([0-9]+)/",
|
||||
"uriFormat": "https://debug.bun.sh/#ws://localhost:%s/",
|
||||
@@ -488,7 +462,6 @@
|
||||
},
|
||||
"console": "internalConsole",
|
||||
// Don't pause when the GC runs while the debugger is open.
|
||||
"postRunCommands": ["command source '${workspaceFolder}/misctools/lldb/lldb_commands'"],
|
||||
},
|
||||
{
|
||||
"type": "lldb",
|
||||
@@ -503,7 +476,6 @@
|
||||
},
|
||||
"console": "internalConsole",
|
||||
// Don't pause when the GC runs while the debugger is open.
|
||||
"postRunCommands": ["command source '${workspaceFolder}/misctools/lldb/lldb_commands'"],
|
||||
},
|
||||
// Windows: bun test [file]
|
||||
{
|
||||
@@ -1129,7 +1101,24 @@
|
||||
],
|
||||
"console": "internalConsole",
|
||||
// Don't pause when the GC runs while the debugger is open.
|
||||
"postRunCommands": ["command source '${workspaceFolder}/misctools/lldb/lldb_commands'"],
|
||||
},
|
||||
{
|
||||
"type": "bun",
|
||||
"name": "[JS] bun test [file]",
|
||||
"runtime": "${workspaceFolder}/build/debug/bun-debug",
|
||||
"runtimeArgs": ["test", "${file}"],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"env": {
|
||||
"BUN_DEBUG_QUIET_LOGS": "1",
|
||||
"BUN_GARBAGE_COLLECTOR_LEVEL": "2",
|
||||
},
|
||||
},
|
||||
{
|
||||
"type": "midas-rr",
|
||||
"request": "attach",
|
||||
"name": "rr",
|
||||
"trace": "Off",
|
||||
"setupCommands": ["handle SIGPWR nostop noprint pass"],
|
||||
},
|
||||
],
|
||||
"inputs": [
|
||||
|
||||
@@ -80,7 +80,7 @@ $ sudo zypper install clang18 lld18 llvm18
|
||||
|
||||
{% /codetabs %}
|
||||
|
||||
If none of the above solutions apply, you will have to install it [manually](https://github.com/llvm/llvm-project/releases/tag/llvmorg-18.1.8).
|
||||
If none of the above solutions apply, you will have to install it [manually](https://github.com/llvm/llvm-project/releases/tag/llvmorg-19.1.7).
|
||||
|
||||
Make sure Clang/LLVM 18 is in your path:
|
||||
|
||||
@@ -205,18 +205,30 @@ WebKit is not cloned by default (to save time and disk space). To clone and buil
|
||||
# Clone WebKit into ./vendor/WebKit
|
||||
$ git clone https://github.com/oven-sh/WebKit vendor/WebKit
|
||||
|
||||
# Check out the commit hash specified in `set(WEBKIT_VERSION <commit_hash>)` in cmake/tools/SetupWebKit.cmake
|
||||
$ git -C vendor/WebKit checkout <commit_hash>
|
||||
|
||||
# Make a debug build of JSC. This will output build artifacts in ./vendor/WebKit/WebKitBuild/Debug
|
||||
# Optionally, you can use `make jsc` for a release build
|
||||
$ make jsc-debug
|
||||
$ make jsc-debug && rm vendor/WebKit/WebKitBuild/Debug/JavaScriptCore/DerivedSources/inspector/InspectorProtocolObjects.h
|
||||
|
||||
# Build bun with the local JSC build
|
||||
$ bun run build:local
|
||||
```
|
||||
|
||||
Using `bun run build:local` will build Bun in the `./build/debug-local` directory (instead of `./build/debug`), you'll have to change a couple of places to use this new directory:
|
||||
|
||||
- The first line in [`src/js/builtins.d.ts`](/src/js/builtins.d.ts)
|
||||
- The `CompilationDatabase` line in [`.clangd` config](/.clangd) should be `CompilationDatabase: build/debug-local`
|
||||
- In [`build.zig`](/build.zig), the `codegen_path` option should be `build/debug-local/codegen` (instead of `build/debug/codegen`)
|
||||
- In [`.vscode/launch.json`](/.vscode/launch.json), many configurations use `./build/debug/`, change them as you see fit
|
||||
|
||||
Note that the WebKit folder, including build artifacts, is 8GB+ in size.
|
||||
|
||||
If you are using a JSC debug build and using VScode, make sure to run the `C/C++: Select a Configuration` command to configure intellisense to find the debug headers.
|
||||
|
||||
Note that if you change make changes to our [WebKit fork](https://github.com/oven-sh/WebKit), you will also have to change [`SetupWebKit.cmake`](/cmake/tools/SetupWebKit.cmake) to point to the commit hash.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### 'span' file not found on Ubuntu
|
||||
|
||||
22
Makefile
22
Makefile
@@ -91,9 +91,9 @@ ZIG ?= $(shell which zig 2>/dev/null || echo -e "error: Missing zig. Please make
|
||||
# This is easier to happen than you'd expect.
|
||||
# Using realpath here causes issues because clang uses clang++ as a symlink
|
||||
# so if that's resolved, it won't build for C++
|
||||
REAL_CC = $(shell which clang-18 2>/dev/null || which clang 2>/dev/null)
|
||||
REAL_CXX = $(shell which clang++-18 2>/dev/null || which clang++ 2>/dev/null)
|
||||
CLANG_FORMAT = $(shell which clang-format-18 2>/dev/null || which clang-format 2>/dev/null)
|
||||
REAL_CC = $(shell which clang-19 2>/dev/null || which clang 2>/dev/null)
|
||||
REAL_CXX = $(shell which clang++-19 2>/dev/null || which clang++ 2>/dev/null)
|
||||
CLANG_FORMAT = $(shell which clang-format-19 2>/dev/null || which clang-format 2>/dev/null)
|
||||
|
||||
CC = $(REAL_CC)
|
||||
CXX = $(REAL_CXX)
|
||||
@@ -117,14 +117,14 @@ CC_WITH_CCACHE = $(CCACHE_PATH) $(CC)
|
||||
ifeq ($(OS_NAME),darwin)
|
||||
# Find LLVM
|
||||
ifeq ($(wildcard $(LLVM_PREFIX)),)
|
||||
LLVM_PREFIX = $(shell brew --prefix llvm@18)
|
||||
LLVM_PREFIX = $(shell brew --prefix llvm@19)
|
||||
endif
|
||||
ifeq ($(wildcard $(LLVM_PREFIX)),)
|
||||
LLVM_PREFIX = $(shell brew --prefix llvm)
|
||||
endif
|
||||
ifeq ($(wildcard $(LLVM_PREFIX)),)
|
||||
# This is kinda ugly, but I can't find a better way to error :(
|
||||
LLVM_PREFIX = $(shell echo -e "error: Unable to find llvm. Please run 'brew install llvm@18' or set LLVM_PREFIX=/path/to/llvm")
|
||||
LLVM_PREFIX = $(shell echo -e "error: Unable to find llvm. Please run 'brew install llvm@19' or set LLVM_PREFIX=/path/to/llvm")
|
||||
endif
|
||||
|
||||
LDFLAGS += -L$(LLVM_PREFIX)/lib
|
||||
@@ -164,7 +164,7 @@ CMAKE_FLAGS_WITHOUT_RELEASE = -DCMAKE_C_COMPILER=$(CC) \
|
||||
-DCMAKE_OSX_DEPLOYMENT_TARGET=$(MIN_MACOS_VERSION) \
|
||||
$(CMAKE_CXX_COMPILER_LAUNCHER_FLAG) \
|
||||
-DCMAKE_AR=$(AR) \
|
||||
-DCMAKE_RANLIB=$(which llvm-18-ranlib 2>/dev/null || which llvm-ranlib 2>/dev/null) \
|
||||
-DCMAKE_RANLIB=$(which llvm-19-ranlib 2>/dev/null || which llvm-ranlib 2>/dev/null) \
|
||||
-DCMAKE_CXX_STANDARD=20 \
|
||||
-DCMAKE_C_STANDARD=17 \
|
||||
-DCMAKE_CXX_STANDARD_REQUIRED=ON \
|
||||
@@ -191,7 +191,7 @@ endif
|
||||
|
||||
ifeq ($(OS_NAME),linux)
|
||||
LIBICONV_PATH =
|
||||
AR = $(shell which llvm-ar-18 2>/dev/null || which llvm-ar 2>/dev/null || which ar 2>/dev/null)
|
||||
AR = $(shell which llvm-ar-19 2>/dev/null || which llvm-ar 2>/dev/null || which ar 2>/dev/null)
|
||||
endif
|
||||
|
||||
OPTIMIZATION_LEVEL=-O3 $(MARCH_NATIVE)
|
||||
@@ -255,7 +255,7 @@ DEFAULT_LINKER_FLAGS= -pthread -ldl
|
||||
endif
|
||||
ifeq ($(OS_NAME),darwin)
|
||||
_MIMALLOC_OBJECT_FILE = 0
|
||||
JSC_BUILD_STEPS += jsc-build-mac jsc-copy-headers
|
||||
JSC_BUILD_STEPS += jsc-build-mac
|
||||
JSC_BUILD_STEPS_DEBUG += jsc-build-mac-debug
|
||||
_MIMALLOC_FILE = libmimalloc.a
|
||||
_MIMALLOC_INPUT_PATH = libmimalloc.a
|
||||
@@ -286,7 +286,7 @@ STRIP=/usr/bin/strip
|
||||
endif
|
||||
|
||||
ifeq ($(OS_NAME),linux)
|
||||
STRIP=$(shell which llvm-strip 2>/dev/null || which llvm-strip-18 2>/dev/null || which strip 2>/dev/null || echo "Missing strip")
|
||||
STRIP=$(shell which llvm-strip 2>/dev/null || which llvm-strip-19 2>/dev/null || which strip 2>/dev/null || echo "Missing strip")
|
||||
endif
|
||||
|
||||
|
||||
@@ -674,7 +674,7 @@ endif
|
||||
.PHONY: assert-deps
|
||||
assert-deps:
|
||||
@echo "Checking if the required utilities are available..."
|
||||
@if [ $(CLANG_VERSION) -lt "18" ]; then echo -e "ERROR: clang version >=18 required, found: $(CLANG_VERSION). Install with:\n\n $(POSIX_PKG_MANAGER) install llvm@18"; exit 1; fi
|
||||
@if [ $(CLANG_VERSION) -lt "19" ]; then echo -e "ERROR: clang version >=19 required, found: $(CLANG_VERSION). Install with:\n\n $(POSIX_PKG_MANAGER) install llvm@19"; exit 1; fi
|
||||
@cmake --version >/dev/null 2>&1 || (echo -e "ERROR: cmake is required."; exit 1)
|
||||
@$(PYTHON) --version >/dev/null 2>&1 || (echo -e "ERROR: python is required."; exit 1)
|
||||
@$(ESBUILD) --version >/dev/null 2>&1 || (echo -e "ERROR: esbuild is required."; exit 1)
|
||||
@@ -924,7 +924,7 @@ bun-codesign-release-local-debug:
|
||||
|
||||
|
||||
.PHONY: jsc
|
||||
jsc: jsc-build jsc-copy-headers jsc-bindings
|
||||
jsc: jsc-build
|
||||
.PHONY: jsc-debug
|
||||
jsc-debug: jsc-build-debug
|
||||
.PHONY: jsc-build
|
||||
|
||||
53
bench/crypto/diffie-hellman.mjs
Normal file
53
bench/crypto/diffie-hellman.mjs
Normal file
@@ -0,0 +1,53 @@
|
||||
import crypto from "node:crypto";
|
||||
import { bench, run } from "../runner.mjs";
|
||||
|
||||
// Pre-generate DH params to avoid including setup in benchmarks
|
||||
const dhSize = 1024; // Reduced from 2048 for faster testing
|
||||
const dh = crypto.createDiffieHellman(dhSize);
|
||||
const dhPrime = dh.getPrime();
|
||||
const dhGenerator = dh.getGenerator();
|
||||
|
||||
// Classical Diffie-Hellman
|
||||
bench("DH - generateKeys", () => {
|
||||
const alice = crypto.createDiffieHellman(dhPrime, dhGenerator);
|
||||
return alice.generateKeys();
|
||||
});
|
||||
|
||||
bench("DH - computeSecret", () => {
|
||||
// Setup
|
||||
const alice = crypto.createDiffieHellman(dhPrime, dhGenerator);
|
||||
const aliceKey = alice.generateKeys();
|
||||
const bob = crypto.createDiffieHellman(dhPrime, dhGenerator);
|
||||
const bobKey = bob.generateKeys();
|
||||
|
||||
// Benchmark just the secret computation
|
||||
return alice.computeSecret(bobKey);
|
||||
});
|
||||
|
||||
// ECDH with prime256v1 (P-256)
|
||||
bench("ECDH-P256 - generateKeys", () => {
|
||||
const ecdh = crypto.createECDH("prime256v1");
|
||||
return ecdh.generateKeys();
|
||||
});
|
||||
|
||||
bench("ECDH-P256 - computeSecret", () => {
|
||||
// Setup
|
||||
const alice = crypto.createECDH("prime256v1");
|
||||
const aliceKey = alice.generateKeys();
|
||||
const bob = crypto.createECDH("prime256v1");
|
||||
const bobKey = bob.generateKeys();
|
||||
|
||||
// Benchmark just the secret computation
|
||||
return alice.computeSecret(bobKey);
|
||||
});
|
||||
|
||||
// ECDH with secp384r1 (P-384)
|
||||
bench("ECDH-P384 - computeSecret", () => {
|
||||
const alice = crypto.createECDH("secp384r1");
|
||||
const aliceKey = alice.generateKeys();
|
||||
const bob = crypto.createECDH("secp384r1");
|
||||
const bobKey = bob.generateKeys();
|
||||
return alice.computeSecret(bobKey);
|
||||
});
|
||||
|
||||
await run();
|
||||
44
bench/crypto/ecdh-convert-key.mjs
Normal file
44
bench/crypto/ecdh-convert-key.mjs
Normal file
@@ -0,0 +1,44 @@
|
||||
import crypto from "node:crypto";
|
||||
import { bench, run } from "../runner.mjs";
|
||||
|
||||
function generateTestKeyPairs() {
|
||||
const curves = crypto.getCurves();
|
||||
const keys = {};
|
||||
|
||||
for (const curve of curves) {
|
||||
const ecdh = crypto.createECDH(curve);
|
||||
ecdh.generateKeys();
|
||||
|
||||
keys[curve] = {
|
||||
compressed: ecdh.getPublicKey("hex", "compressed"),
|
||||
uncompressed: ecdh.getPublicKey("hex", "uncompressed"),
|
||||
instance: ecdh,
|
||||
};
|
||||
}
|
||||
|
||||
return keys;
|
||||
}
|
||||
|
||||
const testKeys = generateTestKeyPairs();
|
||||
|
||||
bench("ECDH key format - P256 compressed to uncompressed", () => {
|
||||
const publicKey = testKeys["prime256v1"].compressed;
|
||||
return crypto.ECDH.convertKey(publicKey, "prime256v1", "hex", "hex", "uncompressed");
|
||||
});
|
||||
|
||||
bench("ECDH key format - P256 uncompressed to compressed", () => {
|
||||
const publicKey = testKeys["prime256v1"].uncompressed;
|
||||
return crypto.ECDH.convertKey(publicKey, "prime256v1", "hex", "hex", "compressed");
|
||||
});
|
||||
|
||||
bench("ECDH key format - P384 compressed to uncompressed", () => {
|
||||
const publicKey = testKeys["secp384r1"].compressed;
|
||||
return crypto.ECDH.convertKey(publicKey, "secp384r1", "hex", "hex", "uncompressed");
|
||||
});
|
||||
|
||||
bench("ECDH key format - P384 uncompressed to compressed", () => {
|
||||
const publicKey = testKeys["secp384r1"].uncompressed;
|
||||
return crypto.ECDH.convertKey(publicKey, "secp384r1", "hex", "hex", "compressed");
|
||||
});
|
||||
|
||||
await run();
|
||||
50
bench/crypto/hkdf.mjs
Normal file
50
bench/crypto/hkdf.mjs
Normal file
@@ -0,0 +1,50 @@
|
||||
import crypto from "node:crypto";
|
||||
import { bench, run } from "../runner.mjs";
|
||||
|
||||
// Sample keys with different lengths
|
||||
const keys = {
|
||||
short: "secret",
|
||||
long: "this-is-a-much-longer-secret-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
|
||||
};
|
||||
|
||||
// Test parameters
|
||||
const salts = ["", "salt"];
|
||||
const infos = ["", "info"];
|
||||
const hashes = ["sha256", "sha512"];
|
||||
const sizes = [10, 1024];
|
||||
|
||||
// Benchmark sync HKDF
|
||||
for (const hash of hashes) {
|
||||
for (const keyName of Object.keys(keys)) {
|
||||
const key = keys[keyName];
|
||||
for (const size of sizes) {
|
||||
bench(`hkdfSync ${hash} ${keyName}-key ${size} bytes`, () => {
|
||||
return crypto.hkdfSync(hash, key, "salt", "info", size);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Benchmark different combinations of salt and info
|
||||
for (const salt of salts) {
|
||||
for (const info of infos) {
|
||||
bench(`hkdfSync sha256 with ${salt ? "salt" : "no-salt"} and ${info ? "info" : "no-info"}`, () => {
|
||||
return crypto.hkdfSync("sha256", "secret", salt, info, 64);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Benchmark async HKDF (using promises for cleaner benchmark)
|
||||
// Note: async benchmarks in Mitata require returning a Promise
|
||||
for (const hash of hashes) {
|
||||
bench(`hkdf ${hash} async`, async () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
crypto.hkdf(hash, "secret", "salt", "info", 64, (err, derivedKey) => {
|
||||
if (err) reject(err);
|
||||
else resolve(derivedKey);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
await run();
|
||||
43
bench/crypto/primes.mjs
Normal file
43
bench/crypto/primes.mjs
Normal file
@@ -0,0 +1,43 @@
|
||||
import { checkPrime, checkPrimeSync, generatePrime, generatePrimeSync } from "node:crypto";
|
||||
import { bench, run } from "../runner.mjs";
|
||||
|
||||
const prime512 = generatePrimeSync(512);
|
||||
const prime2048 = generatePrimeSync(2048);
|
||||
|
||||
bench("checkPrimeSync 512", () => {
|
||||
return checkPrimeSync(prime512);
|
||||
});
|
||||
|
||||
bench("checkPrimeSync 2048", () => {
|
||||
return checkPrimeSync(prime2048);
|
||||
});
|
||||
|
||||
bench("checkPrime 512", async () => {
|
||||
const promises = Array.from({ length: 10 }, () => new Promise(resolve => checkPrime(prime512, resolve)));
|
||||
await Promise.all(promises);
|
||||
});
|
||||
|
||||
bench("checkPrime 2048", async () => {
|
||||
const promises = Array.from({ length: 10 }, () => new Promise(resolve => checkPrime(prime2048, resolve)));
|
||||
await Promise.all(promises);
|
||||
});
|
||||
|
||||
bench("generatePrimeSync 512", () => {
|
||||
return generatePrimeSync(512);
|
||||
});
|
||||
|
||||
bench("generatePrimeSync 2048", () => {
|
||||
return generatePrimeSync(2048);
|
||||
});
|
||||
|
||||
bench("generatePrime 512", async () => {
|
||||
const promises = Array.from({ length: 10 }, () => new Promise(resolve => generatePrime(512, resolve)));
|
||||
await Promise.all(promises);
|
||||
});
|
||||
|
||||
bench("generatePrime 2048", async () => {
|
||||
const promises = Array.from({ length: 10 }, () => new Promise(resolve => generatePrime(2048, resolve)));
|
||||
await Promise.all(promises);
|
||||
});
|
||||
|
||||
await run();
|
||||
50
bench/crypto/random.mjs
Normal file
50
bench/crypto/random.mjs
Normal file
@@ -0,0 +1,50 @@
|
||||
import crypto from "crypto";
|
||||
import { bench, run } from "../runner.mjs";
|
||||
|
||||
bench("randomInt - sync", () => {
|
||||
crypto.randomInt(1000);
|
||||
});
|
||||
|
||||
bench("randomInt - async", async () => {
|
||||
const { promise, resolve } = Promise.withResolvers();
|
||||
crypto.randomInt(1000, () => {
|
||||
resolve();
|
||||
});
|
||||
await promise;
|
||||
});
|
||||
|
||||
bench("randonBytes - 32", () => {
|
||||
crypto.randomBytes(32);
|
||||
});
|
||||
|
||||
bench("randomBytes - 256", () => {
|
||||
crypto.randomBytes(256);
|
||||
});
|
||||
|
||||
const buf = Buffer.alloc(256);
|
||||
|
||||
bench("randomFill - 32", async () => {
|
||||
const { promise, resolve } = Promise.withResolvers();
|
||||
crypto.randomFill(buf, 0, 32, () => {
|
||||
resolve();
|
||||
});
|
||||
await promise;
|
||||
});
|
||||
|
||||
bench("randomFill - 256", async () => {
|
||||
const { promise, resolve } = Promise.withResolvers();
|
||||
crypto.randomFill(buf, 0, 256, () => {
|
||||
resolve();
|
||||
});
|
||||
await promise;
|
||||
});
|
||||
|
||||
bench("randomFillSync - 32", () => {
|
||||
crypto.randomFillSync(buf, 0, 32);
|
||||
});
|
||||
|
||||
bench("randomFillSync - 256", () => {
|
||||
crypto.randomFillSync(buf, 0, 256);
|
||||
});
|
||||
|
||||
await run();
|
||||
@@ -12,6 +12,7 @@
|
||||
"eventemitter3": "^5.0.0",
|
||||
"execa": "^8.0.1",
|
||||
"fast-glob": "3.3.1",
|
||||
"fastify": "^5.0.0",
|
||||
"fdir": "^6.1.0",
|
||||
"mitata": "^1.0.25",
|
||||
"react": "^18.3.1",
|
||||
|
||||
13
bench/snippets/express-hello.mjs
Normal file
13
bench/snippets/express-hello.mjs
Normal file
@@ -0,0 +1,13 @@
|
||||
import express from "express";
|
||||
|
||||
const app = express();
|
||||
const port = 3000;
|
||||
|
||||
var i = 0;
|
||||
app.get("/", (req, res) => {
|
||||
res.send("Hello World!" + i++);
|
||||
});
|
||||
|
||||
app.listen(port, () => {
|
||||
console.log(`Express app listening at http://localhost:${port}`);
|
||||
});
|
||||
20
bench/snippets/fastify.mjs
Normal file
20
bench/snippets/fastify.mjs
Normal file
@@ -0,0 +1,20 @@
|
||||
import Fastify from "fastify";
|
||||
|
||||
const fastify = Fastify({
|
||||
logger: false,
|
||||
});
|
||||
|
||||
fastify.get("/", async (request, reply) => {
|
||||
return { hello: "world" };
|
||||
});
|
||||
|
||||
const start = async () => {
|
||||
try {
|
||||
await fastify.listen({ port: 3000 });
|
||||
} catch (err) {
|
||||
fastify.log.error(err);
|
||||
process.exit(1);
|
||||
}
|
||||
};
|
||||
|
||||
start();
|
||||
37
build.zig
37
build.zig
@@ -19,17 +19,17 @@ const OperatingSystem = @import("src/env.zig").OperatingSystem;
|
||||
const pathRel = fs.path.relative;
|
||||
|
||||
/// Do not rename this constant. It is scanned by some scripts to determine which zig version to install.
|
||||
const recommended_zig_version = "0.14.0-dev.2987+183bb8b08";
|
||||
const recommended_zig_version = "0.14.0";
|
||||
|
||||
comptime {
|
||||
if (!std.mem.eql(u8, builtin.zig_version_string, recommended_zig_version)) {
|
||||
@compileError(
|
||||
"" ++
|
||||
"Bun requires Zig version " ++ recommended_zig_version ++ " (found " ++
|
||||
builtin.zig_version_string ++ "). This is " ++
|
||||
"automatically configured via Bun's CMake setup. You likely meant to run " ++
|
||||
"`bun setup`. If you are trying to upgrade the Zig compiler, " ++
|
||||
"run `./scripts/download-zig.sh master` or comment this message out.",
|
||||
"Bun requires Zig version " ++ recommended_zig_version ++ ", but you have " ++
|
||||
builtin.zig_version_string ++ ". This is automatically configured via Bun's " ++
|
||||
"CMake setup. You likely meant to run `bun run build`. If you are trying to " ++
|
||||
"upgrade the Zig compiler, edit ZIG_COMMIT in cmake/tools/SetupZig.cmake or " ++
|
||||
"comment this error out.",
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -319,7 +319,21 @@ pub fn build(b: *Build) !void {
|
||||
.{ .os = .linux, .arch = .aarch64 },
|
||||
.{ .os = .linux, .arch = .x86_64, .musl = true },
|
||||
.{ .os = .linux, .arch = .aarch64, .musl = true },
|
||||
});
|
||||
}, &.{ .Debug, .ReleaseFast });
|
||||
}
|
||||
|
||||
// zig build check-all-debug
|
||||
{
|
||||
const step = b.step("check-all-debug", "Check for semantic analysis errors on all supported platforms in debug mode");
|
||||
addMultiCheck(b, step, build_options, &.{
|
||||
.{ .os = .windows, .arch = .x86_64 },
|
||||
.{ .os = .mac, .arch = .x86_64 },
|
||||
.{ .os = .mac, .arch = .aarch64 },
|
||||
.{ .os = .linux, .arch = .x86_64 },
|
||||
.{ .os = .linux, .arch = .aarch64 },
|
||||
.{ .os = .linux, .arch = .x86_64, .musl = true },
|
||||
.{ .os = .linux, .arch = .aarch64, .musl = true },
|
||||
}, &.{.Debug});
|
||||
}
|
||||
|
||||
// zig build check-windows
|
||||
@@ -327,21 +341,21 @@ pub fn build(b: *Build) !void {
|
||||
const step = b.step("check-windows", "Check for semantic analysis errors on Windows");
|
||||
addMultiCheck(b, step, build_options, &.{
|
||||
.{ .os = .windows, .arch = .x86_64 },
|
||||
});
|
||||
}, &.{ .Debug, .ReleaseFast });
|
||||
}
|
||||
{
|
||||
const step = b.step("check-macos", "Check for semantic analysis errors on Windows");
|
||||
addMultiCheck(b, step, build_options, &.{
|
||||
.{ .os = .mac, .arch = .x86_64 },
|
||||
.{ .os = .mac, .arch = .aarch64 },
|
||||
});
|
||||
}, &.{ .Debug, .ReleaseFast });
|
||||
}
|
||||
{
|
||||
const step = b.step("check-linux", "Check for semantic analysis errors on Windows");
|
||||
addMultiCheck(b, step, build_options, &.{
|
||||
.{ .os = .linux, .arch = .x86_64 },
|
||||
.{ .os = .linux, .arch = .aarch64 },
|
||||
});
|
||||
}, &.{ .Debug, .ReleaseFast });
|
||||
}
|
||||
|
||||
// zig build translate-c-headers
|
||||
@@ -369,9 +383,10 @@ pub fn addMultiCheck(
|
||||
parent_step: *Step,
|
||||
root_build_options: BunBuildOptions,
|
||||
to_check: []const struct { os: OperatingSystem, arch: Arch, musl: bool = false },
|
||||
optimize: []const std.builtin.OptimizeMode,
|
||||
) void {
|
||||
for (to_check) |check| {
|
||||
for ([_]std.builtin.Mode{ .Debug, .ReleaseFast }) |mode| {
|
||||
for (optimize) |mode| {
|
||||
const check_target = b.resolveTargetQuery(.{
|
||||
.os_tag = OperatingSystem.stdOSTag(check.os),
|
||||
.cpu_arch = check.arch,
|
||||
|
||||
@@ -2,3 +2,7 @@
|
||||
# https://github.com/oven-sh/bun/issues/16289
|
||||
[test]
|
||||
preload = ["./test/js/node/harness.ts", "./test/preload.ts"]
|
||||
|
||||
[install]
|
||||
# Node.js never auto-installs modules.
|
||||
auto = "disable"
|
||||
|
||||
@@ -419,7 +419,15 @@ function(register_command)
|
||||
list(APPEND CMD_EFFECTIVE_OUTPUTS ${artifact})
|
||||
if(BUILDKITE)
|
||||
file(RELATIVE_PATH filename ${BUILD_PATH} ${artifact})
|
||||
list(APPEND CMD_COMMANDS COMMAND ${CMAKE_COMMAND} -E chdir ${BUILD_PATH} buildkite-agent artifact upload ${filename})
|
||||
if(filename STREQUAL "libbun-profile.a")
|
||||
# libbun-profile.a is now over 5gb in size, compress it first
|
||||
list(APPEND CMD_COMMANDS COMMAND ${CMAKE_COMMAND} -E chdir ${BUILD_PATH} rm -r ${BUILD_PATH}/codegen)
|
||||
list(APPEND CMD_COMMANDS COMMAND ${CMAKE_COMMAND} -E chdir ${BUILD_PATH} rm -r ${CACHE_PATH})
|
||||
list(APPEND CMD_COMMANDS COMMAND ${CMAKE_COMMAND} -E chdir ${BUILD_PATH} gzip -6 libbun-profile.a)
|
||||
list(APPEND CMD_COMMANDS COMMAND ${CMAKE_COMMAND} -E chdir ${BUILD_PATH} buildkite-agent artifact upload libbun-profile.a.gz)
|
||||
else()
|
||||
list(APPEND CMD_COMMANDS COMMAND ${CMAKE_COMMAND} -E chdir ${BUILD_PATH} buildkite-agent artifact upload ${filename})
|
||||
endif()
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
|
||||
@@ -738,7 +738,7 @@ endif()
|
||||
# --- C/C++ Properties ---
|
||||
|
||||
set_target_properties(${bun} PROPERTIES
|
||||
CXX_STANDARD 20
|
||||
CXX_STANDARD 23
|
||||
CXX_STANDARD_REQUIRED YES
|
||||
CXX_EXTENSIONS YES
|
||||
CXX_VISIBILITY_PRESET hidden
|
||||
@@ -747,6 +747,18 @@ set_target_properties(${bun} PROPERTIES
|
||||
VISIBILITY_INLINES_HIDDEN YES
|
||||
)
|
||||
|
||||
if (NOT WIN32)
|
||||
# Enable precompiled headers
|
||||
# Only enable in these scenarios:
|
||||
# 1. NOT in CI, OR
|
||||
# 2. In CI AND BUN_CPP_ONLY is enabled
|
||||
if(NOT CI OR (CI AND BUN_CPP_ONLY))
|
||||
target_precompile_headers(${bun} PRIVATE
|
||||
"$<$<COMPILE_LANGUAGE:CXX>:${CWD}/src/bun.js/bindings/root.h>"
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# --- C/C++ Includes ---
|
||||
|
||||
if(WIN32)
|
||||
@@ -901,6 +913,10 @@ if(NOT WIN32)
|
||||
-Werror
|
||||
)
|
||||
endif()
|
||||
else()
|
||||
target_compile_options(${bun} PUBLIC
|
||||
-Wno-nullability-completeness
|
||||
)
|
||||
endif()
|
||||
|
||||
# --- Linker options ---
|
||||
@@ -943,28 +959,17 @@ endif()
|
||||
|
||||
if(LINUX)
|
||||
if(NOT ABI STREQUAL "musl")
|
||||
# on arm64
|
||||
if(CMAKE_SYSTEM_PROCESSOR MATCHES "arm|ARM|arm64|ARM64|aarch64|AARCH64")
|
||||
target_link_options(${bun} PUBLIC
|
||||
-Wl,--wrap=exp
|
||||
-Wl,--wrap=expf
|
||||
-Wl,--wrap=fcntl64
|
||||
-Wl,--wrap=log
|
||||
-Wl,--wrap=log2
|
||||
-Wl,--wrap=log2f
|
||||
-Wl,--wrap=logf
|
||||
-Wl,--wrap=pow
|
||||
-Wl,--wrap=powf
|
||||
)
|
||||
else()
|
||||
target_link_options(${bun} PUBLIC
|
||||
-Wl,--wrap=exp
|
||||
-Wl,--wrap=expf
|
||||
-Wl,--wrap=log2f
|
||||
-Wl,--wrap=logf
|
||||
-Wl,--wrap=powf
|
||||
)
|
||||
endif()
|
||||
target_link_options(${bun} PUBLIC
|
||||
-Wl,--wrap=exp
|
||||
-Wl,--wrap=expf
|
||||
-Wl,--wrap=fcntl64
|
||||
-Wl,--wrap=log
|
||||
-Wl,--wrap=log2
|
||||
-Wl,--wrap=log2f
|
||||
-Wl,--wrap=logf
|
||||
-Wl,--wrap=pow
|
||||
-Wl,--wrap=powf
|
||||
)
|
||||
endif()
|
||||
|
||||
if(NOT ABI STREQUAL "musl")
|
||||
|
||||
@@ -4,7 +4,7 @@ register_repository(
|
||||
REPOSITORY
|
||||
cloudflare/lol-html
|
||||
COMMIT
|
||||
4f8becea13a0021c8b71abd2dcc5899384973b66
|
||||
67f1d4ffd6b74db7e053fb129dcce620193c180d
|
||||
)
|
||||
|
||||
set(LOLHTML_CWD ${VENDOR_PATH}/lolhtml/c-api)
|
||||
|
||||
@@ -120,6 +120,9 @@ foreach(i RANGE ${BUILDKITE_JOBS_MAX_INDEX})
|
||||
endif()
|
||||
|
||||
if(BUILDKITE)
|
||||
if(BUILDKITE_ARTIFACT_PATH STREQUAL "libbun-profile.a")
|
||||
set(BUILDKITE_ARTIFACT_PATH libbun-profile.a.gz)
|
||||
endif()
|
||||
set(BUILDKITE_DOWNLOAD_COMMAND buildkite-agent artifact download ${BUILDKITE_ARTIFACT_PATH} . --build ${BUILDKITE_BUILD_UUID} --step ${BUILDKITE_JOB_ID})
|
||||
else()
|
||||
set(BUILDKITE_DOWNLOAD_COMMAND curl -L -o ${BUILDKITE_ARTIFACT_PATH} ${BUILDKITE_ARTIFACTS_URL}/${BUILDKITE_ARTIFACT_ID})
|
||||
@@ -135,6 +138,20 @@ foreach(i RANGE ${BUILDKITE_JOBS_MAX_INDEX})
|
||||
OUTPUT
|
||||
${BUILD_PATH}/${BUILDKITE_ARTIFACT_PATH}
|
||||
)
|
||||
if(BUILDKITE_ARTIFACT_PATH STREQUAL "libbun-profile.a.gz")
|
||||
add_custom_command(
|
||||
COMMENT
|
||||
"Unpacking libbun-profile.a.gz"
|
||||
VERBATIM COMMAND
|
||||
gunzip libbun-profile.a.gz
|
||||
WORKING_DIRECTORY
|
||||
${BUILD_PATH}
|
||||
OUTPUT
|
||||
${BUILD_PATH}/libbun-profile.a
|
||||
DEPENDS
|
||||
${BUILD_PATH}/libbun-profile.a.gz
|
||||
)
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
list(APPEND BUILDKITE_JOBS_MATCH ${BUILDKITE_JOB_NAME})
|
||||
|
||||
@@ -36,7 +36,8 @@ endif()
|
||||
string(REPLACE "\n" ";" GIT_CHANGED_SOURCES "${GIT_DIFF}")
|
||||
|
||||
if(CI)
|
||||
setx(GIT_CHANGED_SOURCES ${GIT_CHANGED_SOURCES})
|
||||
set(GIT_CHANGED_SOURCES "${GIT_CHANGED_SOURCES}")
|
||||
message(STATUS "Set GIT_CHANGED_SOURCES: ${GIT_CHANGED_SOURCES}")
|
||||
endif()
|
||||
|
||||
list(TRANSFORM GIT_CHANGED_SOURCES PREPEND ${CWD}/)
|
||||
|
||||
@@ -12,7 +12,7 @@ if(NOT ENABLE_LLVM)
|
||||
return()
|
||||
endif()
|
||||
|
||||
set(DEFAULT_LLVM_VERSION "18.1.8")
|
||||
set(DEFAULT_LLVM_VERSION "19.1.7")
|
||||
|
||||
optionx(LLVM_VERSION STRING "The version of LLVM to use" DEFAULT ${DEFAULT_LLVM_VERSION})
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ option(WEBKIT_VERSION "The version of WebKit to use")
|
||||
option(WEBKIT_LOCAL "If a local version of WebKit should be used instead of downloading")
|
||||
|
||||
if(NOT WEBKIT_VERSION)
|
||||
set(WEBKIT_VERSION 0d7d28b5907f628331d4a944c3436856447fbf64)
|
||||
set(WEBKIT_VERSION 91bf2baced1b1309c7e05f19177c97fefec20976)
|
||||
endif()
|
||||
|
||||
string(SUBSTRING ${WEBKIT_VERSION} 0 16 WEBKIT_VERSION_PREFIX)
|
||||
|
||||
@@ -20,7 +20,7 @@ else()
|
||||
unsupported(CMAKE_SYSTEM_NAME)
|
||||
endif()
|
||||
|
||||
set(ZIG_COMMIT "bb9d6ab2c0bbbf20cc24dad03e88f3b3ffdb7de7")
|
||||
set(ZIG_COMMIT "cd1995944508e4c946deb75bd70947d302e0db37")
|
||||
optionx(ZIG_TARGET STRING "The zig target to use" DEFAULT ${DEFAULT_ZIG_TARGET})
|
||||
|
||||
if(CMAKE_BUILD_TYPE STREQUAL "Release")
|
||||
|
||||
@@ -12,5 +12,3 @@ Alternatively, use `process.dlopen`:
|
||||
let mod = { exports: {} };
|
||||
process.dlopen(mod, "./my-node-module.node");
|
||||
```
|
||||
|
||||
Bun polyfills the [`detect-libc`](https://npmjs.com/package/detect-libc) package, which is used by many Node-API modules to detect which `.node` binding to `require`.
|
||||
|
||||
@@ -715,7 +715,7 @@ await S3Client.delete("my-file.txt", credentials);
|
||||
await S3Client.unlink("my-file.txt", credentials);
|
||||
```
|
||||
|
||||
## s3:// protocol
|
||||
## `s3://` protocol
|
||||
|
||||
To make it easier to use the same code for local files and S3 files, the `s3://` protocol is supported in `fetch` and `Bun.file()`.
|
||||
|
||||
|
||||
@@ -77,6 +77,16 @@ console.log(text); // "const input = "hello world".repeat(400); ..."
|
||||
|
||||
---
|
||||
|
||||
- `ReadableStream`
|
||||
- Use a readable stream as input.
|
||||
|
||||
---
|
||||
|
||||
- `Blob`
|
||||
- Use a blob as input.
|
||||
|
||||
---
|
||||
|
||||
- `number`
|
||||
- Read from the file with a given file descriptor.
|
||||
|
||||
@@ -129,13 +139,13 @@ Configure the output stream by passing one of the following values to `stdout/st
|
||||
|
||||
---
|
||||
|
||||
- `Bun.file()`
|
||||
- Write to the specified file.
|
||||
- `"ignore"`
|
||||
- Discard the output.
|
||||
|
||||
---
|
||||
|
||||
- `null`
|
||||
- Write to `/dev/null`.
|
||||
- `Bun.file()`
|
||||
- Write to the specified file.
|
||||
|
||||
---
|
||||
|
||||
@@ -174,7 +184,8 @@ const proc = Bun.spawn(["bun", "--version"]);
|
||||
proc.kill();
|
||||
proc.killed; // true
|
||||
|
||||
proc.kill(); // specify an exit code
|
||||
proc.kill(15); // specify a signal code
|
||||
proc.kill("SIGTERM"); // specify a signal name
|
||||
```
|
||||
|
||||
The parent `bun` process will not terminate until all child processes have exited. Use `proc.unref()` to detach the child process from the parent.
|
||||
@@ -184,6 +195,64 @@ const proc = Bun.spawn(["bun", "--version"]);
|
||||
proc.unref();
|
||||
```
|
||||
|
||||
## Resource usage
|
||||
|
||||
You can get information about the process's resource usage after it has exited:
|
||||
|
||||
```ts
|
||||
const proc = Bun.spawn(["bun", "--version"]);
|
||||
await proc.exited;
|
||||
|
||||
const usage = proc.resourceUsage();
|
||||
console.log(`Max memory used: ${usage.maxRSS} bytes`);
|
||||
console.log(`CPU time (user): ${usage.cpuTime.user} µs`);
|
||||
console.log(`CPU time (system): ${usage.cpuTime.system} µs`);
|
||||
```
|
||||
|
||||
## Using AbortSignal
|
||||
|
||||
You can abort a subprocess using an `AbortSignal`:
|
||||
|
||||
```ts
|
||||
const controller = new AbortController();
|
||||
const { signal } = controller;
|
||||
|
||||
const proc = Bun.spawn({
|
||||
cmd: ["sleep", "100"],
|
||||
signal,
|
||||
});
|
||||
|
||||
// Later, to abort the process:
|
||||
controller.abort();
|
||||
```
|
||||
|
||||
## Using timeout and killSignal
|
||||
|
||||
You can set a timeout for a subprocess to automatically terminate after a specific duration:
|
||||
|
||||
```ts
|
||||
// Kill the process after 5 seconds
|
||||
const proc = Bun.spawn({
|
||||
cmd: ["sleep", "10"],
|
||||
timeout: 5000, // 5 seconds in milliseconds
|
||||
});
|
||||
|
||||
await proc.exited; // Will resolve after 5 seconds
|
||||
```
|
||||
|
||||
By default, timed-out processes are killed with the `SIGTERM` signal. You can specify a different signal with the `killSignal` option:
|
||||
|
||||
```ts
|
||||
// Kill the process with SIGKILL after 5 seconds
|
||||
const proc = Bun.spawn({
|
||||
cmd: ["sleep", "10"],
|
||||
timeout: 5000,
|
||||
killSignal: "SIGKILL", // Can be string name or signal number
|
||||
});
|
||||
```
|
||||
|
||||
The `killSignal` option also controls which signal is sent when an AbortSignal is aborted.
|
||||
|
||||
## Inter-process communication (IPC)
|
||||
|
||||
Bun supports direct inter-process communication channel between two `bun` processes. To receive messages from a spawned Bun subprocess, specify an `ipc` handler.
|
||||
@@ -233,11 +302,17 @@ process.send("Hello from child as string");
|
||||
process.send({ message: "Hello from child as object" });
|
||||
```
|
||||
|
||||
The `ipcMode` option controls the underlying communication format between the two processes:
|
||||
The `serialization` option controls the underlying communication format between the two processes:
|
||||
|
||||
- `advanced`: (default) Messages are serialized using the JSC `serialize` API, which supports cloning [everything `structuredClone` supports](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm). This does not support transferring ownership of objects.
|
||||
- `json`: Messages are serialized using `JSON.stringify` and `JSON.parse`, which does not support as many object types as `advanced` does.
|
||||
|
||||
To disconnect the IPC channel from the parent process, call:
|
||||
|
||||
```ts
|
||||
childProc.disconnect();
|
||||
```
|
||||
|
||||
### IPC between Bun & Node.js
|
||||
|
||||
To use IPC between a `bun` process and a Node.js process, set `serialization: "json"` in `Bun.spawn`. This is because Node.js and Bun use different JavaScript engines with different object serialization formats.
|
||||
@@ -310,7 +385,7 @@ spawnSync echo hi 1.47 ms/iter (1.14 ms … 2.64 ms) 1.57 ms 2.37 ms
|
||||
|
||||
## Reference
|
||||
|
||||
A simple reference of the Spawn API and types are shown below. The real types have complex generics to strongly type the `Subprocess` streams with the options passed to `Bun.spawn` and `Bun.spawnSync`. For full details, find these types as defined [bun.d.ts](https://github.com/oven-sh/bun/blob/main/packages/bun-types/bun.d.ts).
|
||||
A reference of the Spawn API and types are shown below. The real types have complex generics to strongly type the `Subprocess` streams with the options passed to `Bun.spawn` and `Bun.spawnSync`. For full details, find these types as defined [bun.d.ts](https://github.com/oven-sh/bun/blob/main/packages/bun-types/bun.d.ts).
|
||||
|
||||
```ts
|
||||
interface Bun {
|
||||
@@ -329,16 +404,25 @@ interface Bun {
|
||||
namespace SpawnOptions {
|
||||
interface OptionsObject {
|
||||
cwd?: string;
|
||||
env?: Record<string, string>;
|
||||
stdin?: SpawnOptions.Readable;
|
||||
stdout?: SpawnOptions.Writable;
|
||||
stderr?: SpawnOptions.Writable;
|
||||
onExit?: (
|
||||
proc: Subprocess,
|
||||
env?: Record<string, string | undefined>;
|
||||
stdio?: [Writable, Readable, Readable];
|
||||
stdin?: Writable;
|
||||
stdout?: Readable;
|
||||
stderr?: Readable;
|
||||
onExit?(
|
||||
subprocess: Subprocess,
|
||||
exitCode: number | null,
|
||||
signalCode: string | null,
|
||||
error: Error | null,
|
||||
) => void;
|
||||
signalCode: number | null,
|
||||
error?: ErrorLike,
|
||||
): void | Promise<void>;
|
||||
ipc?(message: any, subprocess: Subprocess): void;
|
||||
serialization?: "json" | "advanced";
|
||||
windowsHide?: boolean;
|
||||
windowsVerbatimArguments?: boolean;
|
||||
argv0?: string;
|
||||
signal?: AbortSignal;
|
||||
timeout?: number;
|
||||
killSignal?: string | number;
|
||||
}
|
||||
|
||||
type Readable =
|
||||
@@ -366,39 +450,62 @@ namespace SpawnOptions {
|
||||
| Request;
|
||||
}
|
||||
|
||||
interface Subprocess<Stdin, Stdout, Stderr> {
|
||||
interface Subprocess extends AsyncDisposable {
|
||||
readonly stdin: FileSink | number | undefined;
|
||||
readonly stdout: ReadableStream<Uint8Array> | number | undefined;
|
||||
readonly stderr: ReadableStream<Uint8Array> | number | undefined;
|
||||
readonly readable: ReadableStream<Uint8Array> | number | undefined;
|
||||
readonly pid: number;
|
||||
// the exact stream types here are derived from the generic parameters
|
||||
readonly stdin: number | ReadableStream | FileSink | undefined;
|
||||
readonly stdout: number | ReadableStream | undefined;
|
||||
readonly stderr: number | ReadableStream | undefined;
|
||||
|
||||
readonly exited: Promise<number>;
|
||||
|
||||
readonly exitCode: number | undefined;
|
||||
readonly signalCode: Signal | null;
|
||||
readonly exitCode: number | null;
|
||||
readonly signalCode: NodeJS.Signals | null;
|
||||
readonly killed: boolean;
|
||||
|
||||
kill(exitCode?: number | NodeJS.Signals): void;
|
||||
ref(): void;
|
||||
unref(): void;
|
||||
kill(code?: number): void;
|
||||
|
||||
send(message: any): void;
|
||||
disconnect(): void;
|
||||
resourceUsage(): ResourceUsage | undefined;
|
||||
}
|
||||
|
||||
interface SyncSubprocess<Stdout, Stderr> {
|
||||
readonly pid: number;
|
||||
readonly success: boolean;
|
||||
// the exact buffer types here are derived from the generic parameters
|
||||
readonly stdout: Buffer | undefined;
|
||||
readonly stderr: Buffer | undefined;
|
||||
interface SyncSubprocess {
|
||||
stdout: Buffer | undefined;
|
||||
stderr: Buffer | undefined;
|
||||
exitCode: number;
|
||||
success: boolean;
|
||||
resourceUsage: ResourceUsage;
|
||||
signalCode?: string;
|
||||
exitedDueToTimeout?: true;
|
||||
pid: number;
|
||||
}
|
||||
|
||||
type ReadableSubprocess = Subprocess<any, "pipe", "pipe">;
|
||||
type WritableSubprocess = Subprocess<"pipe", any, any>;
|
||||
type PipedSubprocess = Subprocess<"pipe", "pipe", "pipe">;
|
||||
type NullSubprocess = Subprocess<null, null, null>;
|
||||
interface ResourceUsage {
|
||||
contextSwitches: {
|
||||
voluntary: number;
|
||||
involuntary: number;
|
||||
};
|
||||
|
||||
type ReadableSyncSubprocess = SyncSubprocess<"pipe", "pipe">;
|
||||
type NullSyncSubprocess = SyncSubprocess<null, null>;
|
||||
cpuTime: {
|
||||
user: number;
|
||||
system: number;
|
||||
total: number;
|
||||
};
|
||||
maxRSS: number;
|
||||
|
||||
messages: {
|
||||
sent: number;
|
||||
received: number;
|
||||
};
|
||||
ops: {
|
||||
in: number;
|
||||
out: number;
|
||||
};
|
||||
shmSize: number;
|
||||
signalCount: number;
|
||||
swapCount: number;
|
||||
}
|
||||
|
||||
type Signal =
|
||||
| "SIGABRT"
|
||||
|
||||
@@ -11,7 +11,7 @@ Bun.listen({
|
||||
socket: {
|
||||
data(socket, data) {}, // message received from client
|
||||
open(socket) {}, // socket opened
|
||||
close(socket) {}, // socket closed
|
||||
close(socket, error) {}, // socket closed
|
||||
drain(socket) {}, // socket ready for more data
|
||||
error(socket, error) {}, // error handler
|
||||
},
|
||||
@@ -30,7 +30,7 @@ Bun.listen({
|
||||
open(socket) {},
|
||||
data(socket, data) {},
|
||||
drain(socket) {},
|
||||
close(socket) {},
|
||||
close(socket, error) {},
|
||||
error(socket, error) {},
|
||||
},
|
||||
});
|
||||
@@ -122,7 +122,7 @@ const socket = await Bun.connect({
|
||||
socket: {
|
||||
data(socket, data) {},
|
||||
open(socket) {},
|
||||
close(socket) {},
|
||||
close(socket, error) {},
|
||||
drain(socket) {},
|
||||
error(socket, error) {},
|
||||
|
||||
|
||||
1028
docs/bundler/css.md
Normal file
1028
docs/bundler/css.md
Normal file
File diff suppressed because it is too large
Load Diff
145
docs/bundler/css_modules.md
Normal file
145
docs/bundler/css_modules.md
Normal file
@@ -0,0 +1,145 @@
|
||||
# CSS Modules
|
||||
|
||||
Bun's bundler also supports bundling [CSS modules](https://css-tricks.com/css-modules-part-1-need/) in addition to [regular CSS](/docs/bundler/css) with support for the following features:
|
||||
|
||||
- Automatically detecting CSS module files (`.module.css`) with zero configuration
|
||||
- Composition (`composes` property)
|
||||
- Importing CSS modules into JSX/TSX
|
||||
- Warnings/errors for invalid usages of CSS modules
|
||||
|
||||
A CSS module is a CSS file (with the `.module.css` extension) where are all class names and animations are scoped to the file. This helps you avoid class name collisions as CSS declarations are globally scoped by default.
|
||||
|
||||
Under the hood, Bun's bundler transforms locally scoped class names into unique identifiers.
|
||||
|
||||
## Getting started
|
||||
|
||||
Create a CSS file with the `.module.css` extension:
|
||||
|
||||
```css
|
||||
/* styles.module.css */
|
||||
.button {
|
||||
color: red;
|
||||
}
|
||||
|
||||
/* other-styles.module.css */
|
||||
.button {
|
||||
color: blue;
|
||||
}
|
||||
```
|
||||
|
||||
You can then import this file, for example into a TSX file:
|
||||
|
||||
```tsx
|
||||
import styles from "./styles.module.css";
|
||||
import otherStyles from "./other-styles.module.css";
|
||||
|
||||
export default function App() {
|
||||
return (
|
||||
<>
|
||||
<button className={styles.button}>Red button!</button>
|
||||
<button className={otherStyles.button}>Blue button!</button>
|
||||
</>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
The `styles` object from importing the CSS module file will be an object with all class names as keys and
|
||||
their unique identifiers as values:
|
||||
|
||||
```tsx
|
||||
import styles from "./styles.module.css";
|
||||
import otherStyles from "./other-styles.module.css";
|
||||
|
||||
console.log(styles);
|
||||
console.log(otherStyles);
|
||||
```
|
||||
|
||||
This will output:
|
||||
|
||||
```ts
|
||||
{
|
||||
button: "button_123";
|
||||
}
|
||||
|
||||
{
|
||||
button: "button_456";
|
||||
}
|
||||
```
|
||||
|
||||
As you can see, the class names are unique to each file, avoiding any collisions!
|
||||
|
||||
### Composition
|
||||
|
||||
CSS modules allow you to _compose_ class selectors together. This lets you reuse style rules across multiple classes.
|
||||
|
||||
For example:
|
||||
|
||||
```css
|
||||
/* styles.module.css */
|
||||
.button {
|
||||
composes: background;
|
||||
color: red;
|
||||
}
|
||||
|
||||
.background {
|
||||
background-color: blue;
|
||||
}
|
||||
```
|
||||
|
||||
Would be the same as writing:
|
||||
|
||||
```css
|
||||
.button {
|
||||
background-color: blue;
|
||||
color: red;
|
||||
}
|
||||
|
||||
.background {
|
||||
background-color: blue;
|
||||
}
|
||||
```
|
||||
|
||||
{% callout %}
|
||||
There are a couple rules to keep in mind when using `composes`:
|
||||
|
||||
- A `composes` property must come before any regular CSS properties or declarations
|
||||
- You can only use `composes` on a **simple selector with a single class name**:
|
||||
|
||||
```css
|
||||
#button {
|
||||
/* Invalid! `#button` is not a class selector */
|
||||
composes: background;
|
||||
}
|
||||
|
||||
.button,
|
||||
.button-secondary {
|
||||
/* Invalid! `.button, .button-secondary` is not a simple selector */
|
||||
composes: background;
|
||||
}
|
||||
```
|
||||
|
||||
{% /callout %}
|
||||
|
||||
### Composing from a separate CSS module file
|
||||
|
||||
You can also compose from a separate CSS module file:
|
||||
|
||||
```css
|
||||
/* background.module.css */
|
||||
.background {
|
||||
background-color: blue;
|
||||
}
|
||||
|
||||
/* styles.module.css */
|
||||
.button {
|
||||
composes: background from "./background.module.css";
|
||||
color: red;
|
||||
}
|
||||
```
|
||||
|
||||
{% callout %}
|
||||
When composing classes from separate files, be sure that they do not contain the same properties.
|
||||
|
||||
The CSS module spec says that composing classes from separate files with conflicting properties is
|
||||
undefined behavior, meaning that the output may differ and be unreliable.
|
||||
{% /callout %}
|
||||
@@ -309,5 +309,4 @@ This works similarly to how [`Bun.build` processes HTML files](/docs/bundler/htm
|
||||
|
||||
## This is a work in progress
|
||||
|
||||
- ~Client-side hot reloading isn't wired up yet. It will be in the future.~ New in Bun v1.2.3
|
||||
- This doesn't support `bun build` yet. It also will in the future.
|
||||
|
||||
234
docs/bundler/hmr.md
Normal file
234
docs/bundler/hmr.md
Normal file
@@ -0,0 +1,234 @@
|
||||
Hot Module Replacement (HMR) allows you to update modules in a running
|
||||
application without needing a full page reload. This preserves the application
|
||||
state and improves the development experience.
|
||||
|
||||
HMR is enabled by default when using Bun's full-stack development server.
|
||||
|
||||
## `import.meta.hot` API Reference
|
||||
|
||||
Bun implements a client-side HMR API modeled after [Vite's `import.meta.hot` API](https://vitejs.dev/guide/api-hmr.html). It can be checked for with `if (import.meta.hot)`, tree-shaking it in production
|
||||
|
||||
```ts
|
||||
if (import.meta.hot) {
|
||||
// HMR APIs are available.
|
||||
}
|
||||
```
|
||||
|
||||
However, **this check is often not needed** as Bun will dead-code-eliminate
|
||||
calls to all of the HMR APIs in production builds.
|
||||
|
||||
```ts
|
||||
// This entire function call will be removed in production!
|
||||
import.meta.hot.dispose(() => {
|
||||
console.log("dispose");
|
||||
});
|
||||
```
|
||||
|
||||
For this to work, Bun forces these APIs to be called without indirection. That means the following do not work:
|
||||
|
||||
```ts#invalid-hmr-usage.ts
|
||||
// INVALID: Assigning `hot` to a variable
|
||||
const hot = import.meta.hot;
|
||||
hot.accept();
|
||||
|
||||
// INVALID: Assigning `import.meta` to a variable
|
||||
const meta = import.meta;
|
||||
meta.hot.accept();
|
||||
console.log(meta.hot.data);
|
||||
|
||||
// INVALID: Passing to a function
|
||||
doSomething(import.meta.hot.dispose);
|
||||
|
||||
// OK: The full phrase "import.meta.hot.<API>" must be called directly:
|
||||
import.meta.hot.accept();
|
||||
|
||||
// OK: `data` can be passed to functions:
|
||||
doSomething(import.meta.hot.data);
|
||||
```
|
||||
|
||||
{% callout %}
|
||||
|
||||
**Note** — The HMR API is still a work in progress. Some features are missing. HMR can be disabled in `Bun.serve` by setting the `development` option to `{ hmr: false }`.
|
||||
|
||||
{% endcallout %}
|
||||
|
||||
| | Method | Notes |
|
||||
| --- | ------------------ | --------------------------------------------------------------------- |
|
||||
| ✅ | `hot.accept()` | Indicate that a hot update can be replaced gracefully. |
|
||||
| ✅ | `hot.data` | Persist data between module evaluations. |
|
||||
| ✅ | `hot.dispose()` | Add a callback function to run when a module is about to be replaced. |
|
||||
| ❌ | `hot.invalidate()` | |
|
||||
| ✅ | `hot.on()` | Attach an event listener |
|
||||
| ✅ | `hot.off()` | Remove an event listener from `on`. |
|
||||
| ❌ | `hot.send()` | |
|
||||
| 🚧 | `hot.prune()` | **NOTE**: Callback is currently never called. |
|
||||
| ✅ | `hot.decline()` | No-op to match Vite's `import.meta.hot` |
|
||||
|
||||
### `import.meta.hot.accept()`
|
||||
|
||||
The `accept()` method indicates that a module can be hot-replaced. When called
|
||||
without arguments, it indicates that this module can be replaced simply by
|
||||
re-evaluating the file. After a hot update, importers of this module will be
|
||||
automatically patched.
|
||||
|
||||
```ts#index.ts
|
||||
import { getCount } from "./foo.ts";
|
||||
|
||||
console.log("count is ", getCount());
|
||||
|
||||
import.meta.hot.accept();
|
||||
|
||||
export function getNegativeCount() {
|
||||
return -getCount();
|
||||
}
|
||||
```
|
||||
|
||||
This creates a hot-reloading boundary for all of the files that `index.ts`
|
||||
imports. That means whenever `foo.ts` or any of its dependencies are saved, the
|
||||
update will bubble up to `index.ts` will re-evaluate. Files that import
|
||||
`index.ts` will then be patched to import the new version of
|
||||
`getNegativeCount()`. If only `index.ts` is updated, only the one file will be
|
||||
re-evaluated, and the counter in `foo.ts` is reused.
|
||||
|
||||
This may be used in combination with `import.meta.hot.data` to transfer state
|
||||
from the previous module to the new one.
|
||||
|
||||
When no modules call `import.meta.hot.accept()` (and there isn't React Fast
|
||||
Refresh or a plugin calling it for you), the page will reload when the file
|
||||
updates, and a console warning shows which files were invalidated. This warning
|
||||
is safe to ignore if it makes more sense to rely on full page reloads.
|
||||
|
||||
#### With callback
|
||||
|
||||
When provided one callback, `import.meta.hot.accept` will function how it does
|
||||
in Vite. Instead of patching the importers of this module, it will call the
|
||||
callback with the new module.
|
||||
|
||||
```ts
|
||||
export const count = 0;
|
||||
|
||||
import.meta.hot.accept(newModule => {
|
||||
if (newModule) {
|
||||
// newModule is undefined when SyntaxError happened
|
||||
console.log("updated: count is now ", newModule.count);
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
Prefer using `import.meta.hot.accept()` without an argument as it usually makes your code easier to understand.
|
||||
|
||||
#### Accepting other modules
|
||||
|
||||
```ts
|
||||
import { count } from "./foo";
|
||||
|
||||
import.meta.hot.accept("./foo", () => {
|
||||
if (!newModule) return;
|
||||
|
||||
console.log("updated: count is now ", count);
|
||||
});
|
||||
```
|
||||
|
||||
Indicates that a dependency's module can be accepted. When the dependency is updated, the callback will be called with the new module.
|
||||
|
||||
#### With multiple dependencies
|
||||
|
||||
```ts
|
||||
import.meta.hot.accept(["./foo", "./bar"], newModules => {
|
||||
// newModules is an array where each item corresponds to the updated module
|
||||
// or undefined if that module had a syntax error
|
||||
});
|
||||
```
|
||||
|
||||
Indicates that multiple dependencies' modules can be accepted. This variant accepts an array of dependencies, where the callback will receive the updated modules, and `undefined` for any that had errors.
|
||||
|
||||
### `import.meta.hot.data`
|
||||
|
||||
`import.meta.hot.data` maintains state between module instances during hot
|
||||
replacement, enabling data transfer from previous to new versions. When
|
||||
`import.meta.hot.data` is written into, Bun will also mark this module as
|
||||
capable of self-accepting (equivalent of calling `import.meta.hot.accept()`).
|
||||
|
||||
```ts
|
||||
import { createRoot } from "react-dom/client";
|
||||
import { App } from "./app";
|
||||
|
||||
const root = import.meta.hot.data.root ??= createRoot(elem);
|
||||
root.render(<App />); // re-use an existing root
|
||||
```
|
||||
|
||||
In production, `data` is inlined to be `{}`, meaning it cannot be used as a state holder.
|
||||
|
||||
The above pattern is recommended for stateful modules because Bun knows it can minify `{}.prop ??= value` into `value` in production.
|
||||
|
||||
### `import.meta.hot.dispose()`
|
||||
|
||||
Attaches an on-dispose callback. This is called:
|
||||
|
||||
- Just before the module is replaced with another copy (before the next is loaded)
|
||||
- After the module is detached (removing all imports to this module, see `import.meta.hot.prune()`)
|
||||
|
||||
```ts
|
||||
const sideEffect = setupSideEffect();
|
||||
|
||||
import.meta.hot.dispose(() => {
|
||||
sideEffect.cleanup();
|
||||
});
|
||||
```
|
||||
|
||||
This callback is not called on route navigation or when the browser tab closes.
|
||||
|
||||
Returning a promise will delay module replacement until the module is disposed.
|
||||
All dispose callbacks are called in parallel.
|
||||
|
||||
### `import.meta.hot.prune()`
|
||||
|
||||
Attaches an on-prune callback. This is called when all imports to this module
|
||||
are removed, but the module was previously loaded.
|
||||
|
||||
This can be used to clean up resources that were created when the module was
|
||||
loaded. Unlike `import.meta.hot.dispose()`, this pairs much better with `accept`
|
||||
and `data` to manage stateful resources. A full example managing a `WebSocket`:
|
||||
|
||||
```ts
|
||||
import { something } from "./something";
|
||||
|
||||
// Initialize or re-use a WebSocket connection
|
||||
export const ws = (import.meta.hot.data.ws ??= new WebSocket(location.origin));
|
||||
|
||||
// If the module's import is removed, clean up the WebSocket connection.
|
||||
import.meta.hot.prune(() => {
|
||||
ws.close();
|
||||
});
|
||||
```
|
||||
|
||||
If `dispose` was used instead, the WebSocket would close and re-open on every
|
||||
hot update. Both versions of the code will prevent page reloads when imported
|
||||
files are updated.
|
||||
|
||||
### `import.meta.hot.on()` and `off()`
|
||||
|
||||
`on()` and `off()` are used to listen for events from the HMR runtime. Event names are prefixed with a prefix so that plugins do not conflict with each other.
|
||||
|
||||
```ts
|
||||
import.meta.hot.on("bun:beforeUpdate", () => {
|
||||
console.log("before a hot update");
|
||||
});
|
||||
```
|
||||
|
||||
When a file is replaced, all of its event listeners are automatically removed.
|
||||
|
||||
A list of all built-in events:
|
||||
|
||||
| Event | Emitted when |
|
||||
| ---------------------- | ----------------------------------------------------------------------------------------------- |
|
||||
| `bun:beforeUpdate` | before a hot update is applied. |
|
||||
| `bun:afterUpdate` | after a hot update is applied. |
|
||||
| `bun:beforeFullReload` | before a full page reload happens. |
|
||||
| `bun:beforePrune` | before prune callbacks are called. |
|
||||
| `bun:invalidate` | when a module is invalidated with `import.meta.hot.invalidate()` |
|
||||
| `bun:error` | when a build or runtime error occurs |
|
||||
| `bun:ws:disconnect` | when the HMR WebSocket connection is lost. This can indicate the development server is offline. |
|
||||
| `bun:ws:connect` | when the HMR WebSocket connects or re-connects. |
|
||||
|
||||
For compatibility with Vite, the above events are also available via `vite:*` prefix instead of `bun:*`.
|
||||
@@ -4,6 +4,12 @@ The Bun bundler implements a set of default loaders out of the box. As a rule of
|
||||
|
||||
Bun uses the file extension to determine which built-in _loader_ should be used to parse the file. Every loader has a name, such as `js`, `tsx`, or `json`. These names are used when building [plugins](https://bun.sh/docs/bundler/plugins) that extend Bun with custom loaders.
|
||||
|
||||
You can explicitly specify which loader to use using the 'loader' import attribute.
|
||||
|
||||
```ts
|
||||
import my_toml from "./my_file" with { loader: "toml" };
|
||||
```
|
||||
|
||||
## Built-in loaders
|
||||
|
||||
### `js`
|
||||
|
||||
@@ -82,6 +82,11 @@ The `--dry-run` flag can be used to simulate the publish process without actuall
|
||||
$ bun publish --dry-run
|
||||
```
|
||||
|
||||
### `--gzip-level`
|
||||
|
||||
Specify the level of gzip compression to use when packing the package. Only applies to `bun publish` without a tarball path argument. Values range from `0` to `9` (default is `9`).
|
||||
{% bunCLIUsage command="publish" /%}
|
||||
|
||||
### `--auth-type`
|
||||
|
||||
If you have 2FA enabled for your npm account, `bun publish` will prompt you for a one-time password. This can be done through a browser or the CLI. The `--auth-type` flag can be used to tell the npm registry which method you prefer. The possible values are `web` and `legacy`, with `web` being the default.
|
||||
@@ -102,7 +107,6 @@ Provide a one-time password directly to the CLI. If the password is valid, this
|
||||
$ bun publish --otp 123456
|
||||
```
|
||||
|
||||
### `--gzip-level`
|
||||
|
||||
Specify the level of gzip compression to use when packing the package. Only applies to `bun publish` without a tarball path argument. Values range from `0` to `9` (default is `9`).
|
||||
{% bunCLIUsage command="publish" /%}
|
||||
{% callout %}
|
||||
**Note** - `bun publish` respects the `NPM_CONFIG_TOKEN` environment variable which can be used when publishing in github actions or automated workflows.
|
||||
{% /callout %}
|
||||
|
||||
@@ -215,12 +215,19 @@ export default {
|
||||
page("bundler", "`Bun.build`", {
|
||||
description: "Bundle code for consumption in the browser with Bun's native bundler.",
|
||||
}),
|
||||
page("bundler/html", "Bundle frontend & static sites", {
|
||||
page("bundler/html", "HTML & static sites", {
|
||||
description: `Zero-config HTML bundler for single-page apps and multi-page apps. Automatic bundling, TailwindCSS plugins, TypeScript, JSX, React support, and incredibly fast builds`,
|
||||
}),
|
||||
page("bundler/css", "CSS", {
|
||||
description: `Production ready CSS bundler with support for modern CSS features, CSS modules, and more.`,
|
||||
}),
|
||||
page("bundler/fullstack", "Fullstack Dev Server", {
|
||||
description: "Serve your frontend and backend from the same app with Bun's dev server.",
|
||||
}),
|
||||
page("bundler/hmr", "Hot reloading", {
|
||||
description: `Update modules in a running application without reloading the page using import.meta.hot`,
|
||||
}),
|
||||
|
||||
page("bundler/loaders", "Loaders", {
|
||||
description: "Bun's built-in loaders for the bundler and runtime",
|
||||
}),
|
||||
|
||||
@@ -60,7 +60,7 @@ Visual Studio can be installed graphically using the wizard or through WinGet:
|
||||
|
||||
After Visual Studio, you need the following:
|
||||
|
||||
- LLVM 18.1.8
|
||||
- LLVM 19.1.7
|
||||
- Go
|
||||
- Rust
|
||||
- NASM
|
||||
@@ -81,7 +81,7 @@ After Visual Studio, you need the following:
|
||||
> irm https://get.scoop.sh | iex
|
||||
> scoop install nodejs-lts go rust nasm ruby perl ccache
|
||||
# scoop seems to be buggy if you install llvm and the rest at the same time
|
||||
> scoop install llvm@18.1.8
|
||||
> scoop install llvm@19.1.7
|
||||
```
|
||||
|
||||
{% /codetabs %}
|
||||
|
||||
@@ -174,7 +174,7 @@ Some methods are not optimized yet.
|
||||
|
||||
### [`node:test`](https://nodejs.org/api/test.html)
|
||||
|
||||
🔴 Not implemented. Use [`bun:test`](https://bun.sh/docs/cli/test) instead.
|
||||
🟡 Partly implemented. Missing mocks, snapshots, timers. Use [`bun:test`](https://bun.sh/docs/cli/test) instead.
|
||||
|
||||
### [`node:trace_events`](https://nodejs.org/api/tracing.html)
|
||||
|
||||
@@ -346,7 +346,7 @@ The table below lists all globals implemented by Node.js and Bun's current compa
|
||||
|
||||
### [`process`](https://nodejs.org/api/process.html)
|
||||
|
||||
🟡 Mostly implemented. `process.binding` (internal Node.js bindings some packages rely on) is partially implemented. `process.title` is a currently a no-op on macOS & Linux. `getActiveResourcesInfo` `setActiveResourcesInfo`, `getActiveResources` and `setSourceMapsEnabled` are stubs. Newer APIs like `process.loadEnvFile` and `process.getBuiltinModule` are not implemented yet.
|
||||
🟡 Mostly implemented. `process.binding` (internal Node.js bindings some packages rely on) is partially implemented. `process.title` is currently a no-op on macOS & Linux. `getActiveResourcesInfo` `setActiveResourcesInfo`, `getActiveResources` and `setSourceMapsEnabled` are stubs. Newer APIs like `process.loadEnvFile` and `process.getBuiltinModule` are not implemented yet.
|
||||
|
||||
### [`queueMicrotask()`](https://developer.mozilla.org/en-US/docs/Web/API/queueMicrotask)
|
||||
|
||||
|
||||
@@ -329,7 +329,7 @@ await Bun.build({
|
||||
|
||||
{% callout %}
|
||||
|
||||
**NOTE**: Plugin lifcycle callbacks (`onStart()`, `onResolve()`, etc.) do not have the ability to modify the `build.config` object in the `setup()` function. If you want to mutate `build.config`, you must do so directly in the `setup()` function:
|
||||
**NOTE**: Plugin lifecycle callbacks (`onStart()`, `onResolve()`, etc.) do not have the ability to modify the `build.config` object in the `setup()` function. If you want to mutate `build.config`, you must do so directly in the `setup()` function:
|
||||
|
||||
```ts
|
||||
await Bun.build({
|
||||
@@ -400,7 +400,7 @@ type Loader = "js" | "jsx" | "ts" | "tsx" | "css" | "json" | "toml" | "object";
|
||||
|
||||
### Namespaces
|
||||
|
||||
`onLoad` and `onResolve` accept an optional `namespace` string. What is a namespaace?
|
||||
`onLoad` and `onResolve` accept an optional `namespace` string. What is a namespace?
|
||||
|
||||
Every module has a namespace. Namespaces are used to prefix the import in transpiled code; for instance, a loader with a `filter: /\.yaml$/` and `namespace: "yaml:"` will transform an import from `./myfile.yaml` into `yaml:./myfile.yaml`.
|
||||
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
# Tell LLDB what to do when the debugged process receives SIGPWR: pass it through to the process
|
||||
# (-p), but do not stop the process (-s) or notify the user (-n).
|
||||
#
|
||||
# JSC's garbage collector sends this signal (as configured by Bun WebKit in
|
||||
# Thread::initializePlatformThreading() in ThreadingPOSIX.cpp) to the JS thread to suspend or resume
|
||||
# it. So stopping the process would just create noise when debugging any long-running script.
|
||||
process handle -p true -s false -n false SIGPWR
|
||||
|
||||
command script import misctools/lldb/lldb_pretty_printers.py
|
||||
type category enable zig.lang
|
||||
type category enable zig.std
|
||||
|
||||
command script import misctools/lldb/lldb_webkit.py
|
||||
@@ -329,7 +329,7 @@ def btjs(debugger, command, result, internal_dict):
|
||||
addressFormat = '#0{width}x'.format(width=target.GetAddressByteSize() * 2 + 2)
|
||||
process = target.GetProcess()
|
||||
thread = process.GetSelectedThread()
|
||||
jscModule = target.module["JavaScriptCore"]
|
||||
jscModule = target.module["JavaScriptCore"] or target.module["bun"] or target.module["bun-debug"]
|
||||
|
||||
if jscModule.FindSymbol("JSC::CallFrame::describeFrame").GetSize() or jscModule.FindSymbol("_ZN3JSC9CallFrame13describeFrameEv").GetSize():
|
||||
annotateJSFrames = True
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"private": true,
|
||||
"name": "bun",
|
||||
"version": "1.2.5",
|
||||
"version": "1.2.6",
|
||||
"workspaces": [
|
||||
"./packages/bun-types"
|
||||
],
|
||||
|
||||
@@ -8,7 +8,7 @@ The official [Svelte](https://svelte.dev/) plugin for [Bun](https://bun.sh/).
|
||||
## Installation
|
||||
|
||||
```sh
|
||||
bun add -D bun-plugin-svelte
|
||||
$ bun add -D bun-plugin-svelte
|
||||
```
|
||||
|
||||
## Dev Server Usage
|
||||
@@ -16,52 +16,25 @@ bun add -D bun-plugin-svelte
|
||||
`bun-plugin-svelte` integrates with Bun's [Fullstack Dev Server](https://bun.sh/docs/bundler/fullstack), giving you
|
||||
HMR when developing your Svelte app.
|
||||
|
||||
```html
|
||||
<!-- index.html -->
|
||||
<html>
|
||||
<head>
|
||||
<script type="module" src="./index.ts"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
</body>
|
||||
</html>
|
||||
Start by registering it in your [bunfig.toml](https://bun.sh/docs/runtime/bunfig):
|
||||
|
||||
```toml
|
||||
[serve.static]
|
||||
plugins = ["bun-plugin-svelte"]
|
||||
```
|
||||
|
||||
```ts
|
||||
// index.ts
|
||||
Then start your dev server:
|
||||
|
||||
import { mount, unmount } from "svelte";
|
||||
import App from "./App.svelte";
|
||||
|
||||
// mount the application entrypoint to the DOM
|
||||
const root = document.getElementById("root")!;
|
||||
const app = mount(App, { target: root });
|
||||
```
|
||||
$ bun index.html
|
||||
```
|
||||
|
||||
```svelte
|
||||
<!-- App.svelte -->
|
||||
|
||||
<script lang="ts">
|
||||
// out-of-the-box typescript support
|
||||
let name: string = "Bun";
|
||||
</script>
|
||||
|
||||
<main class="app">
|
||||
<h1>Cookin up apps with {name}</h1>
|
||||
</main>
|
||||
|
||||
<style>
|
||||
h1 {
|
||||
color: #ff3e00;
|
||||
text-align: center;
|
||||
font-size: 2em;
|
||||
}
|
||||
</style>
|
||||
```
|
||||
See the [example](https://github.com/oven-sh/bun/tree/main/packages/bun-plugin-svelte/example) for a complete example.
|
||||
|
||||
## Bundler Usage
|
||||
|
||||
`bun-plugin-svelte` lets you bundle Svelte components with [`Bun.build`](https://bun.sh/docs/bundler).
|
||||
|
||||
```ts
|
||||
// build.ts
|
||||
// to use: bun run build.ts
|
||||
@@ -70,7 +43,7 @@ import { SveltePlugin } from "bun-plugin-svelte"; // NOTE: not published to npm
|
||||
Bun.build({
|
||||
entrypoints: ["src/index.ts"],
|
||||
outdir: "dist",
|
||||
target: "browser", // use "bun" or "node" to use Svelte components server-side
|
||||
target: "browser",
|
||||
sourcemap: true, // sourcemaps not yet supported
|
||||
plugins: [
|
||||
SveltePlugin({
|
||||
@@ -84,3 +57,13 @@ Bun.build({
|
||||
|
||||
`bun-plugin-svelte` does not yet support server-side imports (e.g. for SSR).
|
||||
This will be added in the near future.
|
||||
|
||||
## Not Yet Supported
|
||||
|
||||
Support for these features will be added in the near future
|
||||
|
||||
- Server-side imports/rendering
|
||||
- Source maps
|
||||
- CSS extensions (e.g. tailwind) in `<style>` blocks
|
||||
- TypeScript-specific features (e.g. enums and namespaces). If you're using
|
||||
TypeScript 5.8, consider enabling [`--erasableSyntaxOnly`](https://devblogs.microsoft.com/typescript/announcing-typescript-5-8-beta/#the---erasablesyntaxonly-option)
|
||||
|
||||
311
packages/bun-plugin-svelte/example/App.svelte
Normal file
311
packages/bun-plugin-svelte/example/App.svelte
Normal file
@@ -0,0 +1,311 @@
|
||||
<script lang="ts">
|
||||
import FeatureCard from "./FeatureCard.svelte";
|
||||
|
||||
const links = [
|
||||
{ text: "Bun Documentation", url: "https://bun.sh/docs" },
|
||||
{ text: "Svelte Documentation", url: "https://svelte.dev/docs" },
|
||||
{ text: "GitHub", url: "https://github.com/oven-sh/bun/tree/main/packages/bun-plugin-svelte" },
|
||||
];
|
||||
</script>
|
||||
|
||||
<main>
|
||||
<div class="hero">
|
||||
<div class="logo-container">
|
||||
<a href="https://bun.sh" class="bun-logo">
|
||||
<img
|
||||
src="https://github.com/user-attachments/assets/50282090-adfd-4ddb-9e27-c30753c6b161"
|
||||
alt="Bun Logo"
|
||||
height="42"
|
||||
/>
|
||||
</a>
|
||||
</div>
|
||||
<h1><span class="highlight">bun-plugin-svelte</span></h1>
|
||||
<p class="tagline">The official Svelte plugin for <a href="https://bun.sh" target="_blank">Bun</a></p>
|
||||
|
||||
<div class="cta-buttons">
|
||||
<a href="https://bun.sh/docs/bundler/html" class="button primary">🚀 Get Started</a>
|
||||
<a href="https://github.com/oven-sh/bun/tree/main/packages/bun-plugin-svelte/example" class="button secondary"
|
||||
>👀 View Examples</a
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<section class="usage">
|
||||
<h2>🏃➡️ Quick Start</h2>
|
||||
|
||||
<div class="flex-grid">
|
||||
<div>
|
||||
<h3>1. Install from <a href="https://npmjs.com/package/bun-plugin-svelte" target="_blank">NPM</a></h3>
|
||||
<pre><code class="language-bash">bun add -D bun-plugin-svelte</code></pre>
|
||||
</div>
|
||||
<div>
|
||||
<h3>2. Add it to your <a href="https://bun.sh/docs/runtime/bunfig" target="_blank">bunfig.toml</a></h3>
|
||||
<pre><code class="language-toml">
|
||||
[serve.static]
|
||||
plugins = ["bun-plugin-svelte"];
|
||||
</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="features">
|
||||
<h2>✨ Features</h2>
|
||||
<div class="feature-grid">
|
||||
<FeatureCard title="🔥 HMR Support" link="https://bun.sh/docs/bundler/html">
|
||||
Integrates with Bun's Fullstack Dev Server for hot module replacement
|
||||
</FeatureCard>
|
||||
<FeatureCard title="📦 Bundling" link="https://bun.sh/docs/bundler">
|
||||
Bundle Svelte components with <a href="https://bun.sh/docs/bundler">Bun.build</a>
|
||||
</FeatureCard>
|
||||
</div>
|
||||
|
||||
<section class="resources">
|
||||
<h2>📖 Resources</h2>
|
||||
<ul class="resource-links">
|
||||
{#each links as link}
|
||||
<li><a href={link.url} target="_blank" rel="noopener noreferrer">{link.text}</a></li>
|
||||
{/each}
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<footer>
|
||||
<p>Made with ❤️ by the Bun team</p>
|
||||
</footer>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<style>
|
||||
:global(body) {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans",
|
||||
"Helvetica Neue", sans-serif;
|
||||
background-color: #f9f9f9;
|
||||
color: #333;
|
||||
}
|
||||
:global(a) {
|
||||
color: #ff3e00;
|
||||
text-decoration: none;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
:global(a::after) {
|
||||
content: "";
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 1px;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
background-color: #ff3e00;
|
||||
transform: scaleX(0);
|
||||
transform-origin: bottom right;
|
||||
transition: transform 0.3s ease-out;
|
||||
}
|
||||
|
||||
:global(a:hover::after) {
|
||||
transform: scaleX(1);
|
||||
transform-origin: bottom left;
|
||||
}
|
||||
|
||||
:global(a:visited) {
|
||||
color: #ff3e00;
|
||||
}
|
||||
|
||||
:global(pre > code.hljs) {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
main {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
padding: 2rem;
|
||||
}
|
||||
|
||||
.hero {
|
||||
text-align: center;
|
||||
padding: 3rem 1rem;
|
||||
margin-bottom: 2rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.logo-container {
|
||||
margin-bottom: 1.5rem;
|
||||
margin: auto 25%;
|
||||
}
|
||||
|
||||
.bun-logo {
|
||||
display: block;
|
||||
transition: transform 0.3s ease;
|
||||
}
|
||||
|
||||
.bun-logo:hover {
|
||||
transform: scale(1.05);
|
||||
}
|
||||
|
||||
.bun-logo img {
|
||||
max-width: 33vw;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 2.5rem;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.highlight {
|
||||
color: #ff3e00;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
/* Don't apply the underline effect to buttons and resource links */
|
||||
.button::after,
|
||||
.resource-links li a::after,
|
||||
.bun-logo::after {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.tagline {
|
||||
font-size: 1.2rem;
|
||||
color: #666;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
.cta-buttons {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
gap: 1rem;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
.button {
|
||||
display: inline-block;
|
||||
padding: 0.8rem 1.5rem;
|
||||
border-radius: 4px;
|
||||
text-decoration: none;
|
||||
font-weight: 600;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.button.primary {
|
||||
background-color: #ff3e00;
|
||||
color: white;
|
||||
box-shadow: 0 2px 10px rgba(255, 62, 0, 0.2);
|
||||
}
|
||||
|
||||
.button.primary:hover {
|
||||
background-color: #e63600;
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 4px 12px rgba(255, 62, 0, 0.3);
|
||||
}
|
||||
|
||||
.button.secondary {
|
||||
background-color: #f0f0f0;
|
||||
color: #333;
|
||||
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.button.secondary:hover {
|
||||
background-color: #e6e6e6;
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
|
||||
section {
|
||||
margin-bottom: 3rem;
|
||||
padding: 2rem;
|
||||
background-color: white;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 2px 15px rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 1.8rem;
|
||||
margin-bottom: 1.5rem;
|
||||
color: #333;
|
||||
border-bottom: 2px solid #f0f0f0;
|
||||
padding-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.flex-grid {
|
||||
display: flex;
|
||||
gap: 1.5rem;
|
||||
}
|
||||
.flex-grid > div {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.feature-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
|
||||
gap: 1.5rem;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
pre {
|
||||
background-color: #f5f5f5;
|
||||
padding: 1rem;
|
||||
border-radius: 4px;
|
||||
overflow-x: auto;
|
||||
font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, monospace;
|
||||
font-size: 0.9rem;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
code {
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.resource-links {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
.resource-links li a {
|
||||
display: inline-block;
|
||||
padding: 0.5rem 1rem;
|
||||
background-color: #f5f5f5;
|
||||
color: #333;
|
||||
text-decoration: none;
|
||||
border-radius: 4px;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.resource-links li a:hover {
|
||||
background-color: #ff3e00;
|
||||
color: white;
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
footer {
|
||||
text-align: center;
|
||||
padding: 2rem 0;
|
||||
color: #666;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.feature-grid {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.cta-buttons {
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.button {
|
||||
width: 100%;
|
||||
max-width: 300px;
|
||||
margin-bottom: 0.5rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.resource-links {
|
||||
flex-direction: column;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
28
packages/bun-plugin-svelte/example/FeatureCard.svelte
Normal file
28
packages/bun-plugin-svelte/example/FeatureCard.svelte
Normal file
@@ -0,0 +1,28 @@
|
||||
<script lang="ts">
|
||||
let { title, link, children } = $props();
|
||||
</script>
|
||||
|
||||
<div class="feature-card">
|
||||
<h3>
|
||||
<a href={link}>
|
||||
{title}
|
||||
</a>
|
||||
</h3>
|
||||
<p>
|
||||
{@render children()}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.feature-card {
|
||||
padding: 1rem;
|
||||
border-radius: 0.5rem;
|
||||
background-color: #fff;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||
transition: transform 0.3s ease;
|
||||
}
|
||||
|
||||
.feature-card h3 {
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
</style>
|
||||
2
packages/bun-plugin-svelte/example/bunfig.toml
Normal file
2
packages/bun-plugin-svelte/example/bunfig.toml
Normal file
@@ -0,0 +1,2 @@
|
||||
[serve.static]
|
||||
plugins = ["bun-plugin-svelte"]
|
||||
25
packages/bun-plugin-svelte/example/index.html
Normal file
25
packages/bun-plugin-svelte/example/index.html
Normal file
@@ -0,0 +1,25 @@
|
||||
<html>
|
||||
<head>
|
||||
<script type="module" src="./index.ts"></script>
|
||||
|
||||
<link rel="prefetch" href="https://bun.sh/docs/bundler/plugins" />
|
||||
<link rel="preconnect" href="https://bun.sh" />
|
||||
<link rel="preconnect" href="https://github.com" />
|
||||
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.9.0/build/styles/default.min.css"
|
||||
/>
|
||||
<script src="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.9.0/build/highlight.min.js"></script>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.9.0/build/languages/toml.min.js"></script>
|
||||
|
||||
<script>
|
||||
hljs.highlightAll();
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
</body>
|
||||
</html>
|
||||
29
packages/bun-plugin-svelte/example/index.ts
Normal file
29
packages/bun-plugin-svelte/example/index.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
import { mount, unmount } from "svelte";
|
||||
import App from "./App.svelte";
|
||||
|
||||
declare global {
|
||||
var didMount: boolean | undefined;
|
||||
var hljs: any;
|
||||
}
|
||||
|
||||
let app: Record<string, any> | undefined;
|
||||
|
||||
// mount the application entrypoint to the DOM on first load. On subsequent hot
|
||||
// updates, the app will be unmounted and re-mounted via the accept handler.
|
||||
|
||||
const root = document.getElementById("root")!;
|
||||
if (!globalThis.didMount) {
|
||||
app = mount(App, { target: root });
|
||||
}
|
||||
globalThis.didMount = true;
|
||||
|
||||
if (import.meta.hot) {
|
||||
import.meta.hot.accept(async () => {
|
||||
// avoid unmounting twice when another update gets accepted while outros are playing
|
||||
if (!app) return;
|
||||
const prevApp = app;
|
||||
app = undefined;
|
||||
await unmount(prevApp, { outro: true });
|
||||
app = mount(App, { target: root });
|
||||
});
|
||||
}
|
||||
@@ -1,6 +1,14 @@
|
||||
{
|
||||
"name": "bun-plugin-svelte",
|
||||
"version": "0.0.1",
|
||||
"version": "0.0.5",
|
||||
"description": "Official Svelte plugin for Bun",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/oven-sh/bun",
|
||||
"directory": "packages/bun-plugin-svelte"
|
||||
},
|
||||
"homepage": "https://bun.sh",
|
||||
"license": "MIT",
|
||||
"type": "module",
|
||||
"module": "src/index.ts",
|
||||
"index": "src/index.ts",
|
||||
@@ -8,16 +16,18 @@
|
||||
".": "./src/index.ts"
|
||||
},
|
||||
"scripts": {
|
||||
"example": "bun --config=./example/bunfig.toml example/index.html",
|
||||
"lint": "oxlint .",
|
||||
"fmt": "prettier --write .",
|
||||
"check:types": "tsc --noEmit",
|
||||
"build:types": "tsc --emitDeclarationOnly --declaration --declarationDir ./dist"
|
||||
},
|
||||
"devDependencies": {
|
||||
"bun-types": "canary",
|
||||
"svelte": "^5.20.4"
|
||||
"svelte": "^5.20.4",
|
||||
"@threlte/core": "8.0.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"typescript": "^5",
|
||||
"svelte": "^5"
|
||||
},
|
||||
"files": [
|
||||
|
||||
@@ -1,7 +1,13 @@
|
||||
import type { BunPlugin, BuildConfig, OnLoadResult } from "bun";
|
||||
import { basename } from "node:path";
|
||||
import { compile, compileModule } from "svelte/compiler";
|
||||
import { getBaseCompileOptions, validateOptions, type SvelteOptions, hash } from "./options";
|
||||
import {
|
||||
getBaseCompileOptions,
|
||||
validateOptions,
|
||||
type SvelteOptions,
|
||||
hash,
|
||||
getBaseModuleCompileOptions,
|
||||
} from "./options";
|
||||
|
||||
const kEmptyObject = Object.create(null);
|
||||
const virtualNamespace = "bun-svelte";
|
||||
@@ -23,38 +29,52 @@ function SveltePlugin(options: SvelteOptions = kEmptyObject as SvelteOptions): B
|
||||
return {
|
||||
name: "bun-plugin-svelte",
|
||||
setup(builder) {
|
||||
// resolve "svelte" export conditions
|
||||
//
|
||||
// FIXME: the dev server does not currently respect bundler configs; it
|
||||
// just passes a fake one to plugins and then never uses it. we need to to
|
||||
// update it to ~not~ do this.
|
||||
if (builder?.config) {
|
||||
var conditions = builder.config.conditions ?? [];
|
||||
if (typeof conditions === "string") {
|
||||
conditions = [conditions];
|
||||
}
|
||||
conditions.push("svelte");
|
||||
builder.config.conditions = conditions;
|
||||
}
|
||||
|
||||
const { config = kEmptyObject as Partial<BuildConfig> } = builder;
|
||||
const baseCompileOptions = getBaseCompileOptions(options ?? (kEmptyObject as Partial<SvelteOptions>), config);
|
||||
const baseModuleCompileOptions = getBaseModuleCompileOptions(
|
||||
options ?? (kEmptyObject as Partial<SvelteOptions>),
|
||||
config,
|
||||
);
|
||||
|
||||
const ts = new Bun.Transpiler({
|
||||
loader: "ts",
|
||||
target: config.target,
|
||||
});
|
||||
|
||||
builder
|
||||
.onLoad({ filter: /\.svelte(?:\.[tj]s)?$/ }, async args => {
|
||||
.onLoad({ filter: /\.svelte$/ }, async function onLoadSvelte(args) {
|
||||
const { path } = args;
|
||||
|
||||
var isModule = false;
|
||||
|
||||
switch (path.substring(path.length - 2)) {
|
||||
case "js":
|
||||
case "ts":
|
||||
isModule = true;
|
||||
break;
|
||||
}
|
||||
|
||||
const sourceText = await Bun.file(path).text();
|
||||
|
||||
const side =
|
||||
args && "side" in args // "side" only passed when run from dev server
|
||||
? (args as { side: "client" | "server" }).side
|
||||
: "server";
|
||||
const hmr = Boolean((args as { hmr?: boolean })["hmr"] ?? process.env.NODE_ENV !== "production");
|
||||
const generate = baseCompileOptions.generate ?? side;
|
||||
|
||||
const compileFn = isModule ? compileModule : compile;
|
||||
const result = compileFn(sourceText, {
|
||||
const hmr = Boolean((args as { hmr?: boolean })["hmr"] ?? process.env.NODE_ENV !== "production");
|
||||
const result = compile(sourceText, {
|
||||
...baseCompileOptions,
|
||||
generate,
|
||||
filename: args.path,
|
||||
hmr,
|
||||
});
|
||||
|
||||
var { js, css } = result;
|
||||
if (css?.code && generate != "server") {
|
||||
const uid = `${basename(path)}-${hash(path)}-style`.replaceAll(`"`, `'`);
|
||||
@@ -65,11 +85,37 @@ function SveltePlugin(options: SvelteOptions = kEmptyObject as SvelteOptions): B
|
||||
|
||||
return {
|
||||
contents: result.js.code,
|
||||
loader: "js",
|
||||
loader: "ts",
|
||||
} satisfies OnLoadResult;
|
||||
// TODO: allow plugins to return multiple results.
|
||||
// TODO: support layered sourcemaps
|
||||
})
|
||||
.onLoad({ filter: /\.svelte.[tj]s$/ }, async function onLoadSvelteModule(args) {
|
||||
const { path } = args;
|
||||
|
||||
const side =
|
||||
args && "side" in args // "side" only passed when run from dev server
|
||||
? (args as { side: "client" | "server" }).side
|
||||
: "server";
|
||||
const generate = baseModuleCompileOptions.generate ?? side;
|
||||
|
||||
var sourceText = await Bun.file(path).text();
|
||||
if (path.endsWith(".ts")) {
|
||||
sourceText = await ts.transform(sourceText);
|
||||
}
|
||||
const result = compileModule(sourceText, {
|
||||
...baseModuleCompileOptions,
|
||||
generate,
|
||||
filename: args.path,
|
||||
});
|
||||
|
||||
// NOTE: we assume js/ts modules won't have CSS blocks in them, so no
|
||||
// virtual modules get created.
|
||||
return {
|
||||
contents: result.js.code,
|
||||
loader: "js",
|
||||
};
|
||||
})
|
||||
.onResolve({ filter: /^bun-svelte:/ }, args => {
|
||||
return {
|
||||
path: args.path,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { strict as assert } from "node:assert";
|
||||
import type { BuildConfig } from "bun";
|
||||
import type { CompileOptions } from "svelte/compiler";
|
||||
import { type BuildConfig } from "bun";
|
||||
import type { CompileOptions, ModuleCompileOptions } from "svelte/compiler";
|
||||
|
||||
export interface SvelteOptions {
|
||||
/**
|
||||
@@ -44,8 +44,8 @@ export function validateOptions(options: unknown): asserts options is SvelteOpti
|
||||
* @internal
|
||||
*/
|
||||
export function getBaseCompileOptions(pluginOptions: SvelteOptions, config: Partial<BuildConfig>): CompileOptions {
|
||||
let { forceSide, development = false } = pluginOptions;
|
||||
const { minify = false, target } = config;
|
||||
let { development = false } = pluginOptions;
|
||||
const { minify = false } = config;
|
||||
|
||||
const shouldMinify = Boolean(minify);
|
||||
const {
|
||||
@@ -60,6 +60,38 @@ export function getBaseCompileOptions(pluginOptions: SvelteOptions, config: Part
|
||||
identifiers: shouldMinify,
|
||||
};
|
||||
|
||||
const generate = generateSide(pluginOptions, config);
|
||||
|
||||
return {
|
||||
css: "external",
|
||||
generate,
|
||||
preserveWhitespace: !minifyWhitespace,
|
||||
preserveComments: !shouldMinify,
|
||||
dev: development,
|
||||
cssHash({ css }) {
|
||||
// same prime number seed used by svelte/compiler.
|
||||
// TODO: ensure this provides enough entropy
|
||||
return `svelte-${hash(css)}`;
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export function getBaseModuleCompileOptions(
|
||||
pluginOptions: SvelteOptions,
|
||||
config: Partial<BuildConfig>,
|
||||
): ModuleCompileOptions {
|
||||
const { development = false } = pluginOptions;
|
||||
const generate = generateSide(pluginOptions, config);
|
||||
return {
|
||||
dev: development,
|
||||
generate,
|
||||
};
|
||||
}
|
||||
|
||||
function generateSide(pluginOptions: SvelteOptions, config: Partial<BuildConfig>) {
|
||||
let { forceSide } = pluginOptions;
|
||||
const { target } = config;
|
||||
|
||||
if (forceSide == null && typeof target === "string") {
|
||||
switch (target) {
|
||||
case "browser":
|
||||
@@ -73,19 +105,7 @@ export function getBaseCompileOptions(pluginOptions: SvelteOptions, config: Part
|
||||
// warn? throw?
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
css: "external",
|
||||
generate: forceSide,
|
||||
preserveWhitespace: !minifyWhitespace,
|
||||
preserveComments: !shouldMinify,
|
||||
dev: development,
|
||||
cssHash({ css }) {
|
||||
// same prime number seed used by svelte/compiler.
|
||||
// TODO: ensure this provides enough entropy
|
||||
return `svelte-${hash(css)}`;
|
||||
},
|
||||
};
|
||||
return forceSide;
|
||||
}
|
||||
|
||||
export const hash = (content: string): string => Bun.hash(content, 5381).toString(36);
|
||||
|
||||
17
packages/bun-plugin-svelte/test/fixtures/svelte-export-condition.svelte
vendored
Normal file
17
packages/bun-plugin-svelte/test/fixtures/svelte-export-condition.svelte
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
<script>
|
||||
import { Canvas } from "@threlte/core";
|
||||
let name = "Bun";
|
||||
</script>
|
||||
|
||||
<main class="app">
|
||||
<h1>Cookin up apps with {name}</h1>
|
||||
<Canvas />
|
||||
</main>
|
||||
|
||||
<style>
|
||||
h1 {
|
||||
color: #ff3e00;
|
||||
text-align: center;
|
||||
font-size: 2em;
|
||||
}
|
||||
</style>
|
||||
15
packages/bun-plugin-svelte/test/fixtures/todo-cjs.svelte.ts
vendored
Normal file
15
packages/bun-plugin-svelte/test/fixtures/todo-cjs.svelte.ts
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
class Todo {
|
||||
title: string | undefined = $state();
|
||||
done: boolean = $state(false);
|
||||
createdAt: Date = $state(new Date());
|
||||
|
||||
constructor(title: string) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public toggle(): void {
|
||||
this.done = !this.done;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Todo;
|
||||
13
packages/bun-plugin-svelte/test/fixtures/todo.svelte.ts
vendored
Normal file
13
packages/bun-plugin-svelte/test/fixtures/todo.svelte.ts
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
export class Todo {
|
||||
title: string | undefined = $state();
|
||||
done: boolean = $state(false);
|
||||
createdAt: Date = $state(new Date());
|
||||
|
||||
constructor(title: string) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public toggle(): void {
|
||||
this.done = !this.done;
|
||||
}
|
||||
}
|
||||
25
packages/bun-plugin-svelte/test/fixtures/with-cjs.svelte
vendored
Normal file
25
packages/bun-plugin-svelte/test/fixtures/with-cjs.svelte
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
<script lang="ts">
|
||||
const Todo = require("./todo-cjs.svelte.ts");
|
||||
|
||||
let name = "World";
|
||||
let todo: Todo = $state(new Todo("Hello World!"));
|
||||
</script>
|
||||
|
||||
<main class="app">
|
||||
<h1>Hello {todo.title}!</h1>
|
||||
<!-- clicking calls toggle -->
|
||||
<input type="checkbox" bind:checked={todo.done} />
|
||||
<button onclick={todo.toggle}>Toggle</button>
|
||||
</main>
|
||||
|
||||
<style>
|
||||
h1 {
|
||||
color: #ff3e00;
|
||||
text-align: center;
|
||||
font-size: 2em;
|
||||
font-weight: 100;
|
||||
}
|
||||
.app {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
</style>
|
||||
25
packages/bun-plugin-svelte/test/fixtures/with-modules.svelte
vendored
Normal file
25
packages/bun-plugin-svelte/test/fixtures/with-modules.svelte
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
<script lang="ts">
|
||||
import { Todo } from "./todo.svelte";
|
||||
|
||||
let name = "World";
|
||||
let todo: Todo = $state(new Todo("Hello World!"));
|
||||
</script>
|
||||
|
||||
<main class="app">
|
||||
<h1>Hello {todo.title}!</h1>
|
||||
<!-- clicking calls toggle -->
|
||||
<input type="checkbox" bind:checked={todo.done} />
|
||||
<button onclick={todo.toggle}>Toggle</button>
|
||||
</main>
|
||||
|
||||
<style>
|
||||
h1 {
|
||||
color: #ff3e00;
|
||||
text-align: center;
|
||||
font-size: 2em;
|
||||
font-weight: 100;
|
||||
}
|
||||
.app {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
</style>
|
||||
@@ -4,6 +4,7 @@ import fs from "node:fs";
|
||||
import os from "node:os";
|
||||
import { render } from "svelte/server";
|
||||
import { SveltePlugin } from "../src";
|
||||
import type { BuildOutput } from "bun";
|
||||
|
||||
const fixturePath = (...segs: string[]) => path.join(import.meta.dirname, "fixtures", ...segs);
|
||||
|
||||
@@ -32,6 +33,55 @@ it("hello world component", async () => {
|
||||
expect(res.success).toBeTrue();
|
||||
});
|
||||
|
||||
describe("when importing `.svelte.ts` files with ESM", () => {
|
||||
let res: BuildOutput;
|
||||
|
||||
beforeAll(async () => {
|
||||
res = await Bun.build({
|
||||
entrypoints: [fixturePath("with-modules.svelte")],
|
||||
outdir,
|
||||
plugins: [SveltePlugin()],
|
||||
});
|
||||
});
|
||||
|
||||
it("builds successfully", () => {
|
||||
expect(res.success).toBeTrue();
|
||||
});
|
||||
|
||||
it(`handles "svelte" export condition`, async () => {
|
||||
const res = await Bun.build({
|
||||
entrypoints: [fixturePath("svelte-export-condition.svelte")],
|
||||
outdir,
|
||||
plugins: [SveltePlugin()],
|
||||
});
|
||||
expect(res.success).toBeTrue();
|
||||
});
|
||||
});
|
||||
|
||||
describe("when importing `.svelte.ts` files with CJS", () => {
|
||||
let res: BuildOutput;
|
||||
|
||||
beforeAll(async () => {
|
||||
res = await Bun.build({
|
||||
entrypoints: [fixturePath("with-cjs.svelte")],
|
||||
outdir,
|
||||
plugins: [SveltePlugin()],
|
||||
});
|
||||
});
|
||||
|
||||
it("builds successfully", () => {
|
||||
expect(res.success).toBeTrue();
|
||||
});
|
||||
|
||||
it("does not double-wrap the module with function(module, exports, __filename, __dirname)", async () => {
|
||||
const ts = res.outputs.find(output => output.loader === "ts");
|
||||
expect(ts).toBeDefined();
|
||||
const code = await ts!.text();
|
||||
expect(code).toContain("require_todo_cjs_svelte");
|
||||
expect(code).toContain("var require_todo_cjs_svelte = __commonJS((exports, module) => {\n");
|
||||
});
|
||||
});
|
||||
|
||||
describe("Bun.build", () => {
|
||||
it.each(["node", "bun"] as const)('Generates server-side code when targeting "node" or "bun"', async target => {
|
||||
const res = await Bun.build({
|
||||
|
||||
396
packages/bun-types/bun.d.ts
vendored
396
packages/bun-types/bun.d.ts
vendored
@@ -1,74 +1,3 @@
|
||||
declare class _ShellError extends Error implements ShellOutput {
|
||||
readonly stdout: Buffer;
|
||||
readonly stderr: Buffer;
|
||||
readonly exitCode: number;
|
||||
|
||||
/**
|
||||
* Read from stdout as a string
|
||||
*
|
||||
* @param encoding - The encoding to use when decoding the output
|
||||
* @returns Stdout as a string with the given encoding
|
||||
* @example
|
||||
*
|
||||
* ## Read as UTF-8 string
|
||||
*
|
||||
* ```ts
|
||||
* const output = await $`echo hello`;
|
||||
* console.log(output.text()); // "hello\n"
|
||||
* ```
|
||||
*
|
||||
* ## Read as base64 string
|
||||
*
|
||||
* ```ts
|
||||
* const output = await $`echo ${atob("hello")}`;
|
||||
* console.log(output.text("base64")); // "hello\n"
|
||||
* ```
|
||||
*
|
||||
*/
|
||||
text(encoding?: BufferEncoding): string;
|
||||
|
||||
/**
|
||||
* Read from stdout as a JSON object
|
||||
*
|
||||
* @returns Stdout as a JSON object
|
||||
* @example
|
||||
*
|
||||
* ```ts
|
||||
* const output = await $`echo '{"hello": 123}'`;
|
||||
* console.log(output.json()); // { hello: 123 }
|
||||
* ```
|
||||
*
|
||||
*/
|
||||
json(): any;
|
||||
|
||||
/**
|
||||
* Read from stdout as an ArrayBuffer
|
||||
*
|
||||
* @returns Stdout as an ArrayBuffer
|
||||
* @example
|
||||
*
|
||||
* ```ts
|
||||
* const output = await $`echo hello`;
|
||||
* console.log(output.arrayBuffer()); // ArrayBuffer { byteLength: 6 }
|
||||
* ```
|
||||
*/
|
||||
arrayBuffer(): ArrayBuffer;
|
||||
|
||||
/**
|
||||
* Read from stdout as a Blob
|
||||
*
|
||||
* @returns Stdout as a blob
|
||||
* @example
|
||||
* ```ts
|
||||
* const output = await $`echo hello`;
|
||||
* console.log(output.blob()); // Blob { size: 6, type: "" }
|
||||
* ```
|
||||
*/
|
||||
blob(): Blob;
|
||||
|
||||
bytes(): Uint8Array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Bun.js runtime APIs
|
||||
*
|
||||
@@ -185,6 +114,77 @@ declare module "bun" {
|
||||
| SpawnOptions.Writable
|
||||
| ReadableStream;
|
||||
|
||||
class ShellError extends Error implements ShellOutput {
|
||||
readonly stdout: Buffer;
|
||||
readonly stderr: Buffer;
|
||||
readonly exitCode: number;
|
||||
|
||||
/**
|
||||
* Read from stdout as a string
|
||||
*
|
||||
* @param encoding - The encoding to use when decoding the output
|
||||
* @returns Stdout as a string with the given encoding
|
||||
* @example
|
||||
*
|
||||
* ## Read as UTF-8 string
|
||||
*
|
||||
* ```ts
|
||||
* const output = await $`echo hello`;
|
||||
* console.log(output.text()); // "hello\n"
|
||||
* ```
|
||||
*
|
||||
* ## Read as base64 string
|
||||
*
|
||||
* ```ts
|
||||
* const output = await $`echo ${atob("hello")}`;
|
||||
* console.log(output.text("base64")); // "hello\n"
|
||||
* ```
|
||||
*
|
||||
*/
|
||||
text(encoding?: BufferEncoding): string;
|
||||
|
||||
/**
|
||||
* Read from stdout as a JSON object
|
||||
*
|
||||
* @returns Stdout as a JSON object
|
||||
* @example
|
||||
*
|
||||
* ```ts
|
||||
* const output = await $`echo '{"hello": 123}'`;
|
||||
* console.log(output.json()); // { hello: 123 }
|
||||
* ```
|
||||
*
|
||||
*/
|
||||
json(): any;
|
||||
|
||||
/**
|
||||
* Read from stdout as an ArrayBuffer
|
||||
*
|
||||
* @returns Stdout as an ArrayBuffer
|
||||
* @example
|
||||
*
|
||||
* ```ts
|
||||
* const output = await $`echo hello`;
|
||||
* console.log(output.arrayBuffer()); // ArrayBuffer { byteLength: 6 }
|
||||
* ```
|
||||
*/
|
||||
arrayBuffer(): ArrayBuffer;
|
||||
|
||||
/**
|
||||
* Read from stdout as a Blob
|
||||
*
|
||||
* @returns Stdout as a blob
|
||||
* @example
|
||||
* ```ts
|
||||
* const output = await $`echo hello`;
|
||||
* console.log(output.blob()); // Blob { size: 6, type: "" }
|
||||
* ```
|
||||
*/
|
||||
blob(): Blob;
|
||||
|
||||
bytes(): Uint8Array;
|
||||
}
|
||||
|
||||
class ShellPromise extends Promise<ShellOutput> {
|
||||
get stdin(): WritableStream;
|
||||
/**
|
||||
@@ -304,12 +304,12 @@ declare module "bun" {
|
||||
new (): Shell;
|
||||
}
|
||||
|
||||
type ShellError = _ShellError;
|
||||
|
||||
export interface Shell {
|
||||
(strings: TemplateStringsArray, ...expressions: ShellExpression[]): ShellPromise;
|
||||
|
||||
readonly ShellError: typeof _ShellError;
|
||||
readonly Shell: ShellConstructor;
|
||||
readonly ShellError: typeof ShellError;
|
||||
readonly ShellPromise: typeof ShellPromise;
|
||||
|
||||
/**
|
||||
* Perform bash-like brace expansion on the given pattern.
|
||||
@@ -362,9 +362,6 @@ declare module "bun" {
|
||||
* Configure whether or not the shell should throw an exception on non-zero exit codes.
|
||||
*/
|
||||
throws(shouldThrow: boolean): this;
|
||||
|
||||
readonly ShellPromise: typeof ShellPromise;
|
||||
readonly Shell: ShellConstructor;
|
||||
}
|
||||
|
||||
export interface ShellOutput {
|
||||
@@ -2309,10 +2306,68 @@ declare module "bun" {
|
||||
*/
|
||||
interface SavepointSQL extends SQL {}
|
||||
|
||||
type CSRFAlgorithm = "blake2b256" | "blake2b512" | "sha256" | "sha384" | "sha512" | "sha512-256";
|
||||
interface CSRFGenerateOptions {
|
||||
/**
|
||||
* The number of milliseconds until the token expires. 0 means the token never expires.
|
||||
* @default 24 * 60 * 60 * 1000 (24 hours)
|
||||
*/
|
||||
expiresIn?: number;
|
||||
/**
|
||||
* The encoding of the token.
|
||||
* @default "base64url"
|
||||
*/
|
||||
encoding?: "base64" | "base64url" | "hex";
|
||||
/**
|
||||
* The algorithm to use for the token.
|
||||
* @default "sha256"
|
||||
*/
|
||||
algorithm?: CSRFAlgorithm;
|
||||
}
|
||||
|
||||
interface CSRFVerifyOptions {
|
||||
/**
|
||||
* The secret to use for the token. If not provided, a random default secret will be generated in memory and used.
|
||||
*/
|
||||
secret?: string;
|
||||
/**
|
||||
* The encoding of the token.
|
||||
* @default "base64url"
|
||||
*/
|
||||
encoding?: "base64" | "base64url" | "hex";
|
||||
/**
|
||||
* The algorithm to use for the token.
|
||||
* @default "sha256"
|
||||
*/
|
||||
algorithm?: CSRFAlgorithm;
|
||||
/**
|
||||
* The number of milliseconds until the token expires. 0 means the token never expires.
|
||||
* @default 24 * 60 * 60 * 1000 (24 hours)
|
||||
*/
|
||||
maxAge?: number;
|
||||
}
|
||||
interface CSRF {
|
||||
/**
|
||||
* Generate a CSRF token.
|
||||
* @param secret The secret to use for the token. If not provided, a random default secret will be generated in memory and used.
|
||||
* @param options The options for the token.
|
||||
* @returns The generated token.
|
||||
*/
|
||||
generate(secret?: string, options?: CSRFGenerateOptions): string;
|
||||
/**
|
||||
* Verify a CSRF token.
|
||||
* @param token The token to verify.
|
||||
* @param options The options for the token.
|
||||
* @returns True if the token is valid, false otherwise.
|
||||
*/
|
||||
verify(token: string, options?: CSRFVerifyOptions): boolean;
|
||||
}
|
||||
|
||||
var sql: SQL;
|
||||
var postgres: SQL;
|
||||
var SQL: SQL;
|
||||
|
||||
var CSRF: CSRF;
|
||||
/**
|
||||
* This lets you use macros as regular imports
|
||||
* @example
|
||||
@@ -2657,7 +2712,7 @@ declare module "bun" {
|
||||
loader?: { [k in string]: Loader };
|
||||
/**
|
||||
* Specifies if and how to generate source maps.
|
||||
*
|
||||
*
|
||||
* - `"none"` - No source maps are generated
|
||||
* - `"linked"` - A separate `*.ext.map` file is generated alongside each
|
||||
* `*.ext` file. A `//# sourceMappingURL` comment is added to the output
|
||||
@@ -2665,11 +2720,11 @@ declare module "bun" {
|
||||
* - `"inline"` - an inline source map is appended to the output file.
|
||||
* - `"external"` - Generate a separate source map file for each input file.
|
||||
* No `//# sourceMappingURL` comment is added to the output file.
|
||||
*
|
||||
*
|
||||
* `true` and `false` are aliasees for `"inline"` and `"none"`, respectively.
|
||||
*
|
||||
*
|
||||
* @default "none"
|
||||
*
|
||||
*
|
||||
* @see {@link outdir} required for `"linked"` maps
|
||||
* @see {@link publicPath} to customize the base url of linked source maps
|
||||
*/
|
||||
@@ -2704,10 +2759,10 @@ declare module "bun" {
|
||||
env?: "inline" | "disable" | `${string}*`;
|
||||
/**
|
||||
* Whether to enable minification.
|
||||
*
|
||||
*
|
||||
* Use `true`/`false` to enable/disable all minification options. Alternatively,
|
||||
* you can pass an object for granular control over certain minifications.
|
||||
*
|
||||
*
|
||||
* @default false
|
||||
*/
|
||||
minify?:
|
||||
@@ -3705,6 +3760,7 @@ declare module "bun" {
|
||||
|
||||
interface BunRequest<T extends string = string> extends Request {
|
||||
params: RouterTypes.ExtractRouteParams<T>;
|
||||
readonly cookies: CookieMap;
|
||||
}
|
||||
|
||||
interface GenericServeOptions {
|
||||
@@ -4265,17 +4321,7 @@ declare module "bun" {
|
||||
* Passing other options such as `port` or `hostname` won't do anything.
|
||||
*/
|
||||
reload<T, R extends { [K in keyof R]: RouterTypes.RouteValue<K & string> }>(
|
||||
options: (
|
||||
| (Omit<ServeOptions, "fetch"> & {
|
||||
routes: R;
|
||||
fetch?: (this: Server, request: Request, server: Server) => Response | Promise<Response>;
|
||||
})
|
||||
| (Omit<ServeOptions, "routes"> & {
|
||||
routes?: never;
|
||||
fetch: (this: Server, request: Request, server: Server) => Response | Promise<Response>;
|
||||
})
|
||||
| WebSocketServeOptions<T>
|
||||
) & {
|
||||
options: ServeFunctionOptions<T, R> & {
|
||||
/**
|
||||
* @deprecated Use `routes` instead in new code. This will continue to work for awhile though.
|
||||
*/
|
||||
@@ -4653,17 +4699,7 @@ declare module "bun" {
|
||||
@param options.routes - Route definitions mapping paths to handlers
|
||||
*/
|
||||
function serve<T, R extends { [K in keyof R]: RouterTypes.RouteValue<K & string> }>(
|
||||
options: (
|
||||
| (DistributedOmit<Serve, "fetch"> & {
|
||||
routes: R;
|
||||
fetch?: (this: Server, request: Request, server: Server) => Response | Promise<Response>;
|
||||
})
|
||||
| (DistributedOmit<Serve, "routes"> & {
|
||||
routes?: never;
|
||||
fetch: (this: Server, request: Request, server: Server) => Response | Promise<Response>;
|
||||
})
|
||||
| WebSocketServeOptions<T>
|
||||
) & {
|
||||
options: ServeFunctionOptions<T, R> & {
|
||||
/**
|
||||
* @deprecated Use `routes` instead in new code. This will continue to work for a while though.
|
||||
*/
|
||||
@@ -4671,6 +4707,32 @@ declare module "bun" {
|
||||
},
|
||||
): Server;
|
||||
|
||||
type ServeFunctionOptions<T, R extends { [K in keyof R]: RouterTypes.RouteValue<K & string> }> =
|
||||
| (DistributedOmit<Exclude<Serve<T>, WebSocketServeOptions<T>>, "fetch"> & {
|
||||
routes: R;
|
||||
fetch?: (this: Server, request: Request, server: Server) => Response | Promise<Response>;
|
||||
})
|
||||
| (DistributedOmit<Exclude<Serve<T>, WebSocketServeOptions<T>>, "routes"> & {
|
||||
routes?: never;
|
||||
fetch: (this: Server, request: Request, server: Server) => Response | Promise<Response>;
|
||||
})
|
||||
| (WebSocketServeOptions<T> & {
|
||||
routes: R;
|
||||
fetch?: (
|
||||
this: Server,
|
||||
request: Request,
|
||||
server: Server,
|
||||
) => Response | Promise<Response | void | undefined> | void | undefined;
|
||||
})
|
||||
| (WebSocketServeOptions<T> & {
|
||||
routes?: never;
|
||||
fetch: (
|
||||
this: Server,
|
||||
request: Request,
|
||||
server: Server,
|
||||
) => Response | Promise<Response | void | undefined> | void | undefined;
|
||||
});
|
||||
|
||||
/**
|
||||
* [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob) powered by the fastest system calls available for operating on files.
|
||||
*
|
||||
@@ -6239,7 +6301,7 @@ declare module "bun" {
|
||||
* @param socket
|
||||
*/
|
||||
open?(socket: Socket<Data>): void | Promise<void>;
|
||||
close?(socket: Socket<Data>): void | Promise<void>;
|
||||
close?(socket: Socket<Data>, error?: Error): void | Promise<void>;
|
||||
error?(socket: Socket<Data>, error: Error): void | Promise<void>;
|
||||
data?(socket: Socket<Data>, data: BinaryTypeList[DataBinaryType]): void | Promise<void>;
|
||||
drain?(socket: Socket<Data>): void | Promise<void>;
|
||||
@@ -6638,7 +6700,8 @@ declare module "bun" {
|
||||
* This is useful for aborting a subprocess when some other part of the
|
||||
* program is aborted, such as a `fetch` response.
|
||||
*
|
||||
* Internally, this works by calling `subprocess.kill(1)`.
|
||||
* If the signal is aborted, the process will be killed with the signal
|
||||
* specified by `killSignal` (defaults to SIGTERM).
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
@@ -6657,6 +6720,41 @@ declare module "bun" {
|
||||
* ```
|
||||
*/
|
||||
signal?: AbortSignal;
|
||||
|
||||
/**
|
||||
* The maximum amount of time the process is allowed to run in milliseconds.
|
||||
*
|
||||
* If the timeout is reached, the process will be killed with the signal
|
||||
* specified by `killSignal` (defaults to SIGTERM).
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* // Kill the process after 5 seconds
|
||||
* const subprocess = Bun.spawn({
|
||||
* cmd: ["sleep", "10"],
|
||||
* timeout: 5000,
|
||||
* });
|
||||
* await subprocess.exited; // Will resolve after 5 seconds
|
||||
* ```
|
||||
*/
|
||||
timeout?: number;
|
||||
|
||||
/**
|
||||
* The signal to use when killing the process after a timeout or when the AbortSignal is aborted.
|
||||
*
|
||||
* @default "SIGTERM" (signal 15)
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* // Kill the process with SIGKILL after 5 seconds
|
||||
* const subprocess = Bun.spawn({
|
||||
* cmd: ["sleep", "10"],
|
||||
* timeout: 5000,
|
||||
* killSignal: "SIGKILL",
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
killSignal?: string | number;
|
||||
}
|
||||
|
||||
type OptionsToSubprocess<Opts extends OptionsObject> =
|
||||
@@ -6902,6 +7000,8 @@ declare module "bun" {
|
||||
resourceUsage: ResourceUsage;
|
||||
|
||||
signalCode?: string;
|
||||
exitedDueToTimeout?: true;
|
||||
pid: number;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -7429,4 +7529,86 @@ declare module "bun" {
|
||||
| [pkg: string, info: BunLockFilePackageInfo, bunTag: string]
|
||||
/** root */
|
||||
| [pkg: string, info: Pick<BunLockFileBasePackageInfo, "bin" | "binDir">];
|
||||
|
||||
interface CookieInit {
|
||||
name?: string;
|
||||
value?: string;
|
||||
domain?: string;
|
||||
path?: string;
|
||||
expires?: number | Date;
|
||||
secure?: boolean;
|
||||
sameSite?: CookieSameSite;
|
||||
httpOnly?: boolean;
|
||||
partitioned?: boolean;
|
||||
maxAge?: number;
|
||||
}
|
||||
|
||||
interface CookieStoreDeleteOptions {
|
||||
name: string;
|
||||
domain?: string | null;
|
||||
path?: string;
|
||||
}
|
||||
|
||||
interface CookieStoreGetOptions {
|
||||
name?: string;
|
||||
url?: string;
|
||||
}
|
||||
|
||||
type CookieSameSite = "strict" | "lax" | "none";
|
||||
|
||||
class Cookie {
|
||||
constructor(name: string, value: string, options?: CookieInit);
|
||||
constructor(cookieString: string);
|
||||
constructor(cookieObject?: CookieInit);
|
||||
|
||||
name: string;
|
||||
value: string;
|
||||
domain?: string;
|
||||
path: string;
|
||||
expires?: number;
|
||||
secure: boolean;
|
||||
sameSite: CookieSameSite;
|
||||
partitioned: boolean;
|
||||
maxAge?: number;
|
||||
httpOnly: boolean;
|
||||
|
||||
isExpired(): boolean;
|
||||
|
||||
toString(): string;
|
||||
toJSON(): CookieInit;
|
||||
|
||||
static parse(cookieString: string): Cookie;
|
||||
static from(name: string, value: string, options?: CookieInit): Cookie;
|
||||
static serialize(...cookies: Cookie[]): string;
|
||||
}
|
||||
|
||||
class CookieMap implements Iterable<[string, Cookie]> {
|
||||
constructor(init?: string[][] | Record<string, string> | string);
|
||||
|
||||
get(name: string): Cookie | null;
|
||||
get(options?: CookieStoreGetOptions): Cookie | null;
|
||||
|
||||
getAll(name: string): Cookie[];
|
||||
getAll(options?: CookieStoreGetOptions): Cookie[];
|
||||
|
||||
has(name: string, value?: string): boolean;
|
||||
|
||||
set(name: string, value: string): void;
|
||||
set(options: CookieInit): void;
|
||||
|
||||
delete(name: string): void;
|
||||
delete(options: CookieStoreDeleteOptions): void;
|
||||
|
||||
toString(): string;
|
||||
|
||||
toJSON(): Record<string, ReturnType<Cookie["toJSON"]>>;
|
||||
readonly size: number;
|
||||
|
||||
entries(): IterableIterator<[string, Cookie]>;
|
||||
keys(): IterableIterator<string>;
|
||||
values(): IterableIterator<Cookie>;
|
||||
forEach(callback: (value: Cookie, key: string, map: CookieMap) => void, thisArg?: any): void;
|
||||
|
||||
[Symbol.iterator](): IterableIterator<[string, Cookie]>;
|
||||
}
|
||||
}
|
||||
|
||||
180
packages/bun-types/devserver.d.ts
vendored
180
packages/bun-types/devserver.d.ts
vendored
@@ -1,24 +1,192 @@
|
||||
export {};
|
||||
|
||||
declare global {
|
||||
namespace Bun {
|
||||
type HMREventNames =
|
||||
| "bun:ready"
|
||||
| "bun:beforeUpdate"
|
||||
| "bun:afterUpdate"
|
||||
| "bun:beforeFullReload"
|
||||
| "bun:beforePrune"
|
||||
| "bun:invalidate"
|
||||
| "bun:error"
|
||||
| "bun:ws:disconnect"
|
||||
| "bun:ws:connect";
|
||||
|
||||
/**
|
||||
* The event names for the dev server
|
||||
*/
|
||||
type HMREvent = `bun:${HMREventNames}` | (string & {});
|
||||
}
|
||||
|
||||
interface ImportMeta {
|
||||
/**
|
||||
* Hot module replacement
|
||||
* Hot module replacement APIs. This value is `undefined` in production and
|
||||
* can be used in an `if` statement to check if HMR APIs are available
|
||||
*
|
||||
* https://bun.sh/docs/bundler/fullstack
|
||||
* ```ts
|
||||
* if (import.meta.hot) {
|
||||
* // HMR APIs are available
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* However, this check is usually not needed as Bun will dead-code-eliminate
|
||||
* calls to all of the HMR APIs in production builds.
|
||||
*
|
||||
* https://bun.sh/docs/bundler/hmr
|
||||
*/
|
||||
hot: {
|
||||
/**
|
||||
* import.meta.hot.data maintains state between module instances during hot replacement, enabling data transfer from previous to new versions.
|
||||
* `import.meta.hot.data` maintains state between module instances during
|
||||
* hot replacement, enabling data transfer from previous to new versions.
|
||||
* When `import.meta.hot.data` is written to, Bun will mark this module as
|
||||
* capable of self-accepting (equivalent of calling `accept()`).
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* import.meta.hot.data = {
|
||||
* bun: 'is cool',
|
||||
* };
|
||||
* const root = import.meta.hot.data.root ??= createRoot(elem);
|
||||
* root.render(<App />); // re-use an existing root
|
||||
* ```
|
||||
*
|
||||
* In production, `data` is inlined to be `{}`. This is handy because Bun
|
||||
* knows it can minify `{}.prop ??= value` into `value` in production.
|
||||
*/
|
||||
data: any;
|
||||
|
||||
/**
|
||||
* Indicate that this module can be replaced simply by re-evaluating the
|
||||
* file. After a hot update, importers of this module will be
|
||||
* automatically patched.
|
||||
*
|
||||
* When `import.meta.hot.accept` is not used, the page will reload when
|
||||
* the file updates, and a console message shows which files were checked.
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* import { getCount } from "./foo";
|
||||
*
|
||||
* console.log("count is ", getCount());
|
||||
*
|
||||
* import.meta.hot.accept();
|
||||
* ```
|
||||
*/
|
||||
accept(): void;
|
||||
|
||||
/**
|
||||
* Indicate that this module can be replaced by evaluating the new module,
|
||||
* and then calling the callback with the new module. In this mode, the
|
||||
* importers do not get patched. This is to match Vite, which is unable
|
||||
* to patch their import statements. Prefer using `import.meta.hot.accept()`
|
||||
* without an argument as it usually makes your code easier to understand.
|
||||
*
|
||||
* When `import.meta.hot.accept` is not used, the page will reload when
|
||||
* the file updates, and a console message shows which files were checked.
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* export const count = 0;
|
||||
*
|
||||
* import.meta.hot.accept((newModule) => {
|
||||
* if (newModule) {
|
||||
* // newModule is undefined when SyntaxError happened
|
||||
* console.log('updated: count is now ', newModule.count)
|
||||
* }
|
||||
* });
|
||||
* ```
|
||||
*
|
||||
* In production, calls to this are dead-code-eliminated.
|
||||
*/
|
||||
accept(cb: (newModule: any | undefined) => void): void;
|
||||
|
||||
/**
|
||||
* Indicate that a dependency's module can be accepted. When the dependency
|
||||
* is updated, the callback will be called with the new module.
|
||||
*
|
||||
* When `import.meta.hot.accept` is not used, the page will reload when
|
||||
* the file updates, and a console message shows which files were checked.
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* import.meta.hot.accept('./foo', (newModule) => {
|
||||
* if (newModule) {
|
||||
* // newModule is undefined when SyntaxError happened
|
||||
* console.log('updated: count is now ', newModule.count)
|
||||
* }
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
accept(specifier: string, callback: (newModule: any) => void): void;
|
||||
|
||||
/**
|
||||
* Indicate that a dependency's module can be accepted. This variant
|
||||
* accepts an array of dependencies, where the callback will receive
|
||||
* the one updated module, and `undefined` for the rest.
|
||||
*
|
||||
* When `import.meta.hot.accept` is not used, the page will reload when
|
||||
* the file updates, and a console message shows which files were checked.
|
||||
*/
|
||||
accept(specifiers: string[], callback: (newModules: (any | undefined)[]) => void): void;
|
||||
|
||||
/**
|
||||
* Attach an on-dispose callback. This is called:
|
||||
* - Just before the module is replaced with another copy (before the next is loaded)
|
||||
* - After the module is detached (removing all imports to this module)
|
||||
*
|
||||
* This callback is not called on route navigation or when the browser tab closes.
|
||||
*
|
||||
* Returning a promise will delay module replacement until the module is
|
||||
* disposed. All dispose callbacks are called in parallel.
|
||||
*/
|
||||
dispose(cb: (data: any) => void | Promise<void>): void;
|
||||
|
||||
/**
|
||||
* No-op
|
||||
* @deprecated
|
||||
*/
|
||||
decline(): void;
|
||||
|
||||
// NOTE TO CONTRIBUTORS ////////////////////////////////////////
|
||||
// Callback is currently never called for `.prune()` //
|
||||
// so the types are commented out until we support it. //
|
||||
////////////////////////////////////////////////////////////////
|
||||
// /**
|
||||
// * Attach a callback that is called when the module is removed from the module graph.
|
||||
// *
|
||||
// * This can be used to clean up resources that were created when the module was loaded.
|
||||
// * Unlike `import.meta.hot.dispose()`, this pairs much better with `accept` and `data` to manage stateful resources.
|
||||
// *
|
||||
// * @example
|
||||
// * ```ts
|
||||
// * export const ws = (import.meta.hot.data.ws ??= new WebSocket(location.origin));
|
||||
// *
|
||||
// * import.meta.hot.prune(() => {
|
||||
// * ws.close();
|
||||
// * });
|
||||
// * ```
|
||||
// */
|
||||
// prune(callback: () => void): void;
|
||||
|
||||
/**
|
||||
* Listen for an event from the dev server
|
||||
*
|
||||
* For compatibility with Vite, event names are also available via vite:* prefix instead of bun:*.
|
||||
*
|
||||
* https://bun.sh/docs/bundler/hmr#import-meta-hot-on-and-off
|
||||
* @param event The event to listen to
|
||||
* @param callback The callback to call when the event is emitted
|
||||
*/
|
||||
on(event: Bun.HMREvent, callback: () => void): void;
|
||||
|
||||
/**
|
||||
* Stop listening for an event from the dev server
|
||||
*
|
||||
* For compatibility with Vite, event names are also available via vite:* prefix instead of bun:*.
|
||||
*
|
||||
* https://bun.sh/docs/bundler/hmr#import-meta-hot-on-and-off
|
||||
* @param event The event to stop listening to
|
||||
* @param callback The callback to stop listening to
|
||||
*/
|
||||
off(event: Bun.HMREvent, callback: () => void): void;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
78
packages/bun-types/globals.d.ts
vendored
78
packages/bun-types/globals.d.ts
vendored
@@ -76,6 +76,17 @@ declare global {
|
||||
revision: string;
|
||||
reallyExit(code?: number): never;
|
||||
dlopen(module: { exports: any }, filename: string, flags?: number): void;
|
||||
_exiting: boolean;
|
||||
noDeprecation: boolean;
|
||||
|
||||
binding(m: string): object;
|
||||
binding(m: "constants"): {
|
||||
os: typeof import("node:os").constants;
|
||||
fs: typeof import("node:fs").constants;
|
||||
crypto: typeof import("node:crypto").constants;
|
||||
zlib: typeof import("node:zlib").constants;
|
||||
trace: typeof import("node:trace").constants;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1765,6 +1776,71 @@ declare global {
|
||||
*/
|
||||
bytes(): Promise<Uint8Array>;
|
||||
}
|
||||
|
||||
var Blob: typeof Blob;
|
||||
|
||||
interface Uint8Array {
|
||||
/**
|
||||
* Convert the Uint8Array to a base64 encoded string
|
||||
* @returns The base64 encoded string representation of the Uint8Array
|
||||
*/
|
||||
toBase64(options?: { alphabet?: "base64" | "base64url"; omitPadding?: boolean }): string;
|
||||
|
||||
/**
|
||||
* Set the contents of the Uint8Array from a base64 encoded string
|
||||
* @param base64 The base64 encoded string to decode into the array
|
||||
* @param offset Optional starting index to begin setting the decoded bytes (default: 0)
|
||||
*/
|
||||
setFromBase64(
|
||||
base64: string,
|
||||
offset?: number,
|
||||
): {
|
||||
/**
|
||||
* The number of bytes read from the base64 string
|
||||
*/
|
||||
read: number;
|
||||
/**
|
||||
* The number of bytes written to the Uint8Array
|
||||
* Will never be greater than the `.byteLength` of this Uint8Array
|
||||
*/
|
||||
written: number;
|
||||
};
|
||||
|
||||
/**
|
||||
* Convert the Uint8Array to a hex encoded string
|
||||
* @returns The hex encoded string representation of the Uint8Array
|
||||
*/
|
||||
toHex(): string;
|
||||
|
||||
/**
|
||||
* Set the contents of the Uint8Array from a hex encoded string
|
||||
* @param hex The hex encoded string to decode into the array. The string must have
|
||||
* an even number of characters, be valid hexadecimal characters and contain no whitespace.
|
||||
*/
|
||||
setFromHex(hex: string): {
|
||||
/**
|
||||
* The number of bytes read from the hex string
|
||||
*/
|
||||
read: number;
|
||||
/**
|
||||
* The number of bytes written to the Uint8Array
|
||||
* Will never be greater than the `.byteLength` of this Uint8Array
|
||||
*/
|
||||
written: number;
|
||||
};
|
||||
}
|
||||
|
||||
interface Uint8ArrayConstructor {
|
||||
/**
|
||||
* Create a new Uint8Array from a base64 encoded string
|
||||
* @param base64 The base64 encoded string to convert to a Uint8Array
|
||||
* @returns A new Uint8Array containing the decoded data
|
||||
*/
|
||||
fromBase64(
|
||||
base64: string,
|
||||
options?: {
|
||||
alphabet?: "base64" | "base64url";
|
||||
lastChunkHandling?: "loose" | "strict" | "stop-before-partial";
|
||||
},
|
||||
): Uint8Array;
|
||||
}
|
||||
}
|
||||
|
||||
73
packages/bun-types/sqlite.d.ts
vendored
73
packages/bun-types/sqlite.d.ts
vendored
@@ -477,6 +477,79 @@ declare module "bun:sqlite" {
|
||||
*/
|
||||
static deserialize(serialized: NodeJS.TypedArray | ArrayBufferLike, isReadOnly?: boolean): Database;
|
||||
|
||||
/**
|
||||
* Load a serialized SQLite3 database. This version enables you to specify
|
||||
* additional options such as `strict` to put the database into strict mode.
|
||||
*
|
||||
* Internally, this calls `sqlite3_deserialize`.
|
||||
*
|
||||
* @param serialized Data to load
|
||||
* @returns `Database` instance
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* test("supports serialize/deserialize", () => {
|
||||
* const db = Database.open(":memory:");
|
||||
* db.exec("CREATE TABLE test (id INTEGER PRIMARY KEY, name TEXT)");
|
||||
* db.exec('INSERT INTO test (name) VALUES ("Hello")');
|
||||
* db.exec('INSERT INTO test (name) VALUES ("World")');
|
||||
*
|
||||
* const input = db.serialize();
|
||||
* const db2 = Database.deserialize(input, { strict: true });
|
||||
*
|
||||
* const stmt = db2.prepare("SELECT * FROM test");
|
||||
* expect(JSON.stringify(stmt.get())).toBe(
|
||||
* JSON.stringify({
|
||||
* id: 1,
|
||||
* name: "Hello",
|
||||
* }),
|
||||
* );
|
||||
*
|
||||
* expect(JSON.stringify(stmt.all())).toBe(
|
||||
* JSON.stringify([
|
||||
* {
|
||||
* id: 1,
|
||||
* name: "Hello",
|
||||
* },
|
||||
* {
|
||||
* id: 2,
|
||||
* name: "World",
|
||||
* },
|
||||
* ]),
|
||||
* );
|
||||
* db2.exec("insert into test (name) values ($foo)", { foo: "baz" });
|
||||
* expect(JSON.stringify(stmt.all())).toBe(
|
||||
* JSON.stringify([
|
||||
* {
|
||||
* id: 1,
|
||||
* name: "Hello",
|
||||
* },
|
||||
* {
|
||||
* id: 2,
|
||||
* name: "World",
|
||||
* },
|
||||
* {
|
||||
* id: 3,
|
||||
* name: "baz",
|
||||
* },
|
||||
* ]),
|
||||
* );
|
||||
*
|
||||
* const db3 = Database.deserialize(input, { readonly: true, strict: true });
|
||||
* try {
|
||||
* db3.exec("insert into test (name) values ($foo)", { foo: "baz" });
|
||||
* throw new Error("Expected error");
|
||||
* } catch (e) {
|
||||
* expect(e.message).toBe("attempt to write a readonly database");
|
||||
* }
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
static deserialize(
|
||||
serialized: NodeJS.TypedArray | ArrayBufferLike,
|
||||
options?: { readonly?: boolean; strict?: boolean; safeIntegers?: boolean },
|
||||
): Database;
|
||||
|
||||
/**
|
||||
* See `sqlite3_file_control` for more information.
|
||||
* @link https://www.sqlite.org/c3ref/file_control.html
|
||||
|
||||
8
packages/bun-types/test.d.ts
vendored
8
packages/bun-types/test.d.ts
vendored
@@ -165,8 +165,14 @@ declare module "bun:test" {
|
||||
* @param label the label for the tests
|
||||
* @param fn the function that defines the tests
|
||||
*/
|
||||
|
||||
interface FunctionLike {
|
||||
readonly name: string;
|
||||
}
|
||||
export interface Describe {
|
||||
(label: string, fn: () => void): void;
|
||||
(fn: () => void): void;
|
||||
|
||||
(label: number | string | Function | FunctionLike, fn: () => void): void;
|
||||
/**
|
||||
* Skips all other tests, except this group of tests.
|
||||
*
|
||||
|
||||
@@ -2347,174 +2347,6 @@ CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
|
||||
CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
|
||||
CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
|
||||
|
||||
#
|
||||
# Certificate "SwissSign Silver CA - G2"
|
||||
#
|
||||
# Issuer: CN=SwissSign Silver CA - G2,O=SwissSign AG,C=CH
|
||||
# Serial Number:4f:1b:d4:2f:54:bb:2f:4b
|
||||
# Subject: CN=SwissSign Silver CA - G2,O=SwissSign AG,C=CH
|
||||
# Not Valid Before: Wed Oct 25 08:32:46 2006
|
||||
# Not Valid After : Sat Oct 25 08:32:46 2036
|
||||
# Fingerprint (SHA-256): BE:6C:4D:A2:BB:B9:BA:59:B6:F3:93:97:68:37:42:46:C3:C0:05:99:3F:A9:8F:02:0D:1D:ED:BE:D4:8A:81:D5
|
||||
# Fingerprint (SHA1): 9B:AA:E5:9F:56:EE:21:CB:43:5A:BE:25:93:DF:A7:F0:40:D1:1D:CB
|
||||
CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
|
||||
CKA_TOKEN CK_BBOOL CK_TRUE
|
||||
CKA_PRIVATE CK_BBOOL CK_FALSE
|
||||
CKA_MODIFIABLE CK_BBOOL CK_FALSE
|
||||
CKA_LABEL UTF8 "SwissSign Silver CA - G2"
|
||||
CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
|
||||
CKA_SUBJECT MULTILINE_OCTAL
|
||||
\060\107\061\013\060\011\006\003\125\004\006\023\002\103\110\061
|
||||
\025\060\023\006\003\125\004\012\023\014\123\167\151\163\163\123
|
||||
\151\147\156\040\101\107\061\041\060\037\006\003\125\004\003\023
|
||||
\030\123\167\151\163\163\123\151\147\156\040\123\151\154\166\145
|
||||
\162\040\103\101\040\055\040\107\062
|
||||
END
|
||||
CKA_ID UTF8 "0"
|
||||
CKA_ISSUER MULTILINE_OCTAL
|
||||
\060\107\061\013\060\011\006\003\125\004\006\023\002\103\110\061
|
||||
\025\060\023\006\003\125\004\012\023\014\123\167\151\163\163\123
|
||||
\151\147\156\040\101\107\061\041\060\037\006\003\125\004\003\023
|
||||
\030\123\167\151\163\163\123\151\147\156\040\123\151\154\166\145
|
||||
\162\040\103\101\040\055\040\107\062
|
||||
END
|
||||
CKA_SERIAL_NUMBER MULTILINE_OCTAL
|
||||
\002\010\117\033\324\057\124\273\057\113
|
||||
END
|
||||
CKA_VALUE MULTILINE_OCTAL
|
||||
\060\202\005\275\060\202\003\245\240\003\002\001\002\002\010\117
|
||||
\033\324\057\124\273\057\113\060\015\006\011\052\206\110\206\367
|
||||
\015\001\001\005\005\000\060\107\061\013\060\011\006\003\125\004
|
||||
\006\023\002\103\110\061\025\060\023\006\003\125\004\012\023\014
|
||||
\123\167\151\163\163\123\151\147\156\040\101\107\061\041\060\037
|
||||
\006\003\125\004\003\023\030\123\167\151\163\163\123\151\147\156
|
||||
\040\123\151\154\166\145\162\040\103\101\040\055\040\107\062\060
|
||||
\036\027\015\060\066\061\060\062\065\060\070\063\062\064\066\132
|
||||
\027\015\063\066\061\060\062\065\060\070\063\062\064\066\132\060
|
||||
\107\061\013\060\011\006\003\125\004\006\023\002\103\110\061\025
|
||||
\060\023\006\003\125\004\012\023\014\123\167\151\163\163\123\151
|
||||
\147\156\040\101\107\061\041\060\037\006\003\125\004\003\023\030
|
||||
\123\167\151\163\163\123\151\147\156\040\123\151\154\166\145\162
|
||||
\040\103\101\040\055\040\107\062\060\202\002\042\060\015\006\011
|
||||
\052\206\110\206\367\015\001\001\001\005\000\003\202\002\017\000
|
||||
\060\202\002\012\002\202\002\001\000\304\361\207\177\323\170\061
|
||||
\367\070\311\370\303\231\103\274\307\367\274\067\347\116\161\272
|
||||
\113\217\245\163\035\134\156\230\256\003\127\256\070\067\103\057
|
||||
\027\075\037\310\316\150\020\301\170\256\031\003\053\020\372\054
|
||||
\171\203\366\350\271\150\271\125\362\004\104\247\071\371\374\004
|
||||
\213\036\361\242\115\047\371\141\173\272\267\345\242\023\266\353
|
||||
\141\076\320\154\321\346\373\372\136\355\035\264\236\240\065\133
|
||||
\241\222\313\360\111\222\376\205\012\005\076\346\331\013\342\117
|
||||
\273\334\225\067\374\221\351\062\065\042\321\037\072\116\047\205
|
||||
\235\260\025\224\062\332\141\015\107\115\140\102\256\222\107\350
|
||||
\203\132\120\130\351\212\213\271\135\241\334\335\231\112\037\066
|
||||
\147\273\110\344\203\266\067\353\110\072\257\017\147\217\027\007
|
||||
\350\004\312\357\152\061\207\324\300\266\371\224\161\173\147\144
|
||||
\270\266\221\112\102\173\145\056\060\152\014\365\220\356\225\346
|
||||
\362\315\202\354\331\241\112\354\366\262\113\345\105\205\346\155
|
||||
\170\223\004\056\234\202\155\066\251\304\061\144\037\206\203\013
|
||||
\052\364\065\012\170\311\125\317\101\260\107\351\060\237\231\276
|
||||
\141\250\006\204\271\050\172\137\070\331\033\251\070\260\203\177
|
||||
\163\301\303\073\110\052\202\017\041\233\270\314\250\065\303\204
|
||||
\033\203\263\076\276\244\225\151\001\072\211\000\170\004\331\311
|
||||
\364\231\031\253\126\176\133\213\206\071\025\221\244\020\054\011
|
||||
\062\200\140\263\223\300\052\266\030\013\235\176\215\111\362\020
|
||||
\112\177\371\325\106\057\031\222\243\231\247\046\254\273\214\074
|
||||
\346\016\274\107\007\334\163\121\361\160\144\057\010\371\264\107
|
||||
\035\060\154\104\352\051\067\205\222\150\146\274\203\070\376\173
|
||||
\071\056\323\120\360\037\373\136\140\266\251\246\372\047\101\361
|
||||
\233\030\162\362\365\204\164\112\311\147\304\124\256\110\144\337
|
||||
\214\321\156\260\035\341\007\217\010\036\231\234\161\351\114\330
|
||||
\245\367\107\022\037\164\321\121\236\206\363\302\242\043\100\013
|
||||
\163\333\113\246\347\163\006\214\301\240\351\301\131\254\106\372
|
||||
\346\057\370\317\161\234\106\155\271\304\025\215\070\171\003\105
|
||||
\110\357\304\135\327\010\356\207\071\042\206\262\015\017\130\103
|
||||
\367\161\251\110\056\375\352\326\037\002\003\001\000\001\243\201
|
||||
\254\060\201\251\060\016\006\003\125\035\017\001\001\377\004\004
|
||||
\003\002\001\006\060\017\006\003\125\035\023\001\001\377\004\005
|
||||
\060\003\001\001\377\060\035\006\003\125\035\016\004\026\004\024
|
||||
\027\240\315\301\344\101\266\072\133\073\313\105\235\275\034\302
|
||||
\230\372\206\130\060\037\006\003\125\035\043\004\030\060\026\200
|
||||
\024\027\240\315\301\344\101\266\072\133\073\313\105\235\275\034
|
||||
\302\230\372\206\130\060\106\006\003\125\035\040\004\077\060\075
|
||||
\060\073\006\011\140\205\164\001\131\001\003\001\001\060\056\060
|
||||
\054\006\010\053\006\001\005\005\007\002\001\026\040\150\164\164
|
||||
\160\072\057\057\162\145\160\157\163\151\164\157\162\171\056\163
|
||||
\167\151\163\163\163\151\147\156\056\143\157\155\057\060\015\006
|
||||
\011\052\206\110\206\367\015\001\001\005\005\000\003\202\002\001
|
||||
\000\163\306\201\340\047\322\055\017\340\225\060\342\232\101\177
|
||||
\120\054\137\137\142\141\251\206\152\151\030\014\164\111\326\135
|
||||
\204\352\101\122\030\157\130\255\120\126\040\152\306\275\050\151
|
||||
\130\221\334\221\021\065\251\072\035\274\032\245\140\236\330\037
|
||||
\177\105\221\151\331\176\273\170\162\301\006\017\052\316\217\205
|
||||
\160\141\254\240\315\013\270\071\051\126\204\062\116\206\273\075
|
||||
\304\052\331\327\037\162\356\376\121\241\042\101\261\161\002\143
|
||||
\032\202\260\142\253\136\127\022\037\337\313\335\165\240\300\135
|
||||
\171\220\214\033\340\120\346\336\061\376\230\173\160\137\245\220
|
||||
\330\255\370\002\266\157\323\140\335\100\113\042\305\075\255\072
|
||||
\172\237\032\032\107\221\171\063\272\202\334\062\151\003\226\156
|
||||
\037\113\360\161\376\343\147\162\240\261\277\134\213\344\372\231
|
||||
\042\307\204\271\033\215\043\227\077\355\045\340\317\145\273\365
|
||||
\141\004\357\335\036\262\132\101\042\132\241\237\135\054\350\133
|
||||
\311\155\251\014\014\170\252\140\306\126\217\001\132\014\150\274
|
||||
\151\031\171\304\037\176\227\005\277\305\351\044\121\136\324\325
|
||||
\113\123\355\331\043\132\066\003\145\243\301\003\255\101\060\363
|
||||
\106\033\205\220\257\145\265\325\261\344\026\133\170\165\035\227
|
||||
\172\155\131\251\052\217\173\336\303\207\211\020\231\111\163\170
|
||||
\310\075\275\121\065\164\052\325\361\176\151\033\052\273\073\275
|
||||
\045\270\232\132\075\162\141\220\146\207\356\014\326\115\324\021
|
||||
\164\013\152\376\013\003\374\243\125\127\211\376\112\313\256\133
|
||||
\027\005\310\362\215\043\061\123\070\322\055\152\077\202\271\215
|
||||
\010\152\367\136\101\164\156\303\021\176\007\254\051\140\221\077
|
||||
\070\312\127\020\015\275\060\057\307\245\346\101\240\332\256\005
|
||||
\207\232\240\244\145\154\114\011\014\211\272\270\323\271\300\223
|
||||
\212\060\372\215\345\232\153\025\001\116\147\252\332\142\126\076
|
||||
\204\010\146\322\304\066\175\247\076\020\374\210\340\324\200\345
|
||||
\000\275\252\363\116\006\243\172\152\371\142\162\343\011\117\353
|
||||
\233\016\001\043\361\237\273\174\334\334\154\021\227\045\262\362
|
||||
\264\143\024\322\006\052\147\214\203\365\316\352\007\330\232\152
|
||||
\036\354\344\012\273\052\114\353\011\140\071\316\312\142\330\056
|
||||
\156
|
||||
END
|
||||
CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE
|
||||
CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE
|
||||
CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE
|
||||
|
||||
# Trust for "SwissSign Silver CA - G2"
|
||||
# Issuer: CN=SwissSign Silver CA - G2,O=SwissSign AG,C=CH
|
||||
# Serial Number:4f:1b:d4:2f:54:bb:2f:4b
|
||||
# Subject: CN=SwissSign Silver CA - G2,O=SwissSign AG,C=CH
|
||||
# Not Valid Before: Wed Oct 25 08:32:46 2006
|
||||
# Not Valid After : Sat Oct 25 08:32:46 2036
|
||||
# Fingerprint (SHA-256): BE:6C:4D:A2:BB:B9:BA:59:B6:F3:93:97:68:37:42:46:C3:C0:05:99:3F:A9:8F:02:0D:1D:ED:BE:D4:8A:81:D5
|
||||
# Fingerprint (SHA1): 9B:AA:E5:9F:56:EE:21:CB:43:5A:BE:25:93:DF:A7:F0:40:D1:1D:CB
|
||||
CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
|
||||
CKA_TOKEN CK_BBOOL CK_TRUE
|
||||
CKA_PRIVATE CK_BBOOL CK_FALSE
|
||||
CKA_MODIFIABLE CK_BBOOL CK_FALSE
|
||||
CKA_LABEL UTF8 "SwissSign Silver CA - G2"
|
||||
CKA_CERT_SHA1_HASH MULTILINE_OCTAL
|
||||
\233\252\345\237\126\356\041\313\103\132\276\045\223\337\247\360
|
||||
\100\321\035\313
|
||||
END
|
||||
CKA_CERT_MD5_HASH MULTILINE_OCTAL
|
||||
\340\006\241\311\175\317\311\374\015\300\126\165\226\330\142\023
|
||||
END
|
||||
CKA_ISSUER MULTILINE_OCTAL
|
||||
\060\107\061\013\060\011\006\003\125\004\006\023\002\103\110\061
|
||||
\025\060\023\006\003\125\004\012\023\014\123\167\151\163\163\123
|
||||
\151\147\156\040\101\107\061\041\060\037\006\003\125\004\003\023
|
||||
\030\123\167\151\163\163\123\151\147\156\040\123\151\154\166\145
|
||||
\162\040\103\101\040\055\040\107\062
|
||||
END
|
||||
CKA_SERIAL_NUMBER MULTILINE_OCTAL
|
||||
\002\010\117\033\324\057\124\273\057\113
|
||||
END
|
||||
CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
|
||||
CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
|
||||
CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
|
||||
CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
|
||||
|
||||
#
|
||||
# Certificate "SecureTrust CA"
|
||||
#
|
||||
@@ -21231,7 +21063,7 @@ CKA_SERIAL_NUMBER MULTILINE_OCTAL
|
||||
\002\011\000\326\135\233\263\170\201\056\353
|
||||
END
|
||||
CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
|
||||
CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
|
||||
CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
|
||||
CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
|
||||
CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
|
||||
|
||||
@@ -21399,7 +21231,7 @@ CKA_SERIAL_NUMBER MULTILINE_OCTAL
|
||||
\154\040
|
||||
END
|
||||
CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
|
||||
CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
|
||||
CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
|
||||
CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
|
||||
CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
|
||||
|
||||
@@ -21514,7 +21346,7 @@ CKA_SERIAL_NUMBER MULTILINE_OCTAL
|
||||
\112\353
|
||||
END
|
||||
CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
|
||||
CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
|
||||
CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
|
||||
CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
|
||||
CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
|
||||
|
||||
@@ -25970,3 +25802,339 @@ CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
|
||||
CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
|
||||
CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
|
||||
CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
|
||||
|
||||
#
|
||||
# Certificate "D-TRUST BR Root CA 2 2023"
|
||||
#
|
||||
# Issuer: CN=D-TRUST BR Root CA 2 2023,O=D-Trust GmbH,C=DE
|
||||
# Serial Number:73:3b:30:04:48:5b:d9:4d:78:2e:73:4b:c9:a1:dc:66
|
||||
# Subject: CN=D-TRUST BR Root CA 2 2023,O=D-Trust GmbH,C=DE
|
||||
# Not Valid Before: Tue May 09 08:56:31 2023
|
||||
# Not Valid After : Sun May 09 08:56:30 2038
|
||||
# Fingerprint (SHA-256): 05:52:E6:F8:3F:DF:65:E8:FA:96:70:E6:66:DF:28:A4:E2:13:40:B5:10:CB:E5:25:66:F9:7C:4F:B9:4B:2B:D1
|
||||
# Fingerprint (SHA1): 2D:B0:70:EE:71:94:AF:69:68:17:DB:79:CE:58:9F:A0:6B:96:F7:87
|
||||
CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
|
||||
CKA_TOKEN CK_BBOOL CK_TRUE
|
||||
CKA_PRIVATE CK_BBOOL CK_FALSE
|
||||
CKA_MODIFIABLE CK_BBOOL CK_FALSE
|
||||
CKA_LABEL UTF8 "D-TRUST BR Root CA 2 2023"
|
||||
CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
|
||||
CKA_SUBJECT MULTILINE_OCTAL
|
||||
\060\110\061\013\060\011\006\003\125\004\006\023\002\104\105\061
|
||||
\025\060\023\006\003\125\004\012\023\014\104\055\124\162\165\163
|
||||
\164\040\107\155\142\110\061\042\060\040\006\003\125\004\003\023
|
||||
\031\104\055\124\122\125\123\124\040\102\122\040\122\157\157\164
|
||||
\040\103\101\040\062\040\062\060\062\063
|
||||
END
|
||||
CKA_ID UTF8 "0"
|
||||
CKA_ISSUER MULTILINE_OCTAL
|
||||
\060\110\061\013\060\011\006\003\125\004\006\023\002\104\105\061
|
||||
\025\060\023\006\003\125\004\012\023\014\104\055\124\162\165\163
|
||||
\164\040\107\155\142\110\061\042\060\040\006\003\125\004\003\023
|
||||
\031\104\055\124\122\125\123\124\040\102\122\040\122\157\157\164
|
||||
\040\103\101\040\062\040\062\060\062\063
|
||||
END
|
||||
CKA_SERIAL_NUMBER MULTILINE_OCTAL
|
||||
\002\020\163\073\060\004\110\133\331\115\170\056\163\113\311\241
|
||||
\334\146
|
||||
END
|
||||
CKA_VALUE MULTILINE_OCTAL
|
||||
\060\202\005\251\060\202\003\221\240\003\002\001\002\002\020\163
|
||||
\073\060\004\110\133\331\115\170\056\163\113\311\241\334\146\060
|
||||
\015\006\011\052\206\110\206\367\015\001\001\015\005\000\060\110
|
||||
\061\013\060\011\006\003\125\004\006\023\002\104\105\061\025\060
|
||||
\023\006\003\125\004\012\023\014\104\055\124\162\165\163\164\040
|
||||
\107\155\142\110\061\042\060\040\006\003\125\004\003\023\031\104
|
||||
\055\124\122\125\123\124\040\102\122\040\122\157\157\164\040\103
|
||||
\101\040\062\040\062\060\062\063\060\036\027\015\062\063\060\065
|
||||
\060\071\060\070\065\066\063\061\132\027\015\063\070\060\065\060
|
||||
\071\060\070\065\066\063\060\132\060\110\061\013\060\011\006\003
|
||||
\125\004\006\023\002\104\105\061\025\060\023\006\003\125\004\012
|
||||
\023\014\104\055\124\162\165\163\164\040\107\155\142\110\061\042
|
||||
\060\040\006\003\125\004\003\023\031\104\055\124\122\125\123\124
|
||||
\040\102\122\040\122\157\157\164\040\103\101\040\062\040\062\060
|
||||
\062\063\060\202\002\042\060\015\006\011\052\206\110\206\367\015
|
||||
\001\001\001\005\000\003\202\002\017\000\060\202\002\012\002\202
|
||||
\002\001\000\256\377\011\131\221\200\012\112\150\346\044\077\270
|
||||
\247\344\310\072\012\072\026\315\311\043\141\240\223\161\362\253
|
||||
\213\163\217\240\147\145\140\322\124\153\143\121\157\111\063\340
|
||||
\162\007\023\175\070\315\006\222\007\051\122\153\116\167\154\004
|
||||
\323\225\372\335\114\214\331\135\301\141\175\113\347\050\263\104
|
||||
\201\173\121\257\335\063\261\150\174\326\116\114\376\053\150\271
|
||||
\312\146\151\304\354\136\127\177\367\015\307\234\066\066\345\007
|
||||
\140\254\300\114\352\010\154\357\006\174\117\133\050\172\010\374
|
||||
\223\135\233\366\234\264\213\206\272\041\271\364\360\350\131\132
|
||||
\050\241\064\204\032\045\221\266\265\217\357\262\371\200\372\371
|
||||
\075\074\021\162\330\343\057\206\166\305\171\054\301\251\220\223
|
||||
\106\230\147\313\203\152\240\120\043\247\073\366\201\071\340\355
|
||||
\360\271\277\145\361\330\313\172\373\357\163\003\316\000\364\175
|
||||
\327\340\135\073\146\270\334\216\272\203\313\207\166\003\374\045
|
||||
\331\347\043\157\006\375\147\363\340\377\204\274\107\277\265\026
|
||||
\030\106\151\024\314\005\367\333\323\111\254\153\314\253\344\265
|
||||
\013\103\044\136\113\153\115\147\337\326\265\076\117\170\037\224
|
||||
\161\044\352\336\160\374\361\223\376\236\223\132\344\224\132\227
|
||||
\124\014\065\173\137\154\356\000\037\044\354\003\272\002\365\166
|
||||
\364\237\324\232\355\205\054\070\042\057\307\330\057\166\021\117
|
||||
\375\154\134\350\365\216\047\207\177\031\112\041\107\220\035\171
|
||||
\215\034\133\370\317\112\205\344\355\263\133\215\276\304\144\050
|
||||
\135\101\304\156\254\070\132\117\043\164\164\251\022\303\366\322
|
||||
\271\021\025\063\007\221\330\073\067\072\143\060\006\321\305\042
|
||||
\066\050\142\043\020\340\106\314\227\254\326\053\135\144\044\325
|
||||
\356\034\016\336\373\010\132\165\052\366\143\155\316\013\102\276
|
||||
\321\272\160\034\234\041\345\017\061\151\027\327\374\012\264\336
|
||||
\355\200\234\313\222\264\213\365\336\131\242\130\011\245\143\107
|
||||
\013\341\101\062\064\101\331\232\261\331\250\260\033\132\336\015
|
||||
\015\364\342\262\135\065\200\271\201\324\204\151\221\002\313\165
|
||||
\320\215\305\265\075\011\221\011\217\024\241\024\164\171\076\326
|
||||
\311\025\035\244\131\131\042\334\366\212\105\075\074\022\326\076
|
||||
\135\062\057\002\003\001\000\001\243\201\216\060\201\213\060\017
|
||||
\006\003\125\035\023\001\001\377\004\005\060\003\001\001\377\060
|
||||
\035\006\003\125\035\016\004\026\004\024\147\220\360\326\336\265
|
||||
\030\325\106\051\176\134\253\370\236\010\274\144\225\020\060\016
|
||||
\006\003\125\035\017\001\001\377\004\004\003\002\001\006\060\111
|
||||
\006\003\125\035\037\004\102\060\100\060\076\240\074\240\072\206
|
||||
\070\150\164\164\160\072\057\057\143\162\154\056\144\055\164\162
|
||||
\165\163\164\056\156\145\164\057\143\162\154\057\144\055\164\162
|
||||
\165\163\164\137\142\162\137\162\157\157\164\137\143\141\137\062
|
||||
\137\062\060\062\063\056\143\162\154\060\015\006\011\052\206\110
|
||||
\206\367\015\001\001\015\005\000\003\202\002\001\000\064\367\263
|
||||
\167\123\333\060\026\271\055\245\041\361\100\041\165\353\353\110
|
||||
\026\201\075\163\340\236\047\052\353\167\251\023\244\152\012\132
|
||||
\132\024\063\075\150\037\201\256\151\375\214\237\145\154\064\102
|
||||
\331\055\320\177\170\026\261\072\254\043\061\255\136\177\256\347
|
||||
\256\053\372\272\374\074\227\225\100\223\137\303\055\003\243\355
|
||||
\244\157\123\327\372\100\016\060\365\000\040\054\000\114\214\073
|
||||
\264\243\037\266\277\221\062\253\257\222\230\323\026\346\324\321
|
||||
\124\134\103\133\056\256\357\127\052\250\264\157\244\357\015\126
|
||||
\024\332\041\253\040\166\236\003\374\046\270\236\077\076\003\046
|
||||
\346\114\333\235\137\102\204\075\105\003\003\034\131\210\312\334
|
||||
\056\141\044\132\244\352\047\013\163\022\276\122\263\012\317\062
|
||||
\027\342\036\207\032\026\225\110\155\132\340\320\317\011\222\046
|
||||
\146\221\330\243\141\016\252\201\201\177\350\122\202\321\102\347
|
||||
\340\035\030\372\244\205\066\347\206\340\015\353\274\324\311\326
|
||||
\074\103\361\135\111\156\176\201\233\151\265\211\142\217\210\122
|
||||
\330\327\376\047\301\043\305\313\053\002\273\261\137\376\373\103
|
||||
\205\003\106\276\135\306\312\041\046\377\327\002\236\164\112\334
|
||||
\370\023\025\261\201\127\066\313\145\134\321\035\061\167\351\045
|
||||
\303\303\262\062\067\325\361\230\011\344\155\143\200\010\253\006
|
||||
\222\201\324\351\160\217\247\077\262\355\206\214\202\152\065\310
|
||||
\102\132\202\321\122\032\105\017\025\245\000\360\224\173\145\047
|
||||
\127\071\103\317\174\177\346\275\065\263\173\361\031\114\336\072
|
||||
\226\317\351\166\356\003\347\302\103\122\074\152\201\350\301\132
|
||||
\200\275\021\135\223\153\373\307\346\144\077\273\151\034\351\335
|
||||
\045\213\257\164\311\124\100\312\313\223\023\012\355\373\146\222
|
||||
\021\312\365\300\372\330\203\125\003\174\323\305\042\106\165\160
|
||||
\153\171\110\006\052\202\232\277\346\353\026\016\042\105\001\274
|
||||
\335\066\224\064\251\065\046\212\327\227\271\356\010\162\277\064
|
||||
\222\160\203\200\253\070\252\131\150\335\100\244\030\220\262\363
|
||||
\325\003\312\046\312\357\325\307\340\217\123\216\360\000\343\250
|
||||
\355\237\371\255\167\340\053\143\117\236\303\356\067\273\170\011
|
||||
\204\236\271\156\373\051\231\220\350\200\323\237\044
|
||||
END
|
||||
CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE
|
||||
CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE
|
||||
CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE
|
||||
|
||||
# Trust for "D-TRUST BR Root CA 2 2023"
|
||||
# Issuer: CN=D-TRUST BR Root CA 2 2023,O=D-Trust GmbH,C=DE
|
||||
# Serial Number:73:3b:30:04:48:5b:d9:4d:78:2e:73:4b:c9:a1:dc:66
|
||||
# Subject: CN=D-TRUST BR Root CA 2 2023,O=D-Trust GmbH,C=DE
|
||||
# Not Valid Before: Tue May 09 08:56:31 2023
|
||||
# Not Valid After : Sun May 09 08:56:30 2038
|
||||
# Fingerprint (SHA-256): 05:52:E6:F8:3F:DF:65:E8:FA:96:70:E6:66:DF:28:A4:E2:13:40:B5:10:CB:E5:25:66:F9:7C:4F:B9:4B:2B:D1
|
||||
# Fingerprint (SHA1): 2D:B0:70:EE:71:94:AF:69:68:17:DB:79:CE:58:9F:A0:6B:96:F7:87
|
||||
CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
|
||||
CKA_TOKEN CK_BBOOL CK_TRUE
|
||||
CKA_PRIVATE CK_BBOOL CK_FALSE
|
||||
CKA_MODIFIABLE CK_BBOOL CK_FALSE
|
||||
CKA_LABEL UTF8 "D-TRUST BR Root CA 2 2023"
|
||||
CKA_CERT_SHA1_HASH MULTILINE_OCTAL
|
||||
\055\260\160\356\161\224\257\151\150\027\333\171\316\130\237\240
|
||||
\153\226\367\207
|
||||
END
|
||||
CKA_CERT_MD5_HASH MULTILINE_OCTAL
|
||||
\341\011\355\323\140\324\126\033\107\037\267\014\137\033\137\205
|
||||
END
|
||||
CKA_ISSUER MULTILINE_OCTAL
|
||||
\060\110\061\013\060\011\006\003\125\004\006\023\002\104\105\061
|
||||
\025\060\023\006\003\125\004\012\023\014\104\055\124\162\165\163
|
||||
\164\040\107\155\142\110\061\042\060\040\006\003\125\004\003\023
|
||||
\031\104\055\124\122\125\123\124\040\102\122\040\122\157\157\164
|
||||
\040\103\101\040\062\040\062\060\062\063
|
||||
END
|
||||
CKA_SERIAL_NUMBER MULTILINE_OCTAL
|
||||
\002\020\163\073\060\004\110\133\331\115\170\056\163\113\311\241
|
||||
\334\146
|
||||
END
|
||||
CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
|
||||
CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
|
||||
CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
|
||||
CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
|
||||
|
||||
#
|
||||
# Certificate "D-TRUST EV Root CA 2 2023"
|
||||
#
|
||||
# Issuer: CN=D-TRUST EV Root CA 2 2023,O=D-Trust GmbH,C=DE
|
||||
# Serial Number:69:26:09:7e:80:4b:4c:a0:a7:8c:78:62:53:5f:5a:6f
|
||||
# Subject: CN=D-TRUST EV Root CA 2 2023,O=D-Trust GmbH,C=DE
|
||||
# Not Valid Before: Tue May 09 09:10:33 2023
|
||||
# Not Valid After : Sun May 09 09:10:32 2038
|
||||
# Fingerprint (SHA-256): 8E:82:21:B2:E7:D4:00:78:36:A1:67:2F:0D:CC:29:9C:33:BC:07:D3:16:F1:32:FA:1A:20:6D:58:71:50:F1:CE
|
||||
# Fingerprint (SHA1): A5:5B:D8:47:6C:8F:19:F7:4C:F4:6D:6B:B6:C2:79:82:22:DF:54:8B
|
||||
CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
|
||||
CKA_TOKEN CK_BBOOL CK_TRUE
|
||||
CKA_PRIVATE CK_BBOOL CK_FALSE
|
||||
CKA_MODIFIABLE CK_BBOOL CK_FALSE
|
||||
CKA_LABEL UTF8 "D-TRUST EV Root CA 2 2023"
|
||||
CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
|
||||
CKA_SUBJECT MULTILINE_OCTAL
|
||||
\060\110\061\013\060\011\006\003\125\004\006\023\002\104\105\061
|
||||
\025\060\023\006\003\125\004\012\023\014\104\055\124\162\165\163
|
||||
\164\040\107\155\142\110\061\042\060\040\006\003\125\004\003\023
|
||||
\031\104\055\124\122\125\123\124\040\105\126\040\122\157\157\164
|
||||
\040\103\101\040\062\040\062\060\062\063
|
||||
END
|
||||
CKA_ID UTF8 "0"
|
||||
CKA_ISSUER MULTILINE_OCTAL
|
||||
\060\110\061\013\060\011\006\003\125\004\006\023\002\104\105\061
|
||||
\025\060\023\006\003\125\004\012\023\014\104\055\124\162\165\163
|
||||
\164\040\107\155\142\110\061\042\060\040\006\003\125\004\003\023
|
||||
\031\104\055\124\122\125\123\124\040\105\126\040\122\157\157\164
|
||||
\040\103\101\040\062\040\062\060\062\063
|
||||
END
|
||||
CKA_SERIAL_NUMBER MULTILINE_OCTAL
|
||||
\002\020\151\046\011\176\200\113\114\240\247\214\170\142\123\137
|
||||
\132\157
|
||||
END
|
||||
CKA_VALUE MULTILINE_OCTAL
|
||||
\060\202\005\251\060\202\003\221\240\003\002\001\002\002\020\151
|
||||
\046\011\176\200\113\114\240\247\214\170\142\123\137\132\157\060
|
||||
\015\006\011\052\206\110\206\367\015\001\001\015\005\000\060\110
|
||||
\061\013\060\011\006\003\125\004\006\023\002\104\105\061\025\060
|
||||
\023\006\003\125\004\012\023\014\104\055\124\162\165\163\164\040
|
||||
\107\155\142\110\061\042\060\040\006\003\125\004\003\023\031\104
|
||||
\055\124\122\125\123\124\040\105\126\040\122\157\157\164\040\103
|
||||
\101\040\062\040\062\060\062\063\060\036\027\015\062\063\060\065
|
||||
\060\071\060\071\061\060\063\063\132\027\015\063\070\060\065\060
|
||||
\071\060\071\061\060\063\062\132\060\110\061\013\060\011\006\003
|
||||
\125\004\006\023\002\104\105\061\025\060\023\006\003\125\004\012
|
||||
\023\014\104\055\124\162\165\163\164\040\107\155\142\110\061\042
|
||||
\060\040\006\003\125\004\003\023\031\104\055\124\122\125\123\124
|
||||
\040\105\126\040\122\157\157\164\040\103\101\040\062\040\062\060
|
||||
\062\063\060\202\002\042\060\015\006\011\052\206\110\206\367\015
|
||||
\001\001\001\005\000\003\202\002\017\000\060\202\002\012\002\202
|
||||
\002\001\000\330\216\243\211\200\013\262\127\122\334\251\123\114
|
||||
\067\271\177\143\027\023\357\247\133\043\133\151\165\260\231\012
|
||||
\027\301\213\304\333\250\340\314\061\272\302\362\315\135\351\267
|
||||
\370\035\257\152\304\225\207\327\107\311\225\330\202\004\120\075
|
||||
\201\010\377\344\075\263\261\326\305\262\375\210\011\333\234\204
|
||||
\354\045\027\024\207\177\060\170\233\152\130\311\266\163\050\074
|
||||
\064\367\231\367\177\323\246\370\034\105\174\255\054\214\224\077
|
||||
\330\147\020\123\176\042\315\116\045\121\360\045\044\065\021\136
|
||||
\020\306\354\207\146\211\201\150\272\314\053\235\107\163\037\275
|
||||
\315\221\244\162\152\234\242\033\030\240\157\354\120\364\175\100
|
||||
\302\250\060\317\275\163\310\023\053\020\023\036\213\232\250\072
|
||||
\224\163\323\030\151\012\112\377\301\001\003\377\171\177\265\110
|
||||
\177\173\356\350\051\157\066\114\225\141\206\330\371\242\163\212
|
||||
\356\256\057\226\356\150\315\075\115\050\102\371\105\053\062\033
|
||||
\106\125\026\152\246\113\051\371\273\225\126\277\106\035\354\035
|
||||
\223\035\300\145\262\037\241\103\256\126\236\240\261\217\153\022
|
||||
\267\140\155\170\013\312\212\134\355\036\226\016\203\246\110\225
|
||||
\215\073\243\041\304\256\130\306\000\262\204\264\043\244\226\206
|
||||
\065\270\330\236\330\254\064\111\230\143\225\305\313\155\110\107
|
||||
\342\362\056\030\036\320\061\253\335\164\354\371\334\214\270\034
|
||||
\216\150\043\272\320\363\120\334\317\145\217\163\072\062\307\174
|
||||
\376\312\202\042\117\276\216\142\107\146\345\315\207\342\350\325
|
||||
\017\030\237\345\004\162\113\106\074\020\362\104\302\144\126\161
|
||||
\116\165\350\234\311\046\164\305\175\131\321\012\133\017\155\376
|
||||
\236\165\034\030\306\032\072\174\330\015\004\314\315\267\105\145
|
||||
\172\261\217\270\256\204\110\076\263\172\115\250\003\342\342\176
|
||||
\001\026\131\150\030\103\063\260\322\334\260\032\103\065\356\245
|
||||
\332\251\106\134\256\206\201\101\001\112\164\046\354\237\006\277
|
||||
\302\005\067\144\165\170\051\150\375\305\365\353\376\107\371\344
|
||||
\205\260\341\173\061\235\246\177\162\243\271\304\054\056\314\231
|
||||
\127\016\041\014\105\001\224\145\353\145\011\306\143\042\013\063
|
||||
\111\222\110\074\374\315\316\260\076\216\236\213\370\376\111\305
|
||||
\065\162\107\002\003\001\000\001\243\201\216\060\201\213\060\017
|
||||
\006\003\125\035\023\001\001\377\004\005\060\003\001\001\377\060
|
||||
\035\006\003\125\035\016\004\026\004\024\252\374\221\020\033\207
|
||||
\221\137\026\271\277\117\113\221\136\000\034\261\062\200\060\016
|
||||
\006\003\125\035\017\001\001\377\004\004\003\002\001\006\060\111
|
||||
\006\003\125\035\037\004\102\060\100\060\076\240\074\240\072\206
|
||||
\070\150\164\164\160\072\057\057\143\162\154\056\144\055\164\162
|
||||
\165\163\164\056\156\145\164\057\143\162\154\057\144\055\164\162
|
||||
\165\163\164\137\145\166\137\162\157\157\164\137\143\141\137\062
|
||||
\137\062\060\062\063\056\143\162\154\060\015\006\011\052\206\110
|
||||
\206\367\015\001\001\015\005\000\003\202\002\001\000\223\313\245
|
||||
\037\231\021\354\232\015\137\054\025\223\306\077\276\020\215\170
|
||||
\102\360\156\220\107\107\216\243\222\062\215\160\217\366\133\215
|
||||
\276\211\316\107\001\152\033\040\040\211\133\310\202\020\154\340
|
||||
\347\231\252\153\306\052\240\143\065\221\152\205\045\255\027\070
|
||||
\245\233\176\120\362\166\352\205\005\052\047\101\053\261\201\321
|
||||
\242\366\100\165\251\016\313\361\125\110\330\354\321\354\263\350
|
||||
\316\024\241\065\354\302\136\065\032\253\246\026\001\006\216\352
|
||||
\334\057\243\212\312\054\221\353\122\216\137\014\233\027\317\313
|
||||
\163\007\031\304\152\302\163\124\357\174\103\122\143\301\021\312
|
||||
\302\105\261\364\073\123\365\151\256\074\343\245\336\254\350\124
|
||||
\267\262\221\375\254\251\037\362\207\344\027\306\111\250\174\330
|
||||
\012\101\364\362\076\347\167\064\004\122\335\350\201\362\115\057
|
||||
\124\105\235\025\341\117\314\345\336\064\127\020\311\043\162\027
|
||||
\160\215\120\160\037\126\154\314\271\377\072\132\117\143\172\303
|
||||
\156\145\007\035\204\241\377\251\014\143\211\155\262\100\210\071
|
||||
\327\037\167\150\265\374\234\325\326\147\151\133\250\164\333\374
|
||||
\211\366\033\062\367\244\044\246\166\267\107\123\357\215\111\217
|
||||
\251\266\203\132\245\226\220\105\141\365\336\003\117\046\017\250
|
||||
\213\360\003\226\260\254\025\320\161\132\152\173\224\346\160\223
|
||||
\332\361\151\340\262\142\115\236\217\377\211\235\233\135\315\105
|
||||
\351\224\002\042\215\340\065\177\350\361\004\171\161\154\124\203
|
||||
\370\063\271\005\062\033\130\125\021\117\320\345\047\107\161\354
|
||||
\355\332\147\326\142\246\113\115\017\151\242\311\274\354\042\113
|
||||
\224\307\150\224\027\176\342\216\050\076\266\306\352\365\064\154
|
||||
\237\067\210\007\070\333\206\161\372\315\225\110\103\156\243\117
|
||||
\202\207\327\064\230\156\113\223\171\140\165\151\017\360\032\325
|
||||
\123\372\041\014\302\077\351\077\037\030\214\222\135\170\247\166
|
||||
\147\031\273\262\352\177\351\160\011\126\126\243\260\014\013\055
|
||||
\066\136\305\351\304\325\203\313\206\027\227\054\154\023\157\207
|
||||
\132\257\111\246\035\333\315\070\004\056\137\342\112\065\016\055
|
||||
\113\370\242\044\004\215\330\341\143\136\002\222\064\332\230\141
|
||||
\134\034\157\130\166\144\263\374\002\270\365\235\012
|
||||
END
|
||||
CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE
|
||||
CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE
|
||||
CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE
|
||||
|
||||
# Trust for "D-TRUST EV Root CA 2 2023"
|
||||
# Issuer: CN=D-TRUST EV Root CA 2 2023,O=D-Trust GmbH,C=DE
|
||||
# Serial Number:69:26:09:7e:80:4b:4c:a0:a7:8c:78:62:53:5f:5a:6f
|
||||
# Subject: CN=D-TRUST EV Root CA 2 2023,O=D-Trust GmbH,C=DE
|
||||
# Not Valid Before: Tue May 09 09:10:33 2023
|
||||
# Not Valid After : Sun May 09 09:10:32 2038
|
||||
# Fingerprint (SHA-256): 8E:82:21:B2:E7:D4:00:78:36:A1:67:2F:0D:CC:29:9C:33:BC:07:D3:16:F1:32:FA:1A:20:6D:58:71:50:F1:CE
|
||||
# Fingerprint (SHA1): A5:5B:D8:47:6C:8F:19:F7:4C:F4:6D:6B:B6:C2:79:82:22:DF:54:8B
|
||||
CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
|
||||
CKA_TOKEN CK_BBOOL CK_TRUE
|
||||
CKA_PRIVATE CK_BBOOL CK_FALSE
|
||||
CKA_MODIFIABLE CK_BBOOL CK_FALSE
|
||||
CKA_LABEL UTF8 "D-TRUST EV Root CA 2 2023"
|
||||
CKA_CERT_SHA1_HASH MULTILINE_OCTAL
|
||||
\245\133\330\107\154\217\031\367\114\364\155\153\266\302\171\202
|
||||
\042\337\124\213
|
||||
END
|
||||
CKA_CERT_MD5_HASH MULTILINE_OCTAL
|
||||
\226\264\170\011\360\011\313\167\353\273\033\115\157\066\274\266
|
||||
END
|
||||
CKA_ISSUER MULTILINE_OCTAL
|
||||
\060\110\061\013\060\011\006\003\125\004\006\023\002\104\105\061
|
||||
\025\060\023\006\003\125\004\012\023\014\104\055\124\162\165\163
|
||||
\164\040\107\155\142\110\061\042\060\040\006\003\125\004\003\023
|
||||
\031\104\055\124\122\125\123\124\040\105\126\040\122\157\157\164
|
||||
\040\103\101\040\062\040\062\060\062\063
|
||||
END
|
||||
CKA_SERIAL_NUMBER MULTILINE_OCTAL
|
||||
\002\020\151\046\011\176\200\113\114\240\247\214\170\142\123\137
|
||||
\132\157
|
||||
END
|
||||
CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
|
||||
CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
|
||||
CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
|
||||
CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
|
||||
|
||||
@@ -72,7 +72,7 @@ void us_socket_context_close(int ssl, struct us_socket_context_t *context) {
|
||||
while (ls) {
|
||||
struct us_listen_socket_t *nextLS = (struct us_listen_socket_t *) ls->s.next;
|
||||
us_listen_socket_close(ssl, ls);
|
||||
|
||||
|
||||
ls = nextLS;
|
||||
}
|
||||
|
||||
@@ -310,7 +310,7 @@ struct us_bun_verify_error_t us_socket_verify_error(int ssl, struct us_socket_t
|
||||
}
|
||||
#endif
|
||||
|
||||
return (struct us_bun_verify_error_t) { .error = 0, .code = NULL, .reason = NULL };
|
||||
return (struct us_bun_verify_error_t) { .error = 0, .code = NULL, .reason = NULL };
|
||||
}
|
||||
|
||||
void us_internal_socket_context_free(int ssl, struct us_socket_context_t *context) {
|
||||
@@ -337,7 +337,7 @@ void us_socket_context_ref(int ssl, struct us_socket_context_t *context) {
|
||||
}
|
||||
void us_socket_context_unref(int ssl, struct us_socket_context_t *context) {
|
||||
uint32_t ref_count = context->ref_count;
|
||||
context->ref_count--;
|
||||
context->ref_count--;
|
||||
if (ref_count == 1) {
|
||||
us_internal_socket_context_free(ssl, context);
|
||||
}
|
||||
@@ -520,7 +520,7 @@ void *us_socket_context_connect(int ssl, struct us_socket_context_t *context, co
|
||||
}
|
||||
|
||||
struct us_connecting_socket_t *c = us_calloc(1, sizeof(struct us_connecting_socket_t) + socket_ext_size);
|
||||
c->socket_ext_size = socket_ext_size;
|
||||
c->socket_ext_size = socket_ext_size;
|
||||
c->options = options;
|
||||
c->ssl = ssl > 0;
|
||||
c->timeout = 255;
|
||||
@@ -641,9 +641,9 @@ void us_internal_socket_after_open(struct us_socket_t *s, int error) {
|
||||
|
||||
/* Emit error, close without emitting on_close */
|
||||
|
||||
/* There are two possible states here:
|
||||
1. It's a us_connecting_socket_t*. DNS resolution failed, or a connection failed.
|
||||
2. It's a us_socket_t*
|
||||
/* There are two possible states here:
|
||||
1. It's a us_connecting_socket_t*. DNS resolution failed, or a connection failed.
|
||||
2. It's a us_socket_t*
|
||||
|
||||
We differentiate between these two cases by checking if the connect_state is null.
|
||||
*/
|
||||
@@ -887,7 +887,7 @@ void us_socket_context_on_connect_error(int ssl, struct us_socket_context_t *con
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
context->on_connect_error = on_connect_error;
|
||||
}
|
||||
|
||||
@@ -898,7 +898,7 @@ void us_socket_context_on_socket_connect_error(int ssl, struct us_socket_context
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
context->on_socket_connect_error = on_connect_error;
|
||||
}
|
||||
|
||||
|
||||
@@ -381,38 +381,6 @@ static struct us_cert_string_t root_certs[] = {
|
||||
"W8mw0FfB+j564ZfJ\n"
|
||||
"-----END CERTIFICATE-----",.len=2041},
|
||||
|
||||
/* SwissSign Silver CA - G2 */
|
||||
{.str="-----BEGIN CERTIFICATE-----\n"
|
||||
"MIIFvTCCA6WgAwIBAgIITxvUL1S7L0swDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UEBhMCQ0gx\n"
|
||||
"FTATBgNVBAoTDFN3aXNzU2lnbiBBRzEhMB8GA1UEAxMYU3dpc3NTaWduIFNpbHZlciBDQSAt\n"
|
||||
"IEcyMB4XDTA2MTAyNTA4MzI0NloXDTM2MTAyNTA4MzI0NlowRzELMAkGA1UEBhMCQ0gxFTAT\n"
|
||||
"BgNVBAoTDFN3aXNzU2lnbiBBRzEhMB8GA1UEAxMYU3dpc3NTaWduIFNpbHZlciBDQSAtIEcy\n"
|
||||
"MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxPGHf9N4Mfc4yfjDmUO8x/e8N+dO\n"
|
||||
"cbpLj6VzHVxumK4DV644N0MvFz0fyM5oEMF4rhkDKxD6LHmD9ui5aLlV8gREpzn5/ASLHvGi\n"
|
||||
"TSf5YXu6t+WiE7brYT7QbNHm+/pe7R20nqA1W6GSy/BJkv6FCgU+5tkL4k+73JU3/JHpMjUi\n"
|
||||
"0R86TieFnbAVlDLaYQ1HTWBCrpJH6INaUFjpiou5XaHc3ZlKHzZnu0jkg7Y360g6rw9njxcH\n"
|
||||
"6ATK72oxh9TAtvmUcXtnZLi2kUpCe2UuMGoM9ZDulebyzYLs2aFK7PayS+VFheZteJMELpyC\n"
|
||||
"bTapxDFkH4aDCyr0NQp4yVXPQbBH6TCfmb5hqAaEuSh6XzjZG6k4sIN/c8HDO0gqgg8hm7jM\n"
|
||||
"qDXDhBuDsz6+pJVpATqJAHgE2cn0mRmrVn5bi4Y5FZGkECwJMoBgs5PAKrYYC51+jUnyEEp/\n"
|
||||
"+dVGLxmSo5mnJqy7jDzmDrxHB9xzUfFwZC8I+bRHHTBsROopN4WSaGa8gzj+ezku01DwH/te\n"
|
||||
"YLappvonQfGbGHLy9YR0SslnxFSuSGTfjNFusB3hB48IHpmccelM2KX3RxIfdNFRnobzwqIj\n"
|
||||
"QAtz20um53MGjMGg6cFZrEb65i/4z3GcRm25xBWNOHkDRUjvxF3XCO6HOSKGsg0PWEP3calI\n"
|
||||
"Lv3q1h8CAwEAAaOBrDCBqTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV\n"
|
||||
"HQ4EFgQUF6DNweRBtjpbO8tFnb0cwpj6hlgwHwYDVR0jBBgwFoAUF6DNweRBtjpbO8tFnb0c\n"
|
||||
"wpj6hlgwRgYDVR0gBD8wPTA7BglghXQBWQEDAQEwLjAsBggrBgEFBQcCARYgaHR0cDovL3Jl\n"
|
||||
"cG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIBAHPGgeAn0i0P4JUw\n"
|
||||
"4ppBf1AsX19iYamGamkYDHRJ1l2E6kFSGG9YrVBWIGrGvShpWJHckRE1qTodvBqlYJ7YH39F\n"
|
||||
"kWnZfrt4csEGDyrOj4VwYaygzQu4OSlWhDJOhrs9xCrZ1x9y7v5RoSJBsXECYxqCsGKrXlcS\n"
|
||||
"H9/L3XWgwF15kIwb4FDm3jH+mHtwX6WQ2K34ArZv02DdQEsixT2tOnqfGhpHkXkzuoLcMmkD\n"
|
||||
"lm4fS/Bx/uNncqCxv1yL5PqZIseEuRuNI5c/7SXgz2W79WEE790eslpBIlqhn10s6FvJbakM\n"
|
||||
"DHiqYMZWjwFaDGi8aRl5xB9+lwW/xekkUV7U1UtT7dkjWjYDZaPBA61BMPNGG4WQr2W11bHk\n"
|
||||
"Flt4dR2Xem1ZqSqPe97Dh4kQmUlzeMg9vVE1dCrV8X5pGyq7O70luJpaPXJhkGaH7gzWTdQR\n"
|
||||
"dAtq/gsD/KNVV4n+SsuuWxcFyPKNIzFTONItaj+CuY0IavdeQXRuwxF+B6wpYJE/OMpXEA29\n"
|
||||
"MC/HpeZBoNquBYeaoKRlbEwJDIm6uNO5wJOKMPqN5ZprFQFOZ6raYlY+hAhm0sQ2fac+EPyI\n"
|
||||
"4NSA5QC9qvNOBqN6avlicuMJT+ubDgEj8Z+7fNzcbBGXJbLytGMU0gYqZ4yD9c7qB9iaah7s\n"
|
||||
"5Aq7KkzrCWA5zspi2C5u\n"
|
||||
"-----END CERTIFICATE-----",.len=2045},
|
||||
|
||||
/* SecureTrust CA */
|
||||
{.str="-----BEGIN CERTIFICATE-----\n"
|
||||
"MIIDuDCCAqCgAwIBAgIQDPCOXAgWpa1Cf/DrJxhZ0DANBgkqhkiG9w0BAQUFADBIMQswCQYD\n"
|
||||
@@ -3625,4 +3593,66 @@ static struct us_cert_string_t root_certs[] = {
|
||||
"4E/0BdGF9jVg3PVys0Z9AjBEmEYagoUeYWmJSwdLZrWeqrqgHkHZAXQ6bkU6iYAZezKYVWOr\n"
|
||||
"62Nuk22rGwlgMU4=\n"
|
||||
"-----END CERTIFICATE-----",.len=800},
|
||||
|
||||
/* D-TRUST BR Root CA 2 2023 */
|
||||
{.str="-----BEGIN CERTIFICATE-----\n"
|
||||
"MIIFqTCCA5GgAwIBAgIQczswBEhb2U14LnNLyaHcZjANBgkqhkiG9w0BAQ0FADBIMQswCQYD\n"
|
||||
"VQQGEwJERTEVMBMGA1UEChMMRC1UcnVzdCBHbWJIMSIwIAYDVQQDExlELVRSVVNUIEJSIFJv\n"
|
||||
"b3QgQ0EgMiAyMDIzMB4XDTIzMDUwOTA4NTYzMVoXDTM4MDUwOTA4NTYzMFowSDELMAkGA1UE\n"
|
||||
"BhMCREUxFTATBgNVBAoTDEQtVHJ1c3QgR21iSDEiMCAGA1UEAxMZRC1UUlVTVCBCUiBSb290\n"
|
||||
"IENBIDIgMjAyMzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK7/CVmRgApKaOYk\n"
|
||||
"P7in5Mg6CjoWzckjYaCTcfKri3OPoGdlYNJUa2NRb0kz4HIHE304zQaSBylSa053bATTlfrd\n"
|
||||
"TIzZXcFhfUvnKLNEgXtRr90zsWh81k5M/itoucpmacTsXld/9w3HnDY25QdgrMBM6ghs7wZ8\n"
|
||||
"T1soegj8k12b9py0i4a6Ibn08OhZWiihNIQaJZG2tY/vsvmA+vk9PBFy2OMvhnbFeSzBqZCT\n"
|
||||
"Rphny4NqoFAjpzv2gTng7fC5v2Xx2Mt6++9zA84A9H3X4F07ZrjcjrqDy4d2A/wl2ecjbwb9\n"
|
||||
"Z/Pg/4S8R7+1FhhGaRTMBffb00msa8yr5LULQyReS2tNZ9/WtT5PeB+UcSTq3nD88ZP+npNa\n"
|
||||
"5JRal1QMNXtfbO4AHyTsA7oC9Xb0n9Sa7YUsOCIvx9gvdhFP/Wxc6PWOJ4d/GUohR5AdeY0c\n"
|
||||
"W/jPSoXk7bNbjb7EZChdQcRurDhaTyN0dKkSw/bSuREVMweR2Ds3OmMwBtHFIjYoYiMQ4EbM\n"
|
||||
"l6zWK11kJNXuHA7e+whadSr2Y23OC0K+0bpwHJwh5Q8xaRfX/Aq03u2AnMuStIv13lmiWAml\n"
|
||||
"Y0cL4UEyNEHZmrHZqLAbWt4NDfTisl01gLmB1IRpkQLLddCNxbU9CZEJjxShFHR5PtbJFR2k\n"
|
||||
"WVki3PaKRT08EtY+XTIvAgMBAAGjgY4wgYswDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU\n"
|
||||
"Z5Dw1t61GNVGKX5cq/ieCLxklRAwDgYDVR0PAQH/BAQDAgEGMEkGA1UdHwRCMEAwPqA8oDqG\n"
|
||||
"OGh0dHA6Ly9jcmwuZC10cnVzdC5uZXQvY3JsL2QtdHJ1c3RfYnJfcm9vdF9jYV8yXzIwMjMu\n"
|
||||
"Y3JsMA0GCSqGSIb3DQEBDQUAA4ICAQA097N3U9swFrktpSHxQCF16+tIFoE9c+CeJyrrd6kT\n"
|
||||
"pGoKWloUMz1oH4Guaf2Mn2VsNELZLdB/eBaxOqwjMa1ef67nriv6uvw8l5VAk1/DLQOj7aRv\n"
|
||||
"U9f6QA4w9QAgLABMjDu0ox+2v5Eyq6+SmNMW5tTRVFxDWy6u71cqqLRvpO8NVhTaIasgdp4D\n"
|
||||
"/Ca4nj8+AybmTNudX0KEPUUDAxxZiMrcLmEkWqTqJwtzEr5SswrPMhfiHocaFpVIbVrg0M8J\n"
|
||||
"kiZmkdijYQ6qgYF/6FKC0ULn4B0Y+qSFNueG4A3rvNTJ1jxD8V1Jbn6Bm2m1iWKPiFLY1/4n\n"
|
||||
"wSPFyysCu7Ff/vtDhQNGvl3GyiEm/9cCnnRK3PgTFbGBVzbLZVzRHTF36SXDw7IyN9XxmAnk\n"
|
||||
"bWOACKsGkoHU6XCPpz+y7YaMgmo1yEJagtFSGkUPFaUA8JR7ZSdXOUPPfH/mvTWze/EZTN46\n"
|
||||
"ls/pdu4D58JDUjxqgejBWoC9EV2Ta/vH5mQ/u2kc6d0li690yVRAysuTEwrt+2aSEcr1wPrY\n"
|
||||
"g1UDfNPFIkZ1cGt5SAYqgpq/5usWDiJFAbzdNpQ0qTUmiteXue4Icr80knCDgKs4qllo3UCk\n"
|
||||
"GJCy89UDyibK79XH4I9TjvAA46jtn/mtd+ArY0+ew+43u3gJhJ65bvspmZDogNOfJA==\n"
|
||||
"-----END CERTIFICATE-----",.len=2020},
|
||||
|
||||
/* D-TRUST EV Root CA 2 2023 */
|
||||
{.str="-----BEGIN CERTIFICATE-----\n"
|
||||
"MIIFqTCCA5GgAwIBAgIQaSYJfoBLTKCnjHhiU19abzANBgkqhkiG9w0BAQ0FADBIMQswCQYD\n"
|
||||
"VQQGEwJERTEVMBMGA1UEChMMRC1UcnVzdCBHbWJIMSIwIAYDVQQDExlELVRSVVNUIEVWIFJv\n"
|
||||
"b3QgQ0EgMiAyMDIzMB4XDTIzMDUwOTA5MTAzM1oXDTM4MDUwOTA5MTAzMlowSDELMAkGA1UE\n"
|
||||
"BhMCREUxFTATBgNVBAoTDEQtVHJ1c3QgR21iSDEiMCAGA1UEAxMZRC1UUlVTVCBFViBSb290\n"
|
||||
"IENBIDIgMjAyMzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANiOo4mAC7JXUtyp\n"
|
||||
"U0w3uX9jFxPvp1sjW2l1sJkKF8GLxNuo4MwxusLyzV3pt/gdr2rElYfXR8mV2IIEUD2BCP/k\n"
|
||||
"PbOx1sWy/YgJ25yE7CUXFId/MHibaljJtnMoPDT3mfd/06b4HEV8rSyMlD/YZxBTfiLNTiVR\n"
|
||||
"8CUkNRFeEMbsh2aJgWi6zCudR3Mfvc2RpHJqnKIbGKBv7FD0fUDCqDDPvXPIEysQEx6Lmqg6\n"
|
||||
"lHPTGGkKSv/BAQP/eX+1SH977ugpbzZMlWGG2Pmic4ruri+W7mjNPU0oQvlFKzIbRlUWaqZL\n"
|
||||
"Kfm7lVa/Rh3sHZMdwGWyH6FDrlaeoLGPaxK3YG14C8qKXO0elg6DpkiVjTujIcSuWMYAsoS0\n"
|
||||
"I6SWhjW42J7YrDRJmGOVxcttSEfi8i4YHtAxq9107PncjLgcjmgjutDzUNzPZY9zOjLHfP7K\n"
|
||||
"giJPvo5iR2blzYfi6NUPGJ/lBHJLRjwQ8kTCZFZxTnXonMkmdMV9WdEKWw9t/p51HBjGGjp8\n"
|
||||
"2A0EzM23RWV6sY+4roRIPrN6TagD4uJ+ARZZaBhDM7DS3LAaQzXupdqpRlyuhoFBAUp0Juyf\n"
|
||||
"Br/CBTdkdXgpaP3F9ev+R/nkhbDhezGdpn9yo7nELC7MmVcOIQxFAZRl62UJxmMiCzNJkkg8\n"
|
||||
"/M3OsD6Onov4/knFNXJHAgMBAAGjgY4wgYswDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU\n"
|
||||
"qvyREBuHkV8Wub9PS5FeAByxMoAwDgYDVR0PAQH/BAQDAgEGMEkGA1UdHwRCMEAwPqA8oDqG\n"
|
||||
"OGh0dHA6Ly9jcmwuZC10cnVzdC5uZXQvY3JsL2QtdHJ1c3RfZXZfcm9vdF9jYV8yXzIwMjMu\n"
|
||||
"Y3JsMA0GCSqGSIb3DQEBDQUAA4ICAQCTy6UfmRHsmg1fLBWTxj++EI14QvBukEdHjqOSMo1w\n"
|
||||
"j/Zbjb6JzkcBahsgIIlbyIIQbODnmaprxiqgYzWRaoUlrRc4pZt+UPJ26oUFKidBK7GB0aL2\n"
|
||||
"QHWpDsvxVUjY7NHss+jOFKE17MJeNRqrphYBBo7q3C+jisosketSjl8MmxfPy3MHGcRqwnNU\n"
|
||||
"73xDUmPBEcrCRbH0O1P1aa4846XerOhUt7KR/aypH/KH5BfGSah82ApB9PI+53c0BFLd6IHy\n"
|
||||
"TS9URZ0V4U/M5d40VxDJI3IXcI1QcB9WbMy5/zpaT2N6w25lBx2Eof+pDGOJbbJAiDnXH3do\n"
|
||||
"tfyc1dZnaVuodNv8ifYbMvekJKZ2t0dT741Jj6m2g1qllpBFYfXeA08mD6iL8AOWsKwV0HFa\n"
|
||||
"anuU5nCT2vFp4LJiTZ6P/4mdm13NRemUAiKN4DV/6PEEeXFsVIP4M7kFMhtYVRFP0OUnR3Hs\n"
|
||||
"7dpn1mKmS00PaaLJvOwiS5THaJQXfuKOKD62xur1NGyfN4gHONuGcfrNlUhDbqNPgofXNJhu\n"
|
||||
"S5N5YHVpD/Aa1VP6IQzCP+k/HxiMkl14p3ZnGbuy6n/pcAlWVqOwDAstNl7F6cTVg8uGF5cs\n"
|
||||
"bBNvh1qvSaYd2804BC5f4ko1Di1L+KIkBI3Y4WNeApI02phhXBxvWHZks/wCuPWdCg==\n"
|
||||
"-----END CERTIFICATE-----",.len=2020},
|
||||
};
|
||||
|
||||
@@ -270,7 +270,6 @@ void us_loop_run_bun_tick(struct us_loop_t *loop, const struct timespec* timeout
|
||||
|
||||
/* Fetch ready polls */
|
||||
#ifdef LIBUS_USE_EPOLL
|
||||
|
||||
loop->num_ready_polls = bun_epoll_pwait2(loop->fd, loop->ready_polls, 1024, timeout);
|
||||
#else
|
||||
do {
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <errno.h>
|
||||
|
||||
#ifndef WIN32
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
@@ -168,13 +167,17 @@ void us_connecting_socket_close(int ssl, struct us_connecting_socket_t *c) {
|
||||
if (!c->pending_resolve_callback) {
|
||||
us_connecting_socket_free(ssl, c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct us_socket_t *us_socket_close(int ssl, struct us_socket_t *s, int code, void *reason) {
|
||||
if(ssl) {
|
||||
return (struct us_socket_t *)us_internal_ssl_socket_close((struct us_internal_ssl_socket_t *) s, code, reason);
|
||||
}
|
||||
|
||||
if (!us_socket_is_closed(0, s)) {
|
||||
/* make sure the context is alive until the callback ends */
|
||||
us_socket_context_ref(ssl, s->context);
|
||||
|
||||
if (s->low_prio_state == 1) {
|
||||
/* Unlink this socket from the low-priority queue */
|
||||
if (!s->prev) s->context->loop->data.low_prio_head = s->next;
|
||||
@@ -186,7 +189,6 @@ struct us_socket_t *us_socket_close(int ssl, struct us_socket_t *s, int code, vo
|
||||
s->next = 0;
|
||||
s->low_prio_state = 0;
|
||||
us_socket_context_unref(ssl, s->context);
|
||||
|
||||
} else {
|
||||
us_internal_socket_context_unlink_socket(ssl, s->context, s);
|
||||
}
|
||||
@@ -207,18 +209,27 @@ struct us_socket_t *us_socket_close(int ssl, struct us_socket_t *s, int code, vo
|
||||
|
||||
bsd_close_socket(us_poll_fd((struct us_poll_t *) s));
|
||||
|
||||
/* Link this socket to the close-list and let it be deleted after this iteration */
|
||||
s->next = s->context->loop->data.closed_head;
|
||||
s->context->loop->data.closed_head = s;
|
||||
|
||||
/* Any socket with prev = context is marked as closed */
|
||||
s->prev = (struct us_socket_t *) s->context;
|
||||
|
||||
/* mark it as closed and call the callback */
|
||||
struct us_socket_t *res = s;
|
||||
if (!(us_internal_poll_type(&s->p) & POLL_TYPE_SEMI_SOCKET)) {
|
||||
return s->context->on_close(s, code, reason);
|
||||
res = s->context->on_close(s, code, reason);
|
||||
}
|
||||
|
||||
|
||||
/* Link this socket to the close-list and let it be deleted after this iteration */
|
||||
s->next = s->context->loop->data.closed_head;
|
||||
s->context->loop->data.closed_head = s;
|
||||
|
||||
/* unref the context after the callback ends */
|
||||
us_socket_context_unref(ssl, s->context);
|
||||
|
||||
/* preserve the return value from on_close if its called */
|
||||
return res;
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
@@ -435,18 +446,18 @@ int us_connecting_socket_get_error(int ssl, struct us_connecting_socket_t *c) {
|
||||
return c->error;
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
Note: this assumes that the socket is non-TLS and will be adopted and wrapped with a new TLS context
|
||||
context ext will not be copied to the new context, new context will contain us_wrapped_socket_context_t on ext
|
||||
*/
|
||||
struct us_socket_t *us_socket_wrap_with_tls(int ssl, struct us_socket_t *s, struct us_bun_socket_context_options_t options, struct us_socket_events_t events, int socket_ext_size) {
|
||||
// only accepts non-TLS sockets
|
||||
if (ssl) {
|
||||
return NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return(struct us_socket_t *) us_internal_ssl_socket_wrap_with_tls(s, options, events, socket_ext_size);
|
||||
}
|
||||
}
|
||||
|
||||
// if a TLS socket calls this, it will start SSL call open event and TLS handshake if required
|
||||
// will have no effect if the socket is closed or is not TLS
|
||||
@@ -503,9 +514,14 @@ void us_socket_nodelay(struct us_socket_t *s, int enabled) {
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns 0 on success. Returned error values depend on the platform.
|
||||
/// - on posix, returns `errno`
|
||||
/// - on windows, when libuv is used, returns a UV err code
|
||||
/// - on windows, LIBUS_USE_LIBUV is set, returns `WSAGetLastError()`
|
||||
/// - on windows, otherwise returns result of `WSAGetLastError`
|
||||
int us_socket_keepalive(us_socket_r s, int enabled, unsigned int delay){
|
||||
if (!us_socket_is_shut_down(0, s)) {
|
||||
bsd_socket_keepalive(us_poll_fd((struct us_poll_t *) s), enabled, delay);
|
||||
return bsd_socket_keepalive(us_poll_fd((struct us_poll_t *) s), enabled, delay);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -544,4 +560,4 @@ void us_socket_resume(int ssl, struct us_socket_t *s) {
|
||||
}
|
||||
// we are readable and writable so we resume everything
|
||||
us_poll_change(&s->p, s->context->loop, LIBUS_SOCKET_READABLE | LIBUS_SOCKET_WRITABLE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -189,6 +189,10 @@ public:
|
||||
* This function should probably be optimized a lot in future releases,
|
||||
* it could be O(1) with a hash map of fullnames and their counts. */
|
||||
unsigned int numSubscribers(std::string_view topic) {
|
||||
if (!topicTree) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
Topic *t = topicTree->lookupTopic(topic);
|
||||
if (t) {
|
||||
return (unsigned int) t->size();
|
||||
@@ -408,14 +412,14 @@ public:
|
||||
webSocketContext->getExt()->messageHandler = std::move(behavior.message);
|
||||
webSocketContext->getExt()->drainHandler = std::move(behavior.drain);
|
||||
webSocketContext->getExt()->subscriptionHandler = std::move(behavior.subscription);
|
||||
webSocketContext->getExt()->closeHandler = std::move([closeHandler = std::move(behavior.close)](WebSocket<SSL, true, UserData> *ws, int code, std::string_view message) mutable {
|
||||
webSocketContext->getExt()->closeHandler = [closeHandler = std::move(behavior.close)](WebSocket<SSL, true, UserData> *ws, int code, std::string_view message) mutable {
|
||||
if (closeHandler) {
|
||||
closeHandler(ws, code, message);
|
||||
}
|
||||
|
||||
/* Destruct user data after returning from close handler */
|
||||
((UserData *) ws->getUserData())->~UserData();
|
||||
});
|
||||
};
|
||||
webSocketContext->getExt()->pingHandler = std::move(behavior.ping);
|
||||
webSocketContext->getExt()->pongHandler = std::move(behavior.pong);
|
||||
|
||||
@@ -428,8 +432,8 @@ public:
|
||||
webSocketContext->getExt()->maxLifetime = behavior.maxLifetime;
|
||||
webSocketContext->getExt()->compression = behavior.compression;
|
||||
|
||||
/* Calculate idleTimeoutCompnents */
|
||||
webSocketContext->getExt()->calculateIdleTimeoutCompnents(behavior.idleTimeout);
|
||||
/* Calculate idleTimeoutComponents */
|
||||
webSocketContext->getExt()->calculateIdleTimeoutComponents(behavior.idleTimeout);
|
||||
|
||||
httpContext->onHttp("GET", pattern, [webSocketContext, behavior = std::move(behavior)](auto *res, auto *req) mutable {
|
||||
|
||||
@@ -606,11 +610,20 @@ public:
|
||||
return std::move(*this);
|
||||
}
|
||||
|
||||
void setOnClose(HttpContextData<SSL>::OnSocketClosedCallback onClose) {
|
||||
httpContext->getSocketContextData()->onSocketClosed = onClose;
|
||||
}
|
||||
|
||||
TemplatedApp &&run() {
|
||||
uWS::run();
|
||||
return std::move(*this);
|
||||
}
|
||||
|
||||
TemplatedApp &&setUsingCustomExpectHandler(bool value) {
|
||||
httpContext->getSocketContextData()->usingCustomExpectHandler = value;
|
||||
return std::move(*this);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
typedef TemplatedApp<false> App;
|
||||
|
||||
@@ -30,6 +30,9 @@
|
||||
#include <iostream>
|
||||
|
||||
#include "libusockets.h"
|
||||
#include "bun-usockets/src/internal/internal.h"
|
||||
|
||||
|
||||
|
||||
#include "LoopData.h"
|
||||
#include "AsyncSocketData.h"
|
||||
@@ -54,28 +57,6 @@ struct AsyncSocket {
|
||||
template <typename, typename> friend struct TopicTree;
|
||||
template <bool> friend struct HttpResponse;
|
||||
|
||||
private:
|
||||
/* Helper, do not use directly (todo: move to uSockets or de-crazify) */
|
||||
void throttle_helper(int toggle) {
|
||||
/* These should be exposed by uSockets */
|
||||
static thread_local int us_events[2] = {0, 0};
|
||||
|
||||
struct us_poll_t *p = (struct us_poll_t *) this;
|
||||
struct us_loop_t *loop = us_socket_context_loop(SSL, us_socket_context(SSL, (us_socket_t *) this));
|
||||
|
||||
if (toggle) {
|
||||
/* Pause */
|
||||
int events = us_poll_events(p);
|
||||
if (events) {
|
||||
us_events[getBufferedAmount() ? 1 : 0] = events;
|
||||
}
|
||||
us_poll_change(p, loop, 0);
|
||||
} else {
|
||||
/* Resume */
|
||||
int events = us_events[getBufferedAmount() ? 1 : 0];
|
||||
us_poll_change(p, loop, events);
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
/* Returns SSL pointer or FD as pointer */
|
||||
@@ -105,13 +86,13 @@ public:
|
||||
|
||||
/* Experimental pause */
|
||||
us_socket_t *pause() {
|
||||
throttle_helper(1);
|
||||
us_socket_pause(SSL, (us_socket_t *) this);
|
||||
return (us_socket_t *) this;
|
||||
}
|
||||
|
||||
/* Experimental resume */
|
||||
us_socket_t *resume() {
|
||||
throttle_helper(0);
|
||||
us_socket_resume(SSL, (us_socket_t *) this);
|
||||
return (us_socket_t *) this;
|
||||
}
|
||||
|
||||
|
||||
@@ -81,7 +81,7 @@ struct AsyncSocketData {
|
||||
|
||||
}
|
||||
|
||||
/* Or emppty */
|
||||
/* Or empty */
|
||||
AsyncSocketData() = default;
|
||||
};
|
||||
|
||||
|
||||
@@ -43,10 +43,10 @@ private:
|
||||
HttpContext() = delete;
|
||||
|
||||
/* Maximum delay allowed until an HTTP connection is terminated due to outstanding request or rejected data (slow loris protection) */
|
||||
static const int HTTP_IDLE_TIMEOUT_S = 10;
|
||||
static constexpr int HTTP_IDLE_TIMEOUT_S = 10;
|
||||
|
||||
/* Minimum allowed receive throughput per second (clients uploading less than 16kB/sec get dropped) */
|
||||
static const int HTTP_RECEIVE_THROUGHPUT_BYTES = 16 * 1024;
|
||||
static constexpr int HTTP_RECEIVE_THROUGHPUT_BYTES = 16 * 1024;
|
||||
|
||||
us_socket_context_t *getSocketContext() {
|
||||
return (us_socket_context_t *) this;
|
||||
@@ -115,9 +115,8 @@ private:
|
||||
us_socket_context_on_close(SSL, getSocketContext(), [](us_socket_t *s, int /*code*/, void */*reason*/) {
|
||||
((AsyncSocket<SSL> *)s)->uncorkWithoutSending();
|
||||
|
||||
|
||||
/* Get socket ext */
|
||||
HttpResponseData<SSL> *httpResponseData = (HttpResponseData<SSL> *) us_socket_ext(SSL, s);
|
||||
auto *httpResponseData = reinterpret_cast<HttpResponseData<SSL> *>(us_socket_ext(SSL, s));
|
||||
|
||||
/* Call filter */
|
||||
HttpContextData<SSL> *httpContextData = getSocketContextDataS(s);
|
||||
@@ -130,6 +129,9 @@ private:
|
||||
httpResponseData->onAborted((HttpResponse<SSL> *)s, httpResponseData->userData);
|
||||
}
|
||||
|
||||
if (httpResponseData->socketData && httpContextData->onSocketClosed) {
|
||||
httpContextData->onSocketClosed(httpResponseData->socketData, SSL, s);
|
||||
}
|
||||
|
||||
/* Destruct socket ext */
|
||||
httpResponseData->~HttpResponseData<SSL>();
|
||||
@@ -171,7 +173,7 @@ private:
|
||||
proxyParser = &httpResponseData->proxyParser;
|
||||
#endif
|
||||
|
||||
/* The return value is entirely up to us to interpret. The HttpParser only care for whether the returned value is DIFFERENT or not from passed user */
|
||||
/* The return value is entirely up to us to interpret. The HttpParser cares only for whether the returned value is DIFFERENT from passed user */
|
||||
auto [err, returnedSocket] = httpResponseData->consumePostPadded(data, (unsigned int) length, s, proxyParser, [httpContextData](void *s, HttpRequest *httpRequest) -> void * {
|
||||
/* For every request we reset the timeout and hang until user makes action */
|
||||
/* Warning: if we are in shutdown state, resetting the timer is a security issue! */
|
||||
@@ -182,7 +184,7 @@ private:
|
||||
httpResponseData->offset = 0;
|
||||
|
||||
/* Are we not ready for another request yet? Terminate the connection.
|
||||
* Important for denying async pipelining until, if ever, we want to suppot it.
|
||||
* Important for denying async pipelining until, if ever, we want to support it.
|
||||
* Otherwise requests can get mixed up on the same connection. We still support sync pipelining. */
|
||||
if (httpResponseData->state & HttpResponseData<SSL>::HTTP_RESPONSE_PENDING) {
|
||||
us_socket_close(SSL, (us_socket_t *) s, 0, nullptr);
|
||||
@@ -197,6 +199,8 @@ private:
|
||||
httpResponseData->state |= HttpResponseData<SSL>::HTTP_CONNECTION_CLOSE;
|
||||
}
|
||||
|
||||
httpResponseData->fromAncientRequest = httpRequest->isAncient();
|
||||
|
||||
/* Select the router based on SNI (only possible for SSL) */
|
||||
auto *selectedRouter = &httpContextData->router;
|
||||
if constexpr (SSL) {
|
||||
@@ -358,9 +362,8 @@ private:
|
||||
|
||||
/* Handle HTTP write out (note: SSL_read may trigger this spuriously, the app need to handle spurious calls) */
|
||||
us_socket_context_on_writable(SSL, getSocketContext(), [](us_socket_t *s) {
|
||||
|
||||
AsyncSocket<SSL> *asyncSocket = (AsyncSocket<SSL> *) s;
|
||||
HttpResponseData<SSL> *httpResponseData = (HttpResponseData<SSL> *) asyncSocket->getAsyncSocketData();
|
||||
auto *asyncSocket = reinterpret_cast<AsyncSocket<SSL> *>(s);
|
||||
auto *httpResponseData = reinterpret_cast<HttpResponseData<SSL> *>(asyncSocket->getAsyncSocketData());
|
||||
|
||||
/* Ask the developer to write data and return success (true) or failure (false), OR skip sending anything and return success (true). */
|
||||
if (httpResponseData->onWritable) {
|
||||
@@ -369,7 +372,7 @@ private:
|
||||
|
||||
/* We expect the developer to return whether or not write was successful (true).
|
||||
* If write was never called, the developer should still return true so that we may drain. */
|
||||
bool success = httpResponseData->callOnWritable((HttpResponse<SSL> *)asyncSocket, httpResponseData->offset);
|
||||
bool success = httpResponseData->callOnWritable(reinterpret_cast<HttpResponse<SSL> *>(asyncSocket), httpResponseData->offset);
|
||||
|
||||
/* The developer indicated that their onWritable failed. */
|
||||
if (!success) {
|
||||
@@ -396,28 +399,26 @@ private:
|
||||
}
|
||||
|
||||
/* Expect another writable event, or another request within the timeout */
|
||||
((HttpResponse<SSL> *) s)->resetTimeout();
|
||||
reinterpret_cast<HttpResponse<SSL> *>(s)->resetTimeout();
|
||||
|
||||
return s;
|
||||
});
|
||||
|
||||
/* Handle FIN, HTTP does not support half-closed sockets, so simply close */
|
||||
us_socket_context_on_end(SSL, getSocketContext(), [](us_socket_t *s) {
|
||||
((AsyncSocket<SSL> *)s)->uncorkWithoutSending();
|
||||
|
||||
auto *asyncSocket = reinterpret_cast<AsyncSocket<SSL> *>(s);
|
||||
asyncSocket->uncorkWithoutSending();
|
||||
/* We do not care for half closed sockets */
|
||||
AsyncSocket<SSL> *asyncSocket = (AsyncSocket<SSL> *) s;
|
||||
return asyncSocket->close();
|
||||
|
||||
});
|
||||
|
||||
/* Handle socket timeouts, simply close them so to not confuse client with FIN */
|
||||
us_socket_context_on_timeout(SSL, getSocketContext(), [](us_socket_t *s) {
|
||||
|
||||
/* Force close rather than gracefully shutdown and risk confusing the client with a complete download */
|
||||
AsyncSocket<SSL> *asyncSocket = (AsyncSocket<SSL> *) s;
|
||||
// Node.js by default sclose the connection but they emit the timeout event before that
|
||||
HttpResponseData<SSL> *httpResponseData = (HttpResponseData<SSL> *) asyncSocket->getAsyncSocketData();
|
||||
AsyncSocket<SSL> *asyncSocket = reinterpret_cast<AsyncSocket<SSL> *>(s);
|
||||
// Node.js by default closes the connection but they emit the timeout event before that
|
||||
HttpResponseData<SSL> *httpResponseData = reinterpret_cast<HttpResponseData<SSL> *>(asyncSocket->getAsyncSocketData());
|
||||
|
||||
if (httpResponseData->onTimeout) {
|
||||
httpResponseData->onTimeout((HttpResponse<SSL> *)s, httpResponseData->userData);
|
||||
@@ -493,16 +494,20 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
httpContextData->currentRouter->add(methods, pattern, [handler = std::move(handler), parameterOffsets = std::move(parameterOffsets)](auto *r) mutable {
|
||||
const bool &customContinue = httpContextData->usingCustomExpectHandler;
|
||||
|
||||
httpContextData->currentRouter->add(methods, pattern, [handler = std::move(handler), parameterOffsets = std::move(parameterOffsets), &customContinue](auto *r) mutable {
|
||||
auto user = r->getUserData();
|
||||
user.httpRequest->setYield(false);
|
||||
user.httpRequest->setParameters(r->getParameters());
|
||||
user.httpRequest->setParameterOffsets(¶meterOffsets);
|
||||
|
||||
/* Middleware? Automatically respond to expectations */
|
||||
std::string_view expect = user.httpRequest->getHeader("expect");
|
||||
if (expect.length() && expect == "100-continue") {
|
||||
user.httpResponse->writeContinue();
|
||||
if (!customContinue) {
|
||||
/* Middleware? Automatically respond to expectations */
|
||||
std::string_view expect = user.httpRequest->getHeader("expect");
|
||||
if (expect.length() && expect == "100-continue") {
|
||||
user.httpResponse->writeContinue();
|
||||
}
|
||||
}
|
||||
|
||||
handler(user.httpResponse, user.httpRequest);
|
||||
|
||||
@@ -34,6 +34,7 @@ struct alignas(16) HttpContextData {
|
||||
template <bool> friend struct TemplatedApp;
|
||||
private:
|
||||
std::vector<MoveOnlyFunction<void(HttpResponse<SSL> *, int)>> filterHandlers;
|
||||
using OnSocketClosedCallback = void (*)(void* userData, int is_ssl, struct us_socket_t *rawSocket);
|
||||
|
||||
MoveOnlyFunction<void(const char *hostname)> missingServerNameHandler;
|
||||
|
||||
@@ -50,6 +51,10 @@ private:
|
||||
void *upgradedWebSocket = nullptr;
|
||||
bool isParsingHttp = false;
|
||||
bool rejectUnauthorized = false;
|
||||
bool usingCustomExpectHandler = false;
|
||||
|
||||
/* Used to simulate Node.js socket events. */
|
||||
OnSocketClosedCallback onSocketClosed = nullptr;
|
||||
|
||||
// TODO: SNI
|
||||
void clearRoutes() {
|
||||
|
||||
@@ -239,7 +239,7 @@ namespace uWS
|
||||
}
|
||||
return unsignedIntegerValue;
|
||||
}
|
||||
|
||||
|
||||
static inline uint64_t hasLess(uint64_t x, uint64_t n) {
|
||||
return (((x)-~0ULL/255*(n))&~(x)&~0ULL/255*128);
|
||||
}
|
||||
@@ -283,7 +283,7 @@ namespace uWS
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
static inline void *consumeFieldName(char *p) {
|
||||
/* Best case fast path (particularly useful with clang) */
|
||||
while (true) {
|
||||
@@ -323,14 +323,14 @@ namespace uWS
|
||||
|
||||
uint64_t http;
|
||||
__builtin_memcpy(&http, data, sizeof(uint64_t));
|
||||
|
||||
|
||||
uint32_t first_four_bytes = http & static_cast<uint32_t>(0xFFFFFFFF);
|
||||
// check if any of the first four bytes are > non-ascii
|
||||
if ((first_four_bytes & 0x80808080) != 0) [[unlikely]] {
|
||||
return 0;
|
||||
}
|
||||
first_four_bytes |= 0x20202020; // Lowercase the first four bytes
|
||||
|
||||
|
||||
static constexpr char http_lowercase_bytes[4] = {'h', 't', 't', 'p'};
|
||||
static constexpr uint32_t http_lowercase_bytes_int = __builtin_bit_cast(uint32_t, http_lowercase_bytes);
|
||||
if (first_four_bytes == http_lowercase_bytes_int) [[likely]] {
|
||||
@@ -343,7 +343,7 @@ namespace uWS
|
||||
|
||||
static constexpr char S_colon_slash_slash[4] = {'S', ':', '/', '/'};
|
||||
static constexpr uint32_t S_colon_slash_slash_int = __builtin_bit_cast(uint32_t, S_colon_slash_slash);
|
||||
|
||||
|
||||
// Extract the last four bytes from the uint64_t
|
||||
const uint32_t last_four_bytes = (http >> 32) & static_cast<uint32_t>(0xFFFFFFFF);
|
||||
return (last_four_bytes == s_colon_slash_slash_int) || (last_four_bytes == S_colon_slash_slash_int);
|
||||
@@ -361,7 +361,7 @@ namespace uWS
|
||||
if (&data[1] == end) [[unlikely]] {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
if (data[0] == 32 && (__builtin_expect(data[1] == '/', 1) || isHTTPorHTTPSPrefixForProxies(data + 1, end) == 1)) [[likely]] {
|
||||
header.key = {start, (size_t) (data - start)};
|
||||
data++;
|
||||
@@ -536,7 +536,7 @@ namespace uWS
|
||||
while (headers->value.length() && headers->value.front() < 33) {
|
||||
headers->value.remove_prefix(1);
|
||||
}
|
||||
|
||||
|
||||
headers++;
|
||||
|
||||
/* We definitely have at least one header (or request line), so check if we are done */
|
||||
@@ -598,7 +598,7 @@ namespace uWS
|
||||
for (HttpRequest::Header *h = req->headers; (++h)->key.length(); ) {
|
||||
req->bf.add(h->key);
|
||||
}
|
||||
|
||||
|
||||
/* Break if no host header (but we can have empty string which is different from nullptr) */
|
||||
if (!req->getHeader("host").data()) {
|
||||
return {HTTP_ERROR_400_BAD_REQUEST, FULLPTR};
|
||||
@@ -611,11 +611,12 @@ namespace uWS
|
||||
* ought to be handled as an error. */
|
||||
std::string_view transferEncodingString = req->getHeader("transfer-encoding");
|
||||
std::string_view contentLengthString = req->getHeader("content-length");
|
||||
|
||||
auto transferEncodingStringLen = transferEncodingString.length();
|
||||
auto contentLengthStringLen = contentLengthString.length();
|
||||
if (transferEncodingStringLen && contentLengthStringLen) {
|
||||
/* Returning fullptr is the same as calling the errorHandler */
|
||||
/* We could be smart and set an error in the context along with this, to indicate what
|
||||
/* We could be smart and set an error in the context along with this, to indicate what
|
||||
* http error response we might want to return */
|
||||
return {HTTP_ERROR_400_BAD_REQUEST, FULLPTR};
|
||||
}
|
||||
@@ -623,7 +624,7 @@ namespace uWS
|
||||
/* Parse query */
|
||||
const char *querySeparatorPtr = (const char *) memchr(req->headers->value.data(), '?', req->headers->value.length());
|
||||
req->querySeparator = (unsigned int) ((querySeparatorPtr ? querySeparatorPtr : req->headers->value.data() + req->headers->value.length()) - req->headers->value.data());
|
||||
|
||||
|
||||
// lets check if content len is valid before calling requestHandler
|
||||
if(contentLengthStringLen) {
|
||||
remainingStreamingBytes = toUnsignedInteger(contentLengthString);
|
||||
@@ -633,6 +634,14 @@ namespace uWS
|
||||
}
|
||||
}
|
||||
|
||||
// lets check if content len is valid before calling requestHandler
|
||||
if(contentLengthStringLen) {
|
||||
remainingStreamingBytes = toUnsignedInteger(contentLengthString);
|
||||
if (remainingStreamingBytes == UINT64_MAX) {
|
||||
/* Parser error */
|
||||
return {HTTP_ERROR_400_BAD_REQUEST, FULLPTR};
|
||||
}
|
||||
}
|
||||
/* If returned socket is not what we put in we need
|
||||
* to break here as we either have upgraded to
|
||||
* WebSockets or otherwise closed the socket. */
|
||||
@@ -654,7 +663,7 @@ namespace uWS
|
||||
if (transferEncodingStringLen) {
|
||||
|
||||
/* If a proxy sent us the transfer-encoding header that 100% means it must be chunked or else the proxy is
|
||||
* not RFC 9112 compliant. Therefore it is always better to assume this is the case, since that entirely eliminates
|
||||
* not RFC 9112 compliant. Therefore it is always better to assume this is the case, since that entirely eliminates
|
||||
* all forms of transfer-encoding obfuscation tricks. We just rely on the header. */
|
||||
|
||||
/* RFC 9112 6.3
|
||||
@@ -683,7 +692,6 @@ namespace uWS
|
||||
consumedTotal += consumed;
|
||||
}
|
||||
} else if (contentLengthStringLen) {
|
||||
|
||||
if constexpr (!ConsumeMinimally) {
|
||||
unsigned int emittable = (unsigned int) std::min<uint64_t>(remainingStreamingBytes, length);
|
||||
dataHandler(user, std::string_view(data, emittable), emittable == remainingStreamingBytes);
|
||||
|
||||
@@ -81,8 +81,12 @@ public:
|
||||
|
||||
/* Called only once per request */
|
||||
void writeMark() {
|
||||
if (getHttpResponseData()->state & HttpResponseData<SSL>::HTTP_WROTE_DATE_HEADER) {
|
||||
return;
|
||||
}
|
||||
/* Date is always written */
|
||||
writeHeader("Date", std::string_view(((LoopData *) us_loop_ext(us_socket_context_loop(SSL, (us_socket_context(SSL, (us_socket_t *) this)))))->date, 29));
|
||||
getHttpResponseData()->state |= HttpResponseData<SSL>::HTTP_WROTE_DATE_HEADER;
|
||||
}
|
||||
|
||||
/* Returns true on success, indicating that it might be feasible to write more data.
|
||||
@@ -113,7 +117,8 @@ public:
|
||||
httpResponseData->state |= HttpResponseData<SSL>::HTTP_CONNECTION_CLOSE;
|
||||
}
|
||||
|
||||
if (httpResponseData->state & HttpResponseData<SSL>::HTTP_WRITE_CALLED) {
|
||||
/* if write was called and there was previously no Content-Length header set */
|
||||
if (httpResponseData->state & HttpResponseData<SSL>::HTTP_WRITE_CALLED && !(httpResponseData->state & HttpResponseData<SSL>::HTTP_WROTE_CONTENT_LENGTH_HEADER) && !httpResponseData->fromAncientRequest) {
|
||||
|
||||
/* We do not have tryWrite-like functionalities, so ignore optional in this path */
|
||||
|
||||
@@ -145,6 +150,8 @@ public:
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this->uncork();
|
||||
}
|
||||
|
||||
/* tryEnd can never fail when in chunked mode, since we do not have tryWrite (yet), only write */
|
||||
@@ -152,7 +159,7 @@ public:
|
||||
return true;
|
||||
} else {
|
||||
/* Write content-length on first call */
|
||||
if (!(httpResponseData->state & HttpResponseData<SSL>::HTTP_END_CALLED)) {
|
||||
if (!(httpResponseData->state & (HttpResponseData<SSL>::HTTP_END_CALLED))) {
|
||||
/* Write mark, this propagates to WebSockets too */
|
||||
writeMark();
|
||||
|
||||
@@ -162,7 +169,8 @@ public:
|
||||
Super::write("Content-Length: ", 16);
|
||||
writeUnsigned64(totalSize);
|
||||
Super::write("\r\n\r\n", 4);
|
||||
} else {
|
||||
httpResponseData->state |= HttpResponseData<SSL>::HTTP_WROTE_CONTENT_LENGTH_HEADER;
|
||||
} else if (!(httpResponseData->state & (HttpResponseData<SSL>::HTTP_WRITE_CALLED))) {
|
||||
Super::write("\r\n", 2);
|
||||
}
|
||||
|
||||
@@ -207,6 +215,8 @@ public:
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this->uncork();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -231,7 +241,7 @@ public:
|
||||
/* Manually upgrade to WebSocket. Typically called in upgrade handler. Immediately calls open handler.
|
||||
* NOTE: Will invalidate 'this' as socket might change location in memory. Throw away after use. */
|
||||
template <typename UserData>
|
||||
void upgrade(UserData &&userData, std::string_view secWebSocketKey, std::string_view secWebSocketProtocol,
|
||||
us_socket_t *upgrade(UserData &&userData, std::string_view secWebSocketKey, std::string_view secWebSocketProtocol,
|
||||
std::string_view secWebSocketExtensions,
|
||||
struct us_socket_context_t *webSocketContext) {
|
||||
|
||||
@@ -313,8 +323,8 @@ public:
|
||||
bool wasCorked = Super::isCorked();
|
||||
|
||||
/* Adopting a socket invalidates it, do not rely on it directly to carry any data */
|
||||
WebSocket<SSL, true, UserData> *webSocket = (WebSocket<SSL, true, UserData> *) us_socket_context_adopt_socket(SSL,
|
||||
(us_socket_context_t *) webSocketContext, (us_socket_t *) this, sizeof(WebSocketData) + sizeof(UserData));
|
||||
us_socket_t *usSocket = us_socket_context_adopt_socket(SSL, (us_socket_context_t *) webSocketContext, (us_socket_t *) this, sizeof(WebSocketData) + sizeof(UserData));
|
||||
WebSocket<SSL, true, UserData> *webSocket = (WebSocket<SSL, true, UserData> *) usSocket;
|
||||
|
||||
/* For whatever reason we were corked, update cork to the new socket */
|
||||
if (wasCorked) {
|
||||
@@ -344,6 +354,8 @@ public:
|
||||
if (webSocketContextData->openHandler) {
|
||||
webSocketContextData->openHandler(webSocket);
|
||||
}
|
||||
|
||||
return usSocket;
|
||||
}
|
||||
|
||||
/* Immediately terminate this Http response */
|
||||
@@ -427,7 +439,7 @@ public:
|
||||
|
||||
/* End the response with an optional data chunk. Always starts a timeout. */
|
||||
void end(std::string_view data = {}, bool closeConnection = false) {
|
||||
internalEnd(data, data.length(), false, true, closeConnection);
|
||||
internalEnd(data, data.length(), false, !(this->getHttpResponseData()->state & HttpResponseData<SSL>::HTTP_WROTE_CONTENT_LENGTH_HEADER), closeConnection);
|
||||
}
|
||||
|
||||
/* Try and end the response. Returns [true, true] on success.
|
||||
@@ -441,12 +453,12 @@ public:
|
||||
bool sendTerminatingChunk(bool closeConnection = false) {
|
||||
writeStatus(HTTP_200_OK);
|
||||
HttpResponseData<SSL> *httpResponseData = getHttpResponseData();
|
||||
if (!(httpResponseData->state & HttpResponseData<SSL>::HTTP_WRITE_CALLED)) {
|
||||
if (!(httpResponseData->state & (HttpResponseData<SSL>::HTTP_WRITE_CALLED | HttpResponseData<SSL>::HTTP_WROTE_CONTENT_LENGTH_HEADER))) {
|
||||
/* Write mark on first call to write */
|
||||
writeMark();
|
||||
|
||||
writeHeader("Transfer-Encoding", "chunked");
|
||||
httpResponseData->state |= HttpResponseData<SSL>::HTTP_WRITE_CALLED;
|
||||
httpResponseData->state |= HttpResponseData<SSL>::HTTP_WRITE_CALLED;
|
||||
}
|
||||
|
||||
/* This will be sent always when state is HTTP_WRITE_CALLED inside internalEnd, so no need to write the terminating 0 chunk here */
|
||||
@@ -456,33 +468,46 @@ public:
|
||||
}
|
||||
|
||||
/* Write parts of the response in chunking fashion. Starts timeout if failed. */
|
||||
bool write(std::string_view data) {
|
||||
bool write(std::string_view data, size_t *writtenPtr = nullptr) {
|
||||
writeStatus(HTTP_200_OK);
|
||||
|
||||
/* Do not allow sending 0 chunks, they mark end of response */
|
||||
if (data.empty()) {
|
||||
if (writtenPtr) {
|
||||
*writtenPtr = 0;
|
||||
}
|
||||
/* If you called us, then according to you it was fine to call us so it's fine to still call us */
|
||||
return true;
|
||||
}
|
||||
|
||||
HttpResponseData<SSL> *httpResponseData = getHttpResponseData();
|
||||
|
||||
if (!(httpResponseData->state & HttpResponseData<SSL>::HTTP_WRITE_CALLED)) {
|
||||
/* Write mark on first call to write */
|
||||
writeMark();
|
||||
if (!(httpResponseData->state & HttpResponseData<SSL>::HTTP_WROTE_CONTENT_LENGTH_HEADER) && !httpResponseData->fromAncientRequest) {
|
||||
if (!(httpResponseData->state & HttpResponseData<SSL>::HTTP_WRITE_CALLED)) {
|
||||
/* Write mark on first call to write */
|
||||
writeMark();
|
||||
|
||||
writeHeader("Transfer-Encoding", "chunked");
|
||||
writeHeader("Transfer-Encoding", "chunked");
|
||||
httpResponseData->state |= HttpResponseData<SSL>::HTTP_WRITE_CALLED;
|
||||
}
|
||||
|
||||
Super::write("\r\n", 2);
|
||||
writeUnsignedHex((unsigned int) data.length());
|
||||
Super::write("\r\n", 2);
|
||||
} else if (!(httpResponseData->state & HttpResponseData<SSL>::HTTP_WRITE_CALLED)) {
|
||||
writeMark();
|
||||
Super::write("\r\n", 2);
|
||||
httpResponseData->state |= HttpResponseData<SSL>::HTTP_WRITE_CALLED;
|
||||
}
|
||||
|
||||
Super::write("\r\n", 2);
|
||||
writeUnsignedHex((unsigned int) data.length());
|
||||
Super::write("\r\n", 2);
|
||||
|
||||
auto [written, failed] = Super::write(data.data(), (int) data.length());
|
||||
/* Reset timeout on each sended chunk */
|
||||
this->resetTimeout();
|
||||
|
||||
if (writtenPtr) {
|
||||
*writtenPtr = written;
|
||||
}
|
||||
|
||||
/* If we did not fail the write, accept more */
|
||||
return !failed;
|
||||
}
|
||||
@@ -515,7 +540,7 @@ public:
|
||||
Super::cork();
|
||||
handler();
|
||||
|
||||
/* The only way we could possibly have changed the corked socket during handler call, would be if
|
||||
/* The only way we could possibly have changed the corked socket during handler call, would be if
|
||||
* the HTTP socket was upgraded to WebSocket and caused a realloc. Because of this we cannot use "this"
|
||||
* from here downwards. The corking is done with corkUnchecked() in upgrade. It steals cork. */
|
||||
auto *newCorkedSocket = loopData->getCorkedSocket();
|
||||
@@ -582,7 +607,7 @@ public:
|
||||
/* Attach handler for aborted HTTP request */
|
||||
HttpResponse *onAborted(void* userData, HttpResponseData<SSL>::OnAbortedCallback handler) {
|
||||
HttpResponseData<SSL> *httpResponseData = getHttpResponseData();
|
||||
|
||||
|
||||
httpResponseData->userData = userData;
|
||||
httpResponseData->onAborted = handler;
|
||||
return this;
|
||||
@@ -590,7 +615,7 @@ public:
|
||||
|
||||
HttpResponse *onTimeout(void* userData, HttpResponseData<SSL>::OnTimeoutCallback handler) {
|
||||
HttpResponseData<SSL> *httpResponseData = getHttpResponseData();
|
||||
|
||||
|
||||
httpResponseData->userData = userData;
|
||||
httpResponseData->onTimeout = handler;
|
||||
return this;
|
||||
@@ -620,7 +645,7 @@ public:
|
||||
return this;
|
||||
}
|
||||
/* Attach a read handler for data sent. Will be called with FIN set true if last segment. */
|
||||
void onData(void* userData, HttpResponseData<SSL>::OnDataCallback handler) {
|
||||
void onData(void* userData, HttpResponseData<SSL>::OnDataCallback handler) {
|
||||
HttpResponseData<SSL> *data = getHttpResponseData();
|
||||
data->userData = userData;
|
||||
data->inStream = handler;
|
||||
@@ -629,6 +654,17 @@ public:
|
||||
data->received_bytes_per_timeout = 0;
|
||||
}
|
||||
|
||||
void* getSocketData() {
|
||||
HttpResponseData<SSL> *httpResponseData = getHttpResponseData();
|
||||
|
||||
return httpResponseData->socketData;
|
||||
}
|
||||
|
||||
void setSocketData(void* socketData) {
|
||||
HttpResponseData<SSL> *httpResponseData = getHttpResponseData();
|
||||
|
||||
httpResponseData->socketData = socketData;
|
||||
}
|
||||
|
||||
void setWriteOffset(uint64_t offset) {
|
||||
HttpResponseData<SSL> *httpResponseData = getHttpResponseData();
|
||||
|
||||
@@ -36,7 +36,7 @@ struct HttpResponseData : AsyncSocketData<SSL>, HttpParser {
|
||||
using OnAbortedCallback = void (*)(uWS::HttpResponse<SSL>*, void*);
|
||||
using OnTimeoutCallback = void (*)(uWS::HttpResponse<SSL>*, void*);
|
||||
using OnDataCallback = void (*)(uWS::HttpResponse<SSL>* response, const char* chunk, size_t chunk_length, bool, void*);
|
||||
|
||||
|
||||
/* When we are done with a response we mark it like so */
|
||||
void markDone() {
|
||||
onAborted = nullptr;
|
||||
@@ -53,7 +53,7 @@ struct HttpResponseData : AsyncSocketData<SSL>, HttpParser {
|
||||
}
|
||||
|
||||
/* Caller of onWritable. It is possible onWritable calls markDone so we need to borrow it. */
|
||||
bool callOnWritable( uWS::HttpResponse<SSL>* response, uint64_t offset) {
|
||||
bool callOnWritable(uWS::HttpResponse<SSL>* response, uint64_t offset) {
|
||||
/* Borrow real onWritable */
|
||||
auto* borrowedOnWritable = std::move(onWritable);
|
||||
|
||||
@@ -77,11 +77,14 @@ struct HttpResponseData : AsyncSocketData<SSL>, HttpParser {
|
||||
HTTP_WRITE_CALLED = 2, // used
|
||||
HTTP_END_CALLED = 4, // used
|
||||
HTTP_RESPONSE_PENDING = 8, // used
|
||||
HTTP_CONNECTION_CLOSE = 16 // used
|
||||
HTTP_CONNECTION_CLOSE = 16, // used
|
||||
HTTP_WROTE_CONTENT_LENGTH_HEADER = 32, // used
|
||||
HTTP_WROTE_DATE_HEADER = 64, // used
|
||||
};
|
||||
|
||||
/* Shared context pointer */
|
||||
void* userData = nullptr;
|
||||
void* socketData = nullptr;
|
||||
|
||||
/* Per socket event handlers */
|
||||
OnWritableCallback onWritable = nullptr;
|
||||
@@ -97,6 +100,7 @@ struct HttpResponseData : AsyncSocketData<SSL>, HttpParser {
|
||||
/* Current state (content-length sent, status sent, write called, etc */
|
||||
uint8_t state = 0;
|
||||
uint8_t idleTimeout = 10; // default HTTP_TIMEOUT 10 seconds
|
||||
bool fromAncientRequest = false;
|
||||
|
||||
#ifdef UWS_WITH_PROXY
|
||||
ProxyParser proxyParser;
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "LoopData.h"
|
||||
#include <libusockets.h>
|
||||
#include <iostream>
|
||||
#include "AsyncSocket.h"
|
||||
|
||||
extern "C" int bun_is_exiting();
|
||||
|
||||
@@ -52,6 +53,15 @@ private:
|
||||
for (auto &p : loopData->preHandlers) {
|
||||
p.second((Loop *) loop);
|
||||
}
|
||||
|
||||
void *corkedSocket = loopData->getCorkedSocket();
|
||||
if (corkedSocket) {
|
||||
if (loopData->isCorkedSSL()) {
|
||||
((uWS::AsyncSocket<true> *) corkedSocket)->uncork();
|
||||
} else {
|
||||
((uWS::AsyncSocket<false> *) corkedSocket)->uncork();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void postCb(us_loop_t *loop) {
|
||||
@@ -148,6 +158,10 @@ public:
|
||||
getLazyLoop().loop = nullptr;
|
||||
}
|
||||
|
||||
static LoopData* data(struct us_loop_t *loop) {
|
||||
return (LoopData *) us_loop_ext(loop);
|
||||
}
|
||||
|
||||
void addPostHandler(void *key, MoveOnlyFunction<void(Loop *)> &&handler) {
|
||||
LoopData *loopData = (LoopData *) us_loop_ext((us_loop_t *) this);
|
||||
|
||||
|
||||
@@ -63,6 +63,7 @@ public:
|
||||
}
|
||||
delete [] corkBuffer;
|
||||
}
|
||||
|
||||
void* getCorkedSocket() {
|
||||
return this->corkedSocket;
|
||||
}
|
||||
|
||||
@@ -82,7 +82,14 @@ namespace ofats {
|
||||
|
||||
namespace any_detail {
|
||||
|
||||
using buffer = std::aligned_storage_t<sizeof(void*) * 2, alignof(void*)>;
|
||||
template <std::size_t Len, std::size_t Align>
|
||||
class my_aligned_storage_t {
|
||||
private:
|
||||
alignas(Align) std::byte t_buff[Len];
|
||||
};
|
||||
|
||||
|
||||
using buffer = my_aligned_storage_t<sizeof(void*) * 2, alignof(void*)>;
|
||||
|
||||
template <class T>
|
||||
inline constexpr bool is_small_object_v =
|
||||
|
||||
@@ -115,7 +115,7 @@ public:
|
||||
char header[10];
|
||||
int header_length = (int) protocol::formatMessage<isServer>(header, "", 0, opCode, message.length(), compress, fin);
|
||||
int written = us_socket_write2(0, (struct us_socket_t *)this, header, header_length, message.data(), (int) message.length());
|
||||
|
||||
|
||||
if (written != header_length + (int) message.length()) {
|
||||
/* Buffer up backpressure */
|
||||
if (written > header_length) {
|
||||
@@ -289,7 +289,7 @@ public:
|
||||
);
|
||||
|
||||
WebSocketData *webSocketData = (WebSocketData *) us_socket_ext(SSL, (us_socket_t *) this);
|
||||
|
||||
|
||||
if (!webSocketData->subscriber) { return false; }
|
||||
|
||||
/* Cannot return numSubscribers as this is only for this particular websocket context */
|
||||
|
||||
@@ -82,7 +82,7 @@ public:
|
||||
std::pair<unsigned short, unsigned short> idleTimeoutComponents;
|
||||
|
||||
/* This is run once on start-up */
|
||||
void calculateIdleTimeoutCompnents(unsigned short idleTimeout) {
|
||||
void calculateIdleTimeoutComponents(unsigned short idleTimeout) {
|
||||
unsigned short margin = 4;
|
||||
/* 4, 8 or 16 seconds margin based on idleTimeout */
|
||||
while ((int) idleTimeout - margin * 2 >= margin * 2 && margin < 16) {
|
||||
|
||||
@@ -28,4 +28,9 @@ describe("example", () => {
|
||||
};
|
||||
}).toThrow();
|
||||
});
|
||||
|
||||
test("can run with special chars :)", () => {
|
||||
// if this test runs, it's a success.
|
||||
// a failure is if it's either skipped or fails the runner
|
||||
})
|
||||
});
|
||||
|
||||
@@ -171,11 +171,12 @@ export function registerTestRunner(context: vscode.ExtensionContext) {
|
||||
}
|
||||
|
||||
if (testName && testName.length) {
|
||||
const escapedTestName = escapeRegex(testName);
|
||||
if (customScriptSetting.length) {
|
||||
// escape the quotes in the test name
|
||||
command += ` -t "${testName}"`;
|
||||
command += ` -t "${escapedTestName}"`;
|
||||
} else {
|
||||
command += ` -t "${testName}"`;
|
||||
command += ` -t "${escapedTestName}"`;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -202,3 +203,14 @@ export function registerTestRunner(context: vscode.ExtensionContext) {
|
||||
context.subscriptions.push(runTestCommand);
|
||||
context.subscriptions.push(watchTestCommand);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Escape any special characters in the input string, so that regex-matching on it
|
||||
* will work as expected.
|
||||
* i.e `new RegExp(escapeRegex("hi (:").test("hi (:")` will return true, instead of throwing
|
||||
* an invalid regex error.
|
||||
*/
|
||||
function escapeRegex(source: string) {
|
||||
return source.replaceAll(/[^a-zA-Z0-9_+\-'"\ ]/g, "\\$&");
|
||||
}
|
||||
|
||||
@@ -345,7 +345,7 @@ function Install-Rust {
|
||||
function Install-Llvm {
|
||||
Install-Package llvm `
|
||||
-Command clang-cl `
|
||||
-Version "18.1.8"
|
||||
-Version "19.1.7"
|
||||
Add-To-Path "$env:ProgramFiles\LLVM\bin"
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/bin/sh
|
||||
# Version: 9
|
||||
# Version: 10
|
||||
|
||||
# A script that installs the dependencies needed to build and test Bun.
|
||||
# This should work on macOS and Linux with a POSIX shell.
|
||||
@@ -897,7 +897,7 @@ install_build_essentials() {
|
||||
}
|
||||
|
||||
llvm_version_exact() {
|
||||
print "18.1.8"
|
||||
print "19.1.7"
|
||||
}
|
||||
|
||||
llvm_version() {
|
||||
@@ -915,14 +915,12 @@ install_llvm() {
|
||||
install_packages "llvm@$(llvm_version)"
|
||||
;;
|
||||
apk)
|
||||
# alpine doesn't have a lld19 package on 3.21 atm so use bare one for now
|
||||
install_packages \
|
||||
"llvm$(llvm_version)" \
|
||||
"clang$(llvm_version)" \
|
||||
"scudo-malloc" \
|
||||
--repository "http://dl-cdn.alpinelinux.org/alpine/edge/main"
|
||||
install_packages \
|
||||
"lld$(llvm_version)" \
|
||||
--repository "http://dl-cdn.alpinelinux.org/alpine/edge/community"
|
||||
"lld"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
@@ -966,7 +964,7 @@ install_gcc() {
|
||||
;;
|
||||
esac
|
||||
|
||||
llvm_v="18"
|
||||
llvm_v="19"
|
||||
|
||||
append_to_profile "export CC=clang-${llvm_v}"
|
||||
append_to_profile "export CXX=clang++-${llvm_v}"
|
||||
@@ -1132,6 +1130,35 @@ install_tailscale() {
|
||||
esac
|
||||
}
|
||||
|
||||
install_fuse_python() {
|
||||
# only linux needs this
|
||||
case "$pm" in
|
||||
apk)
|
||||
# Build and install from source (https://github.com/libfuse/python-fuse/blob/master/INSTALL)
|
||||
install_packages \
|
||||
python3-dev \
|
||||
fuse-dev \
|
||||
pkgconf \
|
||||
py3-setuptools
|
||||
python_fuse_version="1.0.9"
|
||||
python_fuse_tarball=$(download_file "https://github.com/libfuse/python-fuse/archive/refs/tags/v$python_fuse_version.tar.gz")
|
||||
python_fuse_tmpdir="$(dirname "$python_fuse_tarball")"
|
||||
execute tar -xzf "$python_fuse_tarball" -C "$python_fuse_tmpdir"
|
||||
execute sh -c "cd '$python_fuse_tmpdir/python-fuse-$python_fuse_version' && python setup.py build"
|
||||
execute_sudo sh -c "cd '$python_fuse_tmpdir/python-fuse-$python_fuse_version' && python setup.py install"
|
||||
|
||||
# For Alpine we also need to make sure the kernel module is automatically loaded
|
||||
execute_sudo sh -c "echo fuse >> /etc/modules-load.d/fuse.conf"
|
||||
|
||||
# Check that it was actually installed
|
||||
execute python -c 'import fuse'
|
||||
;;
|
||||
apt | dnf | yum)
|
||||
install_packages python3-fuse
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
create_buildkite_user() {
|
||||
if ! [ "$ci" = "1" ] || ! [ "$os" = "linux" ]; then
|
||||
return
|
||||
@@ -1323,6 +1350,7 @@ main() {
|
||||
install_common_software
|
||||
install_build_essentials
|
||||
install_chromium
|
||||
install_fuse_python
|
||||
clean_system
|
||||
}
|
||||
|
||||
|
||||
@@ -256,13 +256,15 @@ async function runTests() {
|
||||
for (const testPath of tests) {
|
||||
const absoluteTestPath = join(testsPath, testPath);
|
||||
const title = relative(cwd, absoluteTestPath).replaceAll(sep, "/");
|
||||
if (isNodeParallelTest(testPath)) {
|
||||
const runWithBunTest = title.includes("needs-test") || readFileSync(absoluteTestPath, "utf-8").includes('bun:test');
|
||||
if (isNodeTest(testPath)) {
|
||||
const testContent = readFileSync(absoluteTestPath, "utf-8");
|
||||
const runWithBunTest =
|
||||
title.includes("needs-test") || testContent.includes("bun:test") || testContent.includes("node:test");
|
||||
const subcommand = runWithBunTest ? "test" : "run";
|
||||
await runTest(title, async () => {
|
||||
const { ok, error, stdout } = await spawnBun(execPath, {
|
||||
cwd: cwd,
|
||||
args: [subcommand, "--config=./bunfig.node-test.toml", absoluteTestPath],
|
||||
args: [subcommand, "--config=" + join(import.meta.dirname, "../bunfig.node-test.toml"), absoluteTestPath],
|
||||
timeout: getNodeParallelTestTimeout(title),
|
||||
env: {
|
||||
FORCE_COLOR: "0",
|
||||
@@ -870,11 +872,26 @@ function isJavaScriptTest(path) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} testPath
|
||||
* @param {string} path
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function isNodeParallelTest(testPath) {
|
||||
return testPath.replaceAll(sep, "/").includes("js/node/test/parallel/");
|
||||
function isNodeTest(path) {
|
||||
// Do not run node tests on macOS x64 in CI
|
||||
// TODO: Unclear why we decided to do this?
|
||||
if (isCI && isMacOS && isX64) {
|
||||
return false;
|
||||
}
|
||||
const unixPath = path.replaceAll(sep, "/");
|
||||
return unixPath.includes("js/node/test/parallel/") || unixPath.includes("js/node/test/sequential/");
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} path
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function isClusterTest(path) {
|
||||
const unixPath = path.replaceAll(sep, "/");
|
||||
return unixPath.includes("js/node/cluster/test-") && unixPath.endsWith(".ts");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -882,20 +899,17 @@ function isNodeParallelTest(testPath) {
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function isTest(path) {
|
||||
if (isNodeParallelTest(path) && targetDoesRunNodeTests()) return true;
|
||||
if (path.replaceAll(sep, "/").startsWith("js/node/cluster/test-") && path.endsWith(".ts")) return true;
|
||||
return isTestStrict(path);
|
||||
return isNodeTest(path) || isClusterTest(path) ? true : isTestStrict(path);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} path
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function isTestStrict(path) {
|
||||
return isJavaScript(path) && /\.test|spec\./.test(basename(path));
|
||||
}
|
||||
|
||||
function targetDoesRunNodeTests() {
|
||||
if (isMacOS && isX64) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} path
|
||||
* @returns {boolean}
|
||||
|
||||
@@ -466,11 +466,7 @@ pub const StandaloneModuleGraph = struct {
|
||||
return output_bytes;
|
||||
}
|
||||
|
||||
const page_size = if (Environment.isLinux and Environment.isAarch64)
|
||||
// some linux distros do 64 KB pages on aarch64
|
||||
64 * 1024
|
||||
else
|
||||
std.mem.page_size;
|
||||
const page_size = std.heap.page_size_max;
|
||||
|
||||
pub const InjectOptions = struct {
|
||||
windows_hide_console: bool = false,
|
||||
|
||||
@@ -74,16 +74,17 @@ pub fn allocator(scope: *AllocationScope) Allocator {
|
||||
const vtable: Allocator.VTable = .{
|
||||
.alloc = alloc,
|
||||
.resize = resize,
|
||||
.remap = remap,
|
||||
.free = free,
|
||||
};
|
||||
|
||||
fn alloc(ctx: *anyopaque, len: usize, ptr_align: u8, ret_addr: usize) ?[*]u8 {
|
||||
fn alloc(ctx: *anyopaque, len: usize, alignment: std.mem.Alignment, ret_addr: usize) ?[*]u8 {
|
||||
const scope: *AllocationScope = @ptrCast(@alignCast(ctx));
|
||||
scope.state.mutex.lock();
|
||||
defer scope.state.mutex.unlock();
|
||||
scope.state.allocations.ensureUnusedCapacity(scope.parent, 1) catch
|
||||
return null;
|
||||
const result = scope.parent.vtable.alloc(scope.parent.ptr, len, ptr_align, ret_addr) orelse
|
||||
const result = scope.parent.vtable.alloc(scope.parent.ptr, len, alignment, ret_addr) orelse
|
||||
return null;
|
||||
const trace = StoredTrace.capture(ret_addr);
|
||||
scope.state.allocations.putAssumeCapacityNoClobber(result, .{
|
||||
@@ -94,12 +95,17 @@ fn alloc(ctx: *anyopaque, len: usize, ptr_align: u8, ret_addr: usize) ?[*]u8 {
|
||||
return result;
|
||||
}
|
||||
|
||||
fn resize(ctx: *anyopaque, buf: []u8, buf_align: u8, new_len: usize, ret_addr: usize) bool {
|
||||
fn resize(ctx: *anyopaque, buf: []u8, alignment: std.mem.Alignment, new_len: usize, ret_addr: usize) bool {
|
||||
const scope: *AllocationScope = @ptrCast(@alignCast(ctx));
|
||||
return scope.parent.vtable.resize(scope.parent.ptr, buf, buf_align, new_len, ret_addr);
|
||||
return scope.parent.vtable.resize(scope.parent.ptr, buf, alignment, new_len, ret_addr);
|
||||
}
|
||||
|
||||
fn free(ctx: *anyopaque, buf: []u8, buf_align: u8, ret_addr: usize) void {
|
||||
fn remap(ctx: *anyopaque, buf: []u8, alignment: std.mem.Alignment, new_len: usize, ret_addr: usize) ?[*]u8 {
|
||||
const scope: *AllocationScope = @ptrCast(@alignCast(ctx));
|
||||
return scope.parent.vtable.remap(scope.parent.ptr, buf, alignment, new_len, ret_addr);
|
||||
}
|
||||
|
||||
fn free(ctx: *anyopaque, buf: []u8, alignment: std.mem.Alignment, ret_addr: usize) void {
|
||||
const scope: *AllocationScope = @ptrCast(@alignCast(ctx));
|
||||
scope.state.mutex.lock();
|
||||
defer scope.state.mutex.unlock();
|
||||
@@ -137,7 +143,7 @@ fn free(ctx: *anyopaque, buf: []u8, buf_align: u8, ret_addr: usize) void {
|
||||
// sanitizer does not catch the invalid free.
|
||||
}
|
||||
|
||||
scope.parent.vtable.free(scope.parent.ptr, buf, buf_align, ret_addr);
|
||||
scope.parent.vtable.free(scope.parent.ptr, buf, alignment, ret_addr);
|
||||
|
||||
// If asan did not catch the free, panic now.
|
||||
if (invalid) @panic("Invalid free");
|
||||
|
||||
@@ -33,7 +33,7 @@ pub fn free(this: *const NullableAllocator, bytes: []const u8) void {
|
||||
if (this.get()) |allocator| {
|
||||
if (bun.String.isWTFAllocator(allocator)) {
|
||||
// workaround for https://github.com/ziglang/zig/issues/4298
|
||||
bun.String.StringImplAllocator.free(allocator.ptr, @constCast(bytes), 0, 0);
|
||||
bun.String.StringImplAllocator.free(allocator.ptr, @constCast(bytes), .fromByteUnits(1), 0);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -62,19 +62,15 @@ pub const LinuxMemFdAllocator = struct {
|
||||
}
|
||||
|
||||
const AllocatorInterface = struct {
|
||||
fn alloc(_: *anyopaque, _: usize, _: u8, _: usize) ?[*]u8 {
|
||||
fn alloc(_: *anyopaque, _: usize, _: std.mem.Alignment, _: usize) ?[*]u8 {
|
||||
// it should perform no allocations or resizes
|
||||
return null;
|
||||
}
|
||||
|
||||
fn resize(_: *anyopaque, _: []u8, _: u8, _: usize, _: usize) bool {
|
||||
return false;
|
||||
}
|
||||
|
||||
fn free(
|
||||
ptr: *anyopaque,
|
||||
buf: []u8,
|
||||
_: u8,
|
||||
_: std.mem.Alignment,
|
||||
_: usize,
|
||||
) void {
|
||||
var this: *LinuxMemFdAllocator = @alignCast(@ptrCast(ptr));
|
||||
@@ -86,7 +82,8 @@ pub const LinuxMemFdAllocator = struct {
|
||||
|
||||
pub const VTable = &std.mem.Allocator.VTable{
|
||||
.alloc = &AllocatorInterface.alloc,
|
||||
.resize = &resize,
|
||||
.resize = &std.mem.Allocator.noResize,
|
||||
.remap = &std.mem.Allocator.noRemap,
|
||||
.free = &free,
|
||||
};
|
||||
};
|
||||
@@ -95,7 +92,7 @@ pub const LinuxMemFdAllocator = struct {
|
||||
var size = len;
|
||||
|
||||
// size rounded up to nearest page
|
||||
size += (size + std.mem.page_size - 1) & std.mem.page_size;
|
||||
size = std.mem.alignForward(usize, size, std.heap.pageSize());
|
||||
|
||||
var flags_mut = flags;
|
||||
flags_mut.TYPE = .SHARED;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user