mirror of
https://github.com/oven-sh/bun
synced 2026-02-05 00:18:53 +00:00
Compare commits
199 Commits
fix
...
jarred/fas
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
07f8b23350 | ||
|
|
b566573977 | ||
|
|
666feb3b7e | ||
|
|
5ea32a976e | ||
|
|
34b0e7a2bb | ||
|
|
c5f2280489 | ||
|
|
a686b3bfc1 | ||
|
|
a1fb289c96 | ||
|
|
8ca2194a37 | ||
|
|
03904f73cc | ||
|
|
2106e1d7f6 | ||
|
|
854ddaa909 | ||
|
|
609f81a746 | ||
|
|
fd4c8fb871 | ||
|
|
bab58b7541 | ||
|
|
5c8726d602 | ||
|
|
ae7bc37e94 | ||
|
|
31ab56d362 | ||
|
|
4b333b2d35 | ||
|
|
c4c5eb2d32 | ||
|
|
e7afae305c | ||
|
|
17031936c8 | ||
|
|
b2c576bba2 | ||
|
|
4af4b508a1 | ||
|
|
0c2df4ae01 | ||
|
|
cc0d920018 | ||
|
|
438d54f186 | ||
|
|
c6e1135548 | ||
|
|
ec11170311 | ||
|
|
538bcef731 | ||
|
|
93b0e94410 | ||
|
|
963d4311e6 | ||
|
|
2f5e4fffe9 | ||
|
|
ca42c820d2 | ||
|
|
565d1689e9 | ||
|
|
59570fe237 | ||
|
|
aa8b832ef6 | ||
|
|
fa632c3331 | ||
|
|
5846ad00ed | ||
|
|
e26d3821ce | ||
|
|
fceacea37c | ||
|
|
52b7962dae | ||
|
|
386d8b7836 | ||
|
|
67ee498861 | ||
|
|
42eacaf3a9 | ||
|
|
c0cf7b4501 | ||
|
|
affd06d05c | ||
|
|
7ab8d832fb | ||
|
|
0ecdbf4793 | ||
|
|
284aaec3cd | ||
|
|
9bebb7f03d | ||
|
|
5c0a5646cd | ||
|
|
4d2c86fd5c | ||
|
|
d905dbe214 | ||
|
|
038ca83004 | ||
|
|
d377265b67 | ||
|
|
a415f482db | ||
|
|
954b6fcaf3 | ||
|
|
abe095dd1e | ||
|
|
109ebc14fd | ||
|
|
95ddfcc437 | ||
|
|
ee57935260 | ||
|
|
6bf8f6f9f2 | ||
|
|
8869bac411 | ||
|
|
f61d9ef476 | ||
|
|
3aaec120e7 | ||
|
|
c864976da6 | ||
|
|
a7f5a91cfb | ||
|
|
75816aa3ab | ||
|
|
cac7dcdc76 | ||
|
|
9c374eac96 | ||
|
|
b2e28f133e | ||
|
|
3a93ddfab3 | ||
|
|
979e999403 | ||
|
|
c2755f770c | ||
|
|
31f7f9e2dc | ||
|
|
491e8f7e00 | ||
|
|
bb96aa5156 | ||
|
|
f49a308d2c | ||
|
|
3d0ffc48cb | ||
|
|
bc7b5165be | ||
|
|
a76b07a802 | ||
|
|
33bc507f74 | ||
|
|
3345a7fc3c | ||
|
|
b26b0d886c | ||
|
|
034577c9da | ||
|
|
424717a973 | ||
|
|
e5f93ddf55 | ||
|
|
983039a18a | ||
|
|
a7a01bd52f | ||
|
|
48d726bfd0 | ||
|
|
12a342b6c0 | ||
|
|
1206352b4a | ||
|
|
9da9bac30c | ||
|
|
cd243f40ee | ||
|
|
000417731b | ||
|
|
c77518ff93 | ||
|
|
f0a795b568 | ||
|
|
aa38e51afb | ||
|
|
c21fadf9bc | ||
|
|
0db31c2b43 | ||
|
|
3a0a423bce | ||
|
|
eb90ce50c3 | ||
|
|
c3f8593f8c | ||
|
|
4cbda049e9 | ||
|
|
69396aae01 | ||
|
|
b05879e9e2 | ||
|
|
8001038376 | ||
|
|
c7cc618376 | ||
|
|
9fecb3dfb9 | ||
|
|
617226e584 | ||
|
|
c72c82b970 | ||
|
|
6cae6ebafe | ||
|
|
a2cca6e292 | ||
|
|
01d3b130a9 | ||
|
|
af46a8ded1 | ||
|
|
f00e2be548 | ||
|
|
a4fe433db7 | ||
|
|
f3833376e7 | ||
|
|
4720fa1207 | ||
|
|
df10252979 | ||
|
|
c033d55c47 | ||
|
|
c794ea7ea7 | ||
|
|
02f707f231 | ||
|
|
d356cd5d48 | ||
|
|
b83faf8018 | ||
|
|
2a73d3c793 | ||
|
|
039bbc68ad | ||
|
|
b9460087e3 | ||
|
|
c42a00f9df | ||
|
|
76b9cae259 | ||
|
|
70a87e1181 | ||
|
|
7af757d104 | ||
|
|
9c66fdc703 | ||
|
|
fec0d15c4f | ||
|
|
853e377159 | ||
|
|
8984c81961 | ||
|
|
c6f6db95ff | ||
|
|
8b2c72300c | ||
|
|
8481f2922f | ||
|
|
68e6fe00a4 | ||
|
|
3258bed1c0 | ||
|
|
32d9abcc03 | ||
|
|
0cee640199 | ||
|
|
182e8aa139 | ||
|
|
945093ee7e | ||
|
|
086ca176be | ||
|
|
292647bd53 | ||
|
|
42ded70336 | ||
|
|
3d5573921e | ||
|
|
43752ec3f0 | ||
|
|
e6e3d9e368 | ||
|
|
0de5bb22af | ||
|
|
f670c0fc18 | ||
|
|
09994d6067 | ||
|
|
f81d084f5c | ||
|
|
940c9a8185 | ||
|
|
28d7507a5d | ||
|
|
4f34d48029 | ||
|
|
c78aa5a60f | ||
|
|
7ba4ae11c9 | ||
|
|
5376b5b5d6 | ||
|
|
3ec6c9e4fb | ||
|
|
2eb885c1d8 | ||
|
|
1c46d88728 | ||
|
|
d220d9ee5a | ||
|
|
e77f593b76 | ||
|
|
b305309e64 | ||
|
|
c96f3b303b | ||
|
|
ecb0bd39b6 | ||
|
|
4e4cae0fc3 | ||
|
|
4be15cff02 | ||
|
|
f839cf1ce3 | ||
|
|
1e6a41b5cf | ||
|
|
1ed1723a2f | ||
|
|
7a0b1656c7 | ||
|
|
28f27f733b | ||
|
|
a5100ad380 | ||
|
|
16598555f1 | ||
|
|
a732999da5 | ||
|
|
6d01e6e367 | ||
|
|
50e872fc76 | ||
|
|
318879d174 | ||
|
|
ec3ed67bc9 | ||
|
|
76626ac54b | ||
|
|
116bcf4245 | ||
|
|
f2285a6d71 | ||
|
|
e682ffb61c | ||
|
|
9ebb25427a | ||
|
|
66195ffeed | ||
|
|
662335d81a | ||
|
|
d8817c2d32 | ||
|
|
15ac08474e | ||
|
|
fdfbb18531 | ||
|
|
3ed28f2828 | ||
|
|
fcf9f0a7ee | ||
|
|
33903ea892 | ||
|
|
5bd94b8f47 | ||
|
|
aa5432e162 |
2
.github/workflows/bun-linux-aarch64.yml
vendored
2
.github/workflows/bun-linux-aarch64.yml
vendored
@@ -36,7 +36,7 @@ jobs:
|
||||
arch: aarch64
|
||||
build_arch: arm64
|
||||
runner: linux-arm64
|
||||
webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-1/bun-webkit-linux-arm64-lto.tar.gz"
|
||||
webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-3/bun-webkit-linux-arm64-lto.tar.gz"
|
||||
webkit_basename: "bun-webkit-linux-arm64-lto"
|
||||
build_machine_arch: aarch64
|
||||
|
||||
|
||||
9
.github/workflows/bun-linux-build.yml
vendored
9
.github/workflows/bun-linux-build.yml
vendored
@@ -46,7 +46,7 @@ jobs:
|
||||
arch: x86_64
|
||||
build_arch: amd64
|
||||
runner: big-ubuntu
|
||||
webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-1/bun-webkit-linux-amd64-lto.tar.gz"
|
||||
webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-3/bun-webkit-linux-amd64-lto.tar.gz"
|
||||
webkit_basename: "bun-webkit-linux-amd64-lto"
|
||||
build_machine_arch: x86_64
|
||||
- cpu: nehalem
|
||||
@@ -54,7 +54,7 @@ jobs:
|
||||
arch: x86_64
|
||||
build_arch: amd64
|
||||
runner: big-ubuntu
|
||||
webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-1/bun-webkit-linux-amd64-lto.tar.gz"
|
||||
webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-3/bun-webkit-linux-amd64-lto.tar.gz"
|
||||
webkit_basename: "bun-webkit-linux-amd64-lto"
|
||||
build_machine_arch: x86_64
|
||||
|
||||
@@ -191,6 +191,11 @@ jobs:
|
||||
./bun --version
|
||||
- id: test
|
||||
name: Test (node runner)
|
||||
env:
|
||||
SMTP_SENDGRID_SENDER: ${{ secrets.SMTP_SENDGRID_SENDER }}
|
||||
TLS_POSTGRES_DATABASE_URL: ${{ secrets.TLS_POSTGRES_DATABASE_URL }}
|
||||
PRISMA_POSTGRES_DATABASE_URL: ${{ secrets.PRISMA_POSTGRES_DATABASE_URL }}
|
||||
PRISMA_MONGODB_DATABASE_URL: ${{ secrets.PRISMA_MONGODB_DATABASE_URL }}
|
||||
# if: ${{github.event.inputs.use_bun == 'false'}}
|
||||
run: |
|
||||
bun install
|
||||
|
||||
21
.github/workflows/bun-mac-aarch64.yml
vendored
21
.github/workflows/bun-mac-aarch64.yml
vendored
@@ -117,7 +117,7 @@ jobs:
|
||||
# obj: bun-obj-darwin-x64-baseline
|
||||
# runner: macos-11
|
||||
# artifact: bun-obj-darwin-x64-baseline
|
||||
# webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-1/bun-webkit-macos-amd64-lto.tar.gz"
|
||||
# webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-3/bun-webkit-macos-amd64-lto.tar.gz"
|
||||
# dependencies: true
|
||||
# compile_obj: false
|
||||
# - cpu: haswell
|
||||
@@ -126,7 +126,7 @@ jobs:
|
||||
# obj: bun-obj-darwin-x64
|
||||
# runner: macos-11
|
||||
# artifact: bun-obj-darwin-x64
|
||||
# webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-1/bun-webkit-macos-amd64-lto.tar.gz"
|
||||
# webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-3/bun-webkit-macos-amd64-lto.tar.gz"
|
||||
# dependencies: true
|
||||
# compile_obj: false
|
||||
# - cpu: nehalem
|
||||
@@ -135,7 +135,7 @@ jobs:
|
||||
# obj: bun-obj-darwin-x64-baseline
|
||||
# runner: macos-11
|
||||
# artifact: bun-obj-darwin-x64-baseline
|
||||
# webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-1/bun-webkit-macos-amd64-lto.tar.gz"
|
||||
# webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-3/bun-webkit-macos-amd64-lto.tar.gz"
|
||||
# dependencies: false
|
||||
# compile_obj: true
|
||||
# - cpu: haswell
|
||||
@@ -144,7 +144,7 @@ jobs:
|
||||
# obj: bun-obj-darwin-x64
|
||||
# runner: macos-11
|
||||
# artifact: bun-obj-darwin-x64
|
||||
# webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-1/bun-webkit-macos-amd64-lto.tar.gz"
|
||||
# webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-3/bun-webkit-macos-amd64-lto.tar.gz"
|
||||
# dependencies: false
|
||||
# compile_obj: true
|
||||
- cpu: native
|
||||
@@ -152,7 +152,7 @@ jobs:
|
||||
tag: bun-darwin-aarch64
|
||||
obj: bun-obj-darwin-aarch64
|
||||
artifact: bun-obj-darwin-aarch64
|
||||
webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-1/bun-webkit-macos-arm64-lto.tar.gz"
|
||||
webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-3/bun-webkit-macos-arm64-lto.tar.gz"
|
||||
runner: macos-arm64
|
||||
dependencies: true
|
||||
compile_obj: true
|
||||
@@ -257,7 +257,7 @@ jobs:
|
||||
# package: bun-darwin-x64
|
||||
# runner: macos-11
|
||||
# artifact: bun-obj-darwin-x64-baseline
|
||||
# webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-1/bun-webkit-macos-amd64-lto.tar.gz"
|
||||
# webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-3/bun-webkit-macos-amd64-lto.tar.gz"
|
||||
# - cpu: haswell
|
||||
# arch: x86_64
|
||||
# tag: bun-darwin-x64
|
||||
@@ -265,14 +265,14 @@ jobs:
|
||||
# package: bun-darwin-x64
|
||||
# runner: macos-11
|
||||
# artifact: bun-obj-darwin-x64
|
||||
# webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-1/bun-webkit-macos-amd64-lto.tar.gz"
|
||||
# webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-3/bun-webkit-macos-amd64-lto.tar.gz"
|
||||
- cpu: native
|
||||
arch: aarch64
|
||||
tag: bun-darwin-aarch64
|
||||
obj: bun-obj-darwin-aarch64
|
||||
package: bun-darwin-aarch64
|
||||
artifact: bun-obj-darwin-aarch64
|
||||
webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-1/bun-webkit-macos-arm64-lto.tar.gz"
|
||||
webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-3/bun-webkit-macos-arm64-lto.tar.gz"
|
||||
runner: macos-arm64
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
@@ -430,6 +430,11 @@ jobs:
|
||||
./bun --version
|
||||
- id: test
|
||||
name: Test (node runner)
|
||||
env:
|
||||
SMTP_SENDGRID_SENDER: ${{ secrets.SMTP_SENDGRID_SENDER }}
|
||||
TLS_POSTGRES_DATABASE_URL: ${{ secrets.TLS_POSTGRES_DATABASE_URL }}
|
||||
PRISMA_POSTGRES_DATABASE_URL: ${{ secrets.PRISMA_POSTGRES_DATABASE_URL }}
|
||||
PRISMA_MONGODB_DATABASE_URL: ${{ secrets.PRISMA_MONGODB_DATABASE_URL }}
|
||||
# if: ${{github.event.inputs.use_bun == 'false'}}
|
||||
run: |
|
||||
bun install
|
||||
|
||||
21
.github/workflows/bun-mac-x64-baseline.yml
vendored
21
.github/workflows/bun-mac-x64-baseline.yml
vendored
@@ -117,7 +117,7 @@ jobs:
|
||||
obj: bun-obj-darwin-x64-baseline
|
||||
runner: macos-11
|
||||
artifact: bun-obj-darwin-x64-baseline
|
||||
webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-1/bun-webkit-macos-amd64-lto.tar.gz"
|
||||
webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-3/bun-webkit-macos-amd64-lto.tar.gz"
|
||||
dependencies: true
|
||||
compile_obj: false
|
||||
# - cpu: haswell
|
||||
@@ -126,7 +126,7 @@ jobs:
|
||||
# obj: bun-obj-darwin-x64
|
||||
# runner: macos-11
|
||||
# artifact: bun-obj-darwin-x64
|
||||
# webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-1/bun-webkit-macos-amd64-lto.tar.gz"
|
||||
# webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-3/bun-webkit-macos-amd64-lto.tar.gz"
|
||||
# dependencies: true
|
||||
# compile_obj: false
|
||||
- cpu: nehalem
|
||||
@@ -135,7 +135,7 @@ jobs:
|
||||
obj: bun-obj-darwin-x64-baseline
|
||||
runner: macos-11
|
||||
artifact: bun-obj-darwin-x64-baseline
|
||||
webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-1/bun-webkit-macos-amd64-lto.tar.gz"
|
||||
webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-3/bun-webkit-macos-amd64-lto.tar.gz"
|
||||
dependencies: false
|
||||
compile_obj: true
|
||||
# - cpu: haswell
|
||||
@@ -144,7 +144,7 @@ jobs:
|
||||
# obj: bun-obj-darwin-x64
|
||||
# runner: macos-11
|
||||
# artifact: bun-obj-darwin-x64
|
||||
# webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-1/bun-webkit-macos-amd64-lto.tar.gz"
|
||||
# webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-3/bun-webkit-macos-amd64-lto.tar.gz"
|
||||
# dependencies: false
|
||||
# compile_obj: true
|
||||
# - cpu: native
|
||||
@@ -152,7 +152,7 @@ jobs:
|
||||
# tag: bun-darwin-aarch64
|
||||
# obj: bun-obj-darwin-aarch64
|
||||
# artifact: bun-obj-darwin-aarch64
|
||||
# webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-1/bun-webkit-macos-amd64-lto.tar.gz"
|
||||
# webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-3/bun-webkit-macos-amd64-lto.tar.gz"
|
||||
# runner: macos-arm64
|
||||
# dependencies: true
|
||||
# compile_obj: true
|
||||
@@ -258,7 +258,7 @@ jobs:
|
||||
package: bun-darwin-x64
|
||||
runner: macos-11
|
||||
artifact: bun-obj-darwin-x64-baseline
|
||||
webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-1/bun-webkit-macos-amd64-lto.tar.gz"
|
||||
webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-3/bun-webkit-macos-amd64-lto.tar.gz"
|
||||
# - cpu: haswell
|
||||
# arch: x86_64
|
||||
# tag: bun-darwin-x64
|
||||
@@ -266,14 +266,14 @@ jobs:
|
||||
# package: bun-darwin-x64
|
||||
# runner: macos-11
|
||||
# artifact: bun-obj-darwin-x64
|
||||
# webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-1/bun-webkit-macos-amd64-lto.tar.gz"
|
||||
# webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-3/bun-webkit-macos-amd64-lto.tar.gz"
|
||||
# - cpu: native
|
||||
# arch: aarch64
|
||||
# tag: bun-darwin-aarch64
|
||||
# obj: bun-obj-darwin-aarch64
|
||||
# package: bun-darwin-aarch64
|
||||
# artifact: bun-obj-darwin-aarch64
|
||||
# webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-1/bun-webkit-macos-amd64-lto.tar.gz"
|
||||
# webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-3/bun-webkit-macos-amd64-lto.tar.gz"
|
||||
# runner: macos-arm64
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
@@ -434,6 +434,11 @@ jobs:
|
||||
./bun --version
|
||||
- id: test
|
||||
name: Test (node runner)
|
||||
env:
|
||||
SMTP_SENDGRID_SENDER: ${{ secrets.SMTP_SENDGRID_SENDER }}
|
||||
TLS_POSTGRES_DATABASE_URL: ${{ secrets.TLS_POSTGRES_DATABASE_URL }}
|
||||
PRISMA_POSTGRES_DATABASE_URL: ${{ secrets.PRISMA_POSTGRES_DATABASE_URL }}
|
||||
PRISMA_MONGODB_DATABASE_URL: ${{ secrets.PRISMA_MONGODB_DATABASE_URL }}
|
||||
# if: ${{github.event.inputs.use_bun == 'false'}}
|
||||
run: |
|
||||
bun install
|
||||
|
||||
21
.github/workflows/bun-mac-x64.yml
vendored
21
.github/workflows/bun-mac-x64.yml
vendored
@@ -117,7 +117,7 @@ jobs:
|
||||
# obj: bun-obj-darwin-x64-baseline
|
||||
# runner: macos-11
|
||||
# artifact: bun-obj-darwin-x64-baseline
|
||||
# webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-1/bun-webkit-macos-amd64-lto.tar.gz"
|
||||
# webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-3/bun-webkit-macos-amd64-lto.tar.gz"
|
||||
# dependencies: true
|
||||
# compile_obj: false
|
||||
- cpu: haswell
|
||||
@@ -126,7 +126,7 @@ jobs:
|
||||
obj: bun-obj-darwin-x64
|
||||
runner: macos-11
|
||||
artifact: bun-obj-darwin-x64
|
||||
webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-1/bun-webkit-macos-amd64-lto.tar.gz"
|
||||
webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-3/bun-webkit-macos-amd64-lto.tar.gz"
|
||||
dependencies: true
|
||||
compile_obj: false
|
||||
# - cpu: nehalem
|
||||
@@ -135,7 +135,7 @@ jobs:
|
||||
# obj: bun-obj-darwin-x64-baseline
|
||||
# runner: macos-11
|
||||
# artifact: bun-obj-darwin-x64-baseline
|
||||
# webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-1/bun-webkit-macos-amd64-lto.tar.gz"
|
||||
# webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-3/bun-webkit-macos-amd64-lto.tar.gz"
|
||||
# dependencies: false
|
||||
# compile_obj: true
|
||||
- cpu: haswell
|
||||
@@ -144,7 +144,7 @@ jobs:
|
||||
obj: bun-obj-darwin-x64
|
||||
runner: macos-11
|
||||
artifact: bun-obj-darwin-x64
|
||||
webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-1/bun-webkit-macos-amd64-lto.tar.gz"
|
||||
webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-3/bun-webkit-macos-amd64-lto.tar.gz"
|
||||
dependencies: false
|
||||
compile_obj: true
|
||||
# - cpu: native
|
||||
@@ -152,7 +152,7 @@ jobs:
|
||||
# tag: bun-darwin-aarch64
|
||||
# obj: bun-obj-darwin-aarch64
|
||||
# artifact: bun-obj-darwin-aarch64
|
||||
# webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-1/bun-webkit-macos-arm64-lto.tar.gz"
|
||||
# webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-3/bun-webkit-macos-arm64-lto.tar.gz"
|
||||
# runner: macos-arm64
|
||||
# dependencies: true
|
||||
# compile_obj: true
|
||||
@@ -260,7 +260,7 @@ jobs:
|
||||
# package: bun-darwin-x64
|
||||
# runner: macos-11
|
||||
# artifact: bun-obj-darwin-x64-baseline
|
||||
# webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-1/bun-webkit-macos-amd64-lto.tar.gz"
|
||||
# webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-3/bun-webkit-macos-amd64-lto.tar.gz"
|
||||
- cpu: haswell
|
||||
arch: x86_64
|
||||
tag: bun-darwin-x64
|
||||
@@ -268,14 +268,14 @@ jobs:
|
||||
package: bun-darwin-x64
|
||||
runner: macos-11
|
||||
artifact: bun-obj-darwin-x64
|
||||
webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-1/bun-webkit-macos-amd64-lto.tar.gz"
|
||||
webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-3/bun-webkit-macos-amd64-lto.tar.gz"
|
||||
# - cpu: native
|
||||
# arch: aarch64
|
||||
# tag: bun-darwin-aarch64
|
||||
# obj: bun-obj-darwin-aarch64
|
||||
# package: bun-darwin-aarch64
|
||||
# artifact: bun-obj-darwin-aarch64
|
||||
# webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-1/bun-webkit-macos-arm64-lto.tar.gz"
|
||||
# webkit_url: "https://github.com/oven-sh/WebKit/releases/download/may20-3/bun-webkit-macos-arm64-lto.tar.gz"
|
||||
# runner: macos-arm64
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
@@ -436,6 +436,11 @@ jobs:
|
||||
./bun --version
|
||||
- id: test
|
||||
name: Test (node runner)
|
||||
env:
|
||||
SMTP_SENDGRID_SENDER: ${{ secrets.SMTP_SENDGRID_SENDER }}
|
||||
TLS_POSTGRES_DATABASE_URL: ${{ secrets.TLS_POSTGRES_DATABASE_URL }}
|
||||
PRISMA_POSTGRES_DATABASE_URL: ${{ secrets.PRISMA_POSTGRES_DATABASE_URL }}
|
||||
PRISMA_MONGODB_DATABASE_URL: ${{ secrets.PRISMA_MONGODB_DATABASE_URL }}
|
||||
# if: ${{github.event.inputs.use_bun == 'false'}}
|
||||
run: |
|
||||
bun install
|
||||
|
||||
4
.github/workflows/bun-release.yml
vendored
4
.github/workflows/bun-release.yml
vendored
@@ -156,8 +156,8 @@ jobs:
|
||||
with:
|
||||
images: oven/bun
|
||||
tags: |
|
||||
type=match,pattern=(bun-v)?(\d.\d.\d),group=2,value=${{ env.TAG }}
|
||||
type=match,pattern=(bun-v)?(\d.\d),group=2,value=${{ env.TAG }}
|
||||
type=match,pattern=(bun-v)?(\d+.\d+.\d+),group=2,value=${{ env.TAG }}
|
||||
type=match,pattern=(bun-v)?(\d+.\d+),group=2,value=${{ env.TAG }}
|
||||
- id: login
|
||||
name: Login to Docker
|
||||
uses: docker/login-action@v2
|
||||
|
||||
8
.gitmodules
vendored
8
.gitmodules
vendored
@@ -68,4 +68,10 @@ fetchRecurseSubmodules = false
|
||||
[submodule "src/deps/zstd"]
|
||||
path = src/deps/zstd
|
||||
url = https://github.com/facebook/zstd.git
|
||||
ignore = dirty
|
||||
ignore = dirty
|
||||
[submodule "src/deps/base64"]
|
||||
path = src/deps/base64
|
||||
url = https://github.com/aklomp/base64.git
|
||||
ignore = dirty
|
||||
depth = 1
|
||||
shallow = true
|
||||
19
.vscode/launch.json
generated
vendored
19
.vscode/launch.json
generated
vendored
@@ -14,7 +14,8 @@
|
||||
"name": "bun test [file]",
|
||||
"program": "bun-debug",
|
||||
"args": ["test", "${file}"],
|
||||
"cwd": "${fileDirname}",
|
||||
// The cwd here must be the same as in CI. Or you will cause test failures that only happen in CI.
|
||||
"cwd": "${workspaceFolder}/test",
|
||||
"env": {
|
||||
"FORCE_COLOR": "1",
|
||||
"BUN_DEBUG_QUIET_LOGS": "1",
|
||||
@@ -29,7 +30,8 @@
|
||||
"name": "bun test [file] (fast)",
|
||||
"program": "bun-debug",
|
||||
"args": ["test", "${file}"],
|
||||
"cwd": "${fileDirname}",
|
||||
// The cwd here must be the same as in CI. Or you will cause test failures that only happen in CI.
|
||||
"cwd": "${workspaceFolder}/test",
|
||||
"env": {
|
||||
"FORCE_COLOR": "1",
|
||||
"BUN_DEBUG_QUIET_LOGS": "1"
|
||||
@@ -44,7 +46,8 @@
|
||||
"name": "bun test [file] (verbose)",
|
||||
"program": "bun-debug",
|
||||
"args": ["test", "${file}"],
|
||||
"cwd": "${fileDirname}",
|
||||
// The cwd here must be the same as in CI. Or you will cause test failures that only happen in CI.
|
||||
"cwd": "${workspaceFolder}/test",
|
||||
"env": {
|
||||
"FORCE_COLOR": "1"
|
||||
},
|
||||
@@ -57,7 +60,8 @@
|
||||
"name": "bun test [file] --watch",
|
||||
"program": "bun-debug",
|
||||
"args": ["test", "--watch", "${file}"],
|
||||
"cwd": "${fileDirname}",
|
||||
// The cwd here must be the same as in CI. Or you will cause test failures that only happen in CI.
|
||||
"cwd": "${workspaceFolder}/test",
|
||||
"env": {
|
||||
"FORCE_COLOR": "1",
|
||||
"BUN_DEBUG_QUIET_LOGS": "1"
|
||||
@@ -71,7 +75,8 @@
|
||||
"name": "bun test [file] --only",
|
||||
"program": "bun-debug",
|
||||
"args": ["test", "--only", "${file}"],
|
||||
"cwd": "${fileDirname}",
|
||||
// The cwd here must be the same as in CI. Or you will cause test failures that only happen in CI.
|
||||
"cwd": "${workspaceFolder}/test",
|
||||
"env": {
|
||||
"FORCE_COLOR": "1",
|
||||
"BUN_DEBUG_QUIET_LOGS": "1"
|
||||
@@ -100,6 +105,7 @@
|
||||
"name": "bun test [*] (fast)",
|
||||
"program": "bun-debug",
|
||||
"args": ["test"],
|
||||
// The cwd here must be the same as in CI. Or you will cause test failures that only happen in CI.
|
||||
"cwd": "${workspaceFolder}/test",
|
||||
"env": {
|
||||
"FORCE_COLOR": "1",
|
||||
@@ -114,6 +120,7 @@
|
||||
"name": "bun test [*] --only",
|
||||
"program": "bun-debug",
|
||||
"args": ["test", "--only"],
|
||||
// The cwd here must be the same as in CI. Or you will cause test failures that only happen in CI.
|
||||
"cwd": "${workspaceFolder}/test",
|
||||
"env": {
|
||||
"FORCE_COLOR": "1",
|
||||
@@ -318,7 +325,7 @@
|
||||
"name": "bun install",
|
||||
"program": "bun-debug",
|
||||
"args": ["install"],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"cwd": "${fileDirname}",
|
||||
"console": "internalConsole",
|
||||
"env": {
|
||||
"BUN_DEBUG_QUIET_LOGS": "1"
|
||||
|
||||
2
.vscode/settings.json
vendored
2
.vscode/settings.json
vendored
@@ -7,6 +7,8 @@
|
||||
"search.followSymlinks": false,
|
||||
"search.useIgnoreFiles": true,
|
||||
"zig.buildOnSave": false,
|
||||
// We do this until we upgrade to latest Zig so that zls doesn't break our code.
|
||||
"zig.formattingProvider": "extension",
|
||||
"zig.buildArgs": ["obj", "-Dfor-editor"],
|
||||
"zig.buildOption": "build",
|
||||
"zig.buildFilePath": "${workspaceFolder}/build.zig",
|
||||
|
||||
24
Dockerfile
24
Dockerfile
@@ -10,7 +10,7 @@ ARG ARCH=x86_64
|
||||
ARG BUILD_MACHINE_ARCH=x86_64
|
||||
ARG TRIPLET=${ARCH}-linux-gnu
|
||||
ARG BUILDARCH=amd64
|
||||
ARG WEBKIT_TAG=may20-1
|
||||
ARG WEBKIT_TAG=may20-3
|
||||
ARG ZIG_TAG=jul1
|
||||
ARG ZIG_VERSION="0.11.0-dev.3737+9eb008717"
|
||||
ARG WEBKIT_BASENAME="bun-webkit-linux-$BUILDARCH"
|
||||
@@ -295,6 +295,27 @@ WORKDIR $BUN_DIR
|
||||
RUN cd $BUN_DIR && \
|
||||
make uws && rm -rf src/deps/uws Makefile
|
||||
|
||||
FROM bun-base as base64
|
||||
|
||||
ARG DEBIAN_FRONTEND
|
||||
ARG GITHUB_WORKSPACE
|
||||
ARG ZIG_PATH
|
||||
# Directory extracts to "bun-webkit"
|
||||
ARG WEBKIT_DIR
|
||||
ARG BUN_RELEASE_DIR
|
||||
ARG BUN_DEPS_OUT_DIR
|
||||
ARG BUN_DIR
|
||||
ARG CPU_TARGET
|
||||
ENV CPU_TARGET=${CPU_TARGET}
|
||||
|
||||
COPY Makefile ${BUN_DIR}/Makefile
|
||||
COPY src/deps/base64 ${BUN_DIR}/src/deps/base64
|
||||
|
||||
WORKDIR $BUN_DIR
|
||||
|
||||
RUN cd $BUN_DIR && \
|
||||
make base64 && rm -rf src/deps/base64 Makefile
|
||||
|
||||
FROM bun-base as picohttp
|
||||
|
||||
ARG DEBIAN_FRONTEND
|
||||
@@ -556,6 +577,7 @@ ENV JSC_BASE_DIR=${WEBKIT_DIR}
|
||||
ENV LIB_ICU_PATH=${WEBKIT_DIR}/lib
|
||||
|
||||
COPY --from=zlib ${BUN_DEPS_OUT_DIR}/*.a ${BUN_DEPS_OUT_DIR}/
|
||||
COPY --from=base64 ${BUN_DEPS_OUT_DIR}/*.a ${BUN_DEPS_OUT_DIR}/
|
||||
COPY --from=libarchive ${BUN_DEPS_OUT_DIR}/*.a ${BUN_DEPS_OUT_DIR}/
|
||||
COPY --from=boringssl ${BUN_DEPS_OUT_DIR}/*.a ${BUN_DEPS_OUT_DIR}/
|
||||
COPY --from=lolhtml ${BUN_DEPS_OUT_DIR}/*.a ${BUN_DEPS_OUT_DIR}/
|
||||
|
||||
12
Makefile
12
Makefile
@@ -453,7 +453,8 @@ MINIMUM_ARCHIVE_FILES = -L$(BUN_DEPS_OUT_DIR) \
|
||||
-ldecrepit \
|
||||
-lssl \
|
||||
-lcrypto \
|
||||
-llolhtml
|
||||
-llolhtml \
|
||||
-lbase64
|
||||
|
||||
ARCHIVE_FILES_WITHOUT_LIBCRYPTO = $(MINIMUM_ARCHIVE_FILES) \
|
||||
-larchive \
|
||||
@@ -1694,7 +1695,7 @@ sizegen:
|
||||
# Linux uses bundled SQLite3
|
||||
ifeq ($(OS_NAME),linux)
|
||||
sqlite:
|
||||
$(CC) $(EMIT_LLVM_FOR_RELEASE) $(CFLAGS) $(INCLUDE_DIRS) -DSQLITE_ENABLE_COLUMN_METADATA= -DSQLITE_MAX_VARIABLE_NUMBER=250000 -DSQLITE_ENABLE_RTREE=1 -DSQLITE_ENABLE_FTS3=1 -DSQLITE_ENABLE_FTS3_PARENTHESIS=1 -DSQLITE_ENABLE_JSON1=1 $(SRC_DIR)/sqlite/sqlite3.c -c -o $(SQLITE_OBJECT)
|
||||
$(CC) $(EMIT_LLVM_FOR_RELEASE) $(CFLAGS) $(INCLUDE_DIRS) -DSQLITE_ENABLE_COLUMN_METADATA= -DSQLITE_MAX_VARIABLE_NUMBER=250000 -DSQLITE_ENABLE_RTREE=1 -DSQLITE_ENABLE_FTS3=1 -DSQLITE_ENABLE_FTS3_PARENTHESIS=1 -DSQLITE_ENABLE_FTS5=1 -DSQLITE_ENABLE_JSON1=1 $(SRC_DIR)/sqlite/sqlite3.c -c -o $(SQLITE_OBJECT)
|
||||
endif
|
||||
|
||||
picohttp:
|
||||
@@ -1850,6 +1851,10 @@ copy-to-bun-release-dir-bin:
|
||||
|
||||
PACKAGE_MAP = --pkg-begin async_io $(BUN_DIR)/src/io/io_darwin.zig --pkg-begin bun $(BUN_DIR)/src/bun_redirect.zig --pkg-end --pkg-end --pkg-begin javascript_core $(BUN_DIR)/src/jsc.zig --pkg-begin bun $(BUN_DIR)/src/bun_redirect.zig --pkg-end --pkg-end --pkg-begin bun $(BUN_DIR)/src/bun_redirect.zig --pkg-end
|
||||
|
||||
.PHONY: base64
|
||||
base64:
|
||||
cd $(BUN_DEPS_DIR)/base64 && make clean && cmake $(CMAKE_FLAGS) . && make
|
||||
cp $(BUN_DEPS_DIR)/base64/libbase64.a $(BUN_DEPS_OUT_DIR)/libbase64.a
|
||||
|
||||
.PHONY: cold-jsc-start
|
||||
cold-jsc-start:
|
||||
@@ -1868,7 +1873,8 @@ cold-jsc-start:
|
||||
misctools/cold-jsc-start.cpp -o cold-jsc-start
|
||||
|
||||
.PHONY: vendor-without-npm
|
||||
vendor-without-npm: node-fallbacks runtime_js fallback_decoder bun_error mimalloc picohttp zlib boringssl libarchive lolhtml sqlite usockets uws tinycc c-ares zstd
|
||||
vendor-without-npm: node-fallbacks runtime_js fallback_decoder bun_error mimalloc picohttp zlib boringssl libarchive lolhtml sqlite usockets uws tinycc c-ares zstd base64
|
||||
|
||||
|
||||
.PHONY: vendor-without-check
|
||||
vendor-without-check: npm-install vendor-without-npm
|
||||
|
||||
14
bench/snippets/base64-buffer-to-string.mjs
Normal file
14
bench/snippets/base64-buffer-to-string.mjs
Normal file
@@ -0,0 +1,14 @@
|
||||
import { bench, run } from "./runner.mjs";
|
||||
import { Buffer } from "node:buffer";
|
||||
|
||||
const bigBuffer = Buffer.from("hello world".repeat(10000));
|
||||
const converted = bigBuffer.toString("base64");
|
||||
bench("Buffer.toString('base64')", () => {
|
||||
return bigBuffer.toString("base64");
|
||||
});
|
||||
|
||||
// bench("Buffer.from(str, 'base64')", () => {
|
||||
// return Buffer.from(converted, "base64");
|
||||
// });
|
||||
|
||||
await run();
|
||||
@@ -1,12 +1,6 @@
|
||||
// so it can run in environments without node module resolution
|
||||
import { bench, run } from "../node_modules/mitata/src/cli.mjs";
|
||||
|
||||
var crypto = globalThis.crypto;
|
||||
|
||||
if (!crypto) {
|
||||
crypto = await import("node:crypto");
|
||||
}
|
||||
|
||||
import crypto from "node:crypto";
|
||||
var foo = new Uint8Array(65536);
|
||||
bench("crypto.getRandomValues(65536)", () => {
|
||||
crypto.getRandomValues(foo);
|
||||
@@ -22,4 +16,8 @@ bench("crypto.randomUUID()", () => {
|
||||
return crypto.randomUUID()[2];
|
||||
});
|
||||
|
||||
bench("crypto.randomInt()", () => {
|
||||
return crypto.randomInt(0, 100);
|
||||
});
|
||||
|
||||
await run();
|
||||
|
||||
12
bench/snippets/error-capturestack.mjs
Normal file
12
bench/snippets/error-capturestack.mjs
Normal file
@@ -0,0 +1,12 @@
|
||||
import { bench, run } from "./runner.mjs";
|
||||
|
||||
var err = new Error();
|
||||
bench("Error.captureStackTrace(err)", () => {
|
||||
Error.captureStackTrace(err);
|
||||
});
|
||||
|
||||
bench("Error.prototype.stack", () => {
|
||||
new Error().stack;
|
||||
});
|
||||
|
||||
await run();
|
||||
33
bench/snippets/process-info.mjs
Normal file
33
bench/snippets/process-info.mjs
Normal file
@@ -0,0 +1,33 @@
|
||||
import { bench, run } from "./runner.mjs";
|
||||
import { performance } from "perf_hooks";
|
||||
|
||||
bench("process.memoryUsage()", () => {
|
||||
process.memoryUsage();
|
||||
});
|
||||
|
||||
bench("process.memoryUsage.rss()", () => {
|
||||
process.memoryUsage.rss();
|
||||
});
|
||||
|
||||
bench("process.cpuUsage()", () => {
|
||||
process.cpuUsage();
|
||||
});
|
||||
|
||||
const init = process.cpuUsage();
|
||||
bench("process.cpuUsage(delta)", () => {
|
||||
process.cpuUsage(init);
|
||||
});
|
||||
|
||||
bench("performance.now()", () => {
|
||||
performance.now();
|
||||
});
|
||||
|
||||
bench("process.hrtime()", () => {
|
||||
process.hrtime();
|
||||
});
|
||||
|
||||
bench("process.hrtime.bigint()", () => {
|
||||
process.hrtime.bigint();
|
||||
});
|
||||
|
||||
await run();
|
||||
17
bench/snippets/readfile-not-found.mjs
Normal file
17
bench/snippets/readfile-not-found.mjs
Normal file
@@ -0,0 +1,17 @@
|
||||
import { bench, run } from "./runner.mjs";
|
||||
import { readFileSync, existsSync } from "node:fs";
|
||||
import { readFile } from "node:fs/promises";
|
||||
|
||||
bench(`readFileSync(/tmp/404-not-found)`, () => {
|
||||
try {
|
||||
readFileSync("/tmp/404-not-found");
|
||||
} catch (e) {}
|
||||
});
|
||||
|
||||
bench(`readFile(/tmp/404-not-found)`, async () => {
|
||||
try {
|
||||
await readFile("/tmp/404-not-found");
|
||||
} catch (e) {}
|
||||
});
|
||||
|
||||
await run();
|
||||
@@ -92,10 +92,10 @@ _bun_completions() {
|
||||
PACKAGE_OPTIONS[REMOVE_OPTIONS_LONG]="";
|
||||
PACKAGE_OPTIONS[REMOVE_OPTIONS_SHORT]="";
|
||||
|
||||
PACKAGE_OPTIONS[SHARED_OPTIONS_LONG]="--config --yarn --production --no-save --dry-run --lockfile --force --cache-dir --no-cache --silent --verbose --global --cwd --backend --link-native-bins --help";
|
||||
PACKAGE_OPTIONS[SHARED_OPTIONS_LONG]="--config --yarn --production --frozen-lockfile --no-save --dry-run --lockfile --force --cache-dir --no-cache --silent --verbose --global --cwd --backend --link-native-bins --help";
|
||||
PACKAGE_OPTIONS[SHARED_OPTIONS_SHORT]="-c -y -p -f -g";
|
||||
|
||||
PM_OPTIONS[LONG_OPTIONS]="--config --yarn --production --no-save --dry-run --lockfile --force --cache-dir --no-cache --silent --verbose --no-progress --no-summary --no-verify --ignore-scripts --global --cwd --backend --link-native-bins --help"
|
||||
PM_OPTIONS[LONG_OPTIONS]="--config --yarn --production --frozen-lockfile --no-save --dry-run --lockfile --force --cache-dir --no-cache --silent --verbose --no-progress --no-summary --no-verify --ignore-scripts --global --cwd --backend --link-native-bins --help"
|
||||
PM_OPTIONS[SHORT_OPTIONS]="-c -y -p -f -g"
|
||||
|
||||
local cur_word="${COMP_WORDS[${COMP_CWORD}]}";
|
||||
|
||||
@@ -47,6 +47,7 @@ _bun() {
|
||||
'-g[Add a package globally]' \
|
||||
'--global[Add a package globally]' \
|
||||
'--production[Don'"'"'t install devDependencies]' \
|
||||
'--frozen-lockfile[Disallow changes to lockfile]' \
|
||||
'--optional[Add dependency to optionalDependencies]' \
|
||||
'--development[Add dependency to devDependencies]' \
|
||||
'-d[Add dependency to devDependencies]' \
|
||||
@@ -88,6 +89,7 @@ _bun() {
|
||||
'--yarn[Write a yarn.lock file (yarn v1)]' \
|
||||
'--global[Add a package globally]' \
|
||||
'--production[Don'"'"'t install devDependencies]' \
|
||||
'--frozen-lockfile[Disallow changes to lockfile]' \
|
||||
'--optional[Add dependency to optionalDependencies]' \
|
||||
'--development[Add dependency to devDependencies]' \
|
||||
'-d[Add dependency to devDependencies]' \
|
||||
@@ -123,6 +125,7 @@ _bun() {
|
||||
'--yarn[Write a yarn.lock file (yarn v1)]' \
|
||||
'--global[Add a package globally]' \
|
||||
'--production[Don'"'"'t install devDependencies]' \
|
||||
'--frozen-lockfile[Disallow changes to lockfile]' \
|
||||
'--optional[Add dependency to optionalDependencies]' \
|
||||
'--development[Add dependency to devDependencies]' \
|
||||
'-d[Add dependency to devDependencies]' \
|
||||
@@ -278,6 +281,7 @@ _bun() {
|
||||
'--yarn[Write a yarn.lock file (yarn v1)]'
|
||||
'-p[Do not install devDependencies]'
|
||||
'--production[Do not install devDependencies]'
|
||||
'--frozen-lockfile[Disallow changes to lockfile]' \
|
||||
'--no-save[Do not save a lockfile]'
|
||||
'--dry-run[Do not install anything]'
|
||||
'--lockfile[Store & load a lockfile at a specific filepath]'
|
||||
@@ -532,6 +536,7 @@ _bun() {
|
||||
'--yarn[Write a yarn.lock file (yarn v1)]' \
|
||||
'--production[Don'"'"'t install devDependencies]' \
|
||||
'-p[Don'"'"'t install devDependencies]' \
|
||||
'--frozen-lockfile[Disallow changes to lockfile]' \
|
||||
'--no-save[]' \
|
||||
'--dry-run[Don'"'"'t install anything]' \
|
||||
'--force[Always request the latest versions from the registry & reinstall all dependenices]' \
|
||||
@@ -565,6 +570,7 @@ _bun() {
|
||||
'--yarn[Write a yarn.lock file (yarn v1)]' \
|
||||
'--production[Don'"'"'t install devDependencies]' \
|
||||
'-p[Don'"'"'t install devDependencies]' \
|
||||
'--frozen-lockfile[Disallow changes to lockfile]' \
|
||||
'--no-save[]' \
|
||||
'--dry-run[Don'"'"'t install anything]' \
|
||||
'-g[Remove a package globally]' \
|
||||
|
||||
@@ -115,6 +115,7 @@ subcommands:
|
||||
- yarn -- "Write a yarn.lock file (yarn v1)"
|
||||
- production -- "Don't install devDependencies"
|
||||
- p -- "Don't install devDependencies"
|
||||
- frozen-lockfile -- "Disallow changes to lockfile"
|
||||
- no-save --
|
||||
- dry-run -- "Don't install anything"
|
||||
- force -- "Always request the latest versions from the registry & reinstall all dependenices"
|
||||
@@ -152,6 +153,7 @@ subcommands:
|
||||
- development -- "Add dependency to devDependencies"
|
||||
- d -- "Add dependency to devDependencies"
|
||||
- p -- "Don't install devDependencies"
|
||||
- frozen-lockfile -- "Disallow changes to lockfile"
|
||||
- no-save --
|
||||
- dry-run -- "Don't install anything"
|
||||
- force -- "Always request the latest versions from the registry & reinstall all dependenices"
|
||||
@@ -192,6 +194,7 @@ subcommands:
|
||||
- yarn -- "Write a yarn.lock file (yarn v1)"
|
||||
- production -- "Don't install devDependencies"
|
||||
- p -- "Don't install devDependencies"
|
||||
- frozen-lockfile -- "Disallow changes to lockfile"
|
||||
- no-save --
|
||||
- dry-run -- "Don't install anything"
|
||||
- force -- "Always request the latest versions from the registry & reinstall all dependenices"
|
||||
|
||||
@@ -285,7 +285,13 @@ interface Bun {
|
||||
|
||||
write(
|
||||
destination: string | number | BunFile | URL,
|
||||
input: string | Blob | ArrayBuffer | SharedArrayBuffer | TypedArray | Response,
|
||||
input:
|
||||
| string
|
||||
| Blob
|
||||
| ArrayBuffer
|
||||
| SharedArrayBuffer
|
||||
| TypedArray
|
||||
| Response,
|
||||
): Promise<number>;
|
||||
}
|
||||
|
||||
@@ -301,7 +307,9 @@ interface BunFile {
|
||||
}
|
||||
|
||||
export interface FileSink {
|
||||
write(chunk: string | ArrayBufferView | ArrayBuffer | SharedArrayBuffer): number;
|
||||
write(
|
||||
chunk: string | ArrayBufferView | ArrayBuffer | SharedArrayBuffer,
|
||||
): number;
|
||||
flush(): number | Promise<number>;
|
||||
end(error?: Error): number | Promise<number>;
|
||||
start(options?: { highWaterMark?: number }): void;
|
||||
|
||||
107
docs/api/http.md
107
docs/api/http.md
@@ -67,7 +67,7 @@ Bun.serve({
|
||||
fetch(req) {
|
||||
throw new Error("woops!");
|
||||
},
|
||||
error(error: Error) {
|
||||
error(error) {
|
||||
return new Response(`<pre>${error}\n${error.stack}</pre>`, {
|
||||
headers: {
|
||||
"Content-Type": "text/html",
|
||||
@@ -95,37 +95,37 @@ server.stop();
|
||||
|
||||
## TLS
|
||||
|
||||
Bun supports TLS out of the box, powered by [OpenSSL](https://www.openssl.org/). Enable TLS by passing in a value for `key` and `cert`; both are required to enable TLS. If needed, supply a `passphrase` to decrypt the `keyFile`.
|
||||
Bun supports TLS out of the box, powered by [BoringSSL](https://boringssl.googlesource.com/boringssl). Enable TLS by passing in a value for `key` and `cert`; both are required to enable TLS.
|
||||
|
||||
```ts
|
||||
Bun.serve({
|
||||
fetch(req) {
|
||||
return new Response("Hello!!!");
|
||||
},
|
||||
```ts-diff
|
||||
Bun.serve({
|
||||
fetch(req) {
|
||||
return new Response("Hello!!!");
|
||||
},
|
||||
|
||||
// can be string, BunFile, TypedArray, Buffer, or array thereof
|
||||
key: Bun.file("./key.pem"),
|
||||
cert: Bun.file("./cert.pem"),
|
||||
|
||||
// passphrase, only required if key is encrypted
|
||||
passphrase: "super-secret",
|
||||
});
|
||||
+ tls: {
|
||||
+ key: Bun.file("./key.pem"),
|
||||
+ cert: Bun.file("./cert.pem"),
|
||||
+ }
|
||||
});
|
||||
```
|
||||
|
||||
The `key` and `cert` fields expect the _contents_ of your TLS key and certificate. This can be a string, `BunFile`, `TypedArray`, or `Buffer`.
|
||||
The `key` and `cert` fields expect the _contents_ of your TLS key and certificate, _not a path to it_. This can be a string, `BunFile`, `TypedArray`, or `Buffer`.
|
||||
|
||||
```ts
|
||||
Bun.serve({
|
||||
fetch() {},
|
||||
|
||||
// BunFile
|
||||
key: Bun.file("./key.pem"),
|
||||
// Buffer
|
||||
key: fs.readFileSync("./key.pem"),
|
||||
// string
|
||||
key: fs.readFileSync("./key.pem", "utf8"),
|
||||
// array of above
|
||||
key: [Bun.file('./key1.pem'), Bun.file('./key2.pem')],
|
||||
tls: {
|
||||
// BunFile
|
||||
key: Bun.file("./key.pem"),
|
||||
// Buffer
|
||||
key: fs.readFileSync("./key.pem"),
|
||||
// string
|
||||
key: fs.readFileSync("./key.pem", "utf8"),
|
||||
// array of above
|
||||
key: [Bun.file("./key1.pem"), Bun.file("./key2.pem")],
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
@@ -135,17 +135,35 @@ Bun.serve({
|
||||
|
||||
{% /callout %}
|
||||
|
||||
If your private key is encrypted with a passphrase, provide a value for `passphrase` to decrypt it.
|
||||
|
||||
```ts-diff
|
||||
Bun.serve({
|
||||
fetch(req) {
|
||||
return new Response("Hello!!!");
|
||||
},
|
||||
|
||||
tls: {
|
||||
key: Bun.file("./key.pem"),
|
||||
cert: Bun.file("./cert.pem"),
|
||||
+ passphrase: "my-secret-passphrase",
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
Optionally, you can override the trusted CA certificates by passing a value for `ca`. By default, the server will trust the list of well-known CAs curated by Mozilla. When `ca` is specified, the Mozilla list is overwritten.
|
||||
|
||||
```ts
|
||||
Bun.serve({
|
||||
fetch(req) {
|
||||
return new Response("Hello!!!");
|
||||
},
|
||||
key: Bun.file("./key.pem"), // path to TLS key
|
||||
cert: Bun.file("./cert.pem"), // path to TLS cert
|
||||
ca: Bun.file("./ca.pem"), // path to root CA certificate
|
||||
});
|
||||
```ts-diff
|
||||
Bun.serve({
|
||||
fetch(req) {
|
||||
return new Response("Hello!!!");
|
||||
},
|
||||
tls: {
|
||||
key: Bun.file("./key.pem"), // path to TLS key
|
||||
cert: Bun.file("./cert.pem"), // path to TLS cert
|
||||
+ ca: Bun.file("./ca.pem"), // path to root CA certificate
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
To override Diffie-Helman parameters:
|
||||
@@ -153,7 +171,10 @@ To override Diffie-Helman parameters:
|
||||
```ts
|
||||
Bun.serve({
|
||||
// ...
|
||||
dhParamsFile: "./dhparams.pem", // path to Diffie Helman parameters
|
||||
tls: {
|
||||
// other config
|
||||
dhParamsFile: "/path/to/dhparams.pem", // path to Diffie Helman parameters
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
@@ -274,11 +295,21 @@ interface Bun {
|
||||
port?: number;
|
||||
development?: boolean;
|
||||
error?: (error: Error) => Response | Promise<Response>;
|
||||
keyFile?: string;
|
||||
certFile?: string;
|
||||
caFile?: string;
|
||||
dhParamsFile?: string;
|
||||
passphrase?: string;
|
||||
tls?: {
|
||||
key?:
|
||||
| string
|
||||
| TypedArray
|
||||
| BunFile
|
||||
| Array<string | TypedArray | BunFile>;
|
||||
cert?:
|
||||
| string
|
||||
| TypedArray
|
||||
| BunFile
|
||||
| Array<string | TypedArray | BunFile>;
|
||||
ca?: string | TypedArray | BunFile | Array<string | TypedArray | BunFile>;
|
||||
passphrase?: string;
|
||||
dhParamsFile?: string;
|
||||
};
|
||||
maxRequestBodySize?: number;
|
||||
lowMemoryMode?: boolean;
|
||||
}): Server;
|
||||
|
||||
@@ -28,8 +28,6 @@ for await (const chunk of stream) {
|
||||
}
|
||||
```
|
||||
|
||||
For a more complete discusson of streams in Bun, see [API > Streams](/docs/api/streams).
|
||||
|
||||
## Direct `ReadableStream`
|
||||
|
||||
Bun implements an optimized version of `ReadableStream` that avoid unnecessary data copying & queue management logic. With a traditional `ReadableStream`, chunks of data are _enqueued_. Each chunk is copied into a queue, where it sits until the stream is ready to send more data.
|
||||
@@ -154,7 +152,9 @@ export class ArrayBufferSink {
|
||||
stream?: boolean;
|
||||
}): void;
|
||||
|
||||
write(chunk: string | ArrayBufferView | ArrayBuffer | SharedArrayBuffer): number;
|
||||
write(
|
||||
chunk: string | ArrayBufferView | ArrayBuffer | SharedArrayBuffer,
|
||||
): number;
|
||||
/**
|
||||
* Flush the internal buffer
|
||||
*
|
||||
|
||||
@@ -47,6 +47,9 @@ registry = "https://registry.yarnpkg.com/"
|
||||
# Install for production? This is the equivalent to the "--production" CLI argument
|
||||
production = false
|
||||
|
||||
# Disallow changes to lockfile? This is the equivalent to the "--fozen-lockfile" CLI argument
|
||||
frozenLockfile = false
|
||||
|
||||
# Don't actually install
|
||||
dryRun = true
|
||||
|
||||
@@ -108,6 +111,7 @@ export interface Install {
|
||||
scopes: Scopes;
|
||||
registry: Registry;
|
||||
production: boolean;
|
||||
frozenLockfile: boolean;
|
||||
dryRun: boolean;
|
||||
optional: boolean;
|
||||
dev: boolean;
|
||||
|
||||
@@ -49,6 +49,12 @@ To install in production mode (i.e. without `devDependencies`):
|
||||
$ bun install --production
|
||||
```
|
||||
|
||||
To install with reproducible dependencies, use `--frozen-lockfile`. If your `package.json` disagrees with `bun.lockb`, Bun will exit with an error. This is useful for production builds and CI environments.
|
||||
|
||||
```bash
|
||||
$ bun install --frozen-lockfile
|
||||
```
|
||||
|
||||
To perform a dry run (i.e. don't actually install anything):
|
||||
|
||||
```bash
|
||||
@@ -80,6 +86,9 @@ peer = false
|
||||
# equivalent to `--production` flag
|
||||
production = false
|
||||
|
||||
# equivalent to `--frozen-lockfile` flag
|
||||
frozenLockfile = false
|
||||
|
||||
# equivalent to `--dry-run` flag
|
||||
dryRun = false
|
||||
```
|
||||
@@ -115,6 +124,26 @@ To add a package as an optional dependency (`"optionalDependencies"`):
|
||||
$ bun add --optional lodash
|
||||
```
|
||||
|
||||
To add a package and pin to the resolved version, use `--exact`. This will resolve the version of the package and add it to your `package.json` with an exact version number instead of a version range.
|
||||
|
||||
```bash
|
||||
$ bun add react --exact
|
||||
```
|
||||
|
||||
This will add the following to your `package.json`:
|
||||
|
||||
```jsonc
|
||||
{
|
||||
"dependencies": {
|
||||
// without --exact
|
||||
"react": "^18.2.0", // this matches >= 18.2.0 < 19.0.0
|
||||
|
||||
// with --exact
|
||||
"react": "18.2.0" // this matches only 18.2.0 exactly
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
To install a package globally:
|
||||
|
||||
```bash
|
||||
@@ -197,6 +226,46 @@ In addition, the `--save` flag can be used to add `cool-pkg` to the `dependencie
|
||||
}
|
||||
```
|
||||
|
||||
## Trusted dependencies
|
||||
|
||||
Unlike other npm clients, Bun does not execute arbitrary lifecycle scripts for installed dependencies, such as `postinstall`. These scripts represent a potential security risk, as they can execute arbitrary code on your machine.
|
||||
|
||||
<!-- Bun maintains an allow-list of popular packages containing `postinstall` scripts that are known to be safe. To run lifecycle scripts for packages that aren't on this list, add the package to `trustedDependencies` in your package.json. -->
|
||||
|
||||
To tell Bun to allow lifecycle scripts for a particular package, add the package to `trustedDependencies` in your package.json.
|
||||
|
||||
<!-- ```json-diff
|
||||
{
|
||||
"name": "my-app",
|
||||
"version": "1.0.0",
|
||||
+ "trustedDependencies": {
|
||||
+ "my-trusted-package": "*"
|
||||
+ }
|
||||
}
|
||||
``` -->
|
||||
|
||||
```json-diff
|
||||
{
|
||||
"name": "my-app",
|
||||
"version": "1.0.0",
|
||||
+ "trustedDependencies": ["my-trusted-package"]
|
||||
}
|
||||
```
|
||||
|
||||
Bun reads this field and will run lifecycle scripts for `my-trusted-package`.
|
||||
|
||||
<!-- If you specify a version range, Bun will only execute lifecycle scripts if the resolved package version matches the range. -->
|
||||
<!--
|
||||
```json
|
||||
{
|
||||
"name": "my-app",
|
||||
"version": "1.0.0",
|
||||
"trustedDependencies": {
|
||||
"my-trusted-package": "^1.0.0"
|
||||
}
|
||||
}
|
||||
``` -->
|
||||
|
||||
## Git dependencies
|
||||
|
||||
To add a dependency from a git repository:
|
||||
|
||||
@@ -65,6 +65,24 @@ $ bun test --preload ./setup.ts
|
||||
|
||||
See [Test > Lifecycle](/docs/test/lifecycle) for complete documentation.
|
||||
|
||||
## Mocks
|
||||
|
||||
Create mocks with the `mock` function. Mocks are automatically reset between tests.
|
||||
|
||||
```
|
||||
import { test, expect, mock } from "bun:test";
|
||||
const random = mock(() => Math.random());
|
||||
|
||||
test("random", async () => {
|
||||
const val = random();
|
||||
expect(val).toBeGreaterThan(0);
|
||||
expect(random).toHaveBeenCalled();
|
||||
expect(random).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
```
|
||||
|
||||
See [Test > Mocks](/docs/test/mocks) for complete documentation.
|
||||
|
||||
## Snapshot testing
|
||||
|
||||
Snapshots are supported by `bun test`. See [Test > Snapshots](/docs/test/snapshots) for complete documentation.
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
[Stric](https://github.com/bunsvr) is a minimalist, fast web framework for Bun.
|
||||
|
||||
```ts#index.ts
|
||||
import { App } from "@stricjs/core";
|
||||
import { Router } from '@stricjs/router';
|
||||
|
||||
// Export the fetch handler and serve with Bun
|
||||
export default new App()
|
||||
// Return "Hi!" on every request
|
||||
.use(() => new Response("Hi!"));
|
||||
export default new Router()
|
||||
// Return 'Hi' on every request
|
||||
.get('/', () => new Response('Hi'));
|
||||
```
|
||||
|
||||
Stric provides support for [ArrowJS](https://www.arrow-js.com), a library for building reactive interfaces in **native** JavaScript.
|
||||
Stric provides support for [ArrowJS](https://www.arrow-js.com), a library for building reactive interfaces.
|
||||
|
||||
{% codetabs %}
|
||||
|
||||
```ts#src/App.ts
|
||||
import { html } from "@stricjs/arrow/utils";
|
||||
import { html } from '@stricjs/arrow/utils';
|
||||
|
||||
// Code inside this function can use web APIs
|
||||
export function render() {
|
||||
@@ -23,10 +23,10 @@ export function render() {
|
||||
};
|
||||
|
||||
// Set the path to handle
|
||||
export const path = "/";
|
||||
export const path = '/';
|
||||
```
|
||||
```ts#index.ts
|
||||
import { PageRouter } from "@stricjs/arrow";
|
||||
import { PageRouter } from '@stricjs/arrow';
|
||||
|
||||
// Create a page router, build and serve directly
|
||||
new PageRouter().serve();
|
||||
|
||||
@@ -49,6 +49,12 @@ To install in production mode (i.e. without `devDependencies`):
|
||||
$ bun install --production
|
||||
```
|
||||
|
||||
To install dependencies without allowing changes to lockfile (useful on CI):
|
||||
|
||||
```bash
|
||||
$ bun install --frozen-lockfile
|
||||
```
|
||||
|
||||
To perform a dry run (i.e. don't actually install anything):
|
||||
|
||||
```bash
|
||||
@@ -80,6 +86,9 @@ peer = false
|
||||
# equivalent to `--production` flag
|
||||
production = false
|
||||
|
||||
# equivalent to `--frozen-lockfile` flag
|
||||
frozenLockfile = false
|
||||
|
||||
# equivalent to `--dry-run` flag
|
||||
dryRun = false
|
||||
```
|
||||
|
||||
@@ -24,3 +24,7 @@ To configure a private registry scoped to a particular organization:
|
||||
# registry with token
|
||||
"@myorg3" = { token = "$npm_token", url = "https://registry.myorg.com/" }
|
||||
```
|
||||
|
||||
### `.npmrc`
|
||||
|
||||
Bun does not currently read `.npmrc` files. For private registries, migrate your registry configuration to `bunfig.toml` as documented above.
|
||||
|
||||
@@ -3,17 +3,17 @@ Bun ships as a single executable that can be installed a few different ways.
|
||||
{% callout %}
|
||||
**Windows users** — Bun does not currently provide a native Windows build. We're working on this; progress can be tracked at [this issue](https://github.com/oven-sh/bun/issues/43). In the meantime, use one of the installation methods below for Windows Subsystem for Linux.
|
||||
|
||||
**Linux users** — Kernel version 5.6 or higher is strongly recommended, but the minimum is 5.1.
|
||||
**Linux users** — The `unzip` package is required to install Bun. Kernel version 5.6 or higher is strongly recommended, but the minimum is 5.1.
|
||||
{% /callout %}
|
||||
|
||||
{% codetabs %}
|
||||
|
||||
```bash#Native
|
||||
$ curl -fsSL https://bun.sh/install | bash # for macOS, Linux, and WSL
|
||||
```bash#NPM
|
||||
$ npm install -g bun # the last `npm` command you'll ever need
|
||||
```
|
||||
|
||||
```bash#npm
|
||||
$ npm install -g bun # the last `npm` command you'll ever need
|
||||
```bash#Native
|
||||
$ curl -fsSL https://bun.sh/install | bash # for macOS, Linux, and WSL
|
||||
```
|
||||
|
||||
```bash#Homebrew
|
||||
@@ -26,7 +26,7 @@ $ docker pull oven/bun
|
||||
$ docker run --rm --init --ulimit memlock=-1:-1 oven/bun
|
||||
```
|
||||
|
||||
```bash#proto
|
||||
```bash#Proto
|
||||
$ proto install bun
|
||||
```
|
||||
|
||||
|
||||
18
docs/nav.ts
18
docs/nav.ts
@@ -135,13 +135,13 @@ export default {
|
||||
description:
|
||||
"Install all dependencies with `bun install`, or manage dependencies with `bun add` and `bun remove`.",
|
||||
}),
|
||||
page("install/workspaces", "Workspaces", {
|
||||
description: "Bun's package manager supports workspaces and mono-repo development workflows.",
|
||||
}),
|
||||
page("install/cache", "Global cache", {
|
||||
description:
|
||||
"Bun's package manager installs all packages into a shared global cache to avoid redundant re-downloads.",
|
||||
}),
|
||||
page("install/workspaces", "Workspaces", {
|
||||
description: "Bun's package manager supports workspaces and mono-repo development workflows.",
|
||||
}),
|
||||
page("install/lockfile", "Lockfile", {
|
||||
description:
|
||||
"Bun's binary lockfile `bun.lockb` tracks your resolved dependency ytrr, making future installs fast and repeatable.",
|
||||
@@ -180,6 +180,9 @@ export default {
|
||||
page("cli/test", "`bun test`", {
|
||||
description: "Bun's test runner uses Jest-compatible syntax but runs 100x faster.",
|
||||
}),
|
||||
page("test/hot", "Watch mode", {
|
||||
description: "Reload your tests automatically on change.",
|
||||
}),
|
||||
page("test/writing", "Writing tests", {
|
||||
description:
|
||||
"Write your tests using Jest-like expect matchers, plus setup/teardown hooks, snapshot testing, and more",
|
||||
@@ -187,15 +190,18 @@ export default {
|
||||
page("test/lifecycle", "Lifecycle hooks", {
|
||||
description: "Add lifecycle hooks to your tests that run before/after each test or test run",
|
||||
}),
|
||||
page("test/mocks", "Mocks", {
|
||||
description: "Mocks functions and track method calls",
|
||||
}),
|
||||
page("test/snapshots", "Snapshots", {
|
||||
description: "Add lifecycle hooks to your tests that run before/after each test or test run",
|
||||
}),
|
||||
page("test/time", "Dates and times", {
|
||||
description: "Control the date & time in your tests for more reliable and deterministic tests",
|
||||
}),
|
||||
page("test/dom", "DOM testing", {
|
||||
description: "Write headless tests for UI and React/Vue/Svelte/Lit components with happy-dom",
|
||||
}),
|
||||
page("test/hot", "Watch mode", {
|
||||
description: "Reload your tests automatically on change.",
|
||||
}),
|
||||
|
||||
divider("Package runner"),
|
||||
page("cli/bunx", "`bunx`", {
|
||||
|
||||
@@ -41,9 +41,7 @@ $ brew install llvm@15
|
||||
```
|
||||
|
||||
```bash#Ubuntu/Debian
|
||||
# On Ubuntu 22.04 and newer, LLVM 15 is available in the default repositories
|
||||
$ sudo apt install llvm-15 lld-15 clang-15
|
||||
# On older versions,
|
||||
$ # LLVM has an automatic installation script that is compatible with all versions of Ubuntu
|
||||
$ wget https://apt.llvm.org/llvm.sh -O - | sudo bash -s -- 15 all
|
||||
```
|
||||
|
||||
@@ -85,7 +83,7 @@ $ brew install automake ccache cmake coreutils esbuild gnu-sed go libiconv libto
|
||||
```
|
||||
|
||||
```bash#Ubuntu/Debian
|
||||
$ sudo apt install cargo ccache cmake esbuild git golang libtool ninja-build pkg-config rustc
|
||||
$ sudo apt install cargo ccache cmake git golang libtool ninja-build pkg-config rustc esbuild
|
||||
```
|
||||
|
||||
```bash#Arch
|
||||
@@ -94,7 +92,19 @@ $ pacman -S base-devel ccache cmake esbuild git go libiconv libtool make ninja p
|
||||
|
||||
{% /codetabs %}
|
||||
|
||||
In addition to this, you will need either `bun` or `npm` installed to install the package.json dependencies.
|
||||
{% details summary="Ubuntu — Unable to locate package esbuild" %}
|
||||
|
||||
The `apt install esbuild` command may fail with an `Unable to locate package` error if you are using a Ubuntu mirror that does not contain an exact copy of the original Ubuntu server. Note that the same error may occur if you are not using any mirror but have the Ubuntu Universe enabled in the `sources.list`. In this case, you can install esbuild manually:
|
||||
|
||||
```bash
|
||||
$ curl -fsSL https://esbuild.github.io/dl/latest | sh
|
||||
$ chmod +x ./esbuild
|
||||
$ sudo mv ./esbuild /usr/local/bin
|
||||
```
|
||||
|
||||
{% /details %}
|
||||
|
||||
In addition to this, you will need an npm package manager (`bun`, `npm`, etc) to install the `package.json` dependencies.
|
||||
|
||||
## Install Zig
|
||||
|
||||
@@ -107,7 +117,7 @@ $ zigup 0.11.0-dev.3737+9eb008717
|
||||
|
||||
## Building
|
||||
|
||||
After cloning the repository, prepare bun to be built:
|
||||
After cloning the repository, run the following command. The runs
|
||||
|
||||
```bash
|
||||
$ make setup
|
||||
@@ -217,6 +227,37 @@ You'll need a very recent version of Valgrind due to DWARF 5 debug symbols. You
|
||||
$ valgrind --fair-sched=try --track-origins=yes bun-debug <args>
|
||||
```
|
||||
|
||||
## Updating `WebKit`
|
||||
|
||||
The Bun team will occasionally bump the version of WebKit used in Bun. When this happens, you may see something like this with you run `git status`.
|
||||
|
||||
```bash
|
||||
$ git status
|
||||
On branch my-branch
|
||||
Changes not staged for commit:
|
||||
(use "git add <file>..." to update what will be committed)
|
||||
(use "git restore <file>..." to discard changes in working directory)
|
||||
modified: src/bun.js/WebKit (new commits)
|
||||
```
|
||||
|
||||
For performance reasons, `bun submodule update` does not automatically update the WebKit submodule. To update, run the following commands from the root of the Bun repo:
|
||||
|
||||
```bash
|
||||
$ bun install
|
||||
$ make bindings
|
||||
```
|
||||
|
||||
<!-- Check the [Bun repo](https://github.com/oven-sh/bun/tree/main/src/bun.js) to get the hash of the commit of WebKit is currently being used.
|
||||
|
||||
{% image width="270" src="https://github.com/oven-sh/bun/assets/3084745/51730b73-89ef-4358-9a41-9563a60a54be" /%} -->
|
||||
|
||||
<!--
|
||||
```bash
|
||||
$ cd src/bun.js/WebKit
|
||||
$ git fetch
|
||||
$ git checkout <hash>
|
||||
``` -->
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### libarchive
|
||||
|
||||
@@ -85,6 +85,11 @@ Bun statically links these libraries:
|
||||
|
||||
---
|
||||
|
||||
- [`libbase64`](https://github.com/aklomp/base64/blob/master/LICENSE)
|
||||
- BSD 2-Clause
|
||||
|
||||
---
|
||||
|
||||
- A fork of [`uWebsockets`](https://github.com/jarred-sumner/uwebsockets)
|
||||
- Apache 2.0 licensed
|
||||
|
||||
|
||||
@@ -129,6 +129,9 @@ peer = false
|
||||
# equivalent to `--production` flag
|
||||
production = false
|
||||
|
||||
# equivalent to `--frozen-lockfile` flag
|
||||
frozenLockfile = false
|
||||
|
||||
# equivalent to `--dry-run` flag
|
||||
dryRun = false
|
||||
```
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
Bun aims for complete Node.js API compatibility. Most `npm` packages intended for `Node.js` environments will work with Bun out of the box; the best way to know for certain is to try it.
|
||||
|
||||
This page is updated regularly to reflect compatibility status of the latest version of Bun.
|
||||
This page is updated regularly to reflect compatibility status of the latest version of Bun. If you run into any bugs with a particular package, please [open an issue](https://bun.sh/issues). Opening issues for compatibility bugs helps us prioritize what to work on next.
|
||||
|
||||
## Built-in modules
|
||||
|
||||
@@ -51,7 +51,7 @@ This page is updated regularly to reflect compatibility status of the latest ver
|
||||
|
||||
- {% anchor id="node_crypto" %} [`node:crypto`](https://nodejs.org/api/crypto.html) {% /anchor %}
|
||||
- 🟡
|
||||
- Missing `crypto.Certificate` `crypto.ECDH` `crypto.KeyObject` `crypto.X509Certificate` `crypto.checkPrime{Sync}` `crypto.createPrivateKey` `crypto.createPublicKey` `crypto.createSecretKey` `crypto.diffieHellman` `crypto.generateKey{Sync}` `crypto.generateKeyPair{Sync}` `crypto.generatePrime{Sync}` `crypto.getCipherInfo` `crypto.getCurves` `crypto.{get|set}Fips` `crypto.hkdf` `crypto.hkdfSync` `crypto.randomInt` `crypto.secureHeapUsed` `crypto.setEngine` `crypto.sign` `crypto.verify`
|
||||
- Missing `crypto.Certificate` `crypto.ECDH` `crypto.KeyObject` `crypto.X509Certificate` `crypto.checkPrime{Sync}` `crypto.createPrivateKey` `crypto.createPublicKey` `crypto.createSecretKey` `crypto.diffieHellman` `crypto.generateKey{Sync}` `crypto.generateKeyPair{Sync}` `crypto.generatePrime{Sync}` `crypto.getCipherInfo` `crypto.{get|set}Fips` `crypto.hkdf` `crypto.hkdfSync` `crypto.secureHeapUsed` `crypto.setEngine` `crypto.sign` `crypto.verify`
|
||||
|
||||
---
|
||||
|
||||
@@ -87,7 +87,7 @@ This page is updated regularly to reflect compatibility status of the latest ver
|
||||
|
||||
- {% anchor id="node_fs" %} [`node:fs`](https://nodejs.org/api/fs.html) {% /anchor %}
|
||||
- 🟡
|
||||
- Missing `fs.fdatasync{Sync}` `fs.opendir{Sync}` `fs.readv{Sync}` `fs.{watch|watchFile|unwatchFile}` `fs.writev{Sync}`.
|
||||
- Missing `fs.fdatasync{Sync}` `fs.opendir{Sync}` `fs.{watchFile|unwatchFile}` `fs.{cp|cpSync}`.
|
||||
|
||||
---
|
||||
|
||||
@@ -123,7 +123,7 @@ This page is updated regularly to reflect compatibility status of the latest ver
|
||||
|
||||
- {% anchor id="node_net" %} [`node:net`](https://nodejs.org/api/net.html) {% /anchor %}
|
||||
- 🟡
|
||||
- Missing `net.createServer` `net.{get|set}DefaultAutoSelectFamily` `net.SocketAddress` `net.BlockList`.
|
||||
- Missing `net.{get|set}DefaultAutoSelectFamily` `net.SocketAddress` `net.BlockList`.
|
||||
|
||||
---
|
||||
|
||||
@@ -201,7 +201,7 @@ This page is updated regularly to reflect compatibility status of the latest ver
|
||||
|
||||
- {% anchor id="node_tls" %} [`node:tls`](https://nodejs.org/api/tls.html) {% /anchor %}
|
||||
- 🟡
|
||||
- Missing `tls.Server` `tls.createServer` `tls.createSecurePair` `tls.checkServerIdentity` `tls.rootCertificates`
|
||||
- Missing `tls.createSecurePair` `tls.checkServerIdentity` `tls.rootCertificates`
|
||||
|
||||
---
|
||||
|
||||
@@ -219,13 +219,13 @@ This page is updated regularly to reflect compatibility status of the latest ver
|
||||
|
||||
- {% anchor id="node_url" %} [`node:url`](https://nodejs.org/api/url.html) {% /anchor %}
|
||||
- 🟡
|
||||
- Missing `url.domainTo{ASCII|Unicode}` `url.urlToHttpOptions`. Recommended to use `URL` and `URLSearchParams` globals instead.
|
||||
- Missing `url.domainTo{ASCII|Unicode}`. Recommended to use `URL` and `URLSearchParams` globals instead.
|
||||
|
||||
---
|
||||
|
||||
- {% anchor id="node_util" %} [`node:util`](https://nodejs.org/api/util.html) {% /anchor %}
|
||||
- 🟡
|
||||
- Missing `util.MIMEParams` `util.MIMEType` `util.formatWithOptions()` `util.getSystemErrorMap()` `util.getSystemErrorName()` `util.parseArgs()` `util.stripVTControlCharacters()` `util.toUSVString()` `util.transferableAbortController()` `util.transferableAbortSignal()`.
|
||||
- Missing `util.MIMEParams` `util.MIMEType` `util.formatWithOptions()` `util.getSystemErrorMap()` `util.getSystemErrorName()` `util.parseArgs()` `util.stripVTControlCharacters()` `util.transferableAbortController()` `util.transferableAbortSignal()`.
|
||||
|
||||
---
|
||||
|
||||
@@ -558,7 +558,7 @@ The table below lists all globals implemented by Node.js and Bun's current compa
|
||||
|
||||
- {% anchor id="node_require" %} [`require()`](https://nodejs.org/api/globals.html#require) {% /anchor %}
|
||||
- 🟢
|
||||
- Fully implemented.
|
||||
- Fully implemented, as well as [`require.main`](https://nodejs.org/api/modules.html#requiremain), [`require.cache`](https://nodejs.org/api/modules.html#requirecache), and [`require.resolve`](https://nodejs.org/api/modules.html#requireresolverequest-options)
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -93,6 +93,17 @@ These are the recommended `compilerOptions` for a Bun project.
|
||||
}
|
||||
```
|
||||
|
||||
### Add DOM types
|
||||
|
||||
Settings `"types": ["bun-types"]` means TypeScript will ignore other global type definitions, including `lib: ["dom"]`. To add DOM types into your project, add the following [triple-slash directives](https://www.typescriptlang.org/docs/handbook/triple-slash-directives.html) at the top of any TypeScript file in your project.
|
||||
|
||||
```ts
|
||||
/// <reference lib="dom" />
|
||||
/// <reference lib="dom.iterable" />
|
||||
```
|
||||
|
||||
The same applies to other global type definition _libs_ like `webworker`.
|
||||
|
||||
## Path mapping
|
||||
|
||||
When resolving modules, Bun's runtime respects path mappings defined in [`compilerOptions.paths`](https://www.typescriptlang.org/tsconfig#paths) in your `tsconfig.json`. No other runtime does this.
|
||||
|
||||
@@ -10,7 +10,7 @@ The test runner supports the following lifecycle hooks. This is useful for loadi
|
||||
Perform per-test setup and teardown logic with `beforeEach` and `afterEach`.
|
||||
|
||||
```ts
|
||||
import { expect, test } from "bun:test";
|
||||
import { beforeEach, afterEach } from "bun:test";
|
||||
|
||||
beforeEach(() => {
|
||||
console.log("running test.");
|
||||
@@ -70,7 +70,7 @@ afterAll(() => {
|
||||
Then use `--preload` to run the setup script before any test files.
|
||||
|
||||
```ts
|
||||
bun test --preload ./setup.ts
|
||||
$ bun test --preload ./setup.ts
|
||||
```
|
||||
|
||||
To avoid typing `--preload` every time you run tests, it can be added to your `bunfig.toml`:
|
||||
|
||||
55
docs/test/mocks.md
Normal file
55
docs/test/mocks.md
Normal file
@@ -0,0 +1,55 @@
|
||||
Create mocks with the `mock` function.
|
||||
|
||||
```ts
|
||||
import { test, expect, mock } from "bun:test";
|
||||
const random = mock(() => Math.random());
|
||||
|
||||
test("random", async () => {
|
||||
const val = random();
|
||||
expect(val).toBeGreaterThan(0);
|
||||
expect(random).toHaveBeenCalled();
|
||||
expect(random).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
```
|
||||
|
||||
The result of `mock()` is a new function that's been decorated with some additional properties.
|
||||
|
||||
```ts
|
||||
import { mock } from "bun:test";
|
||||
const random = mock((multiplier: number) => multiplier * Math.random());
|
||||
|
||||
random(2);
|
||||
random(10);
|
||||
|
||||
random.mock.calls;
|
||||
// [[ 2 ], [ 10 ]]
|
||||
|
||||
random.mock.results;
|
||||
// [
|
||||
// { type: "return", value: 0.6533907460954099 },
|
||||
// { type: "return", value: 0.6452713933037312 }
|
||||
// ]
|
||||
```
|
||||
|
||||
## `.spyOn()`
|
||||
|
||||
It's possible to track calls to a function without replacing it with a mock. Use `spyOn()` to create a spy; these spies can be passed to `.toHaveBeenCalled()` and `.toHaveBeenCalledTimes()`.
|
||||
|
||||
```ts
|
||||
import { test, expect, spyOn } from "bun:test";
|
||||
|
||||
const ringo = {
|
||||
name: "Ringo",
|
||||
sayHi() {
|
||||
console.log(`Hello I'm ${this.name}`);
|
||||
},
|
||||
};
|
||||
|
||||
const spy = spyOn(ringo, "sayHi");
|
||||
|
||||
test("spyon", () => {
|
||||
expect(spy).toHaveBeenCalledTimes(0);
|
||||
ringo.sayHi();
|
||||
expect(spy).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
```
|
||||
106
docs/test/time.md
Normal file
106
docs/test/time.md
Normal file
@@ -0,0 +1,106 @@
|
||||
`bun:test` lets you change what time it is in your tests. This was introduced in Bun v0.6.13.
|
||||
|
||||
This works with any of the following:
|
||||
|
||||
- `Date.now`
|
||||
- `new Date()`
|
||||
- `new Intl.DateTimeFormat().format()`
|
||||
|
||||
Timers are not impacted yet, but may be in a future release of Bun.
|
||||
|
||||
## `setSystemTime`
|
||||
|
||||
To change the system time, use `setSystemTime`:
|
||||
|
||||
```ts
|
||||
import { setSystemTime, beforeAll, test, expect } from "bun:test";
|
||||
|
||||
beforeAll(() => {
|
||||
setSystemTime(new Date("2020-01-01T00:00:00.000Z"));
|
||||
});
|
||||
|
||||
test("it is 2020", () => {
|
||||
expect(new Date().getFullYear()).toBe(2020);
|
||||
});
|
||||
```
|
||||
|
||||
To support existing tests that use Jest's `useFakeTimers` and `useRealTimers`, you can use `useFakeTimers` and `useRealTimers`:
|
||||
|
||||
```ts
|
||||
test("just like in jest", () => {
|
||||
jest.useFakeTimers();
|
||||
jest.setSystemTime(new Date("2020-01-01T00:00:00.000Z"));
|
||||
expect(new Date().getFullYear()).toBe(2020);
|
||||
jest.useRealTimers();
|
||||
expect(new Date().getFullYear()).toBeGreaterThan(2020);
|
||||
});
|
||||
|
||||
test("unlike in jest", () => {
|
||||
const OriginalDate = Date;
|
||||
jest.useFakeTimers();
|
||||
if (typeof Bun === "undefined") {
|
||||
// In Jest, the Date constructor changes
|
||||
// That can cause all sorts of bugs because suddenly Date !== Date before the test.
|
||||
expect(Date).not.toBe(OriginalDate);
|
||||
expect(Date.now).not.toBe(OriginalDate.now);
|
||||
} else {
|
||||
// In bun:test, Date constructor does not change when you useFakeTimers
|
||||
expect(Date).toBe(OriginalDate);
|
||||
expect(Date.now).toBe(OriginalDate.now);
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
{% callout %}
|
||||
**Timers** — Note that we have not implemented builtin support for mocking timers yet, but this is on the roadmap.
|
||||
{% /callout %}
|
||||
|
||||
### Reset the system time
|
||||
|
||||
To reset the system time, pass no arguments to `setSystemTime`:
|
||||
|
||||
```ts
|
||||
import { setSystemTime, beforeAll } from "bun:test";
|
||||
|
||||
test("it was 2020, for a moment.", () => {
|
||||
// Set it to something!
|
||||
setSystemTime(new Date("2020-01-01T00:00:00.000Z"));
|
||||
expect(new Date().getFullYear()).toBe(2020);
|
||||
|
||||
// reset it!
|
||||
setSystemTime();
|
||||
|
||||
expect(new Date().getFullYear()).toBeGreaterThan(2020);
|
||||
});
|
||||
```
|
||||
|
||||
## Set the time zone
|
||||
|
||||
To change the time zone, either pass the `$TZ` environment variable to `bun test`.
|
||||
|
||||
```sh
|
||||
TZ=America/Los_Angeles bun test
|
||||
```
|
||||
|
||||
Or set `process.env.TZ` at runtime:
|
||||
|
||||
```ts
|
||||
import { test, expect } from "bun:test";
|
||||
|
||||
test("Welcome to California!", () => {
|
||||
process.env.TZ = "America/Los_Angeles";
|
||||
expect(new Date().getTimezoneOffset()).toBe(420);
|
||||
expect(new Intl.DateTimeFormat().resolvedOptions().timeZone).toBe(
|
||||
"America/Los_Angeles",
|
||||
);
|
||||
});
|
||||
|
||||
test("Welcome to New York!", () => {
|
||||
// Unlike in Jest, you can set the timezone multiple times at runtime and it will work.
|
||||
process.env.TZ = "America/New_York";
|
||||
expect(new Date().getTimezoneOffset()).toBe(240);
|
||||
expect(new Intl.DateTimeFormat().resolvedOptions().timeZone).toBe(
|
||||
"America/New_York",
|
||||
);
|
||||
});
|
||||
```
|
||||
@@ -63,6 +63,21 @@ test("2 * 2", done => {
|
||||
});
|
||||
```
|
||||
|
||||
## Timeouts
|
||||
|
||||
Optionally specify a per-test timeout in milliseconds by passing a number as the third argument to `test`.
|
||||
|
||||
```ts
|
||||
import { test } from "bun:test";
|
||||
|
||||
test.skip("wat", async () => {
|
||||
const data = await slowOperation();
|
||||
expect(data).toBe(42);
|
||||
}, 500); // test must run in <500ms
|
||||
```
|
||||
|
||||
## `test.skip`
|
||||
|
||||
Skip individual tests with `test.skip`. These tests will not be run.
|
||||
|
||||
```ts
|
||||
@@ -74,6 +89,8 @@ test.skip("wat", () => {
|
||||
});
|
||||
```
|
||||
|
||||
## `test.todo`
|
||||
|
||||
Mark a test as a todo with `test.todo`. These tests _will_ be run, and the test runner will expect them to fail. If they pass, you will be prompted to mark it as a regular test.
|
||||
|
||||
```ts
|
||||
@@ -84,6 +101,71 @@ test.todo("fix this", () => {
|
||||
});
|
||||
```
|
||||
|
||||
To exlusively run tests marked as _todo_, use `bun test --todo`.
|
||||
|
||||
```sh
|
||||
$ bun test --todo
|
||||
```
|
||||
|
||||
## `test.only`
|
||||
|
||||
To run a particular test or suite of tests use `test.only()` or `describe.only()`. Once declared, running `bun test --skip` will only execute tests/suites that have been marked with `.only()`.
|
||||
|
||||
```ts
|
||||
import { test, describe } from "bun:test";
|
||||
|
||||
test("test #1", () => {
|
||||
// does not run
|
||||
});
|
||||
|
||||
test.only("test #2", () => {
|
||||
// runs
|
||||
});
|
||||
|
||||
describe.only("only", () => {
|
||||
test("test #3", () => {
|
||||
// runs
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
The following command will only execute tests #2 and #3.
|
||||
|
||||
```sh
|
||||
$ bun test --only
|
||||
```
|
||||
|
||||
## `test.if`
|
||||
|
||||
To run a test conditionally, use `test.if()`. The test will run if the condition is truthy. This is particularly useful for tests that should only run on specific architectures or operating systems.
|
||||
|
||||
```ts
|
||||
test.if(Math.random() > 0.5)("runs half the time", () => {
|
||||
// ...
|
||||
});
|
||||
```
|
||||
|
||||
```ts
|
||||
test.if(Math.random() > 0.5)("runs half the time", () => {
|
||||
// ...
|
||||
});
|
||||
|
||||
const macOS = process.arch === "darwin";
|
||||
test.if(macOS)("runs on macOS", () => {
|
||||
// runs if macOS
|
||||
});
|
||||
```
|
||||
|
||||
To instead skip a test based on some condition, use `test.skipIf()` or `describe.skipIf()`.
|
||||
|
||||
```ts
|
||||
const macOS = process.arch === "darwin";
|
||||
|
||||
test.skipIf(macOS)("runs on non-macOS", () => {
|
||||
// runs if *not* macOS
|
||||
});
|
||||
```
|
||||
|
||||
## Matchers
|
||||
|
||||
Bun implements the following matchers. Full Jest compatibility is on the roadmap; track progress [here](https://github.com/oven-sh/bun/issues/1825).
|
||||
@@ -217,13 +299,13 @@ Bun implements the following matchers. Full Jest compatibility is on the roadmap
|
||||
|
||||
---
|
||||
|
||||
- 🔴
|
||||
- [`.resolves()`](https://jestjs.io/docs/expect#resolves)
|
||||
- 🟢
|
||||
- [`.resolves()`](https://jestjs.io/docs/expect#resolves) (since Bun v0.6.12+)
|
||||
|
||||
---
|
||||
|
||||
- 🔴
|
||||
- [`.rejects()`](https://jestjs.io/docs/expect#rejects)
|
||||
- 🟢
|
||||
- [`.rejects()`](https://jestjs.io/docs/expect#rejects) (since Bun v0.6.12+)
|
||||
|
||||
---
|
||||
|
||||
@@ -277,7 +359,7 @@ Bun implements the following matchers. Full Jest compatibility is on the roadmap
|
||||
|
||||
---
|
||||
|
||||
- 🔴
|
||||
- 🟢
|
||||
- [`.toBeCloseTo()`](https://jestjs.io/docs/expect#tobeclosetonumber-numdigits)
|
||||
|
||||
---
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
"@types/react": "^18.0.25",
|
||||
"@typescript-eslint/eslint-plugin": "^5.31.0",
|
||||
"@typescript-eslint/parser": "^5.31.0",
|
||||
"bun-webkit": "0.0.1-4b3750ddfe644a5bb131d652407653fac528ad51"
|
||||
"bun-webkit": "0.0.1-26c819733315f0ab64ae8e8e65b77d77d31211e1"
|
||||
},
|
||||
"version": "0.0.0",
|
||||
"prettier": "./.prettierrc.cjs"
|
||||
|
||||
6
packages/bun-types/assert.d.ts
vendored
6
packages/bun-types/assert.d.ts
vendored
@@ -931,7 +931,11 @@ declare module "assert" {
|
||||
* instance of an `Error` then it will be thrown instead of the `AssertionError`.
|
||||
*/
|
||||
// FIXME: assert.doesNotMatch is typed, but not in the browserify polyfill?
|
||||
// function doesNotMatch(value: string, regExp: RegExp, message?: string | Error): void;
|
||||
function doesNotMatch(
|
||||
value: string,
|
||||
regExp: RegExp,
|
||||
message?: string | Error,
|
||||
): void;
|
||||
|
||||
const strict: Omit<
|
||||
typeof assert,
|
||||
|
||||
24
packages/bun-types/buffer.d.ts
vendored
24
packages/bun-types/buffer.d.ts
vendored
@@ -2084,6 +2084,30 @@ declare module "buffer" {
|
||||
values(): IterableIterator<number>;
|
||||
}
|
||||
var Buffer: BufferConstructor;
|
||||
|
||||
/**
|
||||
* This function returns `true` if `input` contains only valid UTF-8-encoded data,
|
||||
* including the case in which `input` is empty.
|
||||
*
|
||||
* Throws if the `input` is a detached array buffer.
|
||||
* @since Bun v0.6.13
|
||||
* @param input The input to validate.
|
||||
*/
|
||||
export function isUtf8(
|
||||
input: TypedArray | ArrayBufferLike | DataView,
|
||||
): boolean;
|
||||
|
||||
/**
|
||||
* This function returns `true` if `input` contains only valid ASCII-encoded data,
|
||||
* including the case in which `input` is empty.
|
||||
*
|
||||
* Throws if the `input` is a detached array buffer.
|
||||
* @since Bun v0.6.13
|
||||
* @param input The input to validate.
|
||||
*/
|
||||
export function isAscii(
|
||||
input: TypedArray | ArrayBufferLike | DataView,
|
||||
): boolean;
|
||||
}
|
||||
}
|
||||
declare module "node:buffer" {
|
||||
|
||||
30
packages/bun-types/bun-test.d.ts
vendored
30
packages/bun-types/bun-test.d.ts
vendored
@@ -29,6 +29,36 @@ declare module "bun:test" {
|
||||
<T extends AnyFunction>(Function: T): Mock<T>;
|
||||
};
|
||||
|
||||
/**
|
||||
* Control the system time used by:
|
||||
* - `Date.now()`
|
||||
* - `new Date()`
|
||||
* - `Intl.DateTimeFormat().format()`
|
||||
*
|
||||
* In the future, we may add support for more functions, but we haven't done that yet.
|
||||
*
|
||||
* @param now The time to set the system time to. If not provided, the system time will be reset.
|
||||
* @returns `this`
|
||||
* @since v0.6.13
|
||||
*
|
||||
* ## Set Date to a specific time
|
||||
*
|
||||
* ```js
|
||||
* import { setSystemTime } from 'bun:test';
|
||||
*
|
||||
* setSystemTime(new Date('2020-01-01T00:00:00.000Z'));
|
||||
* console.log(new Date().toISOString()); // 2020-01-01T00:00:00.000Z
|
||||
* ```
|
||||
* ## Reset Date to the current time
|
||||
*
|
||||
* ```js
|
||||
* import { setSystemTime } from 'bun:test';
|
||||
*
|
||||
* setSystemTime();
|
||||
* ```
|
||||
*/
|
||||
export function setSystemTime(now?: Date | number): ThisType<void>;
|
||||
|
||||
interface Jest {
|
||||
restoreAllMocks(): void;
|
||||
fn<T extends AnyFunction>(func?: T): Mock<T>;
|
||||
|
||||
30
packages/bun-types/bun.d.ts
vendored
30
packages/bun-types/bun.d.ts
vendored
@@ -673,7 +673,29 @@ declare module "bun" {
|
||||
/**
|
||||
* The name or path of the file, as specified in the constructor.
|
||||
*/
|
||||
name?: number;
|
||||
readonly name?: string;
|
||||
|
||||
/**
|
||||
* Does the file exist?
|
||||
*
|
||||
* This returns true for regular files and FIFOs. It returns false for
|
||||
* directories. Note that a race condition can occur where the file is
|
||||
* deleted or renamed after this is called but before you open it.
|
||||
*
|
||||
* This does a system call to check if the file exists, which can be
|
||||
* slow.
|
||||
*
|
||||
* If using this in an HTTP server, it's faster to instead use `return new
|
||||
* Response(Bun.file(path))` and then an `error` handler to handle
|
||||
* exceptions.
|
||||
*
|
||||
* Instead of checking for a file's existence and then performing the
|
||||
* operation, it is faster to just perform the operation and handle the
|
||||
* error.
|
||||
*
|
||||
* For empty Blob, this always returns true.
|
||||
*/
|
||||
exists(): Promise<boolean>;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1890,7 +1912,9 @@ declare module "bun" {
|
||||
|
||||
export interface TLSWebSocketServeOptions<WebSocketDataType = undefined>
|
||||
extends WebSocketServeOptions<WebSocketDataType>,
|
||||
TLSOptions {}
|
||||
TLSOptions {
|
||||
tls?: TLSOptions;
|
||||
}
|
||||
export interface Errorlike extends Error {
|
||||
code?: string;
|
||||
errno?: number;
|
||||
@@ -2001,6 +2025,8 @@ declare module "bun" {
|
||||
* The values are SSL options objects.
|
||||
*/
|
||||
serverNames?: Record<string, TLSOptions>;
|
||||
|
||||
tls?: TLSOptions;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
1
packages/bun-types/ffi.d.ts
vendored
1
packages/bun-types/ffi.d.ts
vendored
@@ -344,6 +344,7 @@ declare module "bun:ffi" {
|
||||
*
|
||||
*/
|
||||
u64_fast = 16,
|
||||
function = 17,
|
||||
}
|
||||
|
||||
type UNTYPED = never;
|
||||
|
||||
213
packages/bun-types/fs.d.ts
vendored
213
packages/bun-types/fs.d.ts
vendored
@@ -3932,100 +3932,141 @@ declare module "fs" {
|
||||
}
|
||||
|
||||
export interface FSWatcher extends EventEmitter {
|
||||
/**
|
||||
* Stop watching for changes on the given `fs.FSWatcher`. Once stopped, the `fs.FSWatcher` object is no longer usable.
|
||||
* @since v0.6.8
|
||||
*/
|
||||
close(): void;
|
||||
|
||||
/**
|
||||
* When called, requests that the Node.js event loop not exit so long as the <fs.FSWatcher> is active. Calling watcher.ref() multiple times will have no effect.
|
||||
*/
|
||||
ref(): void;
|
||||
|
||||
/**
|
||||
* When called, the active <fs.FSWatcher> object will not require the Node.js event loop to remain active. If there is no other activity keeping the event loop running, the process may exit before the <fs.FSWatcher> object's callback is invoked. Calling watcher.unref() multiple times will have no effect.
|
||||
*/
|
||||
unref(): void;
|
||||
|
||||
/**
|
||||
* events.EventEmitter
|
||||
* 1. change
|
||||
* 2. error
|
||||
*/
|
||||
addListener(event: string, listener: (...args: any[]) => void): this;
|
||||
addListener(event: 'change', listener: (eventType: string, filename: string | Buffer) => void): this;
|
||||
addListener(event: 'error', listener: (error: Error) => void): this;
|
||||
addListener(event: 'close', listener: () => void): this;
|
||||
on(event: string, listener: (...args: any[]) => void): this;
|
||||
on(event: 'change', listener: (eventType: string, filename: string | Buffer) => void): this;
|
||||
on(event: 'error', listener: (error: Error) => void): this;
|
||||
on(event: 'close', listener: () => void): this;
|
||||
once(event: string, listener: (...args: any[]) => void): this;
|
||||
once(event: 'change', listener: (eventType: string, filename: string | Buffer) => void): this;
|
||||
once(event: 'error', listener: (error: Error) => void): this;
|
||||
once(event: 'close', listener: () => void): this;
|
||||
prependListener(event: string, listener: (...args: any[]) => void): this;
|
||||
prependListener(event: 'change', listener: (eventType: string, filename: string | Buffer) => void): this;
|
||||
prependListener(event: 'error', listener: (error: Error) => void): this;
|
||||
prependListener(event: 'close', listener: () => void): this;
|
||||
prependOnceListener(event: string, listener: (...args: any[]) => void): this;
|
||||
prependOnceListener(event: 'change', listener: (eventType: string, filename: string | Buffer) => void): this;
|
||||
prependOnceListener(event: 'error', listener: (error: Error) => void): this;
|
||||
prependOnceListener(event: 'close', listener: () => void): this;
|
||||
}
|
||||
/**
|
||||
* Watch for changes on `filename`, where `filename` is either a file or a
|
||||
* directory.
|
||||
*
|
||||
* The second argument is optional. If `options` is provided as a string, it
|
||||
* specifies the `encoding`. Otherwise `options` should be passed as an object.
|
||||
*
|
||||
* The listener callback gets two arguments `(eventType, filename)`. `eventType`is either `'rename'` or `'change'`, and `filename` is the name of the file
|
||||
* which triggered the event.
|
||||
*
|
||||
* On most platforms, `'rename'` is emitted whenever a filename appears or
|
||||
* disappears in the directory.
|
||||
*
|
||||
* The listener callback is attached to the `'change'` event fired by `fs.FSWatcher`, but it is not the same thing as the `'change'` value of`eventType`.
|
||||
*
|
||||
* If a `signal` is passed, aborting the corresponding AbortController will close
|
||||
* the returned `fs.FSWatcher`.
|
||||
/**
|
||||
* Stop watching for changes on the given `fs.FSWatcher`. Once stopped, the `fs.FSWatcher` object is no longer usable.
|
||||
* @since v0.6.8
|
||||
* @param listener
|
||||
*/
|
||||
export function watch(
|
||||
filename: PathLike,
|
||||
options:
|
||||
| (WatchOptions & {
|
||||
encoding: 'buffer';
|
||||
})
|
||||
| 'buffer',
|
||||
listener?: WatchListener<Buffer>
|
||||
): FSWatcher;
|
||||
close(): void;
|
||||
|
||||
/**
|
||||
* Watch for changes on `filename`, where `filename` is either a file or a directory, returning an `FSWatcher`.
|
||||
* @param filename A path to a file or directory. If a URL is provided, it must use the `file:` protocol.
|
||||
* @param options Either the encoding for the filename provided to the listener, or an object optionally specifying encoding, persistent, and recursive options.
|
||||
* If `encoding` is not supplied, the default of `'utf8'` is used.
|
||||
* If `persistent` is not supplied, the default of `true` is used.
|
||||
* If `recursive` is not supplied, the default of `false` is used.
|
||||
* When called, requests that the Node.js event loop not exit so long as the <fs.FSWatcher> is active. Calling watcher.ref() multiple times will have no effect.
|
||||
*/
|
||||
export function watch(filename: PathLike, options?: WatchOptions | BufferEncoding | null, listener?: WatchListener<string>): FSWatcher;
|
||||
ref(): void;
|
||||
|
||||
/**
|
||||
* Watch for changes on `filename`, where `filename` is either a file or a directory, returning an `FSWatcher`.
|
||||
* @param filename A path to a file or directory. If a URL is provided, it must use the `file:` protocol.
|
||||
* @param options Either the encoding for the filename provided to the listener, or an object optionally specifying encoding, persistent, and recursive options.
|
||||
* If `encoding` is not supplied, the default of `'utf8'` is used.
|
||||
* If `persistent` is not supplied, the default of `true` is used.
|
||||
* If `recursive` is not supplied, the default of `false` is used.
|
||||
* When called, the active <fs.FSWatcher> object will not require the Node.js event loop to remain active. If there is no other activity keeping the event loop running, the process may exit before the <fs.FSWatcher> object's callback is invoked. Calling watcher.unref() multiple times will have no effect.
|
||||
*/
|
||||
export function watch(filename: PathLike, options: WatchOptions | string, listener?: WatchListener<string | Buffer>): FSWatcher;
|
||||
unref(): void;
|
||||
|
||||
/**
|
||||
* Watch for changes on `filename`, where `filename` is either a file or a directory, returning an `FSWatcher`.
|
||||
* @param filename A path to a file or directory. If a URL is provided, it must use the `file:` protocol.
|
||||
* events.EventEmitter
|
||||
* 1. change
|
||||
* 2. error
|
||||
*/
|
||||
export function watch(filename: PathLike, listener?: WatchListener<string>): FSWatcher;
|
||||
addListener(event: string, listener: (...args: any[]) => void): this;
|
||||
addListener(
|
||||
event: "change",
|
||||
listener: (eventType: string, filename: string | Buffer) => void,
|
||||
): this;
|
||||
addListener(event: "error", listener: (error: Error) => void): this;
|
||||
addListener(event: "close", listener: () => void): this;
|
||||
on(event: string, listener: (...args: any[]) => void): this;
|
||||
on(
|
||||
event: "change",
|
||||
listener: (eventType: string, filename: string | Buffer) => void,
|
||||
): this;
|
||||
on(event: "error", listener: (error: Error) => void): this;
|
||||
on(event: "close", listener: () => void): this;
|
||||
once(event: string, listener: (...args: any[]) => void): this;
|
||||
once(
|
||||
event: "change",
|
||||
listener: (eventType: string, filename: string | Buffer) => void,
|
||||
): this;
|
||||
once(event: "error", listener: (error: Error) => void): this;
|
||||
once(event: "close", listener: () => void): this;
|
||||
prependListener(event: string, listener: (...args: any[]) => void): this;
|
||||
prependListener(
|
||||
event: "change",
|
||||
listener: (eventType: string, filename: string | Buffer) => void,
|
||||
): this;
|
||||
prependListener(event: "error", listener: (error: Error) => void): this;
|
||||
prependListener(event: "close", listener: () => void): this;
|
||||
prependOnceListener(
|
||||
event: string,
|
||||
listener: (...args: any[]) => void,
|
||||
): this;
|
||||
prependOnceListener(
|
||||
event: "change",
|
||||
listener: (eventType: string, filename: string | Buffer) => void,
|
||||
): this;
|
||||
prependOnceListener(event: "error", listener: (error: Error) => void): this;
|
||||
prependOnceListener(event: "close", listener: () => void): this;
|
||||
}
|
||||
|
||||
type WatchOptions = {
|
||||
encoding?: BufferEncoding;
|
||||
persistent?: boolean;
|
||||
recursive?: boolean;
|
||||
signal?: AbortSignal;
|
||||
};
|
||||
type WatchEventType = "rename" | "change" | "error" | "close";
|
||||
type WatchListener<T> = (
|
||||
event: WatchEventType,
|
||||
filename: T | Error | undefined,
|
||||
) => void;
|
||||
/**
|
||||
* Watch for changes on `filename`, where `filename` is either a file or a
|
||||
* directory.
|
||||
*
|
||||
* The second argument is optional. If `options` is provided as a string, it
|
||||
* specifies the `encoding`. Otherwise `options` should be passed as an object.
|
||||
*
|
||||
* The listener callback gets two arguments `(eventType, filename)`. `eventType`is either `'rename'` or `'change'`, and `filename` is the name of the file
|
||||
* which triggered the event.
|
||||
*
|
||||
* On most platforms, `'rename'` is emitted whenever a filename appears or
|
||||
* disappears in the directory.
|
||||
*
|
||||
* The listener callback is attached to the `'change'` event fired by `fs.FSWatcher`, but it is not the same thing as the `'change'` value of`eventType`.
|
||||
*
|
||||
* If a `signal` is passed, aborting the corresponding AbortController will close
|
||||
* the returned `fs.FSWatcher`.
|
||||
* @since v0.6.8
|
||||
* @param listener
|
||||
*/
|
||||
export function watch(
|
||||
filename: PathLike,
|
||||
options:
|
||||
| (WatchOptions & {
|
||||
encoding: "buffer";
|
||||
})
|
||||
| "buffer",
|
||||
listener?: WatchListener<Buffer>,
|
||||
): FSWatcher;
|
||||
/**
|
||||
* Watch for changes on `filename`, where `filename` is either a file or a directory, returning an `FSWatcher`.
|
||||
* @param filename A path to a file or directory. If a URL is provided, it must use the `file:` protocol.
|
||||
* @param options Either the encoding for the filename provided to the listener, or an object optionally specifying encoding, persistent, and recursive options.
|
||||
* If `encoding` is not supplied, the default of `'utf8'` is used.
|
||||
* If `persistent` is not supplied, the default of `true` is used.
|
||||
* If `recursive` is not supplied, the default of `false` is used.
|
||||
*/
|
||||
export function watch(
|
||||
filename: PathLike,
|
||||
options?: WatchOptions | BufferEncoding | null,
|
||||
listener?: WatchListener<string>,
|
||||
): FSWatcher;
|
||||
/**
|
||||
* Watch for changes on `filename`, where `filename` is either a file or a directory, returning an `FSWatcher`.
|
||||
* @param filename A path to a file or directory. If a URL is provided, it must use the `file:` protocol.
|
||||
* @param options Either the encoding for the filename provided to the listener, or an object optionally specifying encoding, persistent, and recursive options.
|
||||
* If `encoding` is not supplied, the default of `'utf8'` is used.
|
||||
* If `persistent` is not supplied, the default of `true` is used.
|
||||
* If `recursive` is not supplied, the default of `false` is used.
|
||||
*/
|
||||
export function watch(
|
||||
filename: PathLike,
|
||||
options: WatchOptions | string,
|
||||
listener?: WatchListener<string | Buffer>,
|
||||
): FSWatcher;
|
||||
/**
|
||||
* Watch for changes on `filename`, where `filename` is either a file or a directory, returning an `FSWatcher`.
|
||||
* @param filename A path to a file or directory. If a URL is provided, it must use the `file:` protocol.
|
||||
*/
|
||||
export function watch(
|
||||
filename: PathLike,
|
||||
listener?: WatchListener<string>,
|
||||
): FSWatcher;
|
||||
}
|
||||
|
||||
declare module "node:fs" {
|
||||
|
||||
72
packages/bun-types/globals.d.ts
vendored
72
packages/bun-types/globals.d.ts
vendored
@@ -420,6 +420,34 @@ interface Process {
|
||||
emitWarning(warning: string | Error /*name?: string, ctor?: Function*/): void;
|
||||
|
||||
readonly config: Object;
|
||||
|
||||
memoryUsage: {
|
||||
(delta?: MemoryUsageObject): MemoryUsageObject;
|
||||
|
||||
rss(): number;
|
||||
};
|
||||
|
||||
cpuUsage(previousValue?: CPUUsageObject): CPUUsageObject;
|
||||
|
||||
/**
|
||||
* Does nothing in Bun
|
||||
*/
|
||||
setSourceMapsEnabled(enabled: boolean): void;
|
||||
|
||||
kill(pid: number, signal?: string | number): void;
|
||||
}
|
||||
|
||||
interface MemoryUsageObject {
|
||||
rss: number;
|
||||
heapTotal: number;
|
||||
heapUsed: number;
|
||||
external: number;
|
||||
arrayBuffers: number;
|
||||
}
|
||||
|
||||
interface CPUUsageObject {
|
||||
user: number;
|
||||
system: number;
|
||||
}
|
||||
|
||||
declare var process: Process;
|
||||
@@ -888,6 +916,12 @@ type ReadableStreamController<T> = ReadableStreamDefaultController<T>;
|
||||
type ReadableStreamDefaultReadResult<T> =
|
||||
| ReadableStreamDefaultReadValueResult<T>
|
||||
| ReadableStreamDefaultReadDoneResult;
|
||||
interface ReadableStreamDefaultReadManyResult<T> {
|
||||
done: boolean;
|
||||
/** Number of bytes */
|
||||
size: number;
|
||||
value: T[];
|
||||
}
|
||||
type ReadableStreamReader<T> = ReadableStreamDefaultReader<T>;
|
||||
|
||||
interface RequestInit {
|
||||
@@ -1395,21 +1429,6 @@ declare function clearTimeout(id?: number | Timer): void;
|
||||
declare function clearImmediate(id?: number | Timer): void;
|
||||
// declare function createImageBitmap(image: ImageBitmapSource, options?: ImageBitmapOptions): Promise<ImageBitmap>;
|
||||
// declare function createImageBitmap(image: ImageBitmapSource, sx: number, sy: number, sw: number, sh: number, options?: ImageBitmapOptions): Promise<ImageBitmap>;
|
||||
/**
|
||||
* Send a HTTP(s) request
|
||||
*
|
||||
* @param url URL string
|
||||
* @param init A structured value that contains settings for the fetch() request.
|
||||
*
|
||||
* @returns A promise that resolves to {@link Response} object.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
declare function fetch(
|
||||
url: string | URL | Request,
|
||||
init?: FetchRequestInit,
|
||||
): Promise<Response>;
|
||||
|
||||
/**
|
||||
* Send a HTTP(s) request
|
||||
@@ -1423,6 +1442,20 @@ declare function fetch(
|
||||
*/
|
||||
// tslint:disable-next-line:unified-signatures
|
||||
declare function fetch(request: Request, init?: RequestInit): Promise<Response>;
|
||||
/**
|
||||
* Send a HTTP(s) request
|
||||
*
|
||||
* @param url URL string
|
||||
* @param init A structured value that contains settings for the fetch() request.
|
||||
*
|
||||
* @returns A promise that resolves to {@link Response} object.
|
||||
*
|
||||
*
|
||||
*/
|
||||
declare function fetch(
|
||||
url: string | URL | Request,
|
||||
init?: FetchRequestInit,
|
||||
): Promise<Response>;
|
||||
|
||||
declare function queueMicrotask(callback: (...args: any[]) => void): void;
|
||||
/**
|
||||
@@ -1432,8 +1465,8 @@ declare function queueMicrotask(callback: (...args: any[]) => void): void;
|
||||
declare function reportError(error: any): void;
|
||||
|
||||
interface Timer {
|
||||
ref(): void;
|
||||
unref(): void;
|
||||
ref(): Timer;
|
||||
unref(): Timer;
|
||||
hasRef(): boolean;
|
||||
|
||||
[Symbol.toPrimitive](): number;
|
||||
@@ -1945,7 +1978,7 @@ interface URLSearchParams {
|
||||
): void;
|
||||
/** Returns a string containing a query string suitable for use in a URL. Does not include the question mark. */
|
||||
toString(): string;
|
||||
[Symbol.iterator](): IterableIterator<[string, FormDataEntryValue]>;
|
||||
[Symbol.iterator](): IterableIterator<[string, string]>;
|
||||
}
|
||||
|
||||
declare var URLSearchParams: {
|
||||
@@ -2261,7 +2294,8 @@ declare var ReadableStreamDefaultController: {
|
||||
interface ReadableStreamDefaultReader<R = any>
|
||||
extends ReadableStreamGenericReader {
|
||||
read(): Promise<ReadableStreamDefaultReadResult<R>>;
|
||||
readMany(): Promise<ReadableStreamDefaultReadValueResult<R>>;
|
||||
/** Only available in Bun. If there are multiple chunks in the queue, this will return all of them at the same time. */
|
||||
readMany(): Promise<ReadableStreamDefaultReadManyResult<R>>;
|
||||
releaseLock(): void;
|
||||
}
|
||||
|
||||
|
||||
18
packages/bun-types/http.d.ts
vendored
18
packages/bun-types/http.d.ts
vendored
@@ -1785,6 +1785,24 @@ declare module "http" {
|
||||
callback?: (res: IncomingMessage) => void,
|
||||
): ClientRequest;
|
||||
|
||||
/**
|
||||
* Performs the low-level validations on the provided name that are done when `res.setHeader(name, value)` is called.
|
||||
* Passing illegal value as name will result in a TypeError being thrown, identified by `code: 'ERR_INVALID_HTTP_TOKEN'`.
|
||||
* @param name Header name
|
||||
* @since v14.3.0
|
||||
*/
|
||||
function validateHeaderName(name: string): void;
|
||||
/**
|
||||
* Performs the low-level validations on the provided value that are done when `res.setHeader(name, value)` is called.
|
||||
* Passing illegal value as value will result in a TypeError being thrown.
|
||||
* - Undefined value error is identified by `code: 'ERR_HTTP_INVALID_HEADER_VALUE'`.
|
||||
* - Invalid value character error is identified by `code: 'ERR_INVALID_CHAR'`.
|
||||
* @param name Header name
|
||||
* @param value Header value
|
||||
* @since v14.3.0
|
||||
*/
|
||||
function validateHeaderValue(name: string, value: string): void;
|
||||
|
||||
let globalAgent: Agent;
|
||||
|
||||
/**
|
||||
|
||||
26
packages/bun-types/perf_hooks.d.ts
vendored
26
packages/bun-types/perf_hooks.d.ts
vendored
@@ -452,19 +452,19 @@ declare module "perf_hooks" {
|
||||
// },
|
||||
// ): void;
|
||||
// }
|
||||
// namespace constants {
|
||||
// const NODE_PERFORMANCE_GC_MAJOR: number;
|
||||
// const NODE_PERFORMANCE_GC_MINOR: number;
|
||||
// const NODE_PERFORMANCE_GC_INCREMENTAL: number;
|
||||
// const NODE_PERFORMANCE_GC_WEAKCB: number;
|
||||
// const NODE_PERFORMANCE_GC_FLAGS_NO: number;
|
||||
// const NODE_PERFORMANCE_GC_FLAGS_CONSTRUCT_RETAINED: number;
|
||||
// const NODE_PERFORMANCE_GC_FLAGS_FORCED: number;
|
||||
// const NODE_PERFORMANCE_GC_FLAGS_SYNCHRONOUS_PHANTOM_PROCESSING: number;
|
||||
// const NODE_PERFORMANCE_GC_FLAGS_ALL_AVAILABLE_GARBAGE: number;
|
||||
// const NODE_PERFORMANCE_GC_FLAGS_ALL_EXTERNAL_MEMORY: number;
|
||||
// const NODE_PERFORMANCE_GC_FLAGS_SCHEDULE_IDLE: number;
|
||||
// }
|
||||
namespace constants {
|
||||
const NODE_PERFORMANCE_GC_MAJOR: number;
|
||||
const NODE_PERFORMANCE_GC_MINOR: number;
|
||||
const NODE_PERFORMANCE_GC_INCREMENTAL: number;
|
||||
const NODE_PERFORMANCE_GC_WEAKCB: number;
|
||||
const NODE_PERFORMANCE_GC_FLAGS_NO: number;
|
||||
const NODE_PERFORMANCE_GC_FLAGS_CONSTRUCT_RETAINED: number;
|
||||
const NODE_PERFORMANCE_GC_FLAGS_FORCED: number;
|
||||
const NODE_PERFORMANCE_GC_FLAGS_SYNCHRONOUS_PHANTOM_PROCESSING: number;
|
||||
const NODE_PERFORMANCE_GC_FLAGS_ALL_AVAILABLE_GARBAGE: number;
|
||||
const NODE_PERFORMANCE_GC_FLAGS_ALL_EXTERNAL_MEMORY: number;
|
||||
const NODE_PERFORMANCE_GC_FLAGS_SCHEDULE_IDLE: number;
|
||||
}
|
||||
const performance: Performance;
|
||||
// interface EventLoopMonitorOptions {
|
||||
// /**
|
||||
|
||||
1
packages/bun-types/sqlite.d.ts
vendored
1
packages/bun-types/sqlite.d.ts
vendored
@@ -235,6 +235,7 @@ declare module "bun:sqlite" {
|
||||
ParamsType extends SQLQueryBindings | SQLQueryBindings[],
|
||||
>(
|
||||
sqlQuery: string,
|
||||
params?: ParamsType
|
||||
): Statement<
|
||||
ReturnType,
|
||||
ParamsType extends Array<any> ? ParamsType : [ParamsType]
|
||||
|
||||
@@ -1,6 +1,15 @@
|
||||
import { watch } from "node:fs";
|
||||
import * as tsd from "tsd";
|
||||
import * as fs from "fs";
|
||||
import { exists } from "fs/promises";
|
||||
|
||||
tsd.expectType<Promise<boolean>>(exists("/etc/passwd"));
|
||||
tsd.expectType<Promise<boolean>>(fs.promises.exists("/etc/passwd"));
|
||||
|
||||
// file path
|
||||
watch(".", (eventType, filename) => {
|
||||
console.log(`event type = ${eventType}`);
|
||||
if (filename) {
|
||||
console.log(`filename = ${filename}`);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -79,4 +79,27 @@ Bun.serve<User>({
|
||||
},
|
||||
});
|
||||
|
||||
Bun.serve({
|
||||
fetch(req) {
|
||||
throw new Error("woops!");
|
||||
},
|
||||
error(error) {
|
||||
return new Response(`<pre>${error}\n${error.stack}</pre>`, {
|
||||
headers: {
|
||||
"Content-Type": "text/html",
|
||||
},
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
export {};
|
||||
|
||||
Bun.serve({
|
||||
port: 1234,
|
||||
fetch(req, server) {
|
||||
server.upgrade(req);
|
||||
if (Math.random() > 0.5) return undefined;
|
||||
return new Response();
|
||||
},
|
||||
websocket: { message() {} },
|
||||
});
|
||||
|
||||
4
packages/bun-types/timers.d.ts
vendored
4
packages/bun-types/timers.d.ts
vendored
@@ -11,8 +11,8 @@
|
||||
|
||||
declare module "timers" {
|
||||
class Timer {
|
||||
ref(): void;
|
||||
unref(): void;
|
||||
ref(): Timer;
|
||||
unref(): Timer;
|
||||
hasRef(): boolean;
|
||||
}
|
||||
|
||||
|
||||
34
src/api/demo/.gitignore
vendored
34
src/api/demo/.gitignore
vendored
@@ -1,34 +0,0 @@
|
||||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
||||
|
||||
# dependencies
|
||||
/node_modules
|
||||
/.pnp
|
||||
.pnp.js
|
||||
|
||||
# testing
|
||||
/coverage
|
||||
|
||||
# next.js
|
||||
/.next/
|
||||
/out/
|
||||
|
||||
# production
|
||||
/build
|
||||
|
||||
# misc
|
||||
.DS_Store
|
||||
*.pem
|
||||
|
||||
# debug
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
|
||||
# local env files
|
||||
.env.local
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
|
||||
# vercel
|
||||
.vercel
|
||||
@@ -1,34 +0,0 @@
|
||||
This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).
|
||||
|
||||
## Getting Started
|
||||
|
||||
First, run the development server:
|
||||
|
||||
```bash
|
||||
npm run dev
|
||||
# or
|
||||
yarn dev
|
||||
```
|
||||
|
||||
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
|
||||
|
||||
You can start editing the page by modifying `pages/index.js`. The page auto-updates as you edit the file.
|
||||
|
||||
[API routes](https://nextjs.org/docs/api-routes/introduction) can be accessed on [http://localhost:3000/api/hello](http://localhost:3000/api/hello). This endpoint can be edited in `pages/api/hello.js`.
|
||||
|
||||
The `pages/api` directory is mapped to `/api/*`. Files in this directory are treated as [API routes](https://nextjs.org/docs/api-routes/introduction) instead of React pages.
|
||||
|
||||
## Learn More
|
||||
|
||||
To learn more about Next.js, take a look at the following resources:
|
||||
|
||||
- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
|
||||
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
|
||||
|
||||
You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!
|
||||
|
||||
## Deploy on Vercel
|
||||
|
||||
The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
|
||||
|
||||
Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.
|
||||
Binary file not shown.
@@ -1,280 +0,0 @@
|
||||
import * as Schema from "../../schema";
|
||||
import { ByteBuffer } from "peechy";
|
||||
import path from "path";
|
||||
import { Loader } from "../schema";
|
||||
// import { transform as sucraseTransform } from "sucrase";
|
||||
|
||||
export interface WebAssemblyModule {
|
||||
init(): number;
|
||||
transform(a: number): number;
|
||||
bun_malloc(a: number): number;
|
||||
bun_free(a: number): number;
|
||||
scan(a: number): number;
|
||||
}
|
||||
|
||||
const wasm_imports_sym: symbol | string =
|
||||
process.env.NODE_ENV === "development" ? "wasm_imports" : Symbol("wasm_imports");
|
||||
|
||||
const ptr_converter = new ArrayBuffer(16);
|
||||
const ptr_float = new BigUint64Array(ptr_converter);
|
||||
const slice = new Uint32Array(ptr_converter);
|
||||
|
||||
const Wasi = {
|
||||
clock_time_get(clk_id, tp) {
|
||||
return Date.now();
|
||||
},
|
||||
environ_sizes_get() {
|
||||
debugger;
|
||||
return 0;
|
||||
},
|
||||
environ_get(__environ, environ_buf) {
|
||||
debugger;
|
||||
return 0;
|
||||
},
|
||||
|
||||
fd_close(fd) {
|
||||
debugger;
|
||||
return 0;
|
||||
},
|
||||
proc_exit() {},
|
||||
|
||||
fd_seek(fd, offset_bigint, whence, newOffset) {
|
||||
debugger;
|
||||
},
|
||||
fd_write(fd, iov, iovcnt, pnum) {
|
||||
debugger;
|
||||
},
|
||||
};
|
||||
|
||||
var scratch: Uint8Array;
|
||||
var scratch2: Uint8Array;
|
||||
|
||||
export class Bun {
|
||||
static has_initialized = false;
|
||||
static wasm_source: WebAssembly.WebAssemblyInstantiatedSource = null;
|
||||
static get wasm_exports(): WebAssemblyModule {
|
||||
return Bun.wasm_source.instance.exports as any;
|
||||
}
|
||||
static get memory(): WebAssembly.Memory {
|
||||
return Bun.wasm_source.instance.exports.memory as any;
|
||||
}
|
||||
|
||||
static memory_array: Uint8Array;
|
||||
|
||||
static _decoder: TextDecoder;
|
||||
|
||||
static _wasmPtrToSlice(offset: number | bigint) {
|
||||
ptr_float[0] = typeof offset === "number" ? BigInt(offset) : offset;
|
||||
return new Uint8Array(Bun.memory.buffer, slice[0], slice[1]);
|
||||
}
|
||||
|
||||
static _wasmPtrLenToString(slice: number) {
|
||||
if (!Bun._decoder) {
|
||||
Bun._decoder = new TextDecoder("utf8");
|
||||
}
|
||||
|
||||
const region = this._wasmPtrToSlice(slice);
|
||||
return Bun._decoder.decode(region);
|
||||
}
|
||||
|
||||
// We don't want people to be calling these manually
|
||||
static [wasm_imports_sym] = {
|
||||
console_log(slice: number) {
|
||||
console.log(Bun._wasmPtrLenToString(slice));
|
||||
},
|
||||
console_error(slice: number) {
|
||||
console.error(Bun._wasmPtrLenToString(slice));
|
||||
},
|
||||
console_warn(slice: number) {
|
||||
console.warn(Bun._wasmPtrLenToString(slice));
|
||||
},
|
||||
console_info(slice: number) {
|
||||
console.info(Bun._wasmPtrLenToString(slice));
|
||||
},
|
||||
|
||||
__indirect_function_table: new WebAssembly.Table({
|
||||
initial: 0,
|
||||
element: "anyfunc",
|
||||
}),
|
||||
__stack_pointer: new WebAssembly.Global({
|
||||
mutable: true,
|
||||
value: "i32",
|
||||
}),
|
||||
__multi3(one: number, two: number) {
|
||||
return Math.imul(one | 0, two | 0);
|
||||
},
|
||||
fmod(one: number, two: number) {
|
||||
return one % two;
|
||||
},
|
||||
memset(ptr: number, value: number, len: number) {
|
||||
Bun.memory_array.fill(value, ptr, ptr + len);
|
||||
},
|
||||
memcpy(ptr: number, value: number, len: number) {
|
||||
Bun.memory_array.copyWithin(ptr, value, value + len);
|
||||
},
|
||||
// These functions convert a to an unsigned long long, rounding toward zero. Negative values all become zero.
|
||||
__fixunsdfti(a: number) {
|
||||
return Math.floor(a);
|
||||
},
|
||||
// These functions return the remainder of the unsigned division of a and b.
|
||||
__umodti3(a: number, b: number) {
|
||||
return (a | 0) % (b | 0);
|
||||
},
|
||||
// These functions return the quotient of the unsigned division of a and b.
|
||||
__udivti3(a: number, b: number) {
|
||||
return (a | 0) / (b | 0);
|
||||
},
|
||||
// These functions return the result of shifting a left by b bits.
|
||||
__ashlti3(a: number, b: number) {
|
||||
return (a | 0) >> (b | 0);
|
||||
},
|
||||
/* Returns: convert a to a double, rounding toward even. */
|
||||
__floatuntidf(a: number) {
|
||||
const mod = a % 2;
|
||||
if (mod === 0) {
|
||||
return Math.ceil(a);
|
||||
} else if (mod === 1) {
|
||||
return Math.floor(a);
|
||||
}
|
||||
},
|
||||
emscripten_notify_memory_growth() {},
|
||||
};
|
||||
|
||||
static async init(url) {
|
||||
// globalThis.sucraseTransform = sucraseTransform;
|
||||
scratch = new Uint8Array(8096);
|
||||
|
||||
if (Bun.has_initialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
Bun.wasm_source = await globalThis.WebAssembly.instantiateStreaming(fetch(url), {
|
||||
env: Bun[wasm_imports_sym],
|
||||
wasi_snapshot_preview1: Wasi,
|
||||
});
|
||||
|
||||
const res = Bun.wasm_exports.init();
|
||||
if (res < 0) {
|
||||
throw `[Bun] Failed to initialize WASM module: code ${res}`;
|
||||
} else {
|
||||
console.log("WASM loaded.");
|
||||
}
|
||||
|
||||
Bun.has_initialized = true;
|
||||
}
|
||||
|
||||
static transformSync(content: Uint8Array | string, file_name: string) {
|
||||
if (!Bun.has_initialized) {
|
||||
throw "Please run await Bun.init(wasm_url) before using this.";
|
||||
}
|
||||
|
||||
// if (process.env.NODE_ENV === "development") {
|
||||
// console.time("[Bun] Transform " + file_name);
|
||||
// }
|
||||
|
||||
const bb = new ByteBuffer(scratch);
|
||||
bb.length = 0;
|
||||
bb.index = 0;
|
||||
var contents_buffer;
|
||||
if (typeof content === "string") {
|
||||
if (!scratch2) {
|
||||
scratch2 = new Uint8Array(content.length * 2);
|
||||
}
|
||||
|
||||
let i = 0;
|
||||
for (; i < content.length; i++) {
|
||||
if (i > scratch2.length) {
|
||||
var scratch3 = new Uint8Array(scratch2.length * 2);
|
||||
scratch3.set(scratch2);
|
||||
scratch2 = scratch3;
|
||||
}
|
||||
scratch2[i] = content.charCodeAt(i);
|
||||
}
|
||||
contents_buffer = scratch2.subarray(0, i);
|
||||
} else {
|
||||
contents_buffer = content;
|
||||
}
|
||||
|
||||
Schema.encodeTransform(
|
||||
{
|
||||
contents: contents_buffer,
|
||||
path: file_name,
|
||||
loader: {
|
||||
".jsx": Loader.jsx,
|
||||
".tsx": Loader.tsx,
|
||||
".ts": Loader.ts,
|
||||
".js": Loader.js,
|
||||
".json": Loader.json,
|
||||
}[path.extname(file_name)],
|
||||
},
|
||||
bb,
|
||||
);
|
||||
const data = bb.toUint8Array();
|
||||
|
||||
const input_ptr = Bun.wasm_exports.bun_malloc(data.length);
|
||||
var buffer = this._wasmPtrToSlice(input_ptr);
|
||||
buffer.set(data);
|
||||
|
||||
const resp_ptr = Bun.wasm_exports.transform(input_ptr);
|
||||
var _bb = new ByteBuffer(this._wasmPtrToSlice(resp_ptr));
|
||||
const response = Schema.decodeTransformResponse(_bb);
|
||||
Bun.wasm_exports.bun_free(input_ptr);
|
||||
scratch = bb.data;
|
||||
return response;
|
||||
}
|
||||
|
||||
static scan(content: Uint8Array | string, file_name: string, loader?: Loader) {
|
||||
if (!Bun.has_initialized) {
|
||||
throw "Please run await Bun.init(wasm_url) before using this.";
|
||||
}
|
||||
|
||||
// if (process.env.NODE_ENV === "development") {
|
||||
// console.time("[Bun] Transform " + file_name);
|
||||
// }
|
||||
scratch.fill(0);
|
||||
const bb = new ByteBuffer(scratch);
|
||||
bb.length = 0;
|
||||
bb.index = 0;
|
||||
var contents_buffer;
|
||||
if (typeof content === "string") {
|
||||
if (!scratch2) {
|
||||
scratch2 = new Uint8Array(content.length * 2);
|
||||
}
|
||||
const encode_into = new TextEncoder().encodeInto(content, scratch2);
|
||||
contents_buffer = scratch2.subarray(0, encode_into.written);
|
||||
} else {
|
||||
contents_buffer = content;
|
||||
}
|
||||
|
||||
Schema.encodeScan(
|
||||
{
|
||||
contents: contents_buffer,
|
||||
path: file_name,
|
||||
loader:
|
||||
loader ||
|
||||
{
|
||||
".jsx": Loader.jsx,
|
||||
".tsx": Loader.tsx,
|
||||
".ts": Loader.ts,
|
||||
".js": Loader.js,
|
||||
".json": Loader.json,
|
||||
}[path.extname(file_name)],
|
||||
},
|
||||
bb,
|
||||
);
|
||||
const data = bb.toUint8Array();
|
||||
|
||||
const input_ptr = Bun.wasm_exports.bun_malloc(data.length);
|
||||
var buffer = this._wasmPtrToSlice(input_ptr);
|
||||
buffer.set(data);
|
||||
|
||||
const resp_ptr = Bun.wasm_exports.scan(input_ptr);
|
||||
var _bb = new ByteBuffer(this._wasmPtrToSlice(resp_ptr));
|
||||
const response = Schema.decodeScanResult(_bb);
|
||||
Bun.wasm_exports.bun_free(input_ptr);
|
||||
scratch = bb.data;
|
||||
return response;
|
||||
}
|
||||
}
|
||||
|
||||
globalThis.Bun = Bun;
|
||||
@@ -1,70 +0,0 @@
|
||||
import { transform as _transform, initialize } from "esbuild-wasm";
|
||||
import initSwc, { transformSync as transformSyncSWC } from "@swc/wasm-web";
|
||||
import { Bun } from "./api";
|
||||
|
||||
export async function start() {
|
||||
await initialize({
|
||||
worker: false,
|
||||
wasmURL: "/node_modules/esbuild-wasm/esbuild.wasm",
|
||||
});
|
||||
await Bun.init("/bun-wasm.wasm");
|
||||
await initSwc("/node_modules/@swc/wasm-web/wasm_bg.wasm");
|
||||
}
|
||||
|
||||
const swcOptions = {
|
||||
sourceMaps: false,
|
||||
inlineSourcesContent: false,
|
||||
jsc: {
|
||||
target: "es2022",
|
||||
parser: {
|
||||
jsx: true,
|
||||
syntax: "typescript",
|
||||
tsx: false,
|
||||
decorators: false,
|
||||
dynamicImport: false,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export async function transform(contents, file) {
|
||||
var result: any = {
|
||||
timings: {
|
||||
esbuild: 0,
|
||||
bun: 0,
|
||||
swc: 0,
|
||||
},
|
||||
};
|
||||
result.timings.esbuild = performance.now();
|
||||
result.esbuild = await _transform(contents, {
|
||||
sourcefile: file,
|
||||
loader: file.substring(file.lastIndexOf(".") + 1),
|
||||
});
|
||||
result.timings.esbuild = performance.now() - result.timings.esbuild;
|
||||
|
||||
result.timings.bun = performance.now();
|
||||
result.bun = Bun.transformSync(contents, file);
|
||||
result.timings.bun = performance.now() - result.timings.bun;
|
||||
|
||||
if (file.substring(file.lastIndexOf(".") + 1) === "tsx") {
|
||||
swcOptions.jsc.parser.tsx = true;
|
||||
swcOptions.jsc.parser.syntax = "typescript";
|
||||
} else if (file.substring(file.lastIndexOf(".") + 1) === "jsx") {
|
||||
swcOptions.jsc.parser.tsx = false;
|
||||
swcOptions.jsc.parser.jsx = true;
|
||||
swcOptions.jsc.parser.syntax = "typescript";
|
||||
} else {
|
||||
swcOptions.jsc.parser.tsx = false;
|
||||
swcOptions.jsc.parser.jsx = false;
|
||||
swcOptions.jsc.parser.syntax = "javascript";
|
||||
}
|
||||
|
||||
result.timings.swc = performance.now();
|
||||
result.swc = transformSyncSWC(contents, swcOptions as any);
|
||||
result.timings.swc = performance.now() - result.timings.swc;
|
||||
|
||||
console.log("esbuild:", result.timings.esbuild, "ms");
|
||||
console.log("Bun:", result.timings.bun, "ms");
|
||||
console.log("SWC:", result.timings.swc, "ms");
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
import { init, parse } from "es-module-lexer";
|
||||
|
||||
import { Bun } from "./api";
|
||||
|
||||
export async function start() {
|
||||
await init;
|
||||
await Bun.init("/bun-wasm.wasm");
|
||||
}
|
||||
|
||||
const swcOptions = {
|
||||
sourceMaps: false,
|
||||
inlineSourcesContent: false,
|
||||
jsc: {
|
||||
target: "es2022",
|
||||
parser: {
|
||||
jsx: true,
|
||||
syntax: "typescript",
|
||||
tsx: false,
|
||||
decorators: false,
|
||||
dynamicImport: false,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export async function transform(contents, file) {
|
||||
var result: any = {
|
||||
timings: {
|
||||
lexer: 0,
|
||||
bun: 0,
|
||||
},
|
||||
};
|
||||
result.timings.lexer = performance.now();
|
||||
result.lexer = await parse(contents, file);
|
||||
result.timings.lexer = performance.now() - result.timings.lexer;
|
||||
|
||||
result.timings.bun = performance.now();
|
||||
result.bun = Bun.scan(contents, file);
|
||||
result.timings.bun = performance.now() - result.timings.bun;
|
||||
|
||||
console.log("lexer:", result.timings.lexer, "ms");
|
||||
console.log("Bun:", result.timings.bun, "ms");
|
||||
|
||||
return result;
|
||||
}
|
||||
5
src/api/demo/next-env.d.ts
vendored
5
src/api/demo/next-env.d.ts
vendored
@@ -1,5 +0,0 @@
|
||||
/// <reference types="next" />
|
||||
/// <reference types="next/image-types/global" />
|
||||
|
||||
// NOTE: This file should not be edited
|
||||
// see https://nextjs.org/docs/basic-features/typescript for more information.
|
||||
@@ -1,29 +0,0 @@
|
||||
{
|
||||
"name": "demo",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "next dev",
|
||||
"build": "next build",
|
||||
"start": "next start"
|
||||
},
|
||||
"dependencies": {
|
||||
"@swc/wasm-web": "^1.2.146",
|
||||
"bun-framework-next": "^12.1.0",
|
||||
"es-module-loader": "^2.3.0",
|
||||
"esbuild": "^0.14.23",
|
||||
"esbuild-wasm": "^0.14.23",
|
||||
"next": "12",
|
||||
"peechy": "0.4.32",
|
||||
"react": "17.0.2",
|
||||
"react-dom": "17.0.2",
|
||||
"sucrase": "^3.18.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/react": "^17.0.8",
|
||||
"bun-types": "^0.2.2",
|
||||
"typescript": "^4.3.2",
|
||||
"webpack": "^5.38.1",
|
||||
"webpack-cli": "^4.7.0"
|
||||
}
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
import "../styles/globals.css";
|
||||
|
||||
function MyApp({ Component, pageProps }) {
|
||||
return <Component {...pageProps} />;
|
||||
}
|
||||
|
||||
export default MyApp;
|
||||
@@ -1,5 +0,0 @@
|
||||
// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
|
||||
|
||||
export default (req, res) => {
|
||||
res.status(200).json({ name: "John Doe" });
|
||||
};
|
||||
@@ -1,68 +0,0 @@
|
||||
import Head from "next/head";
|
||||
import Image from "next/image";
|
||||
import styles from "../styles/Home.module.css";
|
||||
import { readFile } from "fs/promises";
|
||||
|
||||
import React from "react";
|
||||
|
||||
if (typeof window !== "undefined") {
|
||||
globalThis.Run = await import("../lib/run");
|
||||
await import("../lib/api");
|
||||
}
|
||||
|
||||
export async function getStaticProps(ctx) {
|
||||
return {
|
||||
props: {
|
||||
// not tested
|
||||
code: readFile("/Users/jarred/Build/es-module-lexer/test/samples/magic-string.js", { encoding: "utf-8" }),
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
var textDecoder = new TextDecoder();
|
||||
export default function Home({ code }) {
|
||||
const fileNameRef = React.useRef<HTMLInputElement>(null);
|
||||
const [esbuildResult, setEsbuildResult] = React.useState("");
|
||||
const [bunResult, setBunResult] = React.useState("");
|
||||
const [swcResult, setSWCResult] = React.useState("");
|
||||
React.useEffect(() => {
|
||||
globalThis.Run.start();
|
||||
}, []);
|
||||
|
||||
const runBuild = React.useCallback(
|
||||
event => {
|
||||
globalThis.Run.transform(event.target.value, fileNameRef?.current?.value).then(result => {
|
||||
setEsbuildResult(result.esbuild.code);
|
||||
setBunResult(textDecoder.decode(result.bun.files[0].data));
|
||||
setSWCResult(result.swc.code);
|
||||
}, console.error);
|
||||
},
|
||||
[fileNameRef, setEsbuildResult, setBunResult, setSWCResult],
|
||||
);
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
<Head>
|
||||
<title>Next.js</title>
|
||||
<meta name="description" content="Generated by create next app" />
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
</Head>
|
||||
|
||||
<main className={styles.main}>
|
||||
<div>
|
||||
<input
|
||||
autoComplete="filename"
|
||||
type="text"
|
||||
placeholder="filename"
|
||||
defaultValue="input.tsx"
|
||||
ref={fileNameRef}
|
||||
/>
|
||||
<textarea onChange={runBuild} defaultValue={code}></textarea>
|
||||
|
||||
<textarea readOnly value={esbuildResult}></textarea>
|
||||
<textarea readOnly value={bunResult}></textarea>
|
||||
<textarea readOnly value={swcResult}></textarea>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,67 +0,0 @@
|
||||
import Head from "next/head";
|
||||
import { readFile } from "fs/promises";
|
||||
import styles from "../styles/Home.module.css";
|
||||
|
||||
import React from "react";
|
||||
|
||||
if (typeof window !== "undefined") {
|
||||
globalThis.Scan = await import("../lib/scan");
|
||||
await import("../lib/api");
|
||||
}
|
||||
|
||||
export async function getStaticProps(ctx) {
|
||||
return {
|
||||
props: {
|
||||
// not tested
|
||||
code: readFile("/Users/jarred/Build/es-module-lexer/test/samples/magic-string.js", { encoding: "utf-8" }),
|
||||
defaultFile: "magic-string.js",
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
var textDecoder = new TextDecoder();
|
||||
export default function Home({ code, defaultFile }) {
|
||||
const fileNameRef = React.useRef<HTMLInputElement>(null);
|
||||
const [lexer, setLexer] = React.useState("");
|
||||
const [bunResult, setBunResult] = React.useState("");
|
||||
const [file, setFile] = React.useState(defaultFile);
|
||||
React.useEffect(() => {
|
||||
globalThis.Scan.start();
|
||||
}, []);
|
||||
|
||||
const runBuild = React.useCallback(
|
||||
event => {
|
||||
globalThis.Scan.transform(event.target.value, fileNameRef?.current?.value).then(result => {
|
||||
setLexer(JSON.stringify(result.lexer, null, 2));
|
||||
setBunResult(JSON.stringify(result.bun, null, 2));
|
||||
}, console.error);
|
||||
},
|
||||
[fileNameRef, setBunResult, setLexer],
|
||||
);
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
<Head>
|
||||
<title>Next.js</title>
|
||||
<meta name="description" content="Generated by create next app" />
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
</Head>
|
||||
|
||||
<main className={styles.main}>
|
||||
<div>
|
||||
<input
|
||||
autoComplete="filename"
|
||||
type="text"
|
||||
placeholder="filename"
|
||||
value={file}
|
||||
onChange={event => setFile(event.target.value)}
|
||||
ref={fileNameRef}
|
||||
/>
|
||||
<textarea onChange={runBuild} defaultValue={code}></textarea>
|
||||
|
||||
<textarea readOnly value={bunResult}></textarea>
|
||||
<textarea readOnly value={lexer}></textarea>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
export {};
|
||||
2038
src/api/demo/pnpm-lock.yaml
generated
2038
src/api/demo/pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
Binary file not shown.
|
Before Width: | Height: | Size: 15 KiB |
@@ -1,4 +0,0 @@
|
||||
<svg width="283" height="64" viewBox="0 0 283 64" fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M141.04 16c-11.04 0-19 7.2-19 18s8.96 18 20 18c6.67 0 12.55-2.64 16.19-7.09l-7.65-4.42c-2.02 2.21-5.09 3.5-8.54 3.5-4.79 0-8.86-2.5-10.37-6.5h28.02c.22-1.12.35-2.28.35-3.5 0-10.79-7.96-17.99-19-17.99zm-9.46 14.5c1.25-3.99 4.67-6.5 9.45-6.5 4.79 0 8.21 2.51 9.45 6.5h-18.9zM248.72 16c-11.04 0-19 7.2-19 18s8.96 18 20 18c6.67 0 12.55-2.64 16.19-7.09l-7.65-4.42c-2.02 2.21-5.09 3.5-8.54 3.5-4.79 0-8.86-2.5-10.37-6.5h28.02c.22-1.12.35-2.28.35-3.5 0-10.79-7.96-17.99-19-17.99zm-9.45 14.5c1.25-3.99 4.67-6.5 9.45-6.5 4.79 0 8.21 2.51 9.45 6.5h-18.9zM200.24 34c0 6 3.92 10 10 10 4.12 0 7.21-1.87 8.8-4.92l7.68 4.43c-3.18 5.3-9.14 8.49-16.48 8.49-11.05 0-19-7.2-19-18s7.96-18 19-18c7.34 0 13.29 3.19 16.48 8.49l-7.68 4.43c-1.59-3.05-4.68-4.92-8.8-4.92-6.07 0-10 4-10 10zm82.48-29v46h-9V5h9zM36.95 0L73.9 64H0L36.95 0zm92.38 5l-27.71 48L73.91 5H84.3l17.32 30 17.32-30h10.39zm58.91 12v9.69c-1-.29-2.06-.49-3.2-.49-5.81 0-10 4-10 10V51h-9V17h9v9.2c0-5.08 5.91-9.2 13.2-9.2z" fill="#000"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.1 KiB |
799
src/api/demo/schema.d.ts
vendored
799
src/api/demo/schema.d.ts
vendored
@@ -1,799 +0,0 @@
|
||||
import type { ByteBuffer } from "peechy";
|
||||
|
||||
type byte = number;
|
||||
type float = number;
|
||||
type int = number;
|
||||
type alphanumeric = string;
|
||||
type uint = number;
|
||||
type int8 = number;
|
||||
type lowp = number;
|
||||
type int16 = number;
|
||||
type int32 = number;
|
||||
type float32 = number;
|
||||
type uint16 = number;
|
||||
type uint32 = number;
|
||||
export enum Loader {
|
||||
jsx = 1,
|
||||
js = 2,
|
||||
ts = 3,
|
||||
tsx = 4,
|
||||
css = 5,
|
||||
file = 6,
|
||||
json = 7,
|
||||
toml = 8,
|
||||
wasm = 9,
|
||||
}
|
||||
export const LoaderKeys = {
|
||||
1: "jsx",
|
||||
jsx: "jsx",
|
||||
2: "js",
|
||||
js: "js",
|
||||
3: "ts",
|
||||
ts: "ts",
|
||||
4: "tsx",
|
||||
tsx: "tsx",
|
||||
5: "css",
|
||||
css: "css",
|
||||
6: "file",
|
||||
file: "file",
|
||||
7: "json",
|
||||
json: "json",
|
||||
8: "toml",
|
||||
toml: "toml",
|
||||
9: "wasm",
|
||||
wasm: "wasm",
|
||||
};
|
||||
export enum FrameworkEntryPointType {
|
||||
client = 1,
|
||||
server = 2,
|
||||
fallback = 3,
|
||||
}
|
||||
export const FrameworkEntryPointTypeKeys = {
|
||||
1: "client",
|
||||
client: "client",
|
||||
2: "server",
|
||||
server: "server",
|
||||
3: "fallback",
|
||||
fallback: "fallback",
|
||||
};
|
||||
export enum StackFrameScope {
|
||||
Eval = 1,
|
||||
Module = 2,
|
||||
Function = 3,
|
||||
Global = 4,
|
||||
Wasm = 5,
|
||||
Constructor = 6,
|
||||
}
|
||||
export const StackFrameScopeKeys = {
|
||||
1: "Eval",
|
||||
Eval: "Eval",
|
||||
2: "Module",
|
||||
Module: "Module",
|
||||
3: "Function",
|
||||
Function: "Function",
|
||||
4: "Global",
|
||||
Global: "Global",
|
||||
5: "Wasm",
|
||||
Wasm: "Wasm",
|
||||
6: "Constructor",
|
||||
Constructor: "Constructor",
|
||||
};
|
||||
export enum FallbackStep {
|
||||
ssr_disabled = 1,
|
||||
create_vm = 2,
|
||||
configure_router = 3,
|
||||
configure_defines = 4,
|
||||
resolve_entry_point = 5,
|
||||
load_entry_point = 6,
|
||||
eval_entry_point = 7,
|
||||
fetch_event_handler = 8,
|
||||
}
|
||||
export const FallbackStepKeys = {
|
||||
1: "ssr_disabled",
|
||||
ssr_disabled: "ssr_disabled",
|
||||
2: "create_vm",
|
||||
create_vm: "create_vm",
|
||||
3: "configure_router",
|
||||
configure_router: "configure_router",
|
||||
4: "configure_defines",
|
||||
configure_defines: "configure_defines",
|
||||
5: "resolve_entry_point",
|
||||
resolve_entry_point: "resolve_entry_point",
|
||||
6: "load_entry_point",
|
||||
load_entry_point: "load_entry_point",
|
||||
7: "eval_entry_point",
|
||||
eval_entry_point: "eval_entry_point",
|
||||
8: "fetch_event_handler",
|
||||
fetch_event_handler: "fetch_event_handler",
|
||||
};
|
||||
export enum ResolveMode {
|
||||
disable = 1,
|
||||
lazy = 2,
|
||||
dev = 3,
|
||||
bundle = 4,
|
||||
}
|
||||
export const ResolveModeKeys = {
|
||||
1: "disable",
|
||||
disable: "disable",
|
||||
2: "lazy",
|
||||
lazy: "lazy",
|
||||
3: "dev",
|
||||
dev: "dev",
|
||||
4: "bundle",
|
||||
bundle: "bundle",
|
||||
};
|
||||
export enum Platform {
|
||||
browser = 1,
|
||||
node = 2,
|
||||
bun = 3,
|
||||
bun_macro = 4,
|
||||
}
|
||||
export const PlatformKeys = {
|
||||
1: "browser",
|
||||
browser: "browser",
|
||||
2: "node",
|
||||
node: "node",
|
||||
3: "bun",
|
||||
bun: "bun",
|
||||
4: "bun_macro",
|
||||
bun_macro: "bun_macro",
|
||||
};
|
||||
export enum CSSInJSBehavior {
|
||||
facade = 1,
|
||||
facade_onimportcss = 2,
|
||||
auto_onimportcss = 3,
|
||||
}
|
||||
export const CSSInJSBehaviorKeys = {
|
||||
1: "facade",
|
||||
facade: "facade",
|
||||
2: "facade_onimportcss",
|
||||
facade_onimportcss: "facade_onimportcss",
|
||||
3: "auto_onimportcss",
|
||||
auto_onimportcss: "auto_onimportcss",
|
||||
};
|
||||
export enum JSXRuntime {
|
||||
automatic = 1,
|
||||
classic = 2,
|
||||
}
|
||||
export const JSXRuntimeKeys = {
|
||||
1: "automatic",
|
||||
automatic: "automatic",
|
||||
2: "classic",
|
||||
classic: "classic",
|
||||
};
|
||||
export enum ScanDependencyMode {
|
||||
app = 1,
|
||||
all = 2,
|
||||
}
|
||||
export const ScanDependencyModeKeys = {
|
||||
1: "app",
|
||||
app: "app",
|
||||
2: "all",
|
||||
all: "all",
|
||||
};
|
||||
export enum ModuleImportType {
|
||||
import = 1,
|
||||
require = 2,
|
||||
}
|
||||
export const ModuleImportTypeKeys = {
|
||||
1: "import",
|
||||
import: "import",
|
||||
2: "require",
|
||||
require: "require",
|
||||
};
|
||||
export enum DotEnvBehavior {
|
||||
disable = 1,
|
||||
prefix = 2,
|
||||
load_all = 3,
|
||||
}
|
||||
export const DotEnvBehaviorKeys = {
|
||||
1: "disable",
|
||||
disable: "disable",
|
||||
2: "prefix",
|
||||
prefix: "prefix",
|
||||
3: "load_all",
|
||||
load_all: "load_all",
|
||||
};
|
||||
export enum ImportKind {
|
||||
entry_point = 1,
|
||||
stmt = 2,
|
||||
require = 3,
|
||||
dynamic = 4,
|
||||
require_resolve = 5,
|
||||
at = 6,
|
||||
url = 7,
|
||||
internal = 8,
|
||||
}
|
||||
export const ImportKindKeys = {
|
||||
1: "entry_point",
|
||||
entry_point: "entry_point",
|
||||
2: "stmt",
|
||||
stmt: "stmt",
|
||||
3: "require",
|
||||
require: "require",
|
||||
4: "dynamic",
|
||||
dynamic: "dynamic",
|
||||
5: "require_resolve",
|
||||
require_resolve: "require_resolve",
|
||||
6: "at",
|
||||
at: "at",
|
||||
7: "url",
|
||||
url: "url",
|
||||
8: "internal",
|
||||
internal: "internal",
|
||||
};
|
||||
export enum TransformResponseStatus {
|
||||
success = 1,
|
||||
fail = 2,
|
||||
}
|
||||
export const TransformResponseStatusKeys = {
|
||||
1: "success",
|
||||
success: "success",
|
||||
2: "fail",
|
||||
fail: "fail",
|
||||
};
|
||||
export enum MessageLevel {
|
||||
err = 1,
|
||||
warn = 2,
|
||||
note = 3,
|
||||
info = 4,
|
||||
debug = 5,
|
||||
}
|
||||
export const MessageLevelKeys = {
|
||||
1: "err",
|
||||
err: "err",
|
||||
2: "warn",
|
||||
warn: "warn",
|
||||
3: "note",
|
||||
note: "note",
|
||||
4: "info",
|
||||
info: "info",
|
||||
5: "debug",
|
||||
debug: "debug",
|
||||
};
|
||||
export enum Reloader {
|
||||
disable = 1,
|
||||
live = 2,
|
||||
fast_refresh = 3,
|
||||
}
|
||||
export const ReloaderKeys = {
|
||||
1: "disable",
|
||||
disable: "disable",
|
||||
2: "live",
|
||||
live: "live",
|
||||
3: "fast_refresh",
|
||||
fast_refresh: "fast_refresh",
|
||||
};
|
||||
export enum WebsocketMessageKind {
|
||||
welcome = 1,
|
||||
file_change_notification = 2,
|
||||
build_success = 3,
|
||||
build_fail = 4,
|
||||
manifest_success = 5,
|
||||
manifest_fail = 6,
|
||||
resolve_file = 7,
|
||||
file_change_notification_with_hint = 8,
|
||||
}
|
||||
export const WebsocketMessageKindKeys = {
|
||||
1: "welcome",
|
||||
welcome: "welcome",
|
||||
2: "file_change_notification",
|
||||
file_change_notification: "file_change_notification",
|
||||
3: "build_success",
|
||||
build_success: "build_success",
|
||||
4: "build_fail",
|
||||
build_fail: "build_fail",
|
||||
5: "manifest_success",
|
||||
manifest_success: "manifest_success",
|
||||
6: "manifest_fail",
|
||||
manifest_fail: "manifest_fail",
|
||||
7: "resolve_file",
|
||||
resolve_file: "resolve_file",
|
||||
8: "file_change_notification_with_hint",
|
||||
file_change_notification_with_hint: "file_change_notification_with_hint",
|
||||
};
|
||||
export enum WebsocketCommandKind {
|
||||
build = 1,
|
||||
manifest = 2,
|
||||
build_with_file_path = 3,
|
||||
}
|
||||
export const WebsocketCommandKindKeys = {
|
||||
1: "build",
|
||||
build: "build",
|
||||
2: "manifest",
|
||||
manifest: "manifest",
|
||||
3: "build_with_file_path",
|
||||
build_with_file_path: "build_with_file_path",
|
||||
};
|
||||
export interface StackFrame {
|
||||
function_name: string;
|
||||
file: string;
|
||||
position: StackFramePosition;
|
||||
scope: StackFrameScope;
|
||||
}
|
||||
|
||||
export interface StackFramePosition {
|
||||
source_offset: int32;
|
||||
line: int32;
|
||||
line_start: int32;
|
||||
line_stop: int32;
|
||||
column_start: int32;
|
||||
column_stop: int32;
|
||||
expression_start: int32;
|
||||
expression_stop: int32;
|
||||
}
|
||||
|
||||
export interface SourceLine {
|
||||
line: int32;
|
||||
text: string;
|
||||
}
|
||||
|
||||
export interface StackTrace {
|
||||
source_lines: SourceLine[];
|
||||
frames: StackFrame[];
|
||||
}
|
||||
|
||||
export interface JSException {
|
||||
name?: string;
|
||||
message?: string;
|
||||
runtime_type?: uint16;
|
||||
code?: uint8;
|
||||
stack?: StackTrace;
|
||||
}
|
||||
|
||||
export interface Problems {
|
||||
code: uint16;
|
||||
name: string;
|
||||
exceptions: JSException[];
|
||||
build: Log;
|
||||
}
|
||||
|
||||
export interface Router {
|
||||
routes: StringMap;
|
||||
route: int32;
|
||||
params: StringMap;
|
||||
}
|
||||
|
||||
export interface FallbackMessageContainer {
|
||||
message?: string;
|
||||
router?: Router;
|
||||
reason?: FallbackStep;
|
||||
problems?: Problems;
|
||||
cwd?: string;
|
||||
}
|
||||
|
||||
export interface JSX {
|
||||
factory: string;
|
||||
runtime: JSXRuntime;
|
||||
fragment: string;
|
||||
development: boolean;
|
||||
import_source: string;
|
||||
react_fast_refresh: boolean;
|
||||
}
|
||||
|
||||
export interface StringPointer {
|
||||
offset: uint32;
|
||||
length: uint32;
|
||||
}
|
||||
|
||||
export interface JavascriptBundledModule {
|
||||
path: StringPointer;
|
||||
code: StringPointer;
|
||||
package_id: uint32;
|
||||
id: uint32;
|
||||
path_extname_length: byte;
|
||||
}
|
||||
|
||||
export interface JavascriptBundledPackage {
|
||||
name: StringPointer;
|
||||
version: StringPointer;
|
||||
hash: uint32;
|
||||
modules_offset: uint32;
|
||||
modules_length: uint32;
|
||||
}
|
||||
|
||||
export interface JavascriptBundle {
|
||||
modules: JavascriptBundledModule[];
|
||||
packages: JavascriptBundledPackage[];
|
||||
etag: Uint8Array;
|
||||
generated_at: uint32;
|
||||
app_package_json_dependencies_hash: Uint8Array;
|
||||
import_from_name: Uint8Array;
|
||||
manifest_string: Uint8Array;
|
||||
}
|
||||
|
||||
export interface JavascriptBundleContainer {
|
||||
bundle_format_version?: uint32;
|
||||
routes?: LoadedRouteConfig;
|
||||
framework?: LoadedFramework;
|
||||
bundle?: JavascriptBundle;
|
||||
code_length?: uint32;
|
||||
}
|
||||
|
||||
export interface ModuleImportRecord {
|
||||
kind: ModuleImportType;
|
||||
path: string;
|
||||
dynamic: boolean;
|
||||
}
|
||||
|
||||
export interface Module {
|
||||
path: string;
|
||||
imports: ModuleImportRecord[];
|
||||
}
|
||||
|
||||
export interface StringMap {
|
||||
keys: string[];
|
||||
values: string[];
|
||||
}
|
||||
|
||||
export interface LoaderMap {
|
||||
extensions: string[];
|
||||
loaders: Loader[];
|
||||
}
|
||||
|
||||
export interface EnvConfig {
|
||||
prefix?: string;
|
||||
defaults?: StringMap;
|
||||
}
|
||||
|
||||
export interface LoadedEnvConfig {
|
||||
dotenv: DotEnvBehavior;
|
||||
defaults: StringMap;
|
||||
prefix: string;
|
||||
}
|
||||
|
||||
export interface FrameworkConfig {
|
||||
package?: string;
|
||||
client?: FrameworkEntryPointMessage;
|
||||
server?: FrameworkEntryPointMessage;
|
||||
fallback?: FrameworkEntryPointMessage;
|
||||
development?: boolean;
|
||||
client_css_in_js?: CSSInJSBehavior;
|
||||
display_name?: string;
|
||||
overrideModules?: StringMap;
|
||||
}
|
||||
|
||||
export interface FrameworkEntryPoint {
|
||||
kind: FrameworkEntryPointType;
|
||||
path: string;
|
||||
env: LoadedEnvConfig;
|
||||
}
|
||||
|
||||
export interface FrameworkEntryPointMap {
|
||||
client?: FrameworkEntryPoint;
|
||||
server?: FrameworkEntryPoint;
|
||||
fallback?: FrameworkEntryPoint;
|
||||
}
|
||||
|
||||
export interface FrameworkEntryPointMessage {
|
||||
path?: string;
|
||||
env?: EnvConfig;
|
||||
}
|
||||
|
||||
export interface LoadedFramework {
|
||||
package: string;
|
||||
display_name: string;
|
||||
development: boolean;
|
||||
entry_points: FrameworkEntryPointMap;
|
||||
client_css_in_js: CSSInJSBehavior;
|
||||
overrideModules: StringMap;
|
||||
}
|
||||
|
||||
export interface LoadedRouteConfig {
|
||||
dir: string;
|
||||
extensions: string[];
|
||||
static_dir: string;
|
||||
asset_prefix: string;
|
||||
}
|
||||
|
||||
export interface RouteConfig {
|
||||
dir?: string[];
|
||||
extensions?: string[];
|
||||
static_dir?: string;
|
||||
asset_prefix?: string;
|
||||
}
|
||||
|
||||
export interface TransformOptions {
|
||||
jsx?: JSX;
|
||||
tsconfig_override?: string;
|
||||
resolve?: ResolveMode;
|
||||
origin?: string;
|
||||
absolute_working_dir?: string;
|
||||
define?: StringMap;
|
||||
preserve_symlinks?: boolean;
|
||||
entry_points?: string[];
|
||||
write?: boolean;
|
||||
inject?: string[];
|
||||
output_dir?: string;
|
||||
external?: string[];
|
||||
loaders?: LoaderMap;
|
||||
main_fields?: string[];
|
||||
platform?: Platform;
|
||||
serve?: boolean;
|
||||
extension_order?: string[];
|
||||
generate_node_module_bundle?: boolean;
|
||||
node_modules_bundle_path?: string;
|
||||
node_modules_bundle_path_server?: string;
|
||||
framework?: FrameworkConfig;
|
||||
router?: RouteConfig;
|
||||
no_summary?: boolean;
|
||||
disable_hmr?: boolean;
|
||||
port?: uint16;
|
||||
logLevel?: MessageLevel;
|
||||
}
|
||||
|
||||
export interface FileHandle {
|
||||
path: string;
|
||||
size: uint;
|
||||
fd: uint;
|
||||
}
|
||||
|
||||
export interface Transform {
|
||||
handle?: FileHandle;
|
||||
path?: string;
|
||||
contents?: Uint8Array;
|
||||
loader?: Loader;
|
||||
options?: TransformOptions;
|
||||
}
|
||||
|
||||
export interface Scan {
|
||||
path?: string;
|
||||
contents?: Uint8Array;
|
||||
loader?: Loader;
|
||||
}
|
||||
|
||||
export interface ScanResult {
|
||||
exports: string[];
|
||||
imports: ScannedImport[];
|
||||
}
|
||||
|
||||
export interface ScannedImport {
|
||||
path: string;
|
||||
kind: ImportKind;
|
||||
}
|
||||
|
||||
export interface OutputFile {
|
||||
data: Uint8Array;
|
||||
path: string;
|
||||
}
|
||||
|
||||
export interface TransformResponse {
|
||||
status: TransformResponseStatus;
|
||||
files: OutputFile[];
|
||||
errors: Message[];
|
||||
}
|
||||
|
||||
export interface Location {
|
||||
file: string;
|
||||
namespace: string;
|
||||
line: int32;
|
||||
column: int32;
|
||||
line_text: string;
|
||||
suggestion: string;
|
||||
offset: uint;
|
||||
}
|
||||
|
||||
export interface MessageData {
|
||||
text?: string;
|
||||
location?: Location;
|
||||
}
|
||||
|
||||
export interface MessageMeta {
|
||||
resolve?: string;
|
||||
build?: boolean;
|
||||
}
|
||||
|
||||
export interface Message {
|
||||
level: MessageLevel;
|
||||
data: MessageData;
|
||||
notes: MessageData[];
|
||||
on: MessageMeta;
|
||||
}
|
||||
|
||||
export interface Log {
|
||||
warnings: uint32;
|
||||
errors: uint32;
|
||||
msgs: Message[];
|
||||
}
|
||||
|
||||
export interface WebsocketMessage {
|
||||
timestamp: uint32;
|
||||
kind: WebsocketMessageKind;
|
||||
}
|
||||
|
||||
export interface WebsocketMessageWelcome {
|
||||
epoch: uint32;
|
||||
javascriptReloader: Reloader;
|
||||
cwd: string;
|
||||
}
|
||||
|
||||
export interface WebsocketMessageFileChangeNotification {
|
||||
id: uint32;
|
||||
loader: Loader;
|
||||
}
|
||||
|
||||
export interface WebsocketCommand {
|
||||
kind: WebsocketCommandKind;
|
||||
timestamp: uint32;
|
||||
}
|
||||
|
||||
export interface WebsocketCommandBuild {
|
||||
id: uint32;
|
||||
}
|
||||
|
||||
export interface WebsocketCommandManifest {
|
||||
id: uint32;
|
||||
}
|
||||
|
||||
export interface WebsocketMessageBuildSuccess {
|
||||
id: uint32;
|
||||
from_timestamp: uint32;
|
||||
loader: Loader;
|
||||
module_path: string;
|
||||
blob_length: uint32;
|
||||
}
|
||||
|
||||
export interface WebsocketMessageBuildFailure {
|
||||
id: uint32;
|
||||
from_timestamp: uint32;
|
||||
loader: Loader;
|
||||
module_path: string;
|
||||
log: Log;
|
||||
}
|
||||
|
||||
export interface WebsocketCommandBuildWithFilePath {
|
||||
id: uint32;
|
||||
file_path: string;
|
||||
}
|
||||
|
||||
export interface WebsocketMessageResolveID {
|
||||
id: uint32;
|
||||
}
|
||||
|
||||
export interface NPMRegistry {
|
||||
url: string;
|
||||
username: string;
|
||||
password: string;
|
||||
token: string;
|
||||
}
|
||||
|
||||
export interface NPMRegistryMap {
|
||||
scopes: string[];
|
||||
registries: NPMRegistry[];
|
||||
}
|
||||
|
||||
export interface BunInstall {
|
||||
default_registry?: NPMRegistry;
|
||||
scoped?: NPMRegistryMap;
|
||||
lockfile_path?: string;
|
||||
save_lockfile_path?: string;
|
||||
cache_directory?: string;
|
||||
dry_run?: boolean;
|
||||
force?: boolean;
|
||||
save_dev?: boolean;
|
||||
save_optional?: boolean;
|
||||
save_peer?: boolean;
|
||||
save_lockfile?: boolean;
|
||||
production?: boolean;
|
||||
save_yarn_lockfile?: boolean;
|
||||
native_bin_links?: string[];
|
||||
disable_cache?: boolean;
|
||||
disable_manifest_cache?: boolean;
|
||||
global_dir?: string;
|
||||
global_bin_dir?: string;
|
||||
}
|
||||
|
||||
export declare function encodeStackFrame(message: StackFrame, bb: ByteBuffer): void;
|
||||
export declare function decodeStackFrame(buffer: ByteBuffer): StackFrame;
|
||||
export declare function encodeStackFramePosition(message: StackFramePosition, bb: ByteBuffer): void;
|
||||
export declare function decodeStackFramePosition(buffer: ByteBuffer): StackFramePosition;
|
||||
export declare function encodeSourceLine(message: SourceLine, bb: ByteBuffer): void;
|
||||
export declare function decodeSourceLine(buffer: ByteBuffer): SourceLine;
|
||||
export declare function encodeStackTrace(message: StackTrace, bb: ByteBuffer): void;
|
||||
export declare function decodeStackTrace(buffer: ByteBuffer): StackTrace;
|
||||
export declare function encodeJSException(message: JSException, bb: ByteBuffer): void;
|
||||
export declare function decodeJSException(buffer: ByteBuffer): JSException;
|
||||
export declare function encodeProblems(message: Problems, bb: ByteBuffer): void;
|
||||
export declare function decodeProblems(buffer: ByteBuffer): Problems;
|
||||
export declare function encodeRouter(message: Router, bb: ByteBuffer): void;
|
||||
export declare function decodeRouter(buffer: ByteBuffer): Router;
|
||||
export declare function encodeFallbackMessageContainer(message: FallbackMessageContainer, bb: ByteBuffer): void;
|
||||
export declare function decodeFallbackMessageContainer(buffer: ByteBuffer): FallbackMessageContainer;
|
||||
export declare function encodeJSX(message: JSX, bb: ByteBuffer): void;
|
||||
export declare function decodeJSX(buffer: ByteBuffer): JSX;
|
||||
export declare function encodeStringPointer(message: StringPointer, bb: ByteBuffer): void;
|
||||
export declare function decodeStringPointer(buffer: ByteBuffer): StringPointer;
|
||||
export declare function encodeJavascriptBundledModule(message: JavascriptBundledModule, bb: ByteBuffer): void;
|
||||
export declare function decodeJavascriptBundledModule(buffer: ByteBuffer): JavascriptBundledModule;
|
||||
export declare function encodeJavascriptBundledPackage(message: JavascriptBundledPackage, bb: ByteBuffer): void;
|
||||
export declare function decodeJavascriptBundledPackage(buffer: ByteBuffer): JavascriptBundledPackage;
|
||||
export declare function encodeJavascriptBundle(message: JavascriptBundle, bb: ByteBuffer): void;
|
||||
export declare function decodeJavascriptBundle(buffer: ByteBuffer): JavascriptBundle;
|
||||
export declare function encodeJavascriptBundleContainer(message: JavascriptBundleContainer, bb: ByteBuffer): void;
|
||||
export declare function decodeJavascriptBundleContainer(buffer: ByteBuffer): JavascriptBundleContainer;
|
||||
export declare function encodeModuleImportRecord(message: ModuleImportRecord, bb: ByteBuffer): void;
|
||||
export declare function decodeModuleImportRecord(buffer: ByteBuffer): ModuleImportRecord;
|
||||
export declare function encodeModule(message: Module, bb: ByteBuffer): void;
|
||||
export declare function decodeModule(buffer: ByteBuffer): Module;
|
||||
export declare function encodeStringMap(message: StringMap, bb: ByteBuffer): void;
|
||||
export declare function decodeStringMap(buffer: ByteBuffer): StringMap;
|
||||
export declare function encodeLoaderMap(message: LoaderMap, bb: ByteBuffer): void;
|
||||
export declare function decodeLoaderMap(buffer: ByteBuffer): LoaderMap;
|
||||
export declare function encodeEnvConfig(message: EnvConfig, bb: ByteBuffer): void;
|
||||
export declare function decodeEnvConfig(buffer: ByteBuffer): EnvConfig;
|
||||
export declare function encodeLoadedEnvConfig(message: LoadedEnvConfig, bb: ByteBuffer): void;
|
||||
export declare function decodeLoadedEnvConfig(buffer: ByteBuffer): LoadedEnvConfig;
|
||||
export declare function encodeFrameworkConfig(message: FrameworkConfig, bb: ByteBuffer): void;
|
||||
export declare function decodeFrameworkConfig(buffer: ByteBuffer): FrameworkConfig;
|
||||
export declare function encodeFrameworkEntryPoint(message: FrameworkEntryPoint, bb: ByteBuffer): void;
|
||||
export declare function decodeFrameworkEntryPoint(buffer: ByteBuffer): FrameworkEntryPoint;
|
||||
export declare function encodeFrameworkEntryPointMap(message: FrameworkEntryPointMap, bb: ByteBuffer): void;
|
||||
export declare function decodeFrameworkEntryPointMap(buffer: ByteBuffer): FrameworkEntryPointMap;
|
||||
export declare function encodeFrameworkEntryPointMessage(message: FrameworkEntryPointMessage, bb: ByteBuffer): void;
|
||||
export declare function decodeFrameworkEntryPointMessage(buffer: ByteBuffer): FrameworkEntryPointMessage;
|
||||
export declare function encodeLoadedFramework(message: LoadedFramework, bb: ByteBuffer): void;
|
||||
export declare function decodeLoadedFramework(buffer: ByteBuffer): LoadedFramework;
|
||||
export declare function encodeLoadedRouteConfig(message: LoadedRouteConfig, bb: ByteBuffer): void;
|
||||
export declare function decodeLoadedRouteConfig(buffer: ByteBuffer): LoadedRouteConfig;
|
||||
export declare function encodeRouteConfig(message: RouteConfig, bb: ByteBuffer): void;
|
||||
export declare function decodeRouteConfig(buffer: ByteBuffer): RouteConfig;
|
||||
export declare function encodeTransformOptions(message: TransformOptions, bb: ByteBuffer): void;
|
||||
export declare function decodeTransformOptions(buffer: ByteBuffer): TransformOptions;
|
||||
export declare function encodeFileHandle(message: FileHandle, bb: ByteBuffer): void;
|
||||
export declare function decodeFileHandle(buffer: ByteBuffer): FileHandle;
|
||||
export declare function encodeTransform(message: Transform, bb: ByteBuffer): void;
|
||||
export declare function decodeTransform(buffer: ByteBuffer): Transform;
|
||||
export declare function encodeScan(message: Scan, bb: ByteBuffer): void;
|
||||
export declare function decodeScan(buffer: ByteBuffer): Scan;
|
||||
export declare function encodeScanResult(message: ScanResult, bb: ByteBuffer): void;
|
||||
export declare function decodeScanResult(buffer: ByteBuffer): ScanResult;
|
||||
export declare function encodeScannedImport(message: ScannedImport, bb: ByteBuffer): void;
|
||||
export declare function decodeScannedImport(buffer: ByteBuffer): ScannedImport;
|
||||
export declare function encodeOutputFile(message: OutputFile, bb: ByteBuffer): void;
|
||||
export declare function decodeOutputFile(buffer: ByteBuffer): OutputFile;
|
||||
export declare function encodeTransformResponse(message: TransformResponse, bb: ByteBuffer): void;
|
||||
export declare function decodeTransformResponse(buffer: ByteBuffer): TransformResponse;
|
||||
export declare function encodeLocation(message: Location, bb: ByteBuffer): void;
|
||||
export declare function decodeLocation(buffer: ByteBuffer): Location;
|
||||
export declare function encodeMessageData(message: MessageData, bb: ByteBuffer): void;
|
||||
export declare function decodeMessageData(buffer: ByteBuffer): MessageData;
|
||||
export declare function encodeMessageMeta(message: MessageMeta, bb: ByteBuffer): void;
|
||||
export declare function decodeMessageMeta(buffer: ByteBuffer): MessageMeta;
|
||||
export declare function encodeMessage(message: Message, bb: ByteBuffer): void;
|
||||
export declare function decodeMessage(buffer: ByteBuffer): Message;
|
||||
export declare function encodeLog(message: Log, bb: ByteBuffer): void;
|
||||
export declare function decodeLog(buffer: ByteBuffer): Log;
|
||||
export declare function encodeWebsocketMessage(message: WebsocketMessage, bb: ByteBuffer): void;
|
||||
export declare function decodeWebsocketMessage(buffer: ByteBuffer): WebsocketMessage;
|
||||
export declare function encodeWebsocketMessageWelcome(message: WebsocketMessageWelcome, bb: ByteBuffer): void;
|
||||
export declare function decodeWebsocketMessageWelcome(buffer: ByteBuffer): WebsocketMessageWelcome;
|
||||
export declare function encodeWebsocketMessageFileChangeNotification(
|
||||
message: WebsocketMessageFileChangeNotification,
|
||||
bb: ByteBuffer,
|
||||
): void;
|
||||
export declare function decodeWebsocketMessageFileChangeNotification(
|
||||
buffer: ByteBuffer,
|
||||
): WebsocketMessageFileChangeNotification;
|
||||
export declare function encodeWebsocketCommand(message: WebsocketCommand, bb: ByteBuffer): void;
|
||||
export declare function decodeWebsocketCommand(buffer: ByteBuffer): WebsocketCommand;
|
||||
export declare function encodeWebsocketCommandBuild(message: WebsocketCommandBuild, bb: ByteBuffer): void;
|
||||
export declare function decodeWebsocketCommandBuild(buffer: ByteBuffer): WebsocketCommandBuild;
|
||||
export declare function encodeWebsocketCommandManifest(message: WebsocketCommandManifest, bb: ByteBuffer): void;
|
||||
export declare function decodeWebsocketCommandManifest(buffer: ByteBuffer): WebsocketCommandManifest;
|
||||
export declare function encodeWebsocketMessageBuildSuccess(message: WebsocketMessageBuildSuccess, bb: ByteBuffer): void;
|
||||
export declare function decodeWebsocketMessageBuildSuccess(buffer: ByteBuffer): WebsocketMessageBuildSuccess;
|
||||
export declare function encodeWebsocketMessageBuildFailure(message: WebsocketMessageBuildFailure, bb: ByteBuffer): void;
|
||||
export declare function decodeWebsocketMessageBuildFailure(buffer: ByteBuffer): WebsocketMessageBuildFailure;
|
||||
export declare function encodeWebsocketCommandBuildWithFilePath(
|
||||
message: WebsocketCommandBuildWithFilePath,
|
||||
bb: ByteBuffer,
|
||||
): void;
|
||||
export declare function decodeWebsocketCommandBuildWithFilePath(buffer: ByteBuffer): WebsocketCommandBuildWithFilePath;
|
||||
export declare function encodeWebsocketMessageResolveID(message: WebsocketMessageResolveID, bb: ByteBuffer): void;
|
||||
export declare function decodeWebsocketMessageResolveID(buffer: ByteBuffer): WebsocketMessageResolveID;
|
||||
export declare function encodeNPMRegistry(message: NPMRegistry, bb: ByteBuffer): void;
|
||||
export declare function decodeNPMRegistry(buffer: ByteBuffer): NPMRegistry;
|
||||
export declare function encodeNPMRegistryMap(message: NPMRegistryMap, bb: ByteBuffer): void;
|
||||
export declare function decodeNPMRegistryMap(buffer: ByteBuffer): NPMRegistryMap;
|
||||
export declare function encodeBunInstall(message: BunInstall, bb: ByteBuffer): void;
|
||||
export declare function decodeBunInstall(buffer: ByteBuffer): BunInstall;
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,553 +0,0 @@
|
||||
package Api;
|
||||
|
||||
smol Loader {
|
||||
jsx = 1;
|
||||
js = 2;
|
||||
ts = 3;
|
||||
tsx = 4;
|
||||
css = 5;
|
||||
file = 6;
|
||||
json = 7;
|
||||
toml = 8;
|
||||
wasm = 9;
|
||||
}
|
||||
|
||||
smol FrameworkEntryPointType {
|
||||
client = 1;
|
||||
server = 2;
|
||||
fallback = 3;
|
||||
}
|
||||
|
||||
smol StackFrameScope {
|
||||
Eval = 1;
|
||||
Module = 2;
|
||||
Function = 3;
|
||||
Global = 4;
|
||||
Wasm = 5;
|
||||
Constructor = 6;
|
||||
}
|
||||
|
||||
struct StackFrame {
|
||||
string function_name;
|
||||
string file;
|
||||
StackFramePosition position;
|
||||
StackFrameScope scope;
|
||||
}
|
||||
|
||||
struct StackFramePosition {
|
||||
int32 source_offset;
|
||||
int32 line;
|
||||
int32 line_start;
|
||||
int32 line_stop;
|
||||
int32 column_start;
|
||||
int32 column_stop;
|
||||
int32 expression_start;
|
||||
int32 expression_stop;
|
||||
}
|
||||
|
||||
struct SourceLine {
|
||||
int32 line;
|
||||
string text;
|
||||
}
|
||||
|
||||
struct StackTrace {
|
||||
SourceLine[] source_lines;
|
||||
StackFrame[] frames;
|
||||
}
|
||||
|
||||
|
||||
message JSException {
|
||||
string name = 1;
|
||||
string message = 2;
|
||||
|
||||
uint16 runtime_type = 3;
|
||||
uint8 code = 4;
|
||||
|
||||
StackTrace stack = 5;
|
||||
}
|
||||
|
||||
smol FallbackStep {
|
||||
ssr_disabled = 1;
|
||||
create_vm = 2;
|
||||
configure_router = 3;
|
||||
configure_defines = 4;
|
||||
resolve_entry_point = 5;
|
||||
load_entry_point = 6;
|
||||
eval_entry_point = 7;
|
||||
fetch_event_handler = 8;
|
||||
}
|
||||
|
||||
struct Problems {
|
||||
uint16 code;
|
||||
string name;
|
||||
|
||||
JSException[] exceptions;
|
||||
Log build;
|
||||
}
|
||||
|
||||
struct Router {
|
||||
StringMap routes;
|
||||
int32 route;
|
||||
StringMap params;
|
||||
}
|
||||
|
||||
message FallbackMessageContainer {
|
||||
string message = 1;
|
||||
Router router = 2;
|
||||
FallbackStep reason = 3;
|
||||
Problems problems = 4;
|
||||
string cwd = 5;
|
||||
}
|
||||
|
||||
|
||||
smol ResolveMode {
|
||||
disable = 1;
|
||||
lazy = 2;
|
||||
dev = 3;
|
||||
bundle = 4;
|
||||
}
|
||||
|
||||
smol Target {
|
||||
browser = 1;
|
||||
node = 2;
|
||||
bun = 3;
|
||||
bun_macro = 4;
|
||||
}
|
||||
|
||||
smol CSSInJSBehavior {
|
||||
facade = 1;
|
||||
facade_onimportcss = 2;
|
||||
auto_onimportcss = 3;
|
||||
}
|
||||
|
||||
smol JSXRuntime {
|
||||
automatic = 1;
|
||||
classic = 2;
|
||||
}
|
||||
|
||||
struct JSX {
|
||||
string factory;
|
||||
JSXRuntime runtime;
|
||||
string fragment;
|
||||
bool development;
|
||||
|
||||
// Probably react
|
||||
string import_source;
|
||||
|
||||
bool react_fast_refresh;
|
||||
}
|
||||
|
||||
struct StringPointer {
|
||||
uint32 offset;
|
||||
uint32 length;
|
||||
}
|
||||
|
||||
struct JavascriptBundledModule {
|
||||
// package-relative path including file extension
|
||||
StringPointer path;
|
||||
|
||||
// Source code
|
||||
StringPointer code;
|
||||
|
||||
// index into JavascriptBundle.packages
|
||||
uint32 package_id;
|
||||
|
||||
// The ESM export is this id ("$" + number.toString(16))
|
||||
uint32 id;
|
||||
|
||||
// This lets us efficiently compare strings ignoring the extension
|
||||
byte path_extname_length;
|
||||
}
|
||||
|
||||
struct JavascriptBundledPackage {
|
||||
StringPointer name;
|
||||
StringPointer version;
|
||||
uint32 hash;
|
||||
|
||||
uint32 modules_offset;
|
||||
uint32 modules_length;
|
||||
}
|
||||
|
||||
struct JavascriptBundle {
|
||||
// These are sorted alphabetically so you can do binary search
|
||||
JavascriptBundledModule[] modules;
|
||||
JavascriptBundledPackage[] packages;
|
||||
|
||||
// This is ASCII-encoded so you can send it directly over HTTP
|
||||
byte[] etag;
|
||||
|
||||
uint32 generated_at;
|
||||
|
||||
// generated by hashing all ${name}@${version} in sorted order
|
||||
byte[] app_package_json_dependencies_hash;
|
||||
|
||||
byte[] import_from_name;
|
||||
|
||||
// This is what StringPointer refers to
|
||||
byte[] manifest_string;
|
||||
}
|
||||
|
||||
message JavascriptBundleContainer {
|
||||
uint32 bundle_format_version = 1;
|
||||
|
||||
// These go first so if we change JavaScriptBundle we can still read these
|
||||
LoadedRouteConfig routes = 3;
|
||||
LoadedFramework framework = 2;
|
||||
|
||||
JavascriptBundle bundle = 4;
|
||||
|
||||
// Don't technically need to store this, but it may be helpful as a sanity check
|
||||
uint32 code_length = 5;
|
||||
}
|
||||
|
||||
smol ScanDependencyMode {
|
||||
app = 1;
|
||||
all = 2;
|
||||
}
|
||||
|
||||
smol ModuleImportType {
|
||||
import = 1;
|
||||
require = 2;
|
||||
}
|
||||
|
||||
struct ModuleImportRecord {
|
||||
ModuleImportType kind;
|
||||
string path;
|
||||
|
||||
bool dynamic;
|
||||
}
|
||||
|
||||
struct Module {
|
||||
string path;
|
||||
ModuleImportRecord[] imports;
|
||||
}
|
||||
|
||||
struct StringMap {
|
||||
string[] keys;
|
||||
string[] values;
|
||||
}
|
||||
|
||||
struct LoaderMap {
|
||||
string[] extensions;
|
||||
Loader[] loaders;
|
||||
}
|
||||
|
||||
enum DotEnvBehavior {
|
||||
disable = 1;
|
||||
prefix = 2;
|
||||
load_all = 3;
|
||||
}
|
||||
|
||||
message EnvConfig {
|
||||
string prefix = 1;
|
||||
StringMap defaults = 2;
|
||||
}
|
||||
|
||||
struct LoadedEnvConfig {
|
||||
DotEnvBehavior dotenv;
|
||||
|
||||
StringMap defaults;
|
||||
string prefix;
|
||||
}
|
||||
|
||||
message FrameworkConfig {
|
||||
string package = 1;
|
||||
FrameworkEntryPointMessage client = 2;
|
||||
FrameworkEntryPointMessage server = 3;
|
||||
FrameworkEntryPointMessage fallback = 4;
|
||||
bool development = 5;
|
||||
|
||||
CSSInJSBehavior client_css_in_js = 6;
|
||||
string display_name = 7;
|
||||
|
||||
StringMap overrideModules = 8;
|
||||
}
|
||||
|
||||
struct FrameworkEntryPoint {
|
||||
FrameworkEntryPointType kind;
|
||||
string path;
|
||||
LoadedEnvConfig env;
|
||||
}
|
||||
|
||||
message FrameworkEntryPointMap {
|
||||
FrameworkEntryPoint client = 1;
|
||||
FrameworkEntryPoint server = 2;
|
||||
FrameworkEntryPoint fallback = 3;
|
||||
}
|
||||
|
||||
message FrameworkEntryPointMessage {
|
||||
string path = 1;
|
||||
EnvConfig env = 2;
|
||||
}
|
||||
|
||||
struct LoadedFramework {
|
||||
string package;
|
||||
string display_name;
|
||||
bool development;
|
||||
FrameworkEntryPointMap entry_points;
|
||||
CSSInJSBehavior client_css_in_js;
|
||||
StringMap overrideModules;
|
||||
}
|
||||
|
||||
struct LoadedRouteConfig {
|
||||
string dir;
|
||||
string[] extensions;
|
||||
string static_dir;
|
||||
string asset_prefix;
|
||||
}
|
||||
|
||||
message RouteConfig {
|
||||
string[] dir = 1;
|
||||
string[] extensions = 2;
|
||||
string static_dir = 3;
|
||||
string asset_prefix = 4;
|
||||
}
|
||||
|
||||
message TransformOptions {
|
||||
JSX jsx = 1;
|
||||
string tsconfig_override = 2;
|
||||
ResolveMode resolve = 3;
|
||||
|
||||
string origin = 4;
|
||||
string absolute_working_dir = 5;
|
||||
|
||||
StringMap define = 6;
|
||||
|
||||
bool preserve_symlinks = 7;
|
||||
|
||||
string[] entry_points = 8;
|
||||
bool write = 9;
|
||||
|
||||
string[] inject = 10;
|
||||
string output_dir = 11;
|
||||
|
||||
string[] external = 12;
|
||||
|
||||
LoaderMap loaders = 13;
|
||||
|
||||
string[] main_fields = 14;
|
||||
Target target = 15;
|
||||
|
||||
bool serve = 16;
|
||||
|
||||
string[] extension_order = 17;
|
||||
|
||||
bool generate_node_module_bundle = 18;
|
||||
|
||||
string node_modules_bundle_path = 19;
|
||||
string node_modules_bundle_path_server = 20;
|
||||
|
||||
FrameworkConfig framework = 21;
|
||||
RouteConfig router = 22;
|
||||
bool no_summary = 23;
|
||||
|
||||
bool disable_hmr = 24;
|
||||
|
||||
uint16 port = 25;
|
||||
MessageLevel logLevel = 26;
|
||||
}
|
||||
|
||||
struct FileHandle {
|
||||
string path;
|
||||
uint size;
|
||||
uint fd;
|
||||
}
|
||||
|
||||
message Transform {
|
||||
FileHandle handle = 1;
|
||||
string path = 2;
|
||||
byte[] contents = 3;
|
||||
|
||||
Loader loader = 4;
|
||||
TransformOptions options = 5;
|
||||
}
|
||||
|
||||
enum TransformResponseStatus {
|
||||
success = 1;
|
||||
fail = 2;
|
||||
}
|
||||
|
||||
struct OutputFile {
|
||||
byte[] data;
|
||||
string path;
|
||||
}
|
||||
|
||||
struct TransformResponse {
|
||||
TransformResponseStatus status;
|
||||
OutputFile[] files;
|
||||
Message[] errors;
|
||||
}
|
||||
|
||||
enum MessageLevel {
|
||||
err = 1;
|
||||
warn =2;
|
||||
note = 3;
|
||||
info = 4;
|
||||
debug = 5;
|
||||
}
|
||||
|
||||
struct Location {
|
||||
string file;
|
||||
string namespace;
|
||||
int32 line;
|
||||
int32 column;
|
||||
string line_text;
|
||||
string suggestion;
|
||||
uint offset;
|
||||
}
|
||||
|
||||
message MessageData {
|
||||
string text = 1;
|
||||
Location location = 2;
|
||||
}
|
||||
|
||||
|
||||
|
||||
message MessageMeta {
|
||||
string resolve = 1;
|
||||
bool build = 2;
|
||||
}
|
||||
|
||||
struct Message {
|
||||
MessageLevel level;
|
||||
MessageData data;
|
||||
MessageData[] notes;
|
||||
MessageMeta on;
|
||||
}
|
||||
|
||||
struct Log {
|
||||
uint32 warnings;
|
||||
uint32 errors;
|
||||
Message[] msgs;
|
||||
}
|
||||
|
||||
|
||||
smol Reloader {
|
||||
disable = 1;
|
||||
// equivalent of CMD + R
|
||||
live = 2;
|
||||
// React Fast Refresh
|
||||
fast_refresh = 3;
|
||||
}
|
||||
|
||||
// The WebSocket protocol
|
||||
// Server: "hey, this file changed. Does anyone want it?"
|
||||
// Browser: *checks array* "uhh yeah, ok. rebuild that for me"
|
||||
// Server: "here u go"
|
||||
// This makes the client responsible for tracking which files it needs to listen for.
|
||||
// From a server perspective, this means the filesystem watching thread can send the same WebSocket message
|
||||
// to every client, which is good for performance. It means if you have 5 tabs open it won't really be different than one tab
|
||||
// The clients can just ignore files they don't care about
|
||||
smol WebsocketMessageKind {
|
||||
welcome = 1;
|
||||
file_change_notification = 2;
|
||||
build_success = 3;
|
||||
build_fail = 4;
|
||||
manifest_success = 5;
|
||||
manifest_fail = 6;
|
||||
resolve_file = 7;
|
||||
file_change_notification_with_hint = 8;
|
||||
}
|
||||
|
||||
smol WebsocketCommandKind {
|
||||
build = 1;
|
||||
manifest = 2;
|
||||
build_with_file_path = 3;
|
||||
}
|
||||
|
||||
// Each websocket message has two messages in it!
|
||||
// This is the first.
|
||||
struct WebsocketMessage {
|
||||
uint32 timestamp;
|
||||
WebsocketMessageKind kind;
|
||||
}
|
||||
|
||||
// This is the first.
|
||||
struct WebsocketMessageWelcome {
|
||||
uint32 epoch;
|
||||
Reloader javascriptReloader;
|
||||
string cwd;
|
||||
}
|
||||
|
||||
struct WebsocketMessageFileChangeNotification {
|
||||
uint32 id;
|
||||
Loader loader;
|
||||
}
|
||||
|
||||
struct WebsocketCommand {
|
||||
WebsocketCommandKind kind;
|
||||
uint32 timestamp;
|
||||
}
|
||||
|
||||
// The timestamp is used for client-side deduping
|
||||
struct WebsocketCommandBuild {
|
||||
uint32 id;
|
||||
}
|
||||
|
||||
struct WebsocketCommandManifest {
|
||||
uint32 id;
|
||||
}
|
||||
|
||||
// We copy the module_path here incase they don't already have it
|
||||
struct WebsocketMessageBuildSuccess {
|
||||
uint32 id;
|
||||
uint32 from_timestamp;
|
||||
|
||||
Loader loader;
|
||||
string module_path;
|
||||
|
||||
// This is the length of the blob that immediately follows this message.
|
||||
uint32 blob_length;
|
||||
}
|
||||
|
||||
struct WebsocketMessageBuildFailure {
|
||||
uint32 id;
|
||||
uint32 from_timestamp;
|
||||
Loader loader;
|
||||
|
||||
string module_path;
|
||||
Log log;
|
||||
}
|
||||
|
||||
struct WebsocketCommandBuildWithFilePath {
|
||||
uint32 id;
|
||||
string file_path;
|
||||
}
|
||||
|
||||
struct WebsocketMessageResolveID {
|
||||
uint32 id;
|
||||
}
|
||||
|
||||
struct NPMRegistry {
|
||||
string url;
|
||||
string username;
|
||||
string password;
|
||||
string token;
|
||||
}
|
||||
|
||||
struct NPMRegistryMap {
|
||||
string[] scopes;
|
||||
NPMRegistry[] registries;
|
||||
}
|
||||
|
||||
message BunInstall {
|
||||
NPMRegistry default_registry = 1;
|
||||
NPMRegistryMap scoped = 2;
|
||||
string lockfile_path = 3;
|
||||
string save_lockfile_path = 4;
|
||||
string cache_directory = 5;
|
||||
bool dry_run = 6;
|
||||
bool force = 7;
|
||||
bool save_dev = 8;
|
||||
bool save_optional = 9;
|
||||
bool save_peer = 10;
|
||||
bool save_lockfile = 11;
|
||||
bool production = 12;
|
||||
bool save_yarn_lockfile = 13;
|
||||
string[] native_bin_links = 14;
|
||||
|
||||
bool disable_cache = 15;
|
||||
bool disable_manifest_cache = 16;
|
||||
string global_dir = 17;
|
||||
string global_bin_dir = 18;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,122 +0,0 @@
|
||||
.container {
|
||||
min-height: 100vh;
|
||||
padding: 0 0.5rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 100vh;
|
||||
}
|
||||
|
||||
.main {
|
||||
padding: 5rem 0;
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.footer {
|
||||
width: 100%;
|
||||
height: 100px;
|
||||
border-top: 1px solid #eaeaea;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.footer a {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.title a {
|
||||
color: #0070f3;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.title a:hover,
|
||||
.title a:focus,
|
||||
.title a:active {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.title {
|
||||
margin: 0;
|
||||
line-height: 1.15;
|
||||
font-size: 4rem;
|
||||
}
|
||||
|
||||
.title,
|
||||
.description {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.description {
|
||||
line-height: 1.5;
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
.code {
|
||||
background: #fafafa;
|
||||
border-radius: 5px;
|
||||
padding: 0.75rem;
|
||||
font-size: 1.1rem;
|
||||
font-family: Menlo, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono,
|
||||
Bitstream Vera Sans Mono, Courier New, monospace;
|
||||
}
|
||||
|
||||
.grid {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-wrap: wrap;
|
||||
max-width: 800px;
|
||||
margin-top: 3rem;
|
||||
}
|
||||
|
||||
.card {
|
||||
margin: 1rem;
|
||||
padding: 1.5rem;
|
||||
text-align: left;
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
border: 1px solid #eaeaea;
|
||||
border-radius: 10px;
|
||||
transition: color 0.15s ease, border-color 0.15s ease;
|
||||
width: 45%;
|
||||
}
|
||||
|
||||
.card:hover,
|
||||
.card:focus,
|
||||
.card:active {
|
||||
color: #0070f3;
|
||||
border-color: #0070f3;
|
||||
}
|
||||
|
||||
.card h2 {
|
||||
margin: 0 0 1rem 0;
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
.card p {
|
||||
margin: 0;
|
||||
font-size: 1.25rem;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.logo {
|
||||
height: 1em;
|
||||
margin-left: 0.5rem;
|
||||
}
|
||||
|
||||
@media (max-width: 600px) {
|
||||
.grid {
|
||||
width: 100%;
|
||||
flex-direction: column;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
html,
|
||||
body {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen,
|
||||
Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
|
||||
}
|
||||
|
||||
a {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2020",
|
||||
"lib": [
|
||||
"dom",
|
||||
"dom.iterable",
|
||||
"esnext"
|
||||
],
|
||||
"allowJs": true,
|
||||
"skipLibCheck": true,
|
||||
"strict": true,
|
||||
"noImplicitAny": false,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"noEmit": true,
|
||||
"esModuleInterop": true,
|
||||
"module": "esnext",
|
||||
"moduleResolution": "node",
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"jsx": "preserve",
|
||||
"types": [
|
||||
"bun-types"
|
||||
],
|
||||
"incremental": true
|
||||
},
|
||||
"include": [
|
||||
"next-env.d.ts",
|
||||
"**/*.ts",
|
||||
"**/*.tsx"
|
||||
],
|
||||
"exclude": [
|
||||
"node_modules"
|
||||
]
|
||||
}
|
||||
2
src/api/schema.d.ts
generated
vendored
2
src/api/schema.d.ts
generated
vendored
@@ -709,6 +709,8 @@ export interface BunInstall {
|
||||
disable_manifest_cache?: boolean;
|
||||
global_dir?: string;
|
||||
global_bin_dir?: string;
|
||||
frozen_lockfile?: boolean;
|
||||
exact?: boolean;
|
||||
}
|
||||
|
||||
export interface ClientServerModule {
|
||||
|
||||
20
src/api/schema.js
generated
20
src/api/schema.js
generated
@@ -3044,6 +3044,14 @@ function decodeBunInstall(bb) {
|
||||
result["global_bin_dir"] = bb.readString();
|
||||
break;
|
||||
|
||||
case 19:
|
||||
result["frozen_lockfile"] = !!bb.readByte();
|
||||
break;
|
||||
|
||||
case 20:
|
||||
result["exact"] = !!bb.readByte();
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new Error("Attempted to parse invalid message");
|
||||
}
|
||||
@@ -3164,6 +3172,18 @@ function encodeBunInstall(message, bb) {
|
||||
bb.writeByte(18);
|
||||
bb.writeString(value);
|
||||
}
|
||||
|
||||
var value = message["frozen_lockfile"];
|
||||
if (value != null) {
|
||||
bb.writeByte(19);
|
||||
bb.writeByte(value);
|
||||
}
|
||||
|
||||
var value = message["exact"];
|
||||
if (value != null) {
|
||||
bb.writeByte(20);
|
||||
bb.writeByte(value);
|
||||
}
|
||||
bb.writeByte(0);
|
||||
}
|
||||
|
||||
|
||||
@@ -590,6 +590,8 @@ message BunInstall {
|
||||
bool disable_manifest_cache = 16;
|
||||
string global_dir = 17;
|
||||
string global_bin_dir = 18;
|
||||
bool frozen_lockfile = 19;
|
||||
bool exact = 20;
|
||||
}
|
||||
|
||||
struct ClientServerModule {
|
||||
|
||||
@@ -2901,6 +2901,12 @@ pub const Api = struct {
|
||||
/// global_bin_dir
|
||||
global_bin_dir: ?[]const u8 = null,
|
||||
|
||||
/// frozen_lockfile
|
||||
frozen_lockfile: ?bool = null,
|
||||
|
||||
/// exact
|
||||
exact: ?bool = null,
|
||||
|
||||
pub fn decode(reader: anytype) anyerror!BunInstall {
|
||||
var this = std.mem.zeroes(BunInstall);
|
||||
|
||||
@@ -2964,6 +2970,12 @@ pub const Api = struct {
|
||||
18 => {
|
||||
this.global_bin_dir = try reader.readValue([]const u8);
|
||||
},
|
||||
19 => {
|
||||
this.frozen_lockfile = try reader.readValue(bool);
|
||||
},
|
||||
20 => {
|
||||
this.exact = try reader.readValue(bool);
|
||||
},
|
||||
else => {
|
||||
return error.InvalidMessage;
|
||||
},
|
||||
@@ -3045,6 +3057,14 @@ pub const Api = struct {
|
||||
try writer.writeFieldID(18);
|
||||
try writer.writeValue(@TypeOf(global_bin_dir), global_bin_dir);
|
||||
}
|
||||
if (this.frozen_lockfile) |frozen_lockfile| {
|
||||
try writer.writeFieldID(19);
|
||||
try writer.writeInt(@as(u8, @intFromBool(frozen_lockfile)));
|
||||
}
|
||||
if (this.exact) |exact| {
|
||||
try writer.writeFieldID(20);
|
||||
try writer.writeInt(@as(u8, @intFromBool(exact)));
|
||||
}
|
||||
try writer.endMessage();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -5,6 +5,22 @@ pub const DecodeResult = struct {
|
||||
fail: bool = false,
|
||||
};
|
||||
|
||||
pub const LibBase64 = struct {
|
||||
pub const State = extern struct {
|
||||
eof: c_int,
|
||||
bytes: c_int,
|
||||
flags: c_int,
|
||||
carry: u8,
|
||||
};
|
||||
pub extern fn base64_encode(src: [*]const u8, srclen: usize, out: [*]u8, outlen: *usize, flags: c_int) void;
|
||||
pub extern fn base64_stream_encode_init(state: *State, flags: c_int) void;
|
||||
pub extern fn base64_stream_encode(state: *State, src: [*]const u8, srclen: usize, out: [*]u8, outlen: *usize) void;
|
||||
pub extern fn base64_stream_encode_final(state: *State, out: [*]u8, outlen: *usize) void;
|
||||
pub extern fn base64_decode(src: [*]const u8, srclen: usize, out: [*]u8, outlen: *usize, flags: c_int) c_int;
|
||||
pub extern fn base64_stream_decode_init(state: *State, flags: c_int) void;
|
||||
pub extern fn base64_stream_decode(state: *State, src: [*]const u8, srclen: usize, out: [*]u8, outlen: *usize) c_int;
|
||||
};
|
||||
|
||||
const mixed_decoder = brk: {
|
||||
var decoder = zig_base64.standard.decoderWithIgnore("\xff \t\r\n" ++ [_]u8{
|
||||
std.ascii.control_code.vt,
|
||||
@@ -30,7 +46,9 @@ pub fn decode(destination: []u8, source: []const u8) DecodeResult {
|
||||
}
|
||||
|
||||
pub fn encode(destination: []u8, source: []const u8) usize {
|
||||
return zig_base64.standard.Encoder.encode(destination, source).len;
|
||||
var outlen: usize = destination.len;
|
||||
LibBase64.base64_encode(source.ptr, source.len, destination.ptr, &outlen, 0);
|
||||
return outlen;
|
||||
}
|
||||
|
||||
pub fn decodeLenUpperBound(len: usize) usize {
|
||||
|
||||
@@ -1 +1 @@
|
||||
10
|
||||
14
|
||||
|
||||
Submodule src/bun.js/WebKit updated: 4c8ab8fdfb...26c8197333
@@ -26,7 +26,7 @@ const strings = bun.strings;
|
||||
const NewClass = Base.NewClass;
|
||||
const To = Base.To;
|
||||
const Request = WebCore.Request;
|
||||
|
||||
const String = bun.String;
|
||||
const FetchEvent = WebCore.FetchEvent;
|
||||
const MacroMap = @import("../../resolver/package_json.zig").MacroMap;
|
||||
const TSConfigJSON = @import("../../resolver/tsconfig_json.zig").TSConfigJSON;
|
||||
@@ -871,16 +871,16 @@ pub const JSBundler = struct {
|
||||
|
||||
extern fn JSBundlerPlugin__anyMatches(
|
||||
*Plugin,
|
||||
namespaceString: *const ZigString,
|
||||
path: *const ZigString,
|
||||
namespaceString: *const String,
|
||||
path: *const String,
|
||||
bool,
|
||||
) bool;
|
||||
|
||||
extern fn JSBundlerPlugin__matchOnLoad(
|
||||
*JSC.JSGlobalObject,
|
||||
*Plugin,
|
||||
namespaceString: *const ZigString,
|
||||
path: *const ZigString,
|
||||
namespaceString: *const String,
|
||||
path: *const String,
|
||||
context: *anyopaque,
|
||||
u8,
|
||||
) void;
|
||||
@@ -888,9 +888,9 @@ pub const JSBundler = struct {
|
||||
extern fn JSBundlerPlugin__matchOnResolve(
|
||||
*JSC.JSGlobalObject,
|
||||
*Plugin,
|
||||
namespaceString: *const ZigString,
|
||||
path: *const ZigString,
|
||||
importer: *const ZigString,
|
||||
namespaceString: *const String,
|
||||
path: *const String,
|
||||
importer: *const String,
|
||||
context: *anyopaque,
|
||||
u8,
|
||||
) void;
|
||||
@@ -905,10 +905,10 @@ pub const JSBundler = struct {
|
||||
defer tracer.end();
|
||||
|
||||
const namespace_string = if (path.isFile())
|
||||
ZigString.Empty
|
||||
bun.String.empty
|
||||
else
|
||||
ZigString.fromUTF8(path.namespace);
|
||||
const path_string = ZigString.fromUTF8(path.text);
|
||||
bun.String.create(path.namespace);
|
||||
const path_string = bun.String.create(path.text);
|
||||
return JSBundlerPlugin__anyMatches(this, &namespace_string, &path_string, is_onLoad);
|
||||
}
|
||||
|
||||
@@ -924,10 +924,12 @@ pub const JSBundler = struct {
|
||||
const tracer = bun.tracy.traceNamed(@src(), "JSBundler.matchOnLoad");
|
||||
defer tracer.end();
|
||||
const namespace_string = if (namespace.len == 0)
|
||||
ZigString.init("file")
|
||||
bun.String.static("file")
|
||||
else
|
||||
ZigString.fromUTF8(namespace);
|
||||
const path_string = ZigString.fromUTF8(path);
|
||||
bun.String.create(namespace);
|
||||
const path_string = bun.String.create(path);
|
||||
defer namespace_string.deref();
|
||||
defer path_string.deref();
|
||||
JSBundlerPlugin__matchOnLoad(globalThis, this, &namespace_string, &path_string, context, @intFromEnum(default_loader));
|
||||
}
|
||||
|
||||
@@ -944,11 +946,14 @@ pub const JSBundler = struct {
|
||||
const tracer = bun.tracy.traceNamed(@src(), "JSBundler.matchOnResolve");
|
||||
defer tracer.end();
|
||||
const namespace_string = if (strings.eqlComptime(namespace, "file"))
|
||||
ZigString.Empty
|
||||
bun.String.empty
|
||||
else
|
||||
ZigString.fromUTF8(namespace);
|
||||
const path_string = ZigString.fromUTF8(path);
|
||||
const importer_string = ZigString.fromUTF8(importer);
|
||||
bun.String.create(namespace);
|
||||
const path_string = bun.String.create(path);
|
||||
const importer_string = bun.String.create(importer);
|
||||
defer namespace_string.deref();
|
||||
defer path_string.deref();
|
||||
defer importer_string.deref();
|
||||
JSBundlerPlugin__matchOnResolve(globalThis, this, &namespace_string, &path_string, &importer_string, context, @intFromEnum(import_record_kind));
|
||||
}
|
||||
|
||||
|
||||
@@ -896,6 +896,9 @@ pub fn createNodeFS(
|
||||
) js.JSValueRef {
|
||||
var module = ctx.allocator().create(JSC.Node.NodeJSFS) catch unreachable;
|
||||
module.* = .{};
|
||||
var vm = ctx.bunVM();
|
||||
if (vm.standalone_module_graph != null)
|
||||
module.node_fs.vm = vm;
|
||||
|
||||
return module.toJS(ctx).asObjectRef();
|
||||
}
|
||||
@@ -3712,21 +3715,32 @@ pub const Timer = struct {
|
||||
const kind = this.kind;
|
||||
var map: *TimeoutMap = vm.timer.maps.get(kind);
|
||||
|
||||
// This doesn't deinit the timer
|
||||
// Timers are deinit'd separately
|
||||
// We do need to handle when the timer is cancelled after the job has been enqueued
|
||||
if (kind != .setInterval) {
|
||||
if (map.fetchSwapRemove(this.id) == null) {
|
||||
// if the timeout was cancelled, don't run the callback
|
||||
this.deinit();
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (!map.contains(this.id)) {
|
||||
// if the interval was cancelled, don't run the callback
|
||||
this.deinit();
|
||||
return;
|
||||
const should_cancel_job = brk: {
|
||||
// This doesn't deinit the timer
|
||||
// Timers are deinit'd separately
|
||||
// We do need to handle when the timer is cancelled after the job has been enqueued
|
||||
if (kind != .setInterval) {
|
||||
if (map.get(this.id)) |tombstone_or_timer| {
|
||||
break :brk tombstone_or_timer != null;
|
||||
} else {
|
||||
// clearTimeout has been called
|
||||
break :brk true;
|
||||
}
|
||||
} else {
|
||||
if (map.get(this.id)) |tombstone_or_timer| {
|
||||
// .refresh() was called after CallbackJob enqueued
|
||||
break :brk tombstone_or_timer == null;
|
||||
}
|
||||
}
|
||||
|
||||
break :brk false;
|
||||
};
|
||||
|
||||
if (should_cancel_job) {
|
||||
this.deinit();
|
||||
return;
|
||||
} else if (kind != .setInterval) {
|
||||
_ = map.swapRemove(this.id);
|
||||
}
|
||||
|
||||
var args_buf: [8]JSC.JSValue = undefined;
|
||||
@@ -3791,6 +3805,8 @@ pub const Timer = struct {
|
||||
result.then(globalThis, this, CallbackJob__onResolve, CallbackJob__onReject);
|
||||
},
|
||||
}
|
||||
} else {
|
||||
this.deinit();
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -3820,10 +3836,29 @@ pub const Timer = struct {
|
||||
return timer_js;
|
||||
}
|
||||
|
||||
pub fn doRef(this: *TimerObject, _: *JSC.JSGlobalObject, _: *JSC.CallFrame) callconv(.C) JSValue {
|
||||
pub fn doRef(this: *TimerObject, globalObject: *JSC.JSGlobalObject, callframe: *JSC.CallFrame) callconv(.C) JSValue {
|
||||
const this_value = callframe.this();
|
||||
this_value.ensureStillAlive();
|
||||
if (this.ref_count > 0)
|
||||
this.ref_count +|= 1;
|
||||
return JSValue.jsUndefined();
|
||||
|
||||
var vm = globalObject.bunVM();
|
||||
switch (this.kind) {
|
||||
.setTimeout, .setImmediate, .setInterval => {
|
||||
if (vm.timer.maps.get(this.kind).getPtr(this.id)) |val_| {
|
||||
if (val_.*) |*val| {
|
||||
val.poll_ref.ref(vm);
|
||||
|
||||
if (val.did_unref_timer) {
|
||||
val.did_unref_timer = false;
|
||||
vm.uws_event_loop.?.num_polls += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
return this_value;
|
||||
}
|
||||
|
||||
pub fn doRefresh(this: *TimerObject, globalThis: *JSC.JSGlobalObject, callframe: *JSC.CallFrame) callconv(.C) JSValue {
|
||||
@@ -3919,20 +3954,27 @@ pub const Timer = struct {
|
||||
return JSValue.jsUndefined();
|
||||
}
|
||||
|
||||
pub fn doUnref(this: *TimerObject, globalObject: *JSC.JSGlobalObject, _: *JSC.CallFrame) callconv(.C) JSValue {
|
||||
pub fn doUnref(this: *TimerObject, globalObject: *JSC.JSGlobalObject, callframe: *JSC.CallFrame) callconv(.C) JSValue {
|
||||
const this_value = callframe.this();
|
||||
this_value.ensureStillAlive();
|
||||
this.ref_count -|= 1;
|
||||
if (this.ref_count == 0) {
|
||||
switch (this.kind) {
|
||||
.setTimeout, .setImmediate => {
|
||||
_ = clearTimeout(globalObject, JSValue.jsNumber(this.id));
|
||||
},
|
||||
.setInterval => {
|
||||
_ = clearInterval(globalObject, JSValue.jsNumber(this.id));
|
||||
},
|
||||
}
|
||||
var vm = globalObject.bunVM();
|
||||
switch (this.kind) {
|
||||
.setTimeout, .setImmediate, .setInterval => {
|
||||
if (vm.timer.maps.get(this.kind).getPtr(this.id)) |val_| {
|
||||
if (val_.*) |*val| {
|
||||
val.poll_ref.unref(vm);
|
||||
|
||||
if (!val.did_unref_timer) {
|
||||
val.did_unref_timer = true;
|
||||
vm.uws_event_loop.?.num_polls -= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
return JSValue.jsUndefined();
|
||||
return this_value;
|
||||
}
|
||||
pub fn hasRef(this: *TimerObject, globalObject: *JSC.JSGlobalObject, _: *JSC.CallFrame) callconv(.C) JSValue {
|
||||
return JSValue.jsBoolean(this.ref_count > 0 and globalObject.bunVM().timer.maps.get(this.kind).contains(this.id));
|
||||
@@ -3954,6 +3996,7 @@ pub const Timer = struct {
|
||||
callback: JSC.Strong = .{},
|
||||
globalThis: *JSC.JSGlobalObject,
|
||||
timer: *uws.Timer,
|
||||
did_unref_timer: bool = false,
|
||||
poll_ref: JSC.PollRef = JSC.PollRef.init(),
|
||||
arguments: JSC.Strong = .{},
|
||||
|
||||
@@ -4055,8 +4098,14 @@ pub const Timer = struct {
|
||||
|
||||
var vm = this.globalThis.bunVM();
|
||||
|
||||
this.poll_ref.unrefOnNextTick(vm);
|
||||
this.poll_ref.unref(vm);
|
||||
|
||||
this.timer.deinit();
|
||||
if (this.did_unref_timer) {
|
||||
// balance double-unrefing
|
||||
vm.uws_event_loop.?.num_polls += 1;
|
||||
}
|
||||
|
||||
this.callback.deinit();
|
||||
this.arguments.deinit();
|
||||
}
|
||||
|
||||
@@ -1925,8 +1925,8 @@ pub const DNSResolver = struct {
|
||||
.err => |err| {
|
||||
const system_error = JSC.SystemError{
|
||||
.errno = -1,
|
||||
.code = JSC.ZigString.init(err.code()),
|
||||
.message = JSC.ZigString.init(err.label()),
|
||||
.code = bun.String.static(err.code()),
|
||||
.message = bun.String.static(err.label()),
|
||||
};
|
||||
|
||||
globalThis.throwValue(system_error.toErrorInstance(globalThis));
|
||||
@@ -1972,8 +1972,8 @@ pub const DNSResolver = struct {
|
||||
.err => |err| {
|
||||
const system_error = JSC.SystemError{
|
||||
.errno = -1,
|
||||
.code = JSC.ZigString.init(err.code()),
|
||||
.message = JSC.ZigString.init(err.label()),
|
||||
.code = bun.String.static(err.code()),
|
||||
.message = bun.String.static(err.label()),
|
||||
};
|
||||
|
||||
globalThis.throwValue(system_error.toErrorInstance(globalThis));
|
||||
|
||||
@@ -69,6 +69,11 @@ fn normalizeHost(input: anytype) @TypeOf(input) {
|
||||
|
||||
const BinaryType = JSC.BinaryType;
|
||||
|
||||
const WrappedType = enum {
|
||||
none,
|
||||
tls,
|
||||
tcp,
|
||||
};
|
||||
const Handlers = struct {
|
||||
onOpen: JSC.JSValue = .zero,
|
||||
onClose: JSC.JSValue = .zero,
|
||||
@@ -97,8 +102,8 @@ const Handlers = struct {
|
||||
handlers: *Handlers,
|
||||
socket_context: *uws.SocketContext,
|
||||
|
||||
pub fn exit(this: *Scope, ssl: bool) void {
|
||||
this.handlers.markInactive(ssl, this.socket_context);
|
||||
pub fn exit(this: *Scope, ssl: bool, wrapped: WrappedType) void {
|
||||
this.handlers.markInactive(ssl, this.socket_context, wrapped);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -123,19 +128,24 @@ const Handlers = struct {
|
||||
return true;
|
||||
}
|
||||
|
||||
pub fn markInactive(this: *Handlers, ssl: bool, ctx: *uws.SocketContext) void {
|
||||
pub fn markInactive(this: *Handlers, ssl: bool, ctx: *uws.SocketContext, wrapped: WrappedType) void {
|
||||
Listener.log("markInactive", .{});
|
||||
this.active_connections -= 1;
|
||||
if (this.active_connections == 0 and this.is_server) {
|
||||
var listen_socket: *Listener = @fieldParentPtr(Listener, "handlers", this);
|
||||
// allow it to be GC'd once the last connection is closed and it's not listening anymore
|
||||
if (listen_socket.listener == null) {
|
||||
listen_socket.strong_self.clear();
|
||||
if (this.active_connections == 0) {
|
||||
if (this.is_server) {
|
||||
var listen_socket: *Listener = @fieldParentPtr(Listener, "handlers", this);
|
||||
// allow it to be GC'd once the last connection is closed and it's not listening anymore
|
||||
if (listen_socket.listener == null) {
|
||||
listen_socket.strong_self.clear();
|
||||
}
|
||||
} else {
|
||||
this.unprotect();
|
||||
// will deinit when is not wrapped or when is the TCP wrapped connection
|
||||
if (wrapped != .tls) {
|
||||
ctx.deinit(ssl);
|
||||
}
|
||||
bun.default_allocator.destroy(this);
|
||||
}
|
||||
} else if (this.active_connections == 0 and !this.is_server) {
|
||||
this.unprotect();
|
||||
ctx.deinit(ssl);
|
||||
bun.default_allocator.destroy(this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -364,6 +374,7 @@ pub const Listener = struct {
|
||||
connection: UnixOrHost,
|
||||
socket_context: ?*uws.SocketContext = null,
|
||||
ssl: bool = false,
|
||||
protos: ?[]const u8 = null,
|
||||
|
||||
strong_data: JSC.Strong = .{},
|
||||
strong_self: JSC.Strong = .{},
|
||||
@@ -395,6 +406,19 @@ pub const Listener = struct {
|
||||
port: u16,
|
||||
},
|
||||
|
||||
pub fn clone(this: UnixOrHost) UnixOrHost {
|
||||
switch (this) {
|
||||
.unix => |u| {
|
||||
return .{
|
||||
.unix = (bun.default_allocator.dupe(u8, u) catch unreachable),
|
||||
};
|
||||
},
|
||||
.host => |h| {
|
||||
return .{ .host = .{ .host = (bun.default_allocator.dupe(u8, h.host) catch unreachable), .port = this.host.port } };
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn deinit(this: UnixOrHost) void {
|
||||
switch (this) {
|
||||
.unix => |u| {
|
||||
@@ -455,10 +479,12 @@ pub const Listener = struct {
|
||||
var socket_config = SocketConfig.fromJS(opts, globalObject, exception) orelse {
|
||||
return .zero;
|
||||
};
|
||||
|
||||
var hostname_or_unix = socket_config.hostname_or_unix;
|
||||
var port = socket_config.port;
|
||||
var ssl = socket_config.ssl;
|
||||
var handlers = socket_config.handlers;
|
||||
var protos: ?[]const u8 = null;
|
||||
const exclusive = socket_config.exclusive;
|
||||
handlers.is_server = true;
|
||||
|
||||
@@ -496,6 +522,10 @@ pub const Listener = struct {
|
||||
};
|
||||
|
||||
if (ssl_enabled) {
|
||||
if (ssl.?.protos) |p| {
|
||||
protos = p[0..ssl.?.protos_len];
|
||||
}
|
||||
|
||||
uws.NewSocketHandler(true).configure(
|
||||
socket_context,
|
||||
true,
|
||||
@@ -593,6 +623,7 @@ pub const Listener = struct {
|
||||
.ssl = ssl_enabled,
|
||||
.socket_context = socket_context,
|
||||
.listener = listen_socket,
|
||||
.protos = if (protos) |p| (bun.default_allocator.dupe(u8, p) catch unreachable) else null,
|
||||
};
|
||||
|
||||
socket.handlers.protect();
|
||||
@@ -649,6 +680,8 @@ pub const Listener = struct {
|
||||
.handlers = &listener.handlers,
|
||||
.this_value = .zero,
|
||||
.socket = socket,
|
||||
.protos = listener.protos,
|
||||
.owned_protos = false,
|
||||
};
|
||||
if (listener.strong_data.get()) |default_data| {
|
||||
const globalObject = listener.handlers.globalObject;
|
||||
@@ -715,6 +748,10 @@ pub const Listener = struct {
|
||||
|
||||
this.handlers.unprotect();
|
||||
this.connection.deinit();
|
||||
if (this.protos) |protos| {
|
||||
this.protos = null;
|
||||
bun.default_allocator.destroy(protos);
|
||||
}
|
||||
bun.default_allocator.destroy(this);
|
||||
}
|
||||
|
||||
@@ -775,13 +812,17 @@ pub const Listener = struct {
|
||||
const socket_config = SocketConfig.fromJS(opts, globalObject, exception) orelse {
|
||||
return .zero;
|
||||
};
|
||||
|
||||
var hostname_or_unix = socket_config.hostname_or_unix;
|
||||
var port = socket_config.port;
|
||||
var ssl = socket_config.ssl;
|
||||
var handlers = socket_config.handlers;
|
||||
var default_data = socket_config.default_data;
|
||||
|
||||
var protos: ?[]const u8 = null;
|
||||
var server_name: ?[]const u8 = null;
|
||||
const ssl_enabled = ssl != null;
|
||||
defer if (ssl != null) ssl.?.deinit();
|
||||
|
||||
handlers.protect();
|
||||
|
||||
@@ -797,6 +838,12 @@ pub const Listener = struct {
|
||||
};
|
||||
|
||||
if (ssl_enabled) {
|
||||
if (ssl.?.protos) |p| {
|
||||
protos = p[0..ssl.?.protos_len];
|
||||
}
|
||||
if (ssl.?.server_name) |s| {
|
||||
server_name = bun.default_allocator.dupe(u8, s[0..bun.len(s)]) catch unreachable;
|
||||
}
|
||||
uws.NewSocketHandler(true).configure(
|
||||
socket_context,
|
||||
true,
|
||||
@@ -848,6 +895,8 @@ pub const Listener = struct {
|
||||
.this_value = .zero,
|
||||
.socket = undefined,
|
||||
.connection = connection,
|
||||
.protos = if (protos) |p| (bun.default_allocator.dupe(u8, p) catch unreachable) else null,
|
||||
.server_name = server_name,
|
||||
};
|
||||
|
||||
TLSSocket.dataSetCached(tls.getThisValue(globalObject), globalObject, default_data);
|
||||
@@ -871,6 +920,8 @@ pub const Listener = struct {
|
||||
.this_value = .zero,
|
||||
.socket = undefined,
|
||||
.connection = null,
|
||||
.protos = null,
|
||||
.server_name = null,
|
||||
};
|
||||
|
||||
TCPSocket.dataSetCached(tcp.getThisValue(globalObject), globalObject, default_data);
|
||||
@@ -898,11 +949,41 @@ fn JSSocketType(comptime ssl: bool) type {
|
||||
}
|
||||
}
|
||||
|
||||
fn selectALPNCallback(
|
||||
_: ?*BoringSSL.SSL,
|
||||
out: [*c][*c]const u8,
|
||||
outlen: [*c]u8,
|
||||
in: [*c]const u8,
|
||||
inlen: c_uint,
|
||||
arg: ?*anyopaque,
|
||||
) callconv(.C) c_int {
|
||||
const this = bun.cast(*TLSSocket, arg);
|
||||
if (this.protos) |protos| {
|
||||
if (protos.len == 0) {
|
||||
return BoringSSL.SSL_TLSEXT_ERR_NOACK;
|
||||
}
|
||||
|
||||
const status = BoringSSL.SSL_select_next_proto(bun.cast([*c][*c]u8, out), outlen, protos.ptr, @intCast(c_uint, protos.len), in, inlen);
|
||||
|
||||
// Previous versions of Node.js returned SSL_TLSEXT_ERR_NOACK if no protocol
|
||||
// match was found. This would neither cause a fatal alert nor would it result
|
||||
// in a useful ALPN response as part of the Server Hello message.
|
||||
// We now return SSL_TLSEXT_ERR_ALERT_FATAL in that case as per Section 3.2
|
||||
// of RFC 7301, which causes a fatal no_application_protocol alert.
|
||||
const expected = if (comptime BoringSSL.OPENSSL_NPN_NEGOTIATED == 1) BoringSSL.SSL_TLSEXT_ERR_OK else BoringSSL.SSL_TLSEXT_ERR_ALERT_FATAL;
|
||||
|
||||
return if (status == expected) 1 else 0;
|
||||
} else {
|
||||
return BoringSSL.SSL_TLSEXT_ERR_NOACK;
|
||||
}
|
||||
}
|
||||
|
||||
fn NewSocket(comptime ssl: bool) type {
|
||||
return struct {
|
||||
pub const Socket = uws.NewSocketHandler(ssl);
|
||||
socket: Socket,
|
||||
detached: bool = false,
|
||||
wrapped: WrappedType = .none,
|
||||
handlers: *Handlers,
|
||||
this_value: JSC.JSValue = .zero,
|
||||
poll_ref: JSC.PollRef = JSC.PollRef.init(),
|
||||
@@ -910,6 +991,9 @@ fn NewSocket(comptime ssl: bool) type {
|
||||
last_4: [4]u8 = .{ 0, 0, 0, 0 },
|
||||
authorized: bool = false,
|
||||
connection: ?Listener.UnixOrHost = null,
|
||||
protos: ?[]const u8,
|
||||
owned_protos: bool = true,
|
||||
server_name: ?[]const u8 = null,
|
||||
|
||||
// TODO: switch to something that uses `visitAggregate` and have the
|
||||
// `Listener` keep a list of all the sockets JSValue in there
|
||||
@@ -1022,8 +1106,8 @@ fn NewSocket(comptime ssl: bool) type {
|
||||
var globalObject = handlers.globalObject;
|
||||
const err = JSC.SystemError{
|
||||
.errno = errno,
|
||||
.message = ZigString.init("Failed to connect"),
|
||||
.syscall = ZigString.init("connect"),
|
||||
.message = bun.String.static("Failed to connect"),
|
||||
.syscall = bun.String.static("connect"),
|
||||
};
|
||||
|
||||
if (callback == .zero) {
|
||||
@@ -1079,7 +1163,7 @@ fn NewSocket(comptime ssl: bool) type {
|
||||
var vm = this.handlers.vm;
|
||||
this.reffer.unref(vm);
|
||||
|
||||
this.handlers.markInactive(ssl, this.socket.context());
|
||||
this.handlers.markInactive(ssl, this.socket.context(), this.wrapped);
|
||||
this.poll_ref.unref(vm);
|
||||
this.has_pending_activity.store(false, .Release);
|
||||
}
|
||||
@@ -1091,25 +1175,42 @@ fn NewSocket(comptime ssl: bool) type {
|
||||
|
||||
// Add SNI support for TLS (mongodb and others requires this)
|
||||
if (comptime ssl) {
|
||||
if (this.connection) |connection| {
|
||||
if (connection == .host) {
|
||||
const host = normalizeHost(connection.host.host);
|
||||
var ssl_ptr: *BoringSSL.SSL = @ptrCast(*BoringSSL.SSL, socket.getNativeHandle());
|
||||
if (!ssl_ptr.isInitFinished()) {
|
||||
if (this.server_name) |server_name| {
|
||||
const host = normalizeHost(server_name);
|
||||
if (host.len > 0) {
|
||||
var ssl_ptr: *BoringSSL.SSL = @ptrCast(*BoringSSL.SSL, socket.getNativeHandle());
|
||||
if (!ssl_ptr.isInitFinished()) {
|
||||
var host__ = default_allocator.dupeZ(u8, host) catch unreachable;
|
||||
defer default_allocator.free(host__);
|
||||
ssl_ptr.setHostname(host__);
|
||||
}
|
||||
} else if (this.connection) |connection| {
|
||||
if (connection == .host) {
|
||||
const host = normalizeHost(connection.host.host);
|
||||
if (host.len > 0) {
|
||||
var host__ = default_allocator.dupeZ(u8, host) catch unreachable;
|
||||
defer default_allocator.free(host__);
|
||||
ssl_ptr.setHostname(host__);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (this.protos) |protos| {
|
||||
if (this.handlers.is_server) {
|
||||
BoringSSL.SSL_CTX_set_alpn_select_cb(BoringSSL.SSL_get_SSL_CTX(ssl_ptr), selectALPNCallback, bun.cast(*anyopaque, this));
|
||||
} else {
|
||||
_ = BoringSSL.SSL_set_alpn_protos(ssl_ptr, protos.ptr, @intCast(c_uint, protos.len));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.poll_ref.ref(this.handlers.vm);
|
||||
this.detached = false;
|
||||
this.socket = socket;
|
||||
socket.ext(**anyopaque).?.* = bun.cast(**anyopaque, this);
|
||||
|
||||
if (this.wrapped == .none) {
|
||||
socket.ext(**anyopaque).?.* = bun.cast(**anyopaque, this);
|
||||
}
|
||||
|
||||
const handlers = this.handlers;
|
||||
const callback = handlers.onOpen;
|
||||
@@ -1161,6 +1262,8 @@ fn NewSocket(comptime ssl: bool) type {
|
||||
pub fn onEnd(this: *This, socket: Socket) void {
|
||||
JSC.markBinding(@src());
|
||||
log("onEnd", .{});
|
||||
if (this.detached) return;
|
||||
|
||||
this.detached = true;
|
||||
defer this.markInactive();
|
||||
|
||||
@@ -1174,7 +1277,7 @@ fn NewSocket(comptime ssl: bool) type {
|
||||
// the handlers must be kept alive for the duration of the function call
|
||||
// that way if we need to call the error handler, we can
|
||||
var scope = handlers.enter(socket.context());
|
||||
defer scope.exit(ssl);
|
||||
defer scope.exit(ssl, this.wrapped);
|
||||
|
||||
const globalObject = handlers.globalObject;
|
||||
const this_value = this.getThisValue(globalObject);
|
||||
@@ -1211,7 +1314,7 @@ fn NewSocket(comptime ssl: bool) type {
|
||||
// the handlers must be kept alive for the duration of the function call
|
||||
// that way if we need to call the error handler, we can
|
||||
var scope = handlers.enter(socket.context());
|
||||
defer scope.exit(ssl);
|
||||
defer scope.exit(ssl, this.wrapped);
|
||||
|
||||
const globalObject = handlers.globalObject;
|
||||
const this_value = this.getThisValue(globalObject);
|
||||
@@ -1232,8 +1335,8 @@ fn NewSocket(comptime ssl: bool) type {
|
||||
const reason = if (ssl_error.reason == null) "" else ssl_error.reason[0..bun.len(ssl_error.reason)];
|
||||
|
||||
const fallback = JSC.SystemError{
|
||||
.code = ZigString.init(code),
|
||||
.message = ZigString.init(reason),
|
||||
.code = bun.String.create(code),
|
||||
.message = bun.String.create(reason),
|
||||
};
|
||||
|
||||
authorization_error = fallback.toErrorInstance(globalObject);
|
||||
@@ -1255,7 +1358,6 @@ fn NewSocket(comptime ssl: bool) type {
|
||||
log("onClose", .{});
|
||||
this.detached = true;
|
||||
defer this.markInactive();
|
||||
|
||||
const handlers = this.handlers;
|
||||
this.poll_ref.unref(handlers.vm);
|
||||
|
||||
@@ -1265,7 +1367,7 @@ fn NewSocket(comptime ssl: bool) type {
|
||||
// the handlers must be kept alive for the duration of the function call
|
||||
// that way if we need to call the error handler, we can
|
||||
var scope = handlers.enter(socket.context());
|
||||
defer scope.exit(ssl);
|
||||
defer scope.exit(ssl, this.wrapped);
|
||||
|
||||
var globalObject = handlers.globalObject;
|
||||
const this_value = this.getThisValue(globalObject);
|
||||
@@ -1295,7 +1397,7 @@ fn NewSocket(comptime ssl: bool) type {
|
||||
// the handlers must be kept alive for the duration of the function call
|
||||
// that way if we need to call the error handler, we can
|
||||
var scope = handlers.enter(socket.context());
|
||||
defer scope.exit(ssl);
|
||||
defer scope.exit(ssl, this.wrapped);
|
||||
|
||||
// const encoding = handlers.encoding;
|
||||
const result = callback.callWithThis(globalObject, this_value, &[_]JSValue{
|
||||
@@ -1409,8 +1511,8 @@ fn NewSocket(comptime ssl: bool) type {
|
||||
const reason = if (ssl_error.reason == null) "" else ssl_error.reason[0..bun.len(ssl_error.reason)];
|
||||
|
||||
const fallback = JSC.SystemError{
|
||||
.code = ZigString.init(code),
|
||||
.message = ZigString.init(reason),
|
||||
.code = bun.String.create(code),
|
||||
.message = bun.String.create(reason),
|
||||
};
|
||||
|
||||
return fallback.toErrorInstance(globalObject);
|
||||
@@ -1476,10 +1578,20 @@ fn NewSocket(comptime ssl: bool) type {
|
||||
}
|
||||
|
||||
fn writeMaybeCorked(this: *This, buffer: []const u8, is_end: bool) i32 {
|
||||
if (this.socket.isShutdown() or this.socket.isClosed()) {
|
||||
if (this.detached or this.socket.isShutdown() or this.socket.isClosed()) {
|
||||
return -1;
|
||||
}
|
||||
// we don't cork yet but we might later
|
||||
|
||||
if (comptime ssl) {
|
||||
// TLS wrapped but in TCP mode
|
||||
if (this.wrapped == .tcp) {
|
||||
const res = this.socket.rawWrite(buffer, is_end);
|
||||
log("write({d}, {any}) = {d}", .{ buffer.len, is_end, res });
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
const res = this.socket.write(buffer, is_end);
|
||||
log("write({d}, {any}) = {d}", .{ buffer.len, is_end, res });
|
||||
return res;
|
||||
@@ -1487,7 +1599,6 @@ fn NewSocket(comptime ssl: bool) type {
|
||||
|
||||
fn writeOrEnd(this: *This, globalObject: *JSC.JSGlobalObject, args: []const JSC.JSValue, is_end: bool) WriteResult {
|
||||
if (args.len == 0) return .{ .success = .{} };
|
||||
|
||||
if (args.ptr[0].asArrayBuffer(globalObject)) |array_buffer| {
|
||||
var slice = array_buffer.slice();
|
||||
|
||||
@@ -1681,9 +1792,6 @@ fn NewSocket(comptime ssl: bool) type {
|
||||
if (result.wrote == result.total) {
|
||||
this.socket.flush();
|
||||
this.detached = true;
|
||||
if (!this.socket.isClosed()) {
|
||||
this.socket.close(0, null);
|
||||
}
|
||||
this.markInactive();
|
||||
}
|
||||
break :brk JSValue.jsNumber(result.wrote);
|
||||
@@ -1706,17 +1814,32 @@ fn NewSocket(comptime ssl: bool) type {
|
||||
|
||||
pub fn finalize(this: *This) callconv(.C) void {
|
||||
log("finalize()", .{});
|
||||
if (this.detached) return;
|
||||
this.detached = true;
|
||||
if (!this.socket.isClosed()) {
|
||||
this.socket.close(0, null);
|
||||
if (!this.detached) {
|
||||
this.detached = true;
|
||||
if (!this.socket.isClosed()) {
|
||||
this.socket.close(0, null);
|
||||
}
|
||||
this.markInactive();
|
||||
}
|
||||
if (this.connection) |connection| {
|
||||
connection.deinit();
|
||||
this.connection = null;
|
||||
}
|
||||
this.markInactive();
|
||||
|
||||
this.poll_ref.unref(JSC.VirtualMachine.get());
|
||||
// need to deinit event without being attached
|
||||
if (this.owned_protos) {
|
||||
if (this.protos) |protos| {
|
||||
this.protos = null;
|
||||
default_allocator.free(protos);
|
||||
}
|
||||
}
|
||||
|
||||
if (this.server_name) |server_name| {
|
||||
this.server_name = null;
|
||||
default_allocator.free(server_name);
|
||||
}
|
||||
|
||||
if (this.connection) |connection| {
|
||||
this.connection = null;
|
||||
connection.deinit();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn reload(this: *This, globalObject: *JSC.JSGlobalObject, callframe: *JSC.CallFrame) callconv(.C) JSValue {
|
||||
@@ -1756,8 +1879,384 @@ fn NewSocket(comptime ssl: bool) type {
|
||||
|
||||
return JSValue.jsUndefined();
|
||||
}
|
||||
|
||||
pub fn getALPNProtocol(
|
||||
this: *This,
|
||||
globalObject: *JSC.JSGlobalObject,
|
||||
) callconv(.C) JSValue {
|
||||
if (comptime ssl == false) {
|
||||
return JSValue.jsBoolean(false);
|
||||
}
|
||||
|
||||
if (this.detached) {
|
||||
return JSValue.jsBoolean(false);
|
||||
}
|
||||
|
||||
var alpn_proto: [*c]const u8 = null;
|
||||
var alpn_proto_len: u32 = 0;
|
||||
|
||||
var ssl_ptr: *BoringSSL.SSL = @ptrCast(*BoringSSL.SSL, this.socket.getNativeHandle());
|
||||
BoringSSL.SSL_get0_alpn_selected(ssl_ptr, &alpn_proto, &alpn_proto_len);
|
||||
if (alpn_proto == null or alpn_proto_len == 0) {
|
||||
return JSValue.jsBoolean(false);
|
||||
}
|
||||
|
||||
const slice = alpn_proto[0..alpn_proto_len];
|
||||
if (strings.eql(slice, "h2")) {
|
||||
return ZigString.static("h2").toValue(globalObject);
|
||||
}
|
||||
if (strings.eql(slice, "http/1.1")) {
|
||||
return ZigString.static("http/1.1").toValue(globalObject);
|
||||
}
|
||||
return ZigString.fromUTF8(slice).toValueGC(globalObject);
|
||||
}
|
||||
|
||||
pub fn setServername(
|
||||
this: *This,
|
||||
globalObject: *JSC.JSGlobalObject,
|
||||
callframe: *JSC.CallFrame,
|
||||
) callconv(.C) JSValue {
|
||||
if (comptime ssl == false) {
|
||||
return JSValue.jsUndefined();
|
||||
}
|
||||
|
||||
if (this.handlers.is_server) {
|
||||
globalObject.throw("Cannot issue SNI from a TLS server-side socket", .{});
|
||||
return .zero;
|
||||
}
|
||||
|
||||
const args = callframe.arguments(1);
|
||||
if (args.len < 1) {
|
||||
globalObject.throw("Expected 1 argument", .{});
|
||||
return .zero;
|
||||
}
|
||||
|
||||
const server_name = args.ptr[0];
|
||||
if (!server_name.isString()) {
|
||||
globalObject.throw("Expected \"serverName\" to be a string", .{});
|
||||
return .zero;
|
||||
}
|
||||
|
||||
const slice = server_name.getZigString(globalObject).toOwnedSlice(bun.default_allocator) catch unreachable;
|
||||
if (this.server_name) |old| {
|
||||
this.server_name = slice;
|
||||
default_allocator.free(old);
|
||||
} else {
|
||||
this.server_name = slice;
|
||||
}
|
||||
|
||||
if (this.detached) {
|
||||
// will be attached onOpen
|
||||
return JSValue.jsUndefined();
|
||||
}
|
||||
|
||||
const host = normalizeHost(@as([]const u8, slice));
|
||||
if (host.len > 0) {
|
||||
var ssl_ptr: *BoringSSL.SSL = @ptrCast(*BoringSSL.SSL, this.socket.getNativeHandle());
|
||||
if (ssl_ptr.isInitFinished()) {
|
||||
// match node.js exceptions
|
||||
globalObject.throw("Already started.", .{});
|
||||
return .zero;
|
||||
}
|
||||
var host__ = default_allocator.dupeZ(u8, host) catch unreachable;
|
||||
defer default_allocator.free(host__);
|
||||
ssl_ptr.setHostname(host__);
|
||||
}
|
||||
|
||||
return JSValue.jsUndefined();
|
||||
}
|
||||
|
||||
// this invalidates the current socket returning 2 new sockets
|
||||
// one for non-TLS and another for TLS
|
||||
// handlers for non-TLS are preserved
|
||||
pub fn upgradeTLS(
|
||||
this: *This,
|
||||
globalObject: *JSC.JSGlobalObject,
|
||||
callframe: *JSC.CallFrame,
|
||||
) callconv(.C) JSValue {
|
||||
JSC.markBinding(@src());
|
||||
if (comptime ssl) {
|
||||
return JSValue.jsUndefined();
|
||||
}
|
||||
|
||||
if (this.detached) {
|
||||
return JSValue.jsUndefined();
|
||||
}
|
||||
|
||||
const args = callframe.arguments(1);
|
||||
|
||||
if (args.len < 1) {
|
||||
globalObject.throw("Expected 1 arguments", .{});
|
||||
return .zero;
|
||||
}
|
||||
|
||||
var exception: JSC.C.JSValueRef = null;
|
||||
|
||||
const opts = args.ptr[0];
|
||||
if (opts.isEmptyOrUndefinedOrNull() or opts.isBoolean() or !opts.isObject()) {
|
||||
globalObject.throw("Expected options object", .{});
|
||||
return .zero;
|
||||
}
|
||||
|
||||
var socket_obj = opts.get(globalObject, "socket") orelse {
|
||||
globalObject.throw("Expected \"socket\" option", .{});
|
||||
return .zero;
|
||||
};
|
||||
|
||||
var handlers = Handlers.fromJS(globalObject, socket_obj, &exception) orelse {
|
||||
globalObject.throwValue(exception.?.value());
|
||||
return .zero;
|
||||
};
|
||||
|
||||
var ssl_opts: ?JSC.API.ServerConfig.SSLConfig = null;
|
||||
|
||||
if (opts.getTruthy(globalObject, "tls")) |tls| {
|
||||
if (tls.isBoolean()) {
|
||||
if (tls.toBoolean()) {
|
||||
ssl_opts = JSC.API.ServerConfig.SSLConfig.zero;
|
||||
}
|
||||
} else {
|
||||
if (JSC.API.ServerConfig.SSLConfig.inJS(globalObject, tls, &exception)) |ssl_config| {
|
||||
ssl_opts = ssl_config;
|
||||
} else if (exception != null) {
|
||||
return .zero;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ssl_opts == null) {
|
||||
globalObject.throw("Expected \"tls\" option", .{});
|
||||
return .zero;
|
||||
}
|
||||
|
||||
var default_data = JSValue.zero;
|
||||
if (opts.getTruthy(globalObject, "data")) |default_data_value| {
|
||||
default_data = default_data_value;
|
||||
default_data.ensureStillAlive();
|
||||
}
|
||||
|
||||
var socket_config = ssl_opts.?;
|
||||
defer socket_config.deinit();
|
||||
const options = socket_config.asUSockets();
|
||||
|
||||
const protos = socket_config.protos;
|
||||
const protos_len = socket_config.protos_len;
|
||||
|
||||
const ext_size = @sizeOf(WrappedSocket);
|
||||
|
||||
const is_server = this.handlers.is_server;
|
||||
var tls = handlers.vm.allocator.create(TLSSocket) catch @panic("OOM");
|
||||
var handlers_ptr = handlers.vm.allocator.create(Handlers) catch @panic("OOM");
|
||||
handlers_ptr.* = handlers;
|
||||
handlers_ptr.is_server = is_server;
|
||||
handlers_ptr.protect();
|
||||
|
||||
tls.* = .{
|
||||
.handlers = handlers_ptr,
|
||||
.this_value = .zero,
|
||||
.socket = undefined,
|
||||
.connection = if (this.connection) |c| c.clone() else null,
|
||||
.wrapped = .tls,
|
||||
.protos = if (protos) |p| (bun.default_allocator.dupe(u8, p[0..protos_len]) catch unreachable) else null,
|
||||
.server_name = if (socket_config.server_name) |server_name| (bun.default_allocator.dupe(u8, server_name[0..bun.len(server_name)]) catch unreachable) else null,
|
||||
};
|
||||
|
||||
var tls_js_value = tls.getThisValue(globalObject);
|
||||
TLSSocket.dataSetCached(tls_js_value, globalObject, default_data);
|
||||
|
||||
const TCPHandler = NewWrappedHandler(false);
|
||||
|
||||
// reconfigure context to use the new wrapper handlers
|
||||
Socket.unsafeConfigure(this.socket.context(), true, true, WrappedSocket, TCPHandler);
|
||||
const old_context = this.socket.context();
|
||||
const TLSHandler = NewWrappedHandler(true);
|
||||
const new_socket = this.socket.wrapTLS(
|
||||
options,
|
||||
ext_size,
|
||||
true,
|
||||
WrappedSocket,
|
||||
TLSHandler,
|
||||
) orelse {
|
||||
handlers_ptr.unprotect();
|
||||
handlers.vm.allocator.destroy(handlers_ptr);
|
||||
bun.default_allocator.destroy(tls);
|
||||
return JSValue.jsUndefined();
|
||||
};
|
||||
|
||||
tls.socket = new_socket;
|
||||
|
||||
var raw = handlers.vm.allocator.create(TLSSocket) catch @panic("OOM");
|
||||
var raw_handlers_ptr = handlers.vm.allocator.create(Handlers) catch @panic("OOM");
|
||||
raw_handlers_ptr.* = .{
|
||||
.vm = globalObject.bunVM(),
|
||||
.globalObject = globalObject,
|
||||
.onOpen = this.handlers.onOpen,
|
||||
.onClose = this.handlers.onClose,
|
||||
.onData = this.handlers.onData,
|
||||
.onWritable = this.handlers.onWritable,
|
||||
.onTimeout = this.handlers.onTimeout,
|
||||
.onConnectError = this.handlers.onConnectError,
|
||||
.onEnd = this.handlers.onEnd,
|
||||
.onError = this.handlers.onError,
|
||||
.onHandshake = this.handlers.onHandshake,
|
||||
.binary_type = this.handlers.binary_type,
|
||||
.is_server = is_server,
|
||||
};
|
||||
this.handlers.onOpen = .zero;
|
||||
this.handlers.onClose = .zero;
|
||||
this.handlers.onData = .zero;
|
||||
this.handlers.onWritable = .zero;
|
||||
this.handlers.onTimeout = .zero;
|
||||
this.handlers.onConnectError = .zero;
|
||||
this.handlers.onEnd = .zero;
|
||||
this.handlers.onError = .zero;
|
||||
this.handlers.onHandshake = .zero;
|
||||
raw.* = .{
|
||||
.handlers = raw_handlers_ptr,
|
||||
.this_value = .zero,
|
||||
.socket = new_socket,
|
||||
.connection = if (this.connection) |c| c.clone() else null,
|
||||
.wrapped = .tcp,
|
||||
.protos = null,
|
||||
};
|
||||
|
||||
var raw_js_value = raw.getThisValue(globalObject);
|
||||
if (JSSocketType(ssl).dataGetCached(this.getThisValue(globalObject))) |raw_default_data| {
|
||||
raw_default_data.ensureStillAlive();
|
||||
TLSSocket.dataSetCached(raw_js_value, globalObject, raw_default_data);
|
||||
}
|
||||
// marks both as active
|
||||
raw.markActive();
|
||||
// this will keep tls alive until socket.open() is called to start TLS certificate and the handshake process
|
||||
// open is not immediately called because we need to set bunSocketInternal
|
||||
tls.markActive();
|
||||
|
||||
// mark both instances on socket data
|
||||
new_socket.ext(WrappedSocket).?.* = .{ .tcp = raw, .tls = tls };
|
||||
|
||||
// start TLS handshake after we set ext
|
||||
new_socket.startTLS(!this.handlers.is_server);
|
||||
|
||||
//detach and invalidate the old instance
|
||||
this.detached = true;
|
||||
if (this.reffer.has) {
|
||||
var vm = this.handlers.vm;
|
||||
this.reffer.unref(vm);
|
||||
old_context.deinit(ssl);
|
||||
bun.default_allocator.destroy(this.handlers);
|
||||
this.poll_ref.unref(vm);
|
||||
this.has_pending_activity.store(false, .Release);
|
||||
}
|
||||
|
||||
const array = JSC.JSValue.createEmptyArray(globalObject, 2);
|
||||
array.putIndex(globalObject, 0, raw_js_value);
|
||||
array.putIndex(globalObject, 1, tls_js_value);
|
||||
return array;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
pub const TCPSocket = NewSocket(false);
|
||||
pub const TLSSocket = NewSocket(true);
|
||||
|
||||
pub const WrappedSocket = extern struct {
|
||||
// both shares the same socket but one behaves as TLS and the other as TCP
|
||||
tls: *TLSSocket,
|
||||
tcp: *TLSSocket,
|
||||
};
|
||||
|
||||
pub fn NewWrappedHandler(comptime tls: bool) type {
|
||||
const Socket = uws.NewSocketHandler(true);
|
||||
return struct {
|
||||
pub fn onOpen(
|
||||
this: WrappedSocket,
|
||||
socket: Socket,
|
||||
) void {
|
||||
// only TLS will call onOpen
|
||||
if (comptime tls) {
|
||||
TLSSocket.onOpen(this.tls, socket);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn onEnd(
|
||||
this: WrappedSocket,
|
||||
socket: Socket,
|
||||
) void {
|
||||
if (comptime tls) {
|
||||
TLSSocket.onEnd(this.tls, socket);
|
||||
} else {
|
||||
TLSSocket.onEnd(this.tcp, socket);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn onHandshake(
|
||||
this: WrappedSocket,
|
||||
socket: Socket,
|
||||
success: i32,
|
||||
ssl_error: uws.us_bun_verify_error_t,
|
||||
) void {
|
||||
// only TLS will call onHandshake
|
||||
if (comptime tls) {
|
||||
TLSSocket.onHandshake(this.tls, socket, success, ssl_error);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn onClose(
|
||||
this: WrappedSocket,
|
||||
socket: Socket,
|
||||
err: c_int,
|
||||
data: ?*anyopaque,
|
||||
) void {
|
||||
if (comptime tls) {
|
||||
TLSSocket.onClose(this.tls, socket, err, data);
|
||||
} else {
|
||||
TLSSocket.onClose(this.tcp, socket, err, data);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn onData(
|
||||
this: WrappedSocket,
|
||||
socket: Socket,
|
||||
data: []const u8,
|
||||
) void {
|
||||
if (comptime tls) {
|
||||
TLSSocket.onData(this.tls, socket, data);
|
||||
} else {
|
||||
TLSSocket.onData(this.tcp, socket, data);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn onWritable(
|
||||
this: WrappedSocket,
|
||||
socket: Socket,
|
||||
) void {
|
||||
if (comptime tls) {
|
||||
TLSSocket.onWritable(this.tls, socket);
|
||||
} else {
|
||||
TLSSocket.onWritable(this.tcp, socket);
|
||||
}
|
||||
}
|
||||
pub fn onTimeout(
|
||||
this: WrappedSocket,
|
||||
socket: Socket,
|
||||
) void {
|
||||
if (comptime tls) {
|
||||
TLSSocket.onTimeout(this.tls, socket);
|
||||
} else {
|
||||
TLSSocket.onTimeout(this.tcp, socket);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn onConnectError(
|
||||
this: WrappedSocket,
|
||||
socket: Socket,
|
||||
errno: c_int,
|
||||
) void {
|
||||
if (comptime tls) {
|
||||
TLSSocket.onConnectError(this.tls, socket, errno);
|
||||
} else {
|
||||
TLSSocket.onConnectError(this.tcp, socket, errno);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -311,9 +311,9 @@ pub const FFI = struct {
|
||||
break :brk std.DynLib.open(backup_name) catch {
|
||||
// Then, if that fails, report an error.
|
||||
const system_error = JSC.SystemError{
|
||||
.code = ZigString.init(@tagName(JSC.Node.ErrorCode.ERR_DLOPEN_FAILED)),
|
||||
.message = ZigString.init("Failed to open library. This is usually caused by a missing library or an invalid library path."),
|
||||
.syscall = ZigString.init("dlopen"),
|
||||
.code = bun.String.create(@tagName(JSC.Node.ErrorCode.ERR_DLOPEN_FAILED)),
|
||||
.message = bun.String.create("Failed to open library. This is usually caused by a missing library or an invalid library path."),
|
||||
.syscall = bun.String.create("dlopen"),
|
||||
};
|
||||
return system_error.toErrorInstance(global);
|
||||
};
|
||||
|
||||
@@ -106,7 +106,7 @@ pub const HTMLRewriter = struct {
|
||||
|
||||
var selector = LOLHTML.HTMLSelector.parse(selector_slice) catch
|
||||
return throwLOLHTMLError(global);
|
||||
var handler_ = ElementHandler.init(global, listener, exception);
|
||||
var handler_ = ElementHandler.init(global, listener, exception) catch return .zero;
|
||||
if (exception.* != null) {
|
||||
selector.deinit();
|
||||
return JSValue.fromRef(exception.*);
|
||||
@@ -154,7 +154,7 @@ pub const HTMLRewriter = struct {
|
||||
thisObject: JSC.C.JSObjectRef,
|
||||
exception: JSC.C.ExceptionRef,
|
||||
) JSValue {
|
||||
var handler_ = DocumentHandler.init(global, listener, exception);
|
||||
var handler_ = DocumentHandler.init(global, listener, exception) catch return .zero;
|
||||
if (exception.* != null) {
|
||||
return JSValue.fromRef(exception.*);
|
||||
}
|
||||
@@ -446,10 +446,14 @@ pub const HTMLRewriter = struct {
|
||||
},
|
||||
};
|
||||
|
||||
result.body.init.headers = original.body.init.headers;
|
||||
result.body.init.method = original.body.init.method;
|
||||
result.body.init.status_code = original.body.init.status_code;
|
||||
|
||||
// https://github.com/oven-sh/bun/issues/3334
|
||||
if (original.body.init.headers) |headers| {
|
||||
result.body.init.headers = headers.cloneThis(global);
|
||||
}
|
||||
|
||||
result.url = bun.default_allocator.dupe(u8, original.url) catch unreachable;
|
||||
result.status_text = bun.default_allocator.dupe(u8, original.status_text) catch unreachable;
|
||||
|
||||
@@ -723,29 +727,44 @@ const DocumentHandler = struct {
|
||||
"onEndCallback",
|
||||
);
|
||||
|
||||
pub fn init(global: *JSGlobalObject, thisObject: JSValue, exception: JSC.C.ExceptionRef) DocumentHandler {
|
||||
pub fn init(global: *JSGlobalObject, thisObject: JSValue, exception: JSC.C.ExceptionRef) !DocumentHandler {
|
||||
var handler = DocumentHandler{
|
||||
.thisObject = thisObject,
|
||||
.global = global,
|
||||
};
|
||||
|
||||
switch (thisObject.jsType()) {
|
||||
.Object, .ProxyObject, .Cell, .FinalObject => {},
|
||||
else => |kind| {
|
||||
JSC.throwInvalidArguments(
|
||||
"Expected object but received {s}",
|
||||
.{@as(string, @tagName(kind))},
|
||||
global,
|
||||
exception,
|
||||
);
|
||||
return undefined;
|
||||
},
|
||||
if (!thisObject.isObject()) {
|
||||
JSC.throwInvalidArguments(
|
||||
"Expected object",
|
||||
.{},
|
||||
global,
|
||||
exception,
|
||||
);
|
||||
return error.InvalidArguments;
|
||||
}
|
||||
|
||||
errdefer {
|
||||
if (handler.onDocTypeCallback) |cb| {
|
||||
cb.unprotect();
|
||||
}
|
||||
|
||||
if (handler.onCommentCallback) |cb| {
|
||||
cb.unprotect();
|
||||
}
|
||||
|
||||
if (handler.onTextCallback) |cb| {
|
||||
cb.unprotect();
|
||||
}
|
||||
|
||||
if (handler.onEndCallback) |cb| {
|
||||
cb.unprotect();
|
||||
}
|
||||
}
|
||||
|
||||
if (thisObject.get(global, "doctype")) |val| {
|
||||
if (val.isUndefinedOrNull() or !val.isCell() or !val.isCallable(global.vm())) {
|
||||
JSC.throwInvalidArguments("doctype must be a function", .{}, global, exception);
|
||||
return undefined;
|
||||
return error.InvalidArguments;
|
||||
}
|
||||
JSC.C.JSValueProtect(global, val.asObjectRef());
|
||||
handler.onDocTypeCallback = val;
|
||||
@@ -754,7 +773,7 @@ const DocumentHandler = struct {
|
||||
if (thisObject.get(global, "comments")) |val| {
|
||||
if (val.isUndefinedOrNull() or !val.isCell() or !val.isCallable(global.vm())) {
|
||||
JSC.throwInvalidArguments("comments must be a function", .{}, global, exception);
|
||||
return undefined;
|
||||
return error.InvalidArguments;
|
||||
}
|
||||
JSC.C.JSValueProtect(global, val.asObjectRef());
|
||||
handler.onCommentCallback = val;
|
||||
@@ -763,7 +782,7 @@ const DocumentHandler = struct {
|
||||
if (thisObject.get(global, "text")) |val| {
|
||||
if (val.isUndefinedOrNull() or !val.isCell() or !val.isCallable(global.vm())) {
|
||||
JSC.throwInvalidArguments("text must be a function", .{}, global, exception);
|
||||
return undefined;
|
||||
return error.InvalidArguments;
|
||||
}
|
||||
JSC.C.JSValueProtect(global, val.asObjectRef());
|
||||
handler.onTextCallback = val;
|
||||
@@ -772,7 +791,7 @@ const DocumentHandler = struct {
|
||||
if (thisObject.get(global, "end")) |val| {
|
||||
if (val.isUndefinedOrNull() or !val.isCell() or !val.isCallable(global.vm())) {
|
||||
JSC.throwInvalidArguments("end must be a function", .{}, global, exception);
|
||||
return undefined;
|
||||
return error.InvalidArguments;
|
||||
}
|
||||
JSC.C.JSValueProtect(global, val.asObjectRef());
|
||||
handler.onEndCallback = val;
|
||||
@@ -863,29 +882,39 @@ const ElementHandler = struct {
|
||||
global: *JSGlobalObject,
|
||||
ctx: ?*HTMLRewriter.BufferOutputSink = null,
|
||||
|
||||
pub fn init(global: *JSGlobalObject, thisObject: JSValue, exception: JSC.C.ExceptionRef) ElementHandler {
|
||||
pub fn init(global: *JSGlobalObject, thisObject: JSValue, exception: JSC.C.ExceptionRef) !ElementHandler {
|
||||
var handler = ElementHandler{
|
||||
.thisObject = thisObject,
|
||||
.global = global,
|
||||
};
|
||||
errdefer {
|
||||
if (handler.onCommentCallback) |cb| {
|
||||
cb.unprotect();
|
||||
}
|
||||
|
||||
switch (thisObject.jsType()) {
|
||||
.Object, .ProxyObject, .Cell, .FinalObject => {},
|
||||
else => |kind| {
|
||||
JSC.throwInvalidArguments(
|
||||
"Expected object but received {s}",
|
||||
.{@as(string, @tagName(kind))},
|
||||
global,
|
||||
exception,
|
||||
);
|
||||
return undefined;
|
||||
},
|
||||
if (handler.onElementCallback) |cb| {
|
||||
cb.unprotect();
|
||||
}
|
||||
|
||||
if (handler.onTextCallback) |cb| {
|
||||
cb.unprotect();
|
||||
}
|
||||
}
|
||||
|
||||
if (!thisObject.isObject()) {
|
||||
JSC.throwInvalidArguments(
|
||||
"Expected object",
|
||||
.{},
|
||||
global,
|
||||
exception,
|
||||
);
|
||||
return error.InvalidArguments;
|
||||
}
|
||||
|
||||
if (thisObject.get(global, "element")) |val| {
|
||||
if (val.isUndefinedOrNull() or !val.isCell() or !val.isCallable(global.vm())) {
|
||||
JSC.throwInvalidArguments("element must be a function", .{}, global, exception);
|
||||
return undefined;
|
||||
return error.InvalidArguments;
|
||||
}
|
||||
JSC.C.JSValueProtect(global, val.asObjectRef());
|
||||
handler.onElementCallback = val;
|
||||
@@ -894,7 +923,7 @@ const ElementHandler = struct {
|
||||
if (thisObject.get(global, "comments")) |val| {
|
||||
if (val.isUndefinedOrNull() or !val.isCell() or !val.isCallable(global.vm())) {
|
||||
JSC.throwInvalidArguments("comments must be a function", .{}, global, exception);
|
||||
return undefined;
|
||||
return error.InvalidArguments;
|
||||
}
|
||||
JSC.C.JSValueProtect(global, val.asObjectRef());
|
||||
handler.onCommentCallback = val;
|
||||
@@ -903,7 +932,7 @@ const ElementHandler = struct {
|
||||
if (thisObject.get(global, "text")) |val| {
|
||||
if (val.isUndefinedOrNull() or !val.isCell() or !val.isCallable(global.vm())) {
|
||||
JSC.throwInvalidArguments("text must be a function", .{}, global, exception);
|
||||
return undefined;
|
||||
return error.InvalidArguments;
|
||||
}
|
||||
JSC.C.JSValueProtect(global, val.asObjectRef());
|
||||
handler.onTextCallback = val;
|
||||
@@ -967,26 +996,14 @@ const getterWrap = JSC.getterWrap;
|
||||
const setterWrap = JSC.setterWrap;
|
||||
const wrap = JSC.wrapSync;
|
||||
|
||||
pub fn free_html_writer_string(_: ?*anyopaque, ptr: ?*anyopaque, len: usize) callconv(.C) void {
|
||||
var str = LOLHTML.HTMLString{ .ptr = bun.cast([*]const u8, ptr.?), .len = len };
|
||||
str.deinit();
|
||||
}
|
||||
|
||||
fn throwLOLHTMLError(global: *JSGlobalObject) JSValue {
|
||||
var err = LOLHTML.HTMLString.lastError();
|
||||
return ZigString.init(err.slice()).toErrorInstance(global);
|
||||
const err = LOLHTML.HTMLString.lastError();
|
||||
defer err.deinit();
|
||||
return ZigString.fromUTF8(err.slice()).toErrorInstance(global);
|
||||
}
|
||||
|
||||
fn htmlStringValue(input: LOLHTML.HTMLString, globalObject: *JSGlobalObject) JSValue {
|
||||
var str = ZigString.init(
|
||||
input.slice(),
|
||||
);
|
||||
str.detectEncoding();
|
||||
|
||||
return str.toExternalValueWithCallback(
|
||||
globalObject,
|
||||
free_html_writer_string,
|
||||
);
|
||||
return input.toJS(globalObject);
|
||||
}
|
||||
|
||||
pub const TextChunk = struct {
|
||||
@@ -1016,6 +1033,9 @@ pub const TextChunk = struct {
|
||||
.removed = .{
|
||||
.get = getterWrap(TextChunk, "removed"),
|
||||
},
|
||||
.lastInTextNode = .{
|
||||
.get = getterWrap(TextChunk, "lastInTextNode"),
|
||||
},
|
||||
.text = .{
|
||||
.get = getterWrap(TextChunk, "getText"),
|
||||
},
|
||||
@@ -1084,6 +1104,10 @@ pub const TextChunk = struct {
|
||||
return JSC.JSValue.jsBoolean(this.text_chunk.?.isRemoved());
|
||||
}
|
||||
|
||||
pub fn lastInTextNode(this: *TextChunk, _: *JSGlobalObject) JSValue {
|
||||
return JSC.JSValue.jsBoolean(this.text_chunk.?.isLastInTextNode());
|
||||
}
|
||||
|
||||
pub fn finalize(this: *TextChunk) void {
|
||||
this.text_chunk = null;
|
||||
bun.default_allocator.destroy(this);
|
||||
@@ -1292,7 +1316,7 @@ pub const Comment = struct {
|
||||
pub fn getText(this: *Comment, global: *JSGlobalObject) JSValue {
|
||||
if (this.comment == null)
|
||||
return JSValue.jsNull();
|
||||
return ZigString.init(this.comment.?.getText().slice()).withEncoding().toValueGC(global);
|
||||
return this.comment.?.getText().toJS(global);
|
||||
}
|
||||
|
||||
pub fn setText(
|
||||
@@ -1422,7 +1446,7 @@ pub const EndTag = struct {
|
||||
if (this.end_tag == null)
|
||||
return JSC.JSValue.jsUndefined();
|
||||
|
||||
return ZigString.init(this.end_tag.?.getName().slice()).withEncoding().toValueGC(global);
|
||||
return this.end_tag.?.getName().toJS(global);
|
||||
}
|
||||
|
||||
pub fn setName(
|
||||
@@ -1534,27 +1558,16 @@ pub const AttributeIterator = struct {
|
||||
return JSC.JSValue.jsNull();
|
||||
};
|
||||
|
||||
// TODO: don't clone here
|
||||
const value = attribute.value();
|
||||
const name = attribute.name();
|
||||
defer name.deinit();
|
||||
defer value.deinit();
|
||||
|
||||
var strs = [2]ZigString{
|
||||
ZigString.init(name.slice()),
|
||||
ZigString.init(value.slice()),
|
||||
};
|
||||
|
||||
var valid_strs: []ZigString = strs[0..2];
|
||||
|
||||
var array = JSC.JSValue.createStringArray(
|
||||
return bun.String.toJSArray(
|
||||
globalObject,
|
||||
valid_strs.ptr,
|
||||
valid_strs.len,
|
||||
true,
|
||||
&[_]bun.String{
|
||||
name.toString(),
|
||||
value.toString(),
|
||||
},
|
||||
);
|
||||
|
||||
return array;
|
||||
}
|
||||
};
|
||||
pub const Element = struct {
|
||||
@@ -1660,19 +1673,12 @@ pub const Element = struct {
|
||||
|
||||
var slice = name.toSlice(bun.default_allocator);
|
||||
defer slice.deinit();
|
||||
var attr = this.element.?.getAttribute(slice.slice()).slice();
|
||||
var attr = this.element.?.getAttribute(slice.slice());
|
||||
|
||||
if (attr.len == 0)
|
||||
return JSC.JSValue.jsNull();
|
||||
|
||||
var str = ZigString.init(
|
||||
attr,
|
||||
);
|
||||
|
||||
return str.toExternalValueWithCallback(
|
||||
globalObject,
|
||||
free_html_writer_string,
|
||||
);
|
||||
return attr.toJS(globalObject);
|
||||
}
|
||||
|
||||
/// Returns a boolean indicating whether an attribute exists on the element.
|
||||
@@ -1847,8 +1853,9 @@ pub const Element = struct {
|
||||
pub fn getNamespaceURI(this: *Element, globalObject: *JSGlobalObject) JSValue {
|
||||
if (this.element == null)
|
||||
return JSValue.jsUndefined();
|
||||
|
||||
return ZigString.init(std.mem.span(this.element.?.namespaceURI())).toValueGC(globalObject);
|
||||
var str = bun.String.create(std.mem.span(this.element.?.namespaceURI()));
|
||||
defer str.deref();
|
||||
return str.toJS(globalObject);
|
||||
}
|
||||
|
||||
pub fn getAttributes(this: *Element, globalObject: *JSGlobalObject) JSValue {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -15,10 +15,17 @@ function generate(ssl) {
|
||||
authorized: {
|
||||
getter: "getAuthorized",
|
||||
},
|
||||
alpnProtocol: {
|
||||
getter: "getALPNProtocol",
|
||||
},
|
||||
write: {
|
||||
fn: "write",
|
||||
length: 3,
|
||||
},
|
||||
upgradeTLS: {
|
||||
fn: "upgradeTLS",
|
||||
length: 1,
|
||||
},
|
||||
end: {
|
||||
fn: "end",
|
||||
length: 3,
|
||||
@@ -82,6 +89,11 @@ function generate(ssl) {
|
||||
fn: "reload",
|
||||
length: 1,
|
||||
},
|
||||
|
||||
setServername: {
|
||||
fn: "setServername",
|
||||
length: 1,
|
||||
},
|
||||
},
|
||||
finalize: true,
|
||||
construct: true,
|
||||
|
||||
@@ -86,31 +86,69 @@ BunString toString(JSC::JSGlobalObject* globalObject, JSValue value)
|
||||
return fromJS(globalObject, value);
|
||||
}
|
||||
|
||||
BunString toStringRef(JSC::JSGlobalObject* globalObject, JSValue value)
|
||||
{
|
||||
auto str = value.toWTFString(globalObject);
|
||||
if (str.isEmpty()) {
|
||||
return { BunStringTag::Empty };
|
||||
}
|
||||
|
||||
str.impl()->ref();
|
||||
|
||||
return { BunStringTag::WTFStringImpl, { .wtf = str.impl() } };
|
||||
}
|
||||
|
||||
BunString toString(WTF::String& wtfString)
|
||||
{
|
||||
if (wtfString.length() == 0)
|
||||
if (wtfString.isEmpty())
|
||||
return { BunStringTag::Empty };
|
||||
|
||||
return { BunStringTag::WTFStringImpl, { .wtf = wtfString.impl() } };
|
||||
}
|
||||
BunString toString(const WTF::String& wtfString)
|
||||
{
|
||||
if (wtfString.length() == 0)
|
||||
if (wtfString.isEmpty())
|
||||
return { BunStringTag::Empty };
|
||||
|
||||
return { BunStringTag::WTFStringImpl, { .wtf = wtfString.impl() } };
|
||||
}
|
||||
BunString toString(WTF::StringImpl* wtfString)
|
||||
{
|
||||
if (wtfString->length() == 0)
|
||||
if (wtfString->isEmpty())
|
||||
return { BunStringTag::Empty };
|
||||
|
||||
return { BunStringTag::WTFStringImpl, { .wtf = wtfString } };
|
||||
}
|
||||
|
||||
BunString toStringRef(WTF::String& wtfString)
|
||||
{
|
||||
if (wtfString.isEmpty())
|
||||
return { BunStringTag::Empty };
|
||||
|
||||
wtfString.impl()->ref();
|
||||
return { BunStringTag::WTFStringImpl, { .wtf = wtfString.impl() } };
|
||||
}
|
||||
BunString toStringRef(const WTF::String& wtfString)
|
||||
{
|
||||
if (wtfString.isEmpty())
|
||||
return { BunStringTag::Empty };
|
||||
|
||||
wtfString.impl()->ref();
|
||||
return { BunStringTag::WTFStringImpl, { .wtf = wtfString.impl() } };
|
||||
}
|
||||
BunString toStringRef(WTF::StringImpl* wtfString)
|
||||
{
|
||||
if (wtfString->isEmpty())
|
||||
return { BunStringTag::Empty };
|
||||
|
||||
wtfString->ref();
|
||||
|
||||
return { BunStringTag::WTFStringImpl, { .wtf = wtfString } };
|
||||
}
|
||||
|
||||
BunString fromString(WTF::String& wtfString)
|
||||
{
|
||||
if (wtfString.length() == 0)
|
||||
if (wtfString.isEmpty())
|
||||
return { BunStringTag::Empty };
|
||||
|
||||
return { BunStringTag::WTFStringImpl, { .wtf = wtfString.impl() } };
|
||||
@@ -118,7 +156,7 @@ BunString fromString(WTF::String& wtfString)
|
||||
|
||||
BunString fromString(WTF::StringImpl* wtfString)
|
||||
{
|
||||
if (wtfString->length() == 0)
|
||||
if (wtfString->isEmpty())
|
||||
return { BunStringTag::Empty };
|
||||
|
||||
return { BunStringTag::WTFStringImpl, { .wtf = wtfString } };
|
||||
@@ -131,6 +169,29 @@ extern "C" JSC::EncodedJSValue BunString__toJS(JSC::JSGlobalObject* globalObject
|
||||
return JSValue::encode(Bun::toJS(globalObject, *bunString));
|
||||
}
|
||||
|
||||
extern "C" BunString BunString__fromUTF16Unitialized(size_t length)
|
||||
{
|
||||
unsigned utf16Length = length;
|
||||
UChar* ptr;
|
||||
auto impl = WTF::StringImpl::createUninitialized(utf16Length, ptr);
|
||||
if (UNLIKELY(!ptr))
|
||||
return { BunStringTag::Dead };
|
||||
|
||||
impl->ref();
|
||||
return { BunStringTag::WTFStringImpl, { .wtf = &impl.leakRef() } };
|
||||
}
|
||||
|
||||
extern "C" BunString BunString__fromLatin1Unitialized(size_t length)
|
||||
{
|
||||
unsigned latin1Length = length;
|
||||
LChar* ptr;
|
||||
auto impl = WTF::StringImpl::createUninitialized(latin1Length, ptr);
|
||||
if (UNLIKELY(!ptr))
|
||||
return { BunStringTag::Dead };
|
||||
impl->ref();
|
||||
return { BunStringTag::WTFStringImpl, { .wtf = &impl.leakRef() } };
|
||||
}
|
||||
|
||||
extern "C" BunString BunString__fromUTF8(const char* bytes, size_t length)
|
||||
{
|
||||
if (simdutf::validate_utf8(bytes, length)) {
|
||||
|
||||
@@ -295,6 +295,35 @@ JSC_DEFINE_CUSTOM_SETTER(setterPath,
|
||||
return true;
|
||||
}
|
||||
|
||||
extern "C" EncodedJSValue Resolver__propForRequireMainPaths(JSGlobalObject*);
|
||||
|
||||
JSC_DEFINE_CUSTOM_GETTER(getterPaths, (JSC::JSGlobalObject * globalObject, JSC::EncodedJSValue thisValue, JSC::PropertyName))
|
||||
{
|
||||
JSCommonJSModule* thisObject = jsDynamicCast<JSCommonJSModule*>(JSValue::decode(thisValue));
|
||||
if (UNLIKELY(!thisObject)) {
|
||||
return JSValue::encode(jsUndefined());
|
||||
}
|
||||
|
||||
if (!thisObject->m_paths) {
|
||||
JSValue paths = JSValue::decode(Resolver__propForRequireMainPaths(globalObject));
|
||||
thisObject->m_paths.set(globalObject->vm(), thisObject, paths);
|
||||
}
|
||||
|
||||
return JSValue::encode(thisObject->m_paths.get());
|
||||
}
|
||||
|
||||
JSC_DEFINE_CUSTOM_SETTER(setterPaths,
|
||||
(JSC::JSGlobalObject * globalObject, JSC::EncodedJSValue thisValue,
|
||||
JSC::EncodedJSValue value, JSC::PropertyName propertyName))
|
||||
{
|
||||
JSCommonJSModule* thisObject = jsDynamicCast<JSCommonJSModule*>(JSValue::decode(thisValue));
|
||||
if (!thisObject)
|
||||
return false;
|
||||
|
||||
thisObject->m_paths.set(globalObject->vm(), thisObject, JSValue::decode(value));
|
||||
return true;
|
||||
}
|
||||
|
||||
JSC_DEFINE_CUSTOM_SETTER(setterFilename,
|
||||
(JSC::JSGlobalObject * globalObject, JSC::EncodedJSValue thisValue,
|
||||
JSC::EncodedJSValue value, JSC::PropertyName propertyName))
|
||||
@@ -340,6 +369,7 @@ static const struct HashTableValue JSCommonJSModulePrototypeTableValues[] = {
|
||||
{ "loaded"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback | PropertyAttribute::DontEnum | 0), NoIntrinsic, { HashTableValue::LazyPropertyType, createLoaded } },
|
||||
{ "parent"_s, static_cast<unsigned>(PropertyAttribute::PropertyCallback | PropertyAttribute::DontEnum | 0), NoIntrinsic, { HashTableValue::LazyPropertyType, createParent } },
|
||||
{ "path"_s, static_cast<unsigned>(PropertyAttribute::CustomAccessor), NoIntrinsic, { HashTableValue::GetterSetterType, getterPath, setterPath } },
|
||||
{ "paths"_s, static_cast<unsigned>(PropertyAttribute::CustomAccessor), NoIntrinsic, { HashTableValue::GetterSetterType, getterPaths, setterPaths } },
|
||||
};
|
||||
|
||||
class JSCommonJSModulePrototype final : public JSC::JSNonFinalObject {
|
||||
@@ -556,13 +586,41 @@ void JSCommonJSModule::toSyntheticSource(JSC::JSGlobalObject* globalObject,
|
||||
auto result = this->exportsObject();
|
||||
|
||||
auto& vm = globalObject->vm();
|
||||
exportNames.append(vm.propertyNames->defaultKeyword);
|
||||
exportValues.append(result);
|
||||
|
||||
// This exists to tell ImportMetaObject.ts that this is a CommonJS module.
|
||||
exportNames.append(Identifier::fromUid(vm.symbolRegistry().symbolForKey("CommonJS"_s)));
|
||||
exportValues.append(jsNumber(0));
|
||||
|
||||
// Bun's intepretation of the "__esModule" annotation:
|
||||
//
|
||||
// - If a "default" export does not exist OR the __esModule annotation is not present, then we
|
||||
// set the default export to the exports object
|
||||
//
|
||||
// - If a "default" export also exists, then we set the default export
|
||||
// to the value of it (matching Babel behavior)
|
||||
//
|
||||
// https://stackoverflow.com/questions/50943704/whats-the-purpose-of-object-definepropertyexports-esmodule-value-0
|
||||
// https://github.com/nodejs/node/issues/40891
|
||||
// https://github.com/evanw/bundler-esm-cjs-tests
|
||||
// https://github.com/evanw/esbuild/issues/1591
|
||||
// https://github.com/oven-sh/bun/issues/3383
|
||||
//
|
||||
// Note that this interpretation is slightly different
|
||||
//
|
||||
// - We do not ignore when "type": "module" or when the file
|
||||
// extension is ".mjs". Build tools determine that based on the
|
||||
// caller's behavior, but in a JS runtime, there is only one ModuleNamespaceObject.
|
||||
//
|
||||
// It would be possible to match the behavior at runtime, but
|
||||
// it would need further engine changes which do not match the ES Module spec
|
||||
//
|
||||
// - We ignore the value of the annotation. We only look for the
|
||||
// existence of the value being set. This is for performance reasons, but also
|
||||
// this annotation is meant for tooling and the only usages of setting
|
||||
// it to something that does NOT evaluate to "true" I could find were in
|
||||
// unit tests of build tools. Happy to revisit this if users file an issue.
|
||||
bool needsToAssignDefault = true;
|
||||
|
||||
if (result.isObject()) {
|
||||
auto* exports = asObject(result);
|
||||
|
||||
@@ -571,21 +629,78 @@ void JSCommonJSModule::toSyntheticSource(JSC::JSGlobalObject* globalObject,
|
||||
exportNames.reserveCapacity(size + 2);
|
||||
exportValues.ensureCapacity(size + 2);
|
||||
|
||||
if (canPerformFastEnumeration(structure)) {
|
||||
auto catchScope = DECLARE_CATCH_SCOPE(vm);
|
||||
|
||||
Identifier esModuleMarker = builtinNames(vm).__esModulePublicName();
|
||||
bool hasESModuleMarker = !this->ignoreESModuleAnnotation && exports->hasProperty(globalObject, esModuleMarker);
|
||||
if (catchScope.exception()) {
|
||||
catchScope.clearException();
|
||||
}
|
||||
|
||||
if (hasESModuleMarker) {
|
||||
if (canPerformFastEnumeration(structure)) {
|
||||
exports->structure()->forEachProperty(vm, [&](const PropertyTableEntry& entry) -> bool {
|
||||
auto key = entry.key();
|
||||
if (key->isSymbol() || entry.attributes() & PropertyAttribute::DontEnum || key == esModuleMarker)
|
||||
return true;
|
||||
|
||||
needsToAssignDefault = needsToAssignDefault && key != vm.propertyNames->defaultKeyword;
|
||||
|
||||
JSValue value = exports->getDirect(entry.offset());
|
||||
exportNames.append(Identifier::fromUid(vm, key));
|
||||
exportValues.append(value);
|
||||
return true;
|
||||
});
|
||||
} else {
|
||||
JSC::PropertyNameArray properties(vm, JSC::PropertyNameMode::Strings, JSC::PrivateSymbolMode::Exclude);
|
||||
exports->methodTable()->getOwnPropertyNames(exports, globalObject, properties, DontEnumPropertiesMode::Exclude);
|
||||
if (catchScope.exception()) {
|
||||
catchScope.clearExceptionExceptTermination();
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto property : properties) {
|
||||
if (UNLIKELY(property.isEmpty() || property.isNull() || property == esModuleMarker || property.isPrivateName() || property.isSymbol()))
|
||||
continue;
|
||||
|
||||
// ignore constructor
|
||||
if (property == vm.propertyNames->constructor)
|
||||
continue;
|
||||
|
||||
JSC::PropertySlot slot(exports, PropertySlot::InternalMethodType::Get);
|
||||
if (!exports->getPropertySlot(globalObject, property, slot))
|
||||
continue;
|
||||
|
||||
exportNames.append(property);
|
||||
|
||||
JSValue getterResult = slot.getValue(globalObject, property);
|
||||
|
||||
// If it throws, we keep them in the exports list, but mark it as undefined
|
||||
// This is consistent with what Node.js does.
|
||||
if (catchScope.exception()) {
|
||||
catchScope.clearException();
|
||||
getterResult = jsUndefined();
|
||||
}
|
||||
|
||||
exportValues.append(getterResult);
|
||||
|
||||
needsToAssignDefault = needsToAssignDefault && property != vm.propertyNames->defaultKeyword;
|
||||
}
|
||||
}
|
||||
|
||||
} else if (canPerformFastEnumeration(structure)) {
|
||||
exports->structure()->forEachProperty(vm, [&](const PropertyTableEntry& entry) -> bool {
|
||||
auto key = entry.key();
|
||||
if (key->isSymbol() || key == vm.propertyNames->defaultKeyword || entry.attributes() & PropertyAttribute::DontEnum)
|
||||
if (key->isSymbol() || entry.attributes() & PropertyAttribute::DontEnum || key == vm.propertyNames->defaultKeyword)
|
||||
return true;
|
||||
|
||||
exportNames.append(Identifier::fromUid(vm, key));
|
||||
|
||||
JSValue value = exports->getDirect(entry.offset());
|
||||
|
||||
exportNames.append(Identifier::fromUid(vm, key));
|
||||
exportValues.append(value);
|
||||
return true;
|
||||
});
|
||||
} else {
|
||||
auto catchScope = DECLARE_CATCH_SCOPE(vm);
|
||||
JSC::PropertyNameArray properties(vm, JSC::PropertyNameMode::Strings, JSC::PrivateSymbolMode::Exclude);
|
||||
exports->methodTable()->getOwnPropertyNames(exports, globalObject, properties, DontEnumPropertiesMode::Exclude);
|
||||
if (catchScope.exception()) {
|
||||
@@ -594,11 +709,11 @@ void JSCommonJSModule::toSyntheticSource(JSC::JSGlobalObject* globalObject,
|
||||
}
|
||||
|
||||
for (auto property : properties) {
|
||||
if (UNLIKELY(property.isEmpty() || property.isNull() || property.isPrivateName() || property.isSymbol()))
|
||||
if (UNLIKELY(property.isEmpty() || property.isNull() || property == vm.propertyNames->defaultKeyword || property.isPrivateName() || property.isSymbol()))
|
||||
continue;
|
||||
|
||||
// ignore constructor
|
||||
if (property == vm.propertyNames->constructor || property == vm.propertyNames->defaultKeyword)
|
||||
if (property == vm.propertyNames->constructor)
|
||||
continue;
|
||||
|
||||
JSC::PropertySlot slot(exports, PropertySlot::InternalMethodType::Get);
|
||||
@@ -620,6 +735,11 @@ void JSCommonJSModule::toSyntheticSource(JSC::JSGlobalObject* globalObject,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (needsToAssignDefault) {
|
||||
exportNames.append(vm.propertyNames->defaultKeyword);
|
||||
exportValues.append(result);
|
||||
}
|
||||
}
|
||||
|
||||
JSValue JSCommonJSModule::exportsObject()
|
||||
@@ -675,6 +795,7 @@ void JSCommonJSModule::visitChildrenImpl(JSCell* cell, Visitor& visitor)
|
||||
visitor.append(thisObject->sourceCode);
|
||||
visitor.append(thisObject->m_filename);
|
||||
visitor.append(thisObject->m_dirname);
|
||||
visitor.append(thisObject->m_paths);
|
||||
}
|
||||
|
||||
DEFINE_VISIT_CHILDREN(JSCommonJSModule);
|
||||
@@ -696,6 +817,12 @@ JSC_DEFINE_HOST_FUNCTION(jsFunctionRequireCommonJS, (JSGlobalObject * lexicalGlo
|
||||
WTF::String specifier = specifierValue.toWTFString(globalObject);
|
||||
RETURN_IF_EXCEPTION(throwScope, {});
|
||||
|
||||
// Special-case for "process" to just return the process object directly.
|
||||
if (UNLIKELY(specifier == "process"_s || specifier == "node:process"_s)) {
|
||||
jsDynamicCast<JSCommonJSModule*>(callframe->argument(1))->putDirect(vm, builtinNames(vm).exportsPublicName(), globalObject->processObject(), 0);
|
||||
return JSValue::encode(globalObject->processObject());
|
||||
}
|
||||
|
||||
WTF::String referrer = thisObject->id().toWTFString(globalObject);
|
||||
RETURN_IF_EXCEPTION(throwScope, {});
|
||||
|
||||
@@ -728,6 +855,7 @@ bool JSCommonJSModule::evaluate(
|
||||
{
|
||||
auto& vm = globalObject->vm();
|
||||
auto sourceProvider = Zig::SourceProvider::create(jsCast<Zig::GlobalObject*>(globalObject), source, JSC::SourceProviderSourceType::Program);
|
||||
this->ignoreESModuleAnnotation = source.tag == ResolvedSourceTagPackageJSONTypeModule;
|
||||
JSC::SourceCode rawInputSource(
|
||||
WTFMove(sourceProvider));
|
||||
|
||||
@@ -735,6 +863,7 @@ bool JSCommonJSModule::evaluate(
|
||||
return true;
|
||||
|
||||
this->sourceCode.set(vm, this, JSC::JSSourceCode::create(vm, WTFMove(rawInputSource)));
|
||||
|
||||
WTF::NakedPtr<JSC::Exception> exception;
|
||||
|
||||
evaluateCommonJSModuleOnce(vm, globalObject, this, this->m_dirname.get(), this->m_filename.get(), exception);
|
||||
@@ -765,6 +894,7 @@ std::optional<JSC::SourceCode> createCommonJSModule(
|
||||
JSValue entry = globalObject->requireMap()->get(globalObject, specifierValue);
|
||||
|
||||
auto sourceProvider = Zig::SourceProvider::create(jsCast<Zig::GlobalObject*>(globalObject), source, JSC::SourceProviderSourceType::Program);
|
||||
bool ignoreESModuleAnnotation = source.tag == ResolvedSourceTagPackageJSONTypeModule;
|
||||
SourceOrigin sourceOrigin = sourceProvider->sourceOrigin();
|
||||
|
||||
if (entry) {
|
||||
@@ -796,6 +926,8 @@ std::optional<JSC::SourceCode> createCommonJSModule(
|
||||
globalObject->requireMap()->set(globalObject, requireMapKey, moduleObject);
|
||||
}
|
||||
|
||||
moduleObject->ignoreESModuleAnnotation = ignoreESModuleAnnotation;
|
||||
|
||||
return JSC::SourceCode(
|
||||
JSC::SyntheticSourceProvider::create(
|
||||
[](JSC::JSGlobalObject* lexicalGlobalObject,
|
||||
|
||||
@@ -24,7 +24,9 @@ public:
|
||||
mutable JSC::WriteBarrier<JSC::JSString> m_id;
|
||||
mutable JSC::WriteBarrier<JSC::JSString> m_filename;
|
||||
mutable JSC::WriteBarrier<JSC::JSString> m_dirname;
|
||||
mutable JSC::WriteBarrier<Unknown> m_paths;
|
||||
mutable JSC::WriteBarrier<JSC::JSSourceCode> sourceCode;
|
||||
bool ignoreESModuleAnnotation { false };
|
||||
|
||||
static void destroy(JSC::JSCell*);
|
||||
~JSCommonJSModule();
|
||||
|
||||
@@ -19,7 +19,7 @@ using namespace WebCore;
|
||||
|
||||
namespace Zig {
|
||||
|
||||
JSCStackTrace JSCStackTrace::fromExisting(JSC::VM& vm, const WTF::Vector<JSC::StackFrame>& existingFrames)
|
||||
JSCStackTrace JSCStackTrace::fromExisting(JSC::VM& vm, const WTF::Vector<JSC::StackFrame>& existingFrames, int skipCount)
|
||||
{
|
||||
WTF::Vector<JSCStackFrame> newFrames;
|
||||
|
||||
@@ -29,7 +29,7 @@ JSCStackTrace JSCStackTrace::fromExisting(JSC::VM& vm, const WTF::Vector<JSC::St
|
||||
}
|
||||
|
||||
newFrames.reserveInitialCapacity(frameCount);
|
||||
for (size_t i = 0; i < frameCount; i++) {
|
||||
for (size_t i = skipCount; i < frameCount; i++) {
|
||||
newFrames.constructAndAppend(vm, existingFrames.at(i));
|
||||
}
|
||||
|
||||
|
||||
@@ -139,7 +139,7 @@ public:
|
||||
bool isEmpty() const { return m_frames.isEmpty(); }
|
||||
JSCStackFrame& at(size_t i) { return m_frames.at(i); }
|
||||
|
||||
static JSCStackTrace fromExisting(JSC::VM& vm, const WTF::Vector<JSC::StackFrame>& existingFrames);
|
||||
static JSCStackTrace fromExisting(JSC::VM& vm, const WTF::Vector<JSC::StackFrame>& existingFrames, int skipCount = 0);
|
||||
|
||||
/* This is based on JSC::Interpreter::getStackTrace, but skips native (non js and not wasm)
|
||||
* frames, which is what v8 does. Note that we could have just called JSC::Interpreter::getStackTrace
|
||||
|
||||
@@ -59,6 +59,7 @@ static EncodedJSValue functionRequireResolve(JSC::JSGlobalObject* globalObject,
|
||||
return JSC::JSValue::encode(JSC::JSValue {});
|
||||
}
|
||||
default: {
|
||||
JSValue thisValue = callFrame->thisValue();
|
||||
JSC::JSValue moduleName = callFrame->argument(0);
|
||||
|
||||
auto doIt = [&](const WTF::String& fromStr) -> JSC::EncodedJSValue {
|
||||
@@ -130,7 +131,14 @@ Zig::ImportMetaObject* Zig::ImportMetaObject::create(JSC::JSGlobalObject* global
|
||||
JSC_DECLARE_HOST_FUNCTION(jsFunctionRequireResolve);
|
||||
JSC_DEFINE_HOST_FUNCTION(jsFunctionRequireResolve, (JSC::JSGlobalObject * globalObject, JSC::CallFrame* callFrame))
|
||||
{
|
||||
return functionRequireResolve(globalObject, callFrame, callFrame->thisValue().toWTFString(globalObject));
|
||||
JSValue thisValue = callFrame->thisValue();
|
||||
WTF::String fromStr;
|
||||
|
||||
if (thisValue.isString()) {
|
||||
fromStr = thisValue.toWTFString(globalObject);
|
||||
}
|
||||
|
||||
return functionRequireResolve(globalObject, callFrame, fromStr);
|
||||
}
|
||||
|
||||
JSC_DEFINE_CUSTOM_GETTER(jsRequireCacheGetter, (JSC::JSGlobalObject * globalObject, JSC::EncodedJSValue thisValue, JSC::PropertyName))
|
||||
@@ -224,32 +232,49 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
Structure* Zig::ImportMetaObject::createRequireFunctionStructure(VM& vm, JSGlobalObject* globalObject)
|
||||
JSObject* Zig::ImportMetaObject::createRequireResolveFunctionUnbound(VM& vm, JSGlobalObject* globalObject)
|
||||
{
|
||||
|
||||
return nullptr;
|
||||
return ResolveFunction::create(globalObject);
|
||||
}
|
||||
|
||||
JSObject* Zig::ImportMetaObject::createRequireFunction(VM& vm, JSGlobalObject* lexicalGlobalObject, const WTF::String& pathString)
|
||||
JSObject* Zig::ImportMetaObject::createRequireFunctionUnbound(VM& vm, JSGlobalObject* globalObject)
|
||||
{
|
||||
auto* globalObject = lexicalGlobalObject;
|
||||
JSFunction* requireFunction = JSFunction::create(vm, importMetaObjectRequireCodeGenerator(vm), lexicalGlobalObject);
|
||||
auto& builtinNames = WebCore::builtinNames(vm);
|
||||
|
||||
JSC::JSFunction* requireDotMainFunction = JSFunction::create(
|
||||
vm,
|
||||
moduleMainCodeGenerator(vm),
|
||||
globalObject->globalScope());
|
||||
|
||||
requireFunction->putDirect(
|
||||
auto* prototype = JSC::constructEmptyObject(globalObject, globalObject->functionPrototype());
|
||||
prototype->putDirect(
|
||||
vm,
|
||||
JSC::Identifier::fromString(vm, "main"_s),
|
||||
JSC::GetterSetter::create(vm, globalObject, requireDotMainFunction, JSValue()),
|
||||
PropertyAttribute::Builtin | PropertyAttribute::Accessor | PropertyAttribute::ReadOnly | 0);
|
||||
prototype->putDirect(vm, JSC::Identifier::fromString(vm, "extensions"_s), constructEmptyObject(globalObject), 0);
|
||||
prototype->putDirectCustomAccessor(vm, JSC::Identifier::fromString(vm, "cache"_s), JSC::CustomGetterSetter::create(vm, Zig::jsRequireCacheGetter, Zig::jsRequireCacheSetter), 0);
|
||||
return JSFunction::create(vm, importMetaObjectRequireCodeGenerator(vm), globalObject, JSFunction::createStructure(vm, globalObject, prototype));
|
||||
}
|
||||
|
||||
requireFunction->putDirect(vm, JSC::Identifier::fromString(vm, "extensions"_s), JSC::constructEmptyObject(globalObject), 0);
|
||||
requireFunction->putDirectCustomAccessor(vm, JSC::Identifier::fromString(vm, "cache"_s), JSC::CustomGetterSetter::create(vm, Zig::jsRequireCacheGetter, Zig::jsRequireCacheSetter), 0);
|
||||
requireFunction->putDirect(vm, JSC::Identifier::fromString(vm, "resolve"_s), ResolveFunction::create(globalObject), JSC::PropertyAttribute::Function | 0);
|
||||
requireFunction->putDirect(vm, JSC::Identifier::fromString(vm, "path"_s), jsString(vm, pathString));
|
||||
JSObject* Zig::ImportMetaObject::createRequireFunction(VM& vm, JSGlobalObject* lexicalGlobalObject, const WTF::String& pathString)
|
||||
{
|
||||
auto* globalObject = jsCast<Zig::GlobalObject*>(lexicalGlobalObject);
|
||||
auto& builtinNames = WebCore::builtinNames(vm);
|
||||
|
||||
JSFunction* resolveFunctionUnbound = jsCast<JSFunction*>(globalObject->importMetaRequireResolveFunctionUnbound());
|
||||
JSFunction* requireFunctionUnbound = jsCast<JSFunction*>(globalObject->importMetaRequireFunctionUnbound());
|
||||
auto str = jsString(vm, pathString);
|
||||
|
||||
JSFunction* requireFunction = JSC::JSBoundFunction::create(vm,
|
||||
globalObject, requireFunctionUnbound,
|
||||
str, ArgList(), 1, jsString(vm, String("require"_s)));
|
||||
|
||||
JSFunction* resolveFunction = JSC::JSBoundFunction::create(vm,
|
||||
globalObject, resolveFunctionUnbound,
|
||||
str, ArgList(), 2, jsString(vm, String("resolve"_s)));
|
||||
|
||||
requireFunction->putDirect(vm, builtinNames.resolvePublicName(), resolveFunction, PropertyAttribute::Function | 0);
|
||||
|
||||
return requireFunction;
|
||||
}
|
||||
@@ -262,84 +287,107 @@ extern "C" EncodedJSValue functionImportMeta__resolveSync(JSC::JSGlobalObject* g
|
||||
JSC::VM& vm = globalObject->vm();
|
||||
auto scope = DECLARE_THROW_SCOPE(globalObject->vm());
|
||||
|
||||
switch (callFrame->argumentCount()) {
|
||||
case 0: {
|
||||
JSValue thisValue = callFrame->thisValue();
|
||||
JSC::JSValue moduleName = callFrame->argument(0);
|
||||
JSC::JSValue fromValue = callFrame->argument(1);
|
||||
|
||||
// not "requires" because "require" could be confusing
|
||||
JSC::throwTypeError(globalObject, scope, "needs 1 argument (a string)"_s);
|
||||
if (moduleName.isUndefinedOrNull()) {
|
||||
JSC::throwTypeError(globalObject, scope, "expects a string"_s);
|
||||
scope.release();
|
||||
return JSC::JSValue::encode(JSC::JSValue {});
|
||||
}
|
||||
default: {
|
||||
JSC::JSValue moduleName = callFrame->argument(0);
|
||||
|
||||
if (moduleName.isUndefinedOrNull()) {
|
||||
JSC::throwTypeError(globalObject, scope, "expects a string"_s);
|
||||
scope.release();
|
||||
return JSC::JSValue::encode(JSC::JSValue {});
|
||||
}
|
||||
JSC__JSValue from;
|
||||
bool isESM = true;
|
||||
|
||||
JSC__JSValue from;
|
||||
bool isESM = true;
|
||||
if (callFrame->argumentCount() > 1) {
|
||||
|
||||
if (callFrame->argumentCount() > 1) {
|
||||
JSC::JSValue fromValue = callFrame->argument(1);
|
||||
|
||||
if (callFrame->argumentCount() > 2) {
|
||||
JSC::JSValue isESMValue = callFrame->argument(2);
|
||||
if (isESMValue.isBoolean()) {
|
||||
isESM = isESMValue.toBoolean(globalObject);
|
||||
RETURN_IF_EXCEPTION(scope, JSC::JSValue::encode(JSC::JSValue {}));
|
||||
}
|
||||
}
|
||||
|
||||
if (!fromValue.isUndefinedOrNull() && fromValue.isObject()) {
|
||||
|
||||
if (auto pathsObject = fromValue.getObject()->getIfPropertyExists(globalObject, JSC::Identifier::fromString(vm, "paths"_s))) {
|
||||
if (pathsObject.isCell() && pathsObject.asCell()->type() == JSC::JSType::ArrayType) {
|
||||
auto pathsArray = JSC::jsCast<JSC::JSArray*>(pathsObject);
|
||||
if (pathsArray->length() > 0) {
|
||||
fromValue = pathsArray->getIndex(globalObject, 0);
|
||||
RETURN_IF_EXCEPTION(scope, JSC::JSValue::encode(JSC::JSValue {}));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else if (fromValue.isBoolean()) {
|
||||
isESM = fromValue.toBoolean(globalObject);
|
||||
if (callFrame->argumentCount() > 2) {
|
||||
JSC::JSValue isESMValue = callFrame->argument(2);
|
||||
if (isESMValue.isBoolean()) {
|
||||
isESM = isESMValue.toBoolean(globalObject);
|
||||
RETURN_IF_EXCEPTION(scope, JSC::JSValue::encode(JSC::JSValue {}));
|
||||
}
|
||||
|
||||
if (fromValue.isString()) {
|
||||
from = JSC::JSValue::encode(fromValue);
|
||||
}
|
||||
|
||||
} else {
|
||||
JSC::JSObject* thisObject = JSC::jsDynamicCast<JSC::JSObject*>(callFrame->thisValue());
|
||||
if (UNLIKELY(!thisObject)) {
|
||||
auto scope = DECLARE_THROW_SCOPE(globalObject->vm());
|
||||
JSC::throwTypeError(globalObject, scope, "import.meta.resolveSync must be bound to an import.meta object"_s);
|
||||
return JSC::JSValue::encode(JSC::JSValue {});
|
||||
}
|
||||
|
||||
auto clientData = WebCore::clientData(vm);
|
||||
JSValue pathProperty = thisObject->getIfPropertyExists(globalObject, clientData->builtinNames().pathPublicName());
|
||||
|
||||
if (pathProperty && pathProperty.isString())
|
||||
from = JSC::JSValue::encode(pathProperty);
|
||||
}
|
||||
|
||||
auto result = Bun__resolveSync(globalObject, JSC::JSValue::encode(moduleName), from, isESM);
|
||||
if (!fromValue.isUndefinedOrNull() && fromValue.isObject()) {
|
||||
|
||||
if (!JSC::JSValue::decode(result).isString()) {
|
||||
JSC::throwException(globalObject, scope, JSC::JSValue::decode(result));
|
||||
if (auto pathsObject = fromValue.getObject()->getIfPropertyExists(globalObject, JSC::Identifier::fromString(vm, "paths"_s))) {
|
||||
if (pathsObject.isCell() && pathsObject.asCell()->type() == JSC::JSType::ArrayType) {
|
||||
auto pathsArray = JSC::jsCast<JSC::JSArray*>(pathsObject);
|
||||
if (pathsArray->length() > 0) {
|
||||
fromValue = pathsArray->getIndex(globalObject, 0);
|
||||
RETURN_IF_EXCEPTION(scope, JSC::JSValue::encode(JSC::JSValue {}));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else if (fromValue.isBoolean()) {
|
||||
isESM = fromValue.toBoolean(globalObject);
|
||||
RETURN_IF_EXCEPTION(scope, JSC::JSValue::encode(JSC::JSValue {}));
|
||||
fromValue = JSC::jsUndefined();
|
||||
}
|
||||
|
||||
if (fromValue.isString()) {
|
||||
from = JSC::JSValue::encode(fromValue);
|
||||
} else if (thisValue.isString()) {
|
||||
from = JSC::JSValue::encode(thisValue);
|
||||
}
|
||||
|
||||
} else if (thisValue.isString()) {
|
||||
from = JSC::JSValue::encode(thisValue);
|
||||
} else {
|
||||
JSC::JSObject* thisObject = JSC::jsDynamicCast<JSC::JSObject*>(thisValue);
|
||||
if (UNLIKELY(!thisObject)) {
|
||||
auto scope = DECLARE_THROW_SCOPE(globalObject->vm());
|
||||
JSC::throwTypeError(globalObject, scope, "import.meta.resolveSync must be bound to an import.meta object"_s);
|
||||
return JSC::JSValue::encode(JSC::JSValue {});
|
||||
}
|
||||
|
||||
auto clientData = WebCore::clientData(vm);
|
||||
JSValue pathProperty = thisObject->getIfPropertyExists(globalObject, clientData->builtinNames().pathPublicName());
|
||||
|
||||
if (pathProperty && pathProperty.isString())
|
||||
from = JSC::JSValue::encode(pathProperty);
|
||||
}
|
||||
|
||||
auto result = Bun__resolveSync(globalObject, JSC::JSValue::encode(moduleName), from, isESM);
|
||||
|
||||
if (!JSC::JSValue::decode(result).isString()) {
|
||||
JSC::throwException(globalObject, scope, JSC::JSValue::decode(result));
|
||||
return JSC::JSValue::encode(JSC::JSValue {});
|
||||
}
|
||||
|
||||
scope.release();
|
||||
return result;
|
||||
}
|
||||
|
||||
extern "C" EncodedJSValue functionImportMeta__resolveSyncPrivate(JSC::JSGlobalObject* globalObject, JSC::CallFrame* callFrame)
|
||||
{
|
||||
JSC::VM& vm = globalObject->vm();
|
||||
auto scope = DECLARE_THROW_SCOPE(globalObject->vm());
|
||||
|
||||
JSC::JSValue moduleName = callFrame->argument(0);
|
||||
JSValue from = callFrame->argument(1);
|
||||
bool isESM = callFrame->argument(2).asBoolean();
|
||||
|
||||
if (moduleName.isUndefinedOrNull()) {
|
||||
JSC::throwTypeError(globalObject, scope, "expected module name as a string"_s);
|
||||
scope.release();
|
||||
return result;
|
||||
return JSC::JSValue::encode(JSC::JSValue {});
|
||||
}
|
||||
|
||||
RETURN_IF_EXCEPTION(scope, JSC::JSValue::encode(JSC::JSValue {}));
|
||||
|
||||
auto result = Bun__resolveSync(globalObject, JSC::JSValue::encode(moduleName), JSValue::encode(from), isESM);
|
||||
|
||||
if (!JSC::JSValue::decode(result).isString()) {
|
||||
JSC::throwException(globalObject, scope, JSC::JSValue::decode(result));
|
||||
return JSC::JSValue::encode(JSC::JSValue {});
|
||||
}
|
||||
|
||||
scope.release();
|
||||
return result;
|
||||
}
|
||||
|
||||
JSC_DECLARE_HOST_FUNCTION(functionImportMeta__resolve);
|
||||
@@ -536,7 +584,16 @@ void ImportMetaObject::finishCreation(VM& vm)
|
||||
|
||||
this->requireProperty.initLater([](const JSC::LazyProperty<JSC::JSObject, JSC::JSFunction>::Initializer& init) {
|
||||
ImportMetaObject* meta = jsCast<ImportMetaObject*>(init.owner);
|
||||
JSFunction* value = jsCast<JSFunction*>(ImportMetaObject::createRequireFunction(init.vm, meta->globalObject(), meta->url));
|
||||
|
||||
WTF::URL url = meta->url.startsWith('/') ? WTF::URL::fileURLWithFileSystemPath(meta->url) : WTF::URL(meta->url);
|
||||
WTF::StringView path;
|
||||
if (url.protocolIs("file"_s)) {
|
||||
path = url.fileSystemPath();
|
||||
} else {
|
||||
path = url.path();
|
||||
}
|
||||
|
||||
JSFunction* value = jsCast<JSFunction*>(ImportMetaObject::createRequireFunction(init.vm, meta->globalObject(), path.toString()));
|
||||
init.set(value);
|
||||
});
|
||||
this->urlProperty.initLater([](const JSC::LazyProperty<JSC::JSObject, JSC::JSString>::Initializer& init) {
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "JSDOMWrapperCache.h"
|
||||
|
||||
extern "C" JSC_DECLARE_HOST_FUNCTION(functionImportMeta__resolveSync);
|
||||
extern "C" JSC_DECLARE_HOST_FUNCTION(functionImportMeta__resolveSyncPrivate);
|
||||
extern "C" JSC::EncodedJSValue Bun__resolve(JSC::JSGlobalObject* global, JSC::EncodedJSValue specifier, JSC::EncodedJSValue from, bool is_esm);
|
||||
extern "C" JSC::EncodedJSValue Bun__resolveSync(JSC::JSGlobalObject* global, JSC::EncodedJSValue specifier, JSC::EncodedJSValue from, bool is_esm);
|
||||
extern "C" JSC::EncodedJSValue Bun__resolveSyncWithSource(JSC::JSGlobalObject* global, JSC::EncodedJSValue specifier, BunString* from, bool is_esm);
|
||||
@@ -27,7 +28,8 @@ public:
|
||||
|
||||
static ImportMetaObject* create(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::Structure* structure, const WTF::String& url);
|
||||
|
||||
static JSC::Structure* createRequireFunctionStructure(JSC::VM& vm, JSGlobalObject* globalObject);
|
||||
static JSC::JSObject* createRequireFunctionUnbound(JSC::VM& vm, JSGlobalObject* globalObject);
|
||||
static JSC::JSObject* createRequireResolveFunctionUnbound(JSC::VM& vm, JSGlobalObject* globalObject);
|
||||
static JSObject* createRequireFunction(VM& vm, JSGlobalObject* lexicalGlobalObject, const WTF::String& pathString);
|
||||
|
||||
static ImportMetaObject* create(JSC::JSGlobalObject* globalObject, JSC::JSString* keyString);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user