mirror of
https://github.com/oven-sh/bun
synced 2026-02-07 17:38:46 +00:00
Compare commits
99 Commits
jarred/sta
...
more-platf
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2868b310f6 | ||
|
|
acefcf130c | ||
|
|
3398c5c816 | ||
|
|
812180d591 | ||
|
|
7996d06b8f | ||
|
|
a234e067a5 | ||
|
|
c20901fd4e | ||
|
|
0d5eb73db0 | ||
|
|
87c3b2f8d3 | ||
|
|
1ce2d0e9f5 | ||
|
|
c41ff9da93 | ||
|
|
b0b38b42ba | ||
|
|
62da730060 | ||
|
|
c071415664 | ||
|
|
fc85a2dc92 | ||
|
|
c5b1c9e302 | ||
|
|
65a6803093 | ||
|
|
6ca68cab65 | ||
|
|
6645eafa08 | ||
|
|
29e1ba044d | ||
|
|
fd15e22d64 | ||
|
|
b2cb3603e2 | ||
|
|
a15244a4c9 | ||
|
|
a01f9d8e1b | ||
|
|
3ab3dec34d | ||
|
|
794e416642 | ||
|
|
7885742345 | ||
|
|
7063116c61 | ||
|
|
4a5ec261ef | ||
|
|
e3f4c9fd0b | ||
|
|
f307d2a6ef | ||
|
|
adc86c773b | ||
|
|
15427134e1 | ||
|
|
808e58cc4d | ||
|
|
a375ea94ef | ||
|
|
39b1c0111e | ||
|
|
eda608d629 | ||
|
|
9446fd60c9 | ||
|
|
8e5255d753 | ||
|
|
13ca4544f2 | ||
|
|
4d4dd1c180 | ||
|
|
dd6554294e | ||
|
|
50ed09654f | ||
|
|
0a54c24bd3 | ||
|
|
b39f49a5b9 | ||
|
|
e8fec640d8 | ||
|
|
25abe67d43 | ||
|
|
5f135a21b3 | ||
|
|
b88ed18245 | ||
|
|
f374ae6db1 | ||
|
|
94a656bc4f | ||
|
|
54e177e2f9 | ||
|
|
39342e34b1 | ||
|
|
e1cd7e510e | ||
|
|
54a225953b | ||
|
|
419229d950 | ||
|
|
b8a2a11c6f | ||
|
|
25083a4252 | ||
|
|
87424390e1 | ||
|
|
92e66691fa | ||
|
|
edebd6faa3 | ||
|
|
531d78aa97 | ||
|
|
e831bbf4ca | ||
|
|
9870314ff6 | ||
|
|
e44d10cf17 | ||
|
|
db0750e90c | ||
|
|
98e09efd02 | ||
|
|
944f342072 | ||
|
|
16917f7922 | ||
|
|
27a157b6c1 | ||
|
|
07fd814629 | ||
|
|
e348fef1c6 | ||
|
|
68b910cbd9 | ||
|
|
e2f20d794f | ||
|
|
faa524bf67 | ||
|
|
016ebf7b9b | ||
|
|
2f7ff95e5c | ||
|
|
857a472033 | ||
|
|
7720d23da1 | ||
|
|
ecc3e5e187 | ||
|
|
dcaaeecfa3 | ||
|
|
9ab51983b8 | ||
|
|
af82a446df | ||
|
|
dd12715071 | ||
|
|
514d37b3d2 | ||
|
|
d09df1af47 | ||
|
|
05afe42f31 | ||
|
|
123b5219e0 | ||
|
|
7113206a7d | ||
|
|
89fc3ef34d | ||
|
|
392a58b0ed | ||
|
|
02fb802b25 | ||
|
|
69d33bb1d0 | ||
|
|
4e51f7d85b | ||
|
|
5e97fb8d97 | ||
|
|
d42c032eec | ||
|
|
afe974a175 | ||
|
|
274e5a2022 | ||
|
|
18822b9f45 |
1268
.buildkite/ci.yml
1268
.buildkite/ci.yml
File diff suppressed because it is too large
Load Diff
@@ -11,8 +11,8 @@ body:
|
||||
- type: textarea
|
||||
id: package_json
|
||||
attributes:
|
||||
label: `package.json` file
|
||||
description: Can you upload your `package.json` file? This helps us reproduce the crash.
|
||||
label: "`package.json` file"
|
||||
description: "Can you upload your `package.json` file? This helps us reproduce the crash."
|
||||
render: json
|
||||
- type: textarea
|
||||
id: repro
|
||||
|
||||
22
.github/workflows/clang-format.yml
vendored
22
.github/workflows/clang-format.yml
vendored
@@ -7,18 +7,6 @@ on:
|
||||
workflow_call:
|
||||
workflow_dispatch:
|
||||
pull_request:
|
||||
paths:
|
||||
- ".github/workflows/clang-format.yml"
|
||||
- ".clang-format"
|
||||
- "package.json"
|
||||
- "scripts/**"
|
||||
- "cmake/**"
|
||||
- "src/**/*.c"
|
||||
- "src/**/*.cpp"
|
||||
- "src/**/*.h"
|
||||
- "packages/**/*.c"
|
||||
- "packages/**/*.cpp"
|
||||
- "packages/**/*.h"
|
||||
|
||||
env:
|
||||
BUN_VERSION: "1.1.27"
|
||||
@@ -33,14 +21,7 @@ jobs:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
sparse-checkout: |
|
||||
.github
|
||||
.clang-format
|
||||
package.json
|
||||
scripts
|
||||
cmake
|
||||
src
|
||||
packages
|
||||
fetch-depth: 0
|
||||
- name: Setup Bun
|
||||
uses: ./.github/actions/setup-bun
|
||||
with:
|
||||
@@ -50,7 +31,6 @@ jobs:
|
||||
curl -fsSL https://apt.llvm.org/llvm.sh | sudo bash -s -- ${{ env.LLVM_VERSION_MAJOR }} all
|
||||
- name: Clang Format
|
||||
env:
|
||||
ENABLE_CCACHE: OFF
|
||||
LLVM_VERSION: ${{ env.LLVM_VERSION }}
|
||||
run: |
|
||||
bun run clang-format:diff
|
||||
|
||||
22
.github/workflows/clang-tidy.yml
vendored
22
.github/workflows/clang-tidy.yml
vendored
@@ -7,18 +7,6 @@ on:
|
||||
workflow_call:
|
||||
workflow_dispatch:
|
||||
pull_request:
|
||||
paths:
|
||||
- ".github/workflows/clang-tidy.yml"
|
||||
- ".clang-tidy"
|
||||
- "package.json"
|
||||
- "scripts/**"
|
||||
- "cmake/**"
|
||||
- "src/**/*.c"
|
||||
- "src/**/*.cpp"
|
||||
- "src/**/*.h"
|
||||
- "packages/**/*.c"
|
||||
- "packages/**/*.cpp"
|
||||
- "packages/**/*.h"
|
||||
|
||||
env:
|
||||
BUN_VERSION: "1.1.27"
|
||||
@@ -33,14 +21,7 @@ jobs:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
sparse-checkout: |
|
||||
.github
|
||||
.clang-tidy
|
||||
package.json
|
||||
scripts
|
||||
cmake
|
||||
src
|
||||
packages
|
||||
fetch-depth: 0
|
||||
- name: Setup Bun
|
||||
uses: ./.github/actions/setup-bun
|
||||
with:
|
||||
@@ -50,7 +31,6 @@ jobs:
|
||||
curl -fsSL https://apt.llvm.org/llvm.sh | sudo bash -s -- ${{ env.LLVM_VERSION_MAJOR }} all
|
||||
- name: Clang Tidy
|
||||
env:
|
||||
ENABLE_CCACHE: OFF
|
||||
LLVM_VERSION: ${{ env.LLVM_VERSION }}
|
||||
run: |
|
||||
bun run clang-tidy:diff
|
||||
|
||||
30
.github/workflows/lint-cpp.yml
vendored
30
.github/workflows/lint-cpp.yml
vendored
@@ -1,30 +0,0 @@
|
||||
name: lint-cpp
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event_name == 'workflow_dispatch' && inputs.run-id || github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
run-id:
|
||||
type: string
|
||||
description: The workflow ID to download artifacts (skips the build step)
|
||||
# pull_request:
|
||||
# paths:
|
||||
# - ".github/workflows/lint-cpp.yml"
|
||||
# - "**/*.cpp"
|
||||
# - "vendor/**/*"
|
||||
# - "CMakeLists.txt"
|
||||
|
||||
jobs:
|
||||
lint-cpp:
|
||||
if: ${{ !inputs.run-id }}
|
||||
name: Lint C++
|
||||
uses: ./.github/workflows/run-lint-cpp.yml
|
||||
secrets: inherit
|
||||
with:
|
||||
pr-number: ${{ github.event.number }}
|
||||
17
.github/workflows/prettier-format.yml
vendored
17
.github/workflows/prettier-format.yml
vendored
@@ -7,18 +7,6 @@ on:
|
||||
workflow_call:
|
||||
workflow_dispatch:
|
||||
pull_request:
|
||||
paths:
|
||||
- ".github/workflows/prettier-format.yml"
|
||||
- "package.json"
|
||||
- "scripts/**"
|
||||
- "**.yml"
|
||||
- "**.json"
|
||||
- "**.js"
|
||||
- "**.jsx"
|
||||
- "**.ts"
|
||||
- "**.tsx"
|
||||
- "**.mjs"
|
||||
- "**.cjs"
|
||||
|
||||
env:
|
||||
BUN_VERSION: "1.1.27"
|
||||
@@ -30,6 +18,8 @@ jobs:
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Setup Bun
|
||||
uses: ./.github/actions/setup-bun
|
||||
with:
|
||||
@@ -38,9 +28,6 @@ jobs:
|
||||
run: |
|
||||
bun install
|
||||
- name: Prettier Format
|
||||
env:
|
||||
ENABLE_CCACHE: OFF
|
||||
SKIP_LLVM: ON
|
||||
run: |
|
||||
bun run prettier:diff
|
||||
- name: Commit
|
||||
|
||||
84
.github/workflows/run-lint-cpp.yml
vendored
84
.github/workflows/run-lint-cpp.yml
vendored
@@ -1,84 +0,0 @@
|
||||
name: lint-cpp
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
env:
|
||||
LLVM_VERSION: 18
|
||||
LC_CTYPE: "en_US.UTF-8"
|
||||
LC_ALL: "en_US.UTF-8"
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
pr-number:
|
||||
required: true
|
||||
type: number
|
||||
|
||||
jobs:
|
||||
lint-cpp:
|
||||
name: Lint C++
|
||||
runs-on: ${{ github.repository_owner == 'oven-sh' && 'macos-13-xlarge' || 'macos-13' }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
- name: Setup Bun
|
||||
uses: ./.github/actions/setup-bun
|
||||
with:
|
||||
bun-version: 1.1.23
|
||||
- name: Install Dependencies
|
||||
env:
|
||||
HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK: 1
|
||||
HOMEBREW_NO_AUTO_UPDATE: 1
|
||||
HOMEBREW_NO_INSTALL_CLEANUP: 1
|
||||
run: |
|
||||
brew install \
|
||||
llvm@${{ env.LLVM_VERSION }} \
|
||||
ninja \
|
||||
coreutils \
|
||||
openssl@1.1 \
|
||||
libiconv \
|
||||
gnu-sed --force --overwrite
|
||||
echo "$(brew --prefix coreutils)/libexec/gnubin" >> $GITHUB_PATH
|
||||
echo "$(brew --prefix llvm@$LLVM_VERSION)/bin" >> $GITHUB_PATH
|
||||
brew link --overwrite llvm@$LLVM_VERSION
|
||||
- name: Bun install
|
||||
run: |
|
||||
bun install
|
||||
- name: clang-tidy
|
||||
id: format
|
||||
env:
|
||||
CPU_TARGET: native
|
||||
BUN_SILENT: 1
|
||||
run: |
|
||||
rm -f did_fail format.log
|
||||
echo "${{ inputs.pr-number }}" > pr-number.txt
|
||||
echo "pr_number=$(cat pr-number.txt)" >> $GITHUB_OUTPUT
|
||||
bun run --silent build:tidy &> >(tee -p format.log) && echo 0 > did_succeed.txt
|
||||
# Upload format.log as github artifact for the workflow
|
||||
if [ -f did_succeed.txt ]; then
|
||||
echo "0" > did_fail.txt
|
||||
else
|
||||
echo "1" > did_fail.txt
|
||||
fi
|
||||
echo "did_fail=$(cat did_fail.txt)" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Upload format.log
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: format.log
|
||||
path: format.log
|
||||
- name: Upload PR
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: pr-number.txt
|
||||
path: pr-number.txt
|
||||
- name: Upload PR
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: did_fail.txt
|
||||
path: did_fail.txt
|
||||
- name: Fail if formatting failed
|
||||
if: ${{ steps.format.outputs.did_fail == '1' }}
|
||||
run: exit 1
|
||||
17
.github/workflows/zig-format.yml
vendored
17
.github/workflows/zig-format.yml
vendored
@@ -7,12 +7,6 @@ on:
|
||||
workflow_call:
|
||||
workflow_dispatch:
|
||||
pull_request:
|
||||
paths:
|
||||
- ".github/workflows/zig-format.yml"
|
||||
- "package.json"
|
||||
- "scripts/**"
|
||||
- "cmake/**"
|
||||
- "src/**/*.zig"
|
||||
|
||||
env:
|
||||
BUN_VERSION: "1.1.27"
|
||||
@@ -25,21 +19,12 @@ jobs:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
sparse-checkout: |
|
||||
.github
|
||||
package.json
|
||||
scripts
|
||||
cmake
|
||||
src
|
||||
packages
|
||||
fetch-depth: 0
|
||||
- name: Setup Bun
|
||||
uses: ./.github/actions/setup-bun
|
||||
with:
|
||||
bun-version: ${{ env.BUN_VERSION }}
|
||||
- name: Zig Format
|
||||
env:
|
||||
ENABLE_CCACHE: OFF
|
||||
SKIP_LLVM: ON
|
||||
run: |
|
||||
bun run zig-format:diff
|
||||
- name: Commit
|
||||
|
||||
4
.vscode/launch.json
generated
vendored
4
.vscode/launch.json
generated
vendored
@@ -172,6 +172,8 @@
|
||||
"FORCE_COLOR": "1",
|
||||
"BUN_DEBUG_QUIET_LOGS": "1",
|
||||
"BUN_GARBAGE_COLLECTOR_LEVEL": "0",
|
||||
"BUN_DEBUG_IncrementalGraph": "1",
|
||||
"BUN_DEBUG_Bake": "1",
|
||||
},
|
||||
"console": "internalConsole",
|
||||
},
|
||||
@@ -1192,4 +1194,4 @@
|
||||
"description": "Usage: bun test [...]",
|
||||
},
|
||||
],
|
||||
}
|
||||
}
|
||||
@@ -43,7 +43,9 @@ include(BuildBun)
|
||||
|
||||
# --- Analysis ---
|
||||
|
||||
include(RunClangFormat)
|
||||
include(RunClangTidy)
|
||||
include(RunZigFormat)
|
||||
include(RunPrettier)
|
||||
if(ENABLE_ANALYSIS)
|
||||
include(RunClangFormat)
|
||||
include(RunClangTidy)
|
||||
include(RunZigFormat)
|
||||
include(RunPrettier)
|
||||
endif()
|
||||
|
||||
@@ -116,42 +116,26 @@ $ export PATH="$PATH:/usr/lib/llvm16/bin"
|
||||
|
||||
## Building Bun
|
||||
|
||||
After cloning the repository, run the following command to run the first build. This may take a while as it will clone submodules and build dependencies.
|
||||
|
||||
```bash
|
||||
$ bun setup
|
||||
```
|
||||
|
||||
The binary will be located at `./build/bun-debug`. It is recommended to add this to your `$PATH`. To verify the build worked, let's print the version number on the development build of Bun.
|
||||
|
||||
```bash
|
||||
$ build/bun-debug --version
|
||||
x.y.z_debug
|
||||
```
|
||||
|
||||
To rebuild, you can invoke `bun run build`
|
||||
After cloning the repository, run the following command to build. This may take a while as it will clone submodules and build dependencies.
|
||||
|
||||
```bash
|
||||
$ bun run build
|
||||
```
|
||||
|
||||
These two scripts, `setup` and `build`, are aliases to do roughly the following:
|
||||
The binary will be located at `./build/debug/bun-debug`. It is recommended to add this to your `$PATH`. To verify the build worked, let's print the version number on the development build of Bun.
|
||||
|
||||
```bash
|
||||
$ ./scripts/setup.sh
|
||||
$ cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Debug
|
||||
$ ninja -C build # 'bun run build' runs just this
|
||||
$ build/debug/bun-debug --version
|
||||
x.y.z_debug
|
||||
```
|
||||
|
||||
Advanced users can pass CMake flags to customize the build.
|
||||
|
||||
## VSCode
|
||||
|
||||
VSCode is the recommended IDE for working on Bun, as it has been configured. Once opening, you can run `Extensions: Show Recommended Extensions` to install the recommended extensions for Zig and C++. ZLS is automatically configured.
|
||||
|
||||
If you use a different editor, make sure that you tell ZLS to use the automatically installed Zig compiler, which is located at `./.cache/zig/zig.exe`. The filename is `zig.exe` so that it works as expected on Windows, but it still works on macOS/Linux (it just has a surprising file extension).
|
||||
If you use a different editor, make sure that you tell ZLS to use the automatically installed Zig compiler, which is located at `./vendor/zig/zig.exe`. The filename is `zig.exe` so that it works as expected on Windows, but it still works on macOS/Linux (it just has a surprising file extension).
|
||||
|
||||
We recommend adding `./build` to your `$PATH` so that you can run `bun-debug` in your terminal:
|
||||
We recommend adding `./build/debug` to your `$PATH` so that you can run `bun-debug` in your terminal:
|
||||
|
||||
```sh
|
||||
$ bun-debug
|
||||
@@ -180,7 +164,7 @@ To compile a release build of Bun, run:
|
||||
$ bun run build:release
|
||||
```
|
||||
|
||||
The binary will be located at `./build-release/bun` and `./build-release/bun-profile`.
|
||||
The binary will be located at `./build/release/bun` and `./build/release/bun-profile`.
|
||||
|
||||
### Download release build from pull requests
|
||||
|
||||
@@ -189,8 +173,8 @@ To save you time spent building a release build locally, we provide a way to run
|
||||
To run a release build from a pull request, you can use the `bun-pr` npm package:
|
||||
|
||||
```sh
|
||||
bunx bun-pr pr-number
|
||||
bunx bun-pr branch/branch-name
|
||||
bunx bun-pr <pr-number>
|
||||
bunx bun-pr <branch-name>
|
||||
bunx bun-pr "https://github.com/oven-sh/bun/pull/1234566"
|
||||
```
|
||||
|
||||
@@ -222,24 +206,18 @@ $ valgrind --fair-sched=try --track-origins=yes bun-debug <args>
|
||||
|
||||
## Building WebKit locally + Debug mode of JSC
|
||||
|
||||
{% callout %}
|
||||
|
||||
**TODO**: This is out of date. TLDR is pass `-DUSE_DEBUG_JSC=1` or `-DWEBKIT_DIR=...` to CMake. it will probably need more fiddling. ask @paperdave if you need this.
|
||||
|
||||
{% /callout %}
|
||||
|
||||
WebKit is not cloned by default (to save time and disk space). To clone and build WebKit locally, run:
|
||||
|
||||
```bash
|
||||
# once you run this, `make submodule` can be used to automatically
|
||||
# update WebKit and the other submodules
|
||||
$ git submodule update --init --depth 1 --checkout src/bun.js/WebKit
|
||||
# to make a jsc release build
|
||||
$ make jsc
|
||||
# JSC debug build does not work perfectly with Bun yet, this is actively being
|
||||
# worked on and will eventually become the default.
|
||||
$ make jsc-build-linux-compile-debug cpp
|
||||
$ make jsc-build-mac-compile-debug cpp
|
||||
# Clone WebKit into ./vendor/WebKit
|
||||
$ git clone https://github.com/oven-sh/WebKit vendor/WebKit
|
||||
|
||||
# Make a debug build of JSC. This will output build artifacts in ./vendor/WebKit/WebKitBuild/Debug
|
||||
# Optionally, you can use `make jsc` for a release build
|
||||
$ make jsc-debug
|
||||
|
||||
# Build bun with the local JSC build
|
||||
$ bun run build:local
|
||||
```
|
||||
|
||||
Note that the WebKit folder, including build artifacts, is 8GB+ in size.
|
||||
|
||||
27
Makefile
27
Makefile
@@ -77,7 +77,7 @@ BUN_RELEASE_BIN = $(PACKAGE_DIR)/bun
|
||||
PRETTIER ?= $(shell which prettier 2>/dev/null || echo "./node_modules/.bin/prettier")
|
||||
ESBUILD = "$(shell which esbuild 2>/dev/null || echo "./node_modules/.bin/esbuild")"
|
||||
DSYMUTIL ?= $(shell which dsymutil 2>/dev/null || which dsymutil-15 2>/dev/null)
|
||||
WEBKIT_DIR ?= $(realpath src/bun.js/WebKit)
|
||||
WEBKIT_DIR ?= $(realpath vendor/WebKit)
|
||||
WEBKIT_RELEASE_DIR ?= $(WEBKIT_DIR)/WebKitBuild/Release
|
||||
WEBKIT_DEBUG_DIR ?= $(WEBKIT_DIR)/WebKitBuild/Debug
|
||||
WEBKIT_RELEASE_DIR_LTO ?= $(WEBKIT_DIR)/WebKitBuild/ReleaseLTO
|
||||
@@ -138,8 +138,8 @@ endif
|
||||
SED = $(shell which gsed 2>/dev/null || which sed 2>/dev/null)
|
||||
|
||||
BUN_DIR ?= $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
|
||||
BUN_DEPS_DIR ?= $(shell pwd)/src/deps
|
||||
BUN_DEPS_OUT_DIR ?= $(shell pwd)/build/bun-deps
|
||||
BUN_DEPS_DIR ?= $(shell pwd)/vendor
|
||||
BUN_DEPS_OUT_DIR ?= $(shell pwd)/build/release
|
||||
CPU_COUNT = 2
|
||||
ifeq ($(OS_NAME),darwin)
|
||||
CPU_COUNT = $(shell sysctl -n hw.logicalcpu)
|
||||
@@ -689,19 +689,10 @@ assert-deps:
|
||||
@test $(shell cargo --version | awk '{print $$2}' | cut -d. -f2) -gt 57 || (echo -e "ERROR: cargo version must be at least 1.57."; exit 1)
|
||||
@echo "You have the dependencies installed! Woo"
|
||||
|
||||
# the following allows you to run `make submodule` to update or init submodules. but we will exclude webkit
|
||||
# unless you explicitly clone it yourself (a huge download)
|
||||
SUBMODULE_NAMES=$(shell cat .gitmodules | grep 'path = ' | awk '{print $$3}')
|
||||
ifeq ("$(wildcard src/bun.js/WebKit/.git)", "")
|
||||
SUBMODULE_NAMES := $(filter-out src/bun.js/WebKit, $(SUBMODULE_NAMES))
|
||||
endif
|
||||
|
||||
.PHONY: init-submodules
|
||||
init-submodules: submodule # (backwards-compatibility alias)
|
||||
|
||||
.PHONY: submodule
|
||||
submodule: ## to init or update all submodules
|
||||
git submodule update --init --recursive --progress --depth=1 --checkout $(SUBMODULE_NAMES)
|
||||
|
||||
.PHONY: build-obj
|
||||
build-obj:
|
||||
@@ -804,7 +795,7 @@ cls:
|
||||
@echo -e "\n\n---\n\n"
|
||||
|
||||
jsc-check:
|
||||
@ls $(JSC_BASE_DIR) >/dev/null 2>&1 || (echo -e "Failed to access WebKit build. Please compile the WebKit submodule using the Dockerfile at $(shell pwd)/src/javascript/WebKit/Dockerfile and then copy from /output in the Docker container to $(JSC_BASE_DIR). You can override the directory via JSC_BASE_DIR. \n\n DOCKER_BUILDKIT=1 docker build -t bun-webkit $(shell pwd)/src/bun.js/WebKit -f $(shell pwd)/src/bun.js/WebKit/Dockerfile --progress=plain\n\n docker container create bun-webkit\n\n # Get the container ID\n docker container ls\n\n docker cp DOCKER_CONTAINER_ID_YOU_JUST_FOUND:/output $(JSC_BASE_DIR)" && exit 1)
|
||||
@ls $(JSC_BASE_DIR) >/dev/null 2>&1 || (echo -e "Failed to access WebKit build. Please compile the WebKit submodule using the Dockerfile at $(shell pwd)/src/javascript/WebKit/Dockerfile and then copy from /output in the Docker container to $(JSC_BASE_DIR). You can override the directory via JSC_BASE_DIR. \n\n DOCKER_BUILDKIT=1 docker build -t bun-webkit $(shell pwd)/vendor/WebKit -f $(shell pwd)/vendor/WebKit/Dockerfile --progress=plain\n\n docker container create bun-webkit\n\n # Get the container ID\n docker container ls\n\n docker cp DOCKER_CONTAINER_ID_YOU_JUST_FOUND:/output $(JSC_BASE_DIR)" && exit 1)
|
||||
@ls $(JSC_INCLUDE_DIR) >/dev/null 2>&1 || (echo "Failed to access WebKit include directory at $(JSC_INCLUDE_DIR)." && exit 1)
|
||||
@ls $(JSC_LIB) >/dev/null 2>&1 || (echo "Failed to access WebKit lib directory at $(JSC_LIB)." && exit 1)
|
||||
|
||||
@@ -945,7 +936,7 @@ jsc-bindings: headers bindings
|
||||
|
||||
.PHONY: clone-submodules
|
||||
clone-submodules:
|
||||
git -c submodule."src/bun.js/WebKit".update=none submodule update --init --recursive --depth=1 --progress
|
||||
git -c submodule."vendor/WebKit".update=none submodule update --init --recursive --depth=1 --progress
|
||||
|
||||
|
||||
.PHONY: headers
|
||||
@@ -1265,7 +1256,7 @@ jsc-build-mac-compile:
|
||||
-DENABLE_STATIC_JSC=ON \
|
||||
-DENABLE_SINGLE_THREADED_VM_ENTRY_SCOPE=ON \
|
||||
-DALLOW_LINE_AND_COLUMN_NUMBER_IN_BUILTINS=ON \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DCMAKE_BUILD_TYPE=RelWithDebInfo \
|
||||
-DUSE_THIN_ARCHIVES=OFF \
|
||||
-DBUN_FAST_TLS=ON \
|
||||
-DENABLE_FTL_JIT=ON \
|
||||
@@ -1277,7 +1268,7 @@ jsc-build-mac-compile:
|
||||
$(WEBKIT_DIR) \
|
||||
$(WEBKIT_RELEASE_DIR) && \
|
||||
CFLAGS="$(CFLAGS) -ffat-lto-objects" CXXFLAGS="$(CXXFLAGS) -ffat-lto-objects" \
|
||||
cmake --build $(WEBKIT_RELEASE_DIR) --config Release --target jsc
|
||||
cmake --build $(WEBKIT_RELEASE_DIR) --config RelWithDebInfo --target jsc
|
||||
|
||||
.PHONY: jsc-build-mac-compile-lto
|
||||
jsc-build-mac-compile-lto:
|
||||
@@ -1379,7 +1370,7 @@ jsc-build-linux-compile-config-debug:
|
||||
$(WEBKIT_DEBUG_DIR)
|
||||
|
||||
# If you get "Error: could not load cache"
|
||||
# run rm -rf src/bun.js/WebKit/CMakeCache.txt
|
||||
# run rm -rf vendor/WebKit/CMakeCache.txt
|
||||
.PHONY: jsc-build-linux-compile-build
|
||||
jsc-build-linux-compile-build:
|
||||
mkdir -p $(WEBKIT_RELEASE_DIR) && \
|
||||
@@ -1414,7 +1405,7 @@ jsc-build-copy-debug:
|
||||
cp $(WEBKIT_DEBUG_DIR)/lib/libbmalloc.a $(BUN_DEPS_OUT_DIR)/libbmalloc.a
|
||||
|
||||
clean-jsc:
|
||||
cd src/bun.js/WebKit && rm -rf **/CMakeCache.txt **/CMakeFiles && rm -rf src/bun.js/WebKit/WebKitBuild
|
||||
cd vendor/WebKit && rm -rf **/CMakeCache.txt **/CMakeFiles && rm -rf vendor/WebKit/WebKitBuild
|
||||
clean-bindings:
|
||||
rm -rf $(OBJ_DIR)/*.o $(DEBUG_OBJ_DIR)/*.o $(DEBUG_OBJ_DIR)/webcore/*.o $(DEBUG_BINDINGS_OBJ) $(OBJ_DIR)/webcore/*.o $(BINDINGS_OBJ) $(OBJ_DIR)/*.d $(DEBUG_OBJ_DIR)/*.d
|
||||
|
||||
|
||||
BIN
bench/bun.lockb
BIN
bench/bun.lockb
Binary file not shown.
@@ -7,6 +7,7 @@
|
||||
"@swc/core": "^1.2.133",
|
||||
"benchmark": "^2.1.4",
|
||||
"braces": "^3.0.2",
|
||||
"color": "^4.2.3",
|
||||
"esbuild": "^0.14.12",
|
||||
"eventemitter3": "^5.0.0",
|
||||
"execa": "^8.0.1",
|
||||
@@ -14,6 +15,7 @@
|
||||
"fdir": "^6.1.0",
|
||||
"mitata": "^0.1.6",
|
||||
"string-width": "7.1.0",
|
||||
"tinycolor2": "^1.6.0",
|
||||
"zx": "^7.2.3"
|
||||
},
|
||||
"scripts": {
|
||||
|
||||
25
bench/snippets/color.mjs
Normal file
25
bench/snippets/color.mjs
Normal file
@@ -0,0 +1,25 @@
|
||||
import Color from "color";
|
||||
import tinycolor from "tinycolor2";
|
||||
import { bench, group, run } from "./runner.mjs";
|
||||
|
||||
const inputs = ["#f00", "rgb(255, 0, 0)", "rgba(255, 0, 0, 1)", "hsl(0, 100%, 50%)"];
|
||||
|
||||
for (const input of inputs) {
|
||||
group(`${input}`, () => {
|
||||
if (typeof Bun !== "undefined") {
|
||||
bench("Bun.color()", () => {
|
||||
Bun.color(input, "css");
|
||||
});
|
||||
}
|
||||
|
||||
bench("color", () => {
|
||||
Color(input).hex();
|
||||
});
|
||||
|
||||
bench("'tinycolor2'", () => {
|
||||
tinycolor(input).toHexString();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
await run();
|
||||
11
build.zig
11
build.zig
@@ -52,7 +52,7 @@ const BunBuildOptions = struct {
|
||||
/// instead of at compile time. This is disabled in release or if this flag
|
||||
/// is set (to allow CI to build a portable executable). Affected files:
|
||||
///
|
||||
/// - src/kit/runtime.ts (bundled)
|
||||
/// - src/bake/runtime.ts (bundled)
|
||||
/// - src/bun.js/api/FFI.h
|
||||
///
|
||||
/// A similar technique is used in C++ code for JavaScript builtins
|
||||
@@ -157,7 +157,7 @@ pub fn build(b: *Build) !void {
|
||||
|
||||
// TODO: Upgrade path for 0.14.0
|
||||
// b.graph.zig_lib_directory = brk: {
|
||||
// const sub_path = "src/deps/zig/lib";
|
||||
// const sub_path = "vendor/zig/lib";
|
||||
// const dir = try b.build_root.handle.openDir(sub_path, .{});
|
||||
// break :brk .{ .handle = dir, .path = try b.build_root.join(b.graph.arena, &.{sub_path}) };
|
||||
// };
|
||||
@@ -295,7 +295,7 @@ pub fn build(b: *Build) !void {
|
||||
bun_check_obj.generated_bin = null;
|
||||
step.dependOn(&bun_check_obj.step);
|
||||
|
||||
// The default install step will run zig build check This is so ZLS
|
||||
// The default install step will run zig build check. This is so ZLS
|
||||
// identifies the codebase, as well as performs checking if build on
|
||||
// save is enabled.
|
||||
|
||||
@@ -368,6 +368,7 @@ pub fn addBunObject(b: *Build, opts: *BunBuildOptions) *Compile {
|
||||
.root_source_file = switch (opts.os) {
|
||||
.wasm => b.path("root_wasm.zig"),
|
||||
else => b.path("root.zig"),
|
||||
// else => b.path("root_css.zig"),
|
||||
},
|
||||
.target = opts.target,
|
||||
.optimize = opts.optimize,
|
||||
@@ -474,8 +475,8 @@ fn addInternalPackages(b: *Build, obj: *Compile, opts: *BunBuildOptions) void {
|
||||
.{ .file = "ZigGeneratedClasses.zig", .import = "ZigGeneratedClasses" },
|
||||
.{ .file = "ResolvedSourceTag.zig", .import = "ResolvedSourceTag" },
|
||||
.{ .file = "ErrorCode.zig", .import = "ErrorCode" },
|
||||
.{ .file = "kit.client.js", .import = "kit-codegen/kit.client.js", .enable = opts.shouldEmbedCode() },
|
||||
.{ .file = "kit.server.js", .import = "kit-codegen/kit.server.js", .enable = opts.shouldEmbedCode() },
|
||||
.{ .file = "bake.client.js", .import = "bake-codegen/bake.client.js", .enable = opts.shouldEmbedCode() },
|
||||
.{ .file = "bake.server.js", .import = "bake-codegen/bake.server.js", .enable = opts.shouldEmbedCode() },
|
||||
}) |entry| {
|
||||
if (!@hasField(@TypeOf(entry), "enable") or entry.enable) {
|
||||
const path = b.pathJoin(&.{ opts.generated_code_dir, entry.file });
|
||||
|
||||
@@ -30,6 +30,10 @@ macro(optionx variable type description)
|
||||
set(multiValueArgs)
|
||||
cmake_parse_arguments(${variable} "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
|
||||
|
||||
if(DEFINED ${variable})
|
||||
set(${variable}_VALUE ${${variable}})
|
||||
endif()
|
||||
|
||||
if(NOT ${type} MATCHES "^(BOOL|STRING|FILEPATH|PATH|INTERNAL)$")
|
||||
set(${variable}_REGEX ${type})
|
||||
set(${variable}_TYPE STRING)
|
||||
@@ -65,7 +69,9 @@ macro(optionx variable type description)
|
||||
message(FATAL_ERROR "Invalid ${${variable}_SOURCE}: ${${variable}_PREVIEW}=\"${${variable}}\", please use ${${variable}_PREVIEW}=<${${variable}_REGEX}>")
|
||||
endif()
|
||||
|
||||
message(STATUS "Set ${variable}: ${${variable}}")
|
||||
if(NOT ${variable}_VALUE STREQUAL ${variable})
|
||||
message(STATUS "Set ${variable}: ${${variable}}")
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
# unsupported()
|
||||
@@ -122,6 +128,7 @@ optionx(CACHE_PATH FILEPATH "The path to the cache directory" DEFAULT ${BUILD_PA
|
||||
optionx(CACHE_STRATEGY "read-write|read-only|write-only|none" "The strategy to use for caching" DEFAULT "read-write")
|
||||
|
||||
optionx(CI BOOL "If CI is enabled" DEFAULT OFF)
|
||||
optionx(ENABLE_ANALYSIS BOOL "If static analysis targets should be enabled" DEFAULT OFF)
|
||||
|
||||
if(CI)
|
||||
set(WARNING FATAL_ERROR)
|
||||
@@ -139,24 +146,8 @@ endif()
|
||||
optionx(VENDOR_PATH FILEPATH "The path to the vendor directory" DEFAULT ${CWD}/vendor)
|
||||
optionx(TMP_PATH FILEPATH "The path to the temporary directory" DEFAULT ${BUILD_PATH}/tmp)
|
||||
|
||||
optionx(FRESH BOOL "Set when --fresh is used" DEFAULT OFF)
|
||||
optionx(CLEAN BOOL "Set when --clean is used" DEFAULT OFF)
|
||||
|
||||
# --- Helper functions ---
|
||||
|
||||
function(parse_semver value variable)
|
||||
string(REGEX MATCH "([0-9]+)\\.([0-9]+)\\.([0-9]+)" match "${value}")
|
||||
|
||||
if(NOT match)
|
||||
message(FATAL_ERROR "Invalid semver: \"${value}\"")
|
||||
endif()
|
||||
|
||||
set(${variable}_VERSION "${CMAKE_MATCH_1}.${CMAKE_MATCH_2}.${CMAKE_MATCH_3}" PARENT_SCOPE)
|
||||
set(${variable}_VERSION_MAJOR "${CMAKE_MATCH_1}" PARENT_SCOPE)
|
||||
set(${variable}_VERSION_MINOR "${CMAKE_MATCH_2}" PARENT_SCOPE)
|
||||
set(${variable}_VERSION_PATCH "${CMAKE_MATCH_3}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
# setenv()
|
||||
# Description:
|
||||
# Sets an environment variable during the build step, and writes it to a .env file.
|
||||
@@ -194,102 +185,154 @@ function(setenv variable value)
|
||||
message(STATUS "Set ENV ${variable}: ${value}")
|
||||
endfunction()
|
||||
|
||||
# check_command()
|
||||
# satisfies_range()
|
||||
# Description:
|
||||
# Checks if a command is available, used by `find_command()` as a validator.
|
||||
# Check if a version satisfies a version range
|
||||
# Arguments:
|
||||
# FOUND bool - The variable to set to true if the version is found
|
||||
# CMD string - The executable to check the version of
|
||||
function(check_command FOUND CMD)
|
||||
set(${FOUND} OFF PARENT_SCOPE)
|
||||
|
||||
if(${CMD} MATCHES "zig")
|
||||
set(CHECK_COMMAND ${CMD} version)
|
||||
else()
|
||||
set(CHECK_COMMAND ${CMD} --version)
|
||||
endif()
|
||||
|
||||
execute_process(
|
||||
COMMAND ${CHECK_COMMAND}
|
||||
RESULT_VARIABLE RESULT
|
||||
OUTPUT_VARIABLE OUTPUT
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
|
||||
if(NOT RESULT EQUAL 0 OR NOT OUTPUT)
|
||||
message(DEBUG "${CHECK_COMMAND}, exited with code ${RESULT}")
|
||||
# version string - The version to check (e.g. "1.2.3")
|
||||
# range string - The range to check against (e.g. ">=1.2.3")
|
||||
# variable string - The variable to store the result in
|
||||
function(satisfies_range version range variable)
|
||||
if(range STREQUAL "ignore")
|
||||
set(${variable} ON PARENT_SCOPE)
|
||||
return()
|
||||
endif()
|
||||
|
||||
parse_semver(${OUTPUT} CMD)
|
||||
parse_semver(${CHECK_COMMAND_VERSION} CHECK)
|
||||
set(${variable} OFF PARENT_SCOPE)
|
||||
|
||||
if(CHECK_COMMAND_VERSION MATCHES ">=")
|
||||
if(NOT CMD_VERSION VERSION_GREATER_EQUAL ${CHECK_VERSION})
|
||||
message(DEBUG "${CHECK_COMMAND}, actual: ${CMD_VERSION}, expected: ${CHECK_COMMAND_VERSION}")
|
||||
return()
|
||||
endif()
|
||||
elseif(CHECK_COMMAND_VERSION MATCHES ">")
|
||||
if(NOT CMD_VERSION VERSION_GREATER ${CHECK_VERSION})
|
||||
message(DEBUG "${CHECK_COMMAND}, actual: ${CMD_VERSION}, expected: ${CHECK_COMMAND_VERSION}")
|
||||
return()
|
||||
endif()
|
||||
string(REGEX MATCH "([0-9]+)\\.([0-9]+)\\.([0-9]+)" match "${version}")
|
||||
if(NOT match)
|
||||
return()
|
||||
endif()
|
||||
set(version ${CMAKE_MATCH_1}.${CMAKE_MATCH_2}.${CMAKE_MATCH_3})
|
||||
|
||||
string(REGEX MATCH "(>=|<=|>|<)?([0-9]+)\\.([0-9]+)\\.([0-9]+)" match "${range}")
|
||||
if(NOT match)
|
||||
return()
|
||||
endif()
|
||||
set(comparator ${CMAKE_MATCH_1})
|
||||
set(range ${CMAKE_MATCH_2}.${CMAKE_MATCH_3}.${CMAKE_MATCH_4})
|
||||
|
||||
if(comparator STREQUAL ">=")
|
||||
set(comparator VERSION_GREATER_EQUAL)
|
||||
elseif(comparator STREQUAL ">")
|
||||
set(comparator VERSION_GREATER)
|
||||
elseif(comparator STREQUAL "<=")
|
||||
set(comparator VERSION_LESS_EQUAL)
|
||||
elseif(comparator STREQUAL "<")
|
||||
set(comparator VERSION_LESS)
|
||||
else()
|
||||
if(NOT CMD_VERSION VERSION_EQUAL ${CHECK_VERSION})
|
||||
message(DEBUG "${CHECK_COMMAND}, actual: ${CMD_VERSION}, expected: =${CHECK_COMMAND_VERSION}")
|
||||
return()
|
||||
endif()
|
||||
set(comparator VERSION_EQUAL)
|
||||
endif()
|
||||
|
||||
set(${FOUND} TRUE PARENT_SCOPE)
|
||||
if(version ${comparator} ${range})
|
||||
set(${variable} ON PARENT_SCOPE)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
# find_command()
|
||||
# Description:
|
||||
# Finds a command, similar to `find_program()`, but allows for version checking.
|
||||
# Arguments:
|
||||
# VARIABLE string - The variable to set
|
||||
# COMMAND string[] - The names of the command to find
|
||||
# PATHS string[] - The paths to search for the command
|
||||
# REQUIRED bool - If false, the command is optional
|
||||
# VERSION string - The version of the command to find (e.g. "1.2.3" or ">1.2.3")
|
||||
# VARIABLE string - The variable to set
|
||||
# VERSION_VARIABLE string - The variable to check for the version
|
||||
# COMMAND string[] - The names of the command to find
|
||||
# PATHS string[] - The paths to search for the command
|
||||
# REQUIRED bool - If false, the command is optional
|
||||
# VERSION string - The version of the command to find (e.g. "1.2.3" or ">1.2.3")
|
||||
function(find_command)
|
||||
set(options)
|
||||
set(args VARIABLE VERSION MIN_VERSION REQUIRED)
|
||||
set(args VARIABLE VERSION_VARIABLE REQUIRED VERSION)
|
||||
set(multiArgs COMMAND PATHS)
|
||||
cmake_parse_arguments(CMD "${options}" "${args}" "${multiArgs}" ${ARGN})
|
||||
cmake_parse_arguments(FIND "" "${args}" "${multiArgs}" ${ARGN})
|
||||
|
||||
if(NOT CMD_VARIABLE)
|
||||
message(FATAL_ERROR "find_command: VARIABLE is required")
|
||||
if(NOT FIND_VARIABLE OR NOT FIND_COMMAND)
|
||||
message(FATAL_ERROR "${CMAKE_CURRENT_FUNCTION}: VARIABLE and COMMAND are required")
|
||||
endif()
|
||||
|
||||
if(NOT CMD_COMMAND)
|
||||
message(FATAL_ERROR "find_command: COMMAND is required")
|
||||
if(NOT FIND_VERSION_VARIABLE)
|
||||
set(FIND_VERSION_VARIABLE ${FIND_VARIABLE}_VERSION)
|
||||
endif()
|
||||
|
||||
if(CMD_VERSION)
|
||||
set(CHECK_COMMAND_VERSION ${CMD_VERSION}) # special global variable
|
||||
set(CMD_VALIDATOR VALIDATOR check_command)
|
||||
list(GET FIND_COMMAND 0 FIND_NAME)
|
||||
if(FIND_VERSION)
|
||||
optionx(${FIND_VERSION_VARIABLE} STRING "The version of ${FIND_NAME} to find" DEFAULT "${FIND_VERSION}")
|
||||
|
||||
function(find_command_version variable exe)
|
||||
set(${variable} OFF PARENT_SCOPE)
|
||||
|
||||
if(${exe} MATCHES "(go|zig)(\.exe)?$")
|
||||
set(command ${exe} version)
|
||||
else()
|
||||
set(command ${exe} --version)
|
||||
endif()
|
||||
|
||||
execute_process(
|
||||
COMMAND ${command}
|
||||
RESULT_VARIABLE result
|
||||
OUTPUT_VARIABLE output
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
ERROR_QUIET
|
||||
)
|
||||
|
||||
if(NOT result EQUAL 0)
|
||||
set(reason "exited with ${result}")
|
||||
elseif(NOT output)
|
||||
set(reason "no output")
|
||||
else()
|
||||
string(REGEX MATCH "([0-9]+)\\.([0-9]+)\\.([0-9]+)" match "${output}")
|
||||
if(match)
|
||||
set(version ${CMAKE_MATCH_1}.${CMAKE_MATCH_2}.${CMAKE_MATCH_3})
|
||||
set(reason "\"${version}\"")
|
||||
else()
|
||||
set(reason "no version")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set_property(GLOBAL PROPERTY ${FIND_NAME} "${exe}: ${reason}" APPEND)
|
||||
|
||||
if(version)
|
||||
satisfies_range(${version} ${${FIND_VERSION_VARIABLE}} ${variable})
|
||||
set(${variable} ${${variable}} PARENT_SCOPE)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
set(FIND_VALIDATOR VALIDATOR find_command_version)
|
||||
endif()
|
||||
|
||||
find_program(
|
||||
${CMD_VARIABLE}
|
||||
NAMES ${CMD_COMMAND}
|
||||
PATHS ${CMD_PATHS}
|
||||
${CMD_VALIDATOR}
|
||||
${FIND_VARIABLE}
|
||||
NAMES ${FIND_COMMAND}
|
||||
PATHS ${FIND_PATHS}
|
||||
${FIND_VALIDATOR}
|
||||
)
|
||||
|
||||
if(NOT CMD_REQUIRED STREQUAL "OFF" AND ${CMD_VARIABLE} MATCHES "NOTFOUND")
|
||||
if(CMD_VERSION)
|
||||
message(FATAL_ERROR "Command not found: \"${CMD_COMMAND}\" that matches version \"${CHECK_COMMAND_VERSION}\"")
|
||||
if(NOT FIND_REQUIRED STREQUAL "OFF" AND ${FIND_VARIABLE} MATCHES "NOTFOUND")
|
||||
set(error "Command not found: \"${FIND_NAME}\"")
|
||||
|
||||
if(FIND_VERSION)
|
||||
set(error "${error} that satisfies version \"${${FIND_VERSION_VARIABLE}}\"")
|
||||
endif()
|
||||
message(FATAL_ERROR "Command not found: \"${CMD_COMMAND}\"")
|
||||
|
||||
get_property(FIND_RESULTS GLOBAL PROPERTY ${FIND_NAME})
|
||||
if(NOT FIND_RESULTS MATCHES "NOTFOUND")
|
||||
set(error "${error}\nThe following commands did not satisfy the requirement:")
|
||||
foreach(result ${FIND_RESULTS})
|
||||
set(error "${error}\n ${result}")
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
set(error "${error}\nTo fix this, either:
|
||||
1. Install ${FIND_NAME} ${${FIND_VERSION_VARIABLE}}
|
||||
2. Set -D${FIND_VERSION_VARIABLE}=<version> to require a different version
|
||||
3. Set -D${FIND_VERSION_VARIABLE}=ignore to allow any version
|
||||
")
|
||||
message(FATAL_ERROR ${error})
|
||||
endif()
|
||||
|
||||
if(${CMD_VARIABLE} MATCHES "NOTFOUND")
|
||||
unset(${CMD_VARIABLE} PARENT_SCOPE)
|
||||
if(${FIND_VARIABLE} MATCHES "NOTFOUND")
|
||||
unset(${FIND_VARIABLE} PARENT_SCOPE)
|
||||
else()
|
||||
setx(${CMD_VARIABLE} ${${CMD_VARIABLE}} PARENT_SCOPE)
|
||||
setx(${FIND_VARIABLE} ${${FIND_VARIABLE}} PARENT_SCOPE)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
|
||||
@@ -91,6 +91,8 @@ if(LINUX)
|
||||
optionx(ENABLE_VALGRIND BOOL "If Valgrind support should be enabled" DEFAULT OFF)
|
||||
endif()
|
||||
|
||||
optionx(ENABLE_PRETTIER BOOL "If prettier should be ran" DEFAULT OFF)
|
||||
|
||||
if(USE_VALGRIND AND NOT USE_BASELINE)
|
||||
message(WARNING "If valgrind is enabled, baseline must also be enabled")
|
||||
setx(USE_BASELINE ON)
|
||||
|
||||
@@ -1,14 +1,5 @@
|
||||
# https://clang.llvm.org/docs/ClangFormat.html
|
||||
|
||||
find_command(
|
||||
VARIABLE
|
||||
CLANG_FORMAT_PROGRAM
|
||||
COMMAND
|
||||
clang-format
|
||||
REQUIRED
|
||||
OFF
|
||||
)
|
||||
|
||||
set(CLANG_FORMAT_SOURCES ${BUN_C_SOURCES} ${BUN_CXX_SOURCES})
|
||||
|
||||
register_command(
|
||||
|
||||
@@ -1,16 +1,5 @@
|
||||
# https://clang.llvm.org/extra/clang-tidy/
|
||||
|
||||
find_command(
|
||||
VARIABLE
|
||||
CLANG_TIDY_PROGRAM
|
||||
COMMAND
|
||||
clang-tidy
|
||||
VERSION
|
||||
${LLVM_VERSION}
|
||||
REQUIRED
|
||||
OFF
|
||||
)
|
||||
|
||||
set(CLANG_TIDY_SOURCES ${BUN_C_SOURCES} ${BUN_CXX_SOURCES})
|
||||
|
||||
set(CLANG_TIDY_COMMAND ${CLANG_TIDY_PROGRAM}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# IWYU = "Include What You Use"
|
||||
# https://include-what-you-use.org/
|
||||
|
||||
setx(IWYU_SOURCE_PATH ${CACHE_PATH}/iwyu-${LLVM_VERSION_MAJOR})
|
||||
setx(IWYU_SOURCE_PATH ${CACHE_PATH}/iwyu-${LLVM_VERSION})
|
||||
setx(IWYU_BUILD_PATH ${IWYU_SOURCE_PATH}/build)
|
||||
setx(IWYU_PROGRAM ${IWYU_BUILD_PATH}/bin/include-what-you-use)
|
||||
|
||||
@@ -11,7 +11,7 @@ register_repository(
|
||||
REPOSITORY
|
||||
include-what-you-use/include-what-you-use
|
||||
BRANCH
|
||||
clang_${LLVM_VERSION_MAJOR}
|
||||
clang_${LLVM_VERSION}
|
||||
PATH
|
||||
${IWYU_SOURCE_PATH}
|
||||
)
|
||||
|
||||
@@ -95,7 +95,7 @@ register_command(
|
||||
if(GIT_CHANGED_SOURCES)
|
||||
set(PRETTIER_CHANGED_SOURCES)
|
||||
foreach(source ${PRETTIER_SOURCES})
|
||||
list(FIND PRETTIER_CHANGED_SOURCES ${source} index)
|
||||
list(FIND GIT_CHANGED_SOURCES ${source} index)
|
||||
if(NOT ${index} EQUAL -1)
|
||||
list(APPEND PRETTIER_CHANGED_SOURCES ${source})
|
||||
endif()
|
||||
|
||||
@@ -324,40 +324,41 @@ register_command(
|
||||
${BUN_JAVASCRIPT_OUTPUTS}
|
||||
)
|
||||
|
||||
set(BUN_KIT_RUNTIME_CODEGEN_SCRIPT ${CWD}/src/codegen/kit-codegen.ts)
|
||||
set(BUN_BAKE_RUNTIME_CODEGEN_SCRIPT ${CWD}/src/codegen/bake-codegen.ts)
|
||||
|
||||
file(GLOB_RECURSE BUN_KIT_RUNTIME_SOURCES ${CONFIGURE_DEPENDS}
|
||||
${CWD}/src/kit/*.ts
|
||||
${CWD}/src/kit/*/*.ts
|
||||
file(GLOB_RECURSE BUN_BAKE_RUNTIME_SOURCES ${CONFIGURE_DEPENDS}
|
||||
${CWD}/src/bake/*.ts
|
||||
${CWD}/src/bake/*/*.ts
|
||||
${CWD}/src/bake/*/*.css
|
||||
)
|
||||
|
||||
list(APPEND BUN_KIT_RUNTIME_CODEGEN_SOURCES
|
||||
list(APPEND BUN_BAKE_RUNTIME_CODEGEN_SOURCES
|
||||
${CWD}/src/bun.js/bindings/InternalModuleRegistry.cpp
|
||||
)
|
||||
|
||||
set(BUN_KIT_RUNTIME_OUTPUTS
|
||||
${CODEGEN_PATH}/kit_empty_file
|
||||
${CODEGEN_PATH}/kit.client.js
|
||||
${CODEGEN_PATH}/kit.server.js
|
||||
set(BUN_BAKE_RUNTIME_OUTPUTS
|
||||
${CODEGEN_PATH}/bake.client.js
|
||||
${CODEGEN_PATH}/bake.server.js
|
||||
)
|
||||
|
||||
register_command(
|
||||
TARGET
|
||||
bun-kit-codegen
|
||||
bun-bake-codegen
|
||||
COMMENT
|
||||
"Bundling Kit Runtime"
|
||||
COMMAND
|
||||
${BUN_EXECUTABLE}
|
||||
run
|
||||
${BUN_KIT_RUNTIME_CODEGEN_SCRIPT}
|
||||
${BUN_BAKE_RUNTIME_CODEGEN_SCRIPT}
|
||||
--debug=${DEBUG}
|
||||
--codegen_root=${CODEGEN_PATH}
|
||||
SOURCES
|
||||
${BUN_KIT_RUNTIME_SOURCES}
|
||||
${BUN_KIT_RUNTIME_CODEGEN_SOURCES}
|
||||
${BUN_KIT_RUNTIME_CODEGEN_SCRIPT}
|
||||
${BUN_BAKE_RUNTIME_SOURCES}
|
||||
${BUN_BAKE_RUNTIME_CODEGEN_SOURCES}
|
||||
${BUN_BAKE_RUNTIME_CODEGEN_SCRIPT}
|
||||
OUTPUTS
|
||||
${BUN_KIT_RUNTIME_OUTPUTS}
|
||||
${CODEGEN_PATH}/bake_empty_file
|
||||
${BUN_BAKE_RUNTIME_OUTPUTS}
|
||||
)
|
||||
|
||||
set(BUN_JS_SINK_SCRIPT ${CWD}/src/codegen/generate-jssink.ts)
|
||||
@@ -398,6 +399,7 @@ set(BUN_OBJECT_LUT_SOURCES
|
||||
${CWD}/src/bun.js/bindings/BunProcess.cpp
|
||||
${CWD}/src/bun.js/bindings/ProcessBindingConstants.cpp
|
||||
${CWD}/src/bun.js/bindings/ProcessBindingNatives.cpp
|
||||
${CWD}/src/bun.js/modules/NodeModuleModule.cpp
|
||||
)
|
||||
|
||||
set(BUN_OBJECT_LUT_OUTPUTS
|
||||
@@ -407,8 +409,10 @@ set(BUN_OBJECT_LUT_OUTPUTS
|
||||
${CODEGEN_PATH}/BunProcess.lut.h
|
||||
${CODEGEN_PATH}/ProcessBindingConstants.lut.h
|
||||
${CODEGEN_PATH}/ProcessBindingNatives.lut.h
|
||||
${CODEGEN_PATH}/NodeModuleModule.lut.h
|
||||
)
|
||||
|
||||
|
||||
macro(WEBKIT_ADD_SOURCE_DEPENDENCIES _source _deps)
|
||||
set(_tmp)
|
||||
get_source_file_property(_tmp ${_source} OBJECT_DEPENDS)
|
||||
@@ -499,9 +503,9 @@ set(BUN_ZIG_GENERATED_SOURCES
|
||||
|
||||
# In debug builds, these are not embedded, but rather referenced at runtime.
|
||||
if (DEBUG)
|
||||
list(APPEND BUN_ZIG_GENERATED_SOURCES ${CODEGEN_PATH}/kit_empty_file)
|
||||
list(APPEND BUN_ZIG_GENERATED_SOURCES ${CODEGEN_PATH}/bake_empty_file)
|
||||
else()
|
||||
list(APPEND BUN_ZIG_GENERATED_SOURCES ${BUN_KIT_RUNTIME_OUTPUTS})
|
||||
list(APPEND BUN_ZIG_GENERATED_SOURCES ${BUN_BAKE_RUNTIME_OUTPUTS})
|
||||
endif()
|
||||
|
||||
set(BUN_ZIG_OUTPUT ${BUILD_PATH}/bun-zig.o)
|
||||
@@ -569,7 +573,8 @@ file(GLOB BUN_CXX_SOURCES ${CONFIGURE_DEPENDS}
|
||||
${CWD}/src/bun.js/bindings/webcrypto/*.cpp
|
||||
${CWD}/src/bun.js/bindings/webcrypto/*/*.cpp
|
||||
${CWD}/src/bun.js/bindings/v8/*.cpp
|
||||
${CWD}/src/kit/*.cpp
|
||||
${CWD}/src/bun.js/bindings/v8/shim/*.cpp
|
||||
${CWD}/src/bake/*.cpp
|
||||
${CWD}/src/deps/*.cpp
|
||||
${BUN_USOCKETS_SOURCE}/src/crypto/*.cpp
|
||||
)
|
||||
@@ -616,6 +621,7 @@ list(APPEND BUN_CPP_SOURCES
|
||||
${BUN_C_SOURCES}
|
||||
${BUN_CXX_SOURCES}
|
||||
${VENDOR_PATH}/picohttpparser/picohttpparser.c
|
||||
${NODEJS_HEADERS_PATH}/include/node/node_version.h
|
||||
${BUN_ZIG_GENERATED_CLASSES_OUTPUTS}
|
||||
${BUN_JS_SINK_OUTPUTS}
|
||||
${BUN_JAVASCRIPT_OUTPUTS}
|
||||
@@ -693,6 +699,7 @@ target_include_directories(${bun} PRIVATE
|
||||
${CWD}/src/bun.js/bindings/webcore
|
||||
${CWD}/src/bun.js/bindings/webcrypto
|
||||
${CWD}/src/bun.js/bindings/sqlite
|
||||
${CWD}/src/bun.js/bindings/v8
|
||||
${CWD}/src/bun.js/modules
|
||||
${CWD}/src/js/builtins
|
||||
${CWD}/src/napi
|
||||
@@ -700,6 +707,7 @@ target_include_directories(${bun} PRIVATE
|
||||
${CODEGEN_PATH}
|
||||
${VENDOR_PATH}
|
||||
${VENDOR_PATH}/picohttpparser
|
||||
${NODEJS_HEADERS_PATH}/include
|
||||
)
|
||||
|
||||
# --- C/C++ Definitions ---
|
||||
@@ -875,26 +883,33 @@ else()
|
||||
-Wl,--as-needed
|
||||
-Wl,--gc-sections
|
||||
-Wl,-z,stack-size=12800000
|
||||
-Wl,--wrap=fcntl
|
||||
-Wl,--wrap=fcntl64
|
||||
-Wl,--wrap=stat64
|
||||
-Wl,--wrap=pow
|
||||
-Wl,--wrap=cosf
|
||||
-Wl,--wrap=exp
|
||||
-Wl,--wrap=expf
|
||||
-Wl,--wrap=log
|
||||
-Wl,--wrap=log2
|
||||
-Wl,--wrap=lstat
|
||||
-Wl,--wrap=stat64
|
||||
-Wl,--wrap=stat
|
||||
-Wl,--wrap=fcntl
|
||||
-Wl,--wrap=fcntl64
|
||||
-Wl,--wrap=fmod
|
||||
-Wl,--wrap=fmodf
|
||||
-Wl,--wrap=fstat
|
||||
-Wl,--wrap=fstatat
|
||||
-Wl,--wrap=lstat64
|
||||
-Wl,--wrap=fstat64
|
||||
-Wl,--wrap=fstatat
|
||||
-Wl,--wrap=fstatat64
|
||||
-Wl,--wrap=log
|
||||
-Wl,--wrap=log10f
|
||||
-Wl,--wrap=log2
|
||||
-Wl,--wrap=log2f
|
||||
-Wl,--wrap=logf
|
||||
-Wl,--wrap=lstat
|
||||
-Wl,--wrap=lstat64
|
||||
-Wl,--wrap=mknod
|
||||
-Wl,--wrap=mknodat
|
||||
-Wl,--wrap=pow
|
||||
-Wl,--wrap=sincosf
|
||||
-Wl,--wrap=sinf
|
||||
-Wl,--wrap=stat
|
||||
-Wl,--wrap=stat64
|
||||
-Wl,--wrap=statx
|
||||
-Wl,--wrap=fmod
|
||||
-Wl,--wrap=tanf
|
||||
-Wl,--compress-debug-sections=zlib
|
||||
-Wl,-z,lazy
|
||||
-Wl,-z,norelro
|
||||
|
||||
@@ -11,9 +11,13 @@ find_command(
|
||||
COMMAND
|
||||
ccache
|
||||
REQUIRED
|
||||
ON
|
||||
${CI}
|
||||
)
|
||||
|
||||
if(NOT CCACHE_PROGRAM)
|
||||
return()
|
||||
endif()
|
||||
|
||||
set(CCACHE_ARGS CMAKE_C_COMPILER_LAUNCHER CMAKE_CXX_COMPILER_LAUNCHER)
|
||||
foreach(arg ${CCACHE_ARGS})
|
||||
setx(${arg} ${CCACHE_PROGRAM})
|
||||
|
||||
@@ -11,7 +11,7 @@ if(NOT GIT_PROGRAM)
|
||||
return()
|
||||
endif()
|
||||
|
||||
set(GIT_DIFF_COMMAND ${GIT_PROGRAM} diff --no-color --name-only --diff-filter=AMCR)
|
||||
set(GIT_DIFF_COMMAND ${GIT_PROGRAM} diff --no-color --name-only --diff-filter=AMCR origin/main HEAD)
|
||||
|
||||
execute_process(
|
||||
COMMAND
|
||||
@@ -34,5 +34,10 @@ if(NOT GIT_DIFF_RESULT EQUAL 0)
|
||||
endif()
|
||||
|
||||
string(REPLACE "\n" ";" GIT_CHANGED_SOURCES "${GIT_DIFF}")
|
||||
|
||||
if(CI)
|
||||
setx(GIT_CHANGED_SOURCES ${GIT_CHANGED_SOURCES})
|
||||
endif()
|
||||
|
||||
list(TRANSFORM GIT_CHANGED_SOURCES PREPEND ${CWD}/)
|
||||
list(LENGTH GIT_CHANGED_SOURCES GIT_CHANGED_SOURCES_COUNT)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
optionx(SKIP_LLVM BOOL "If LLVM setup should be skipped" DEFAULT OFF)
|
||||
optionx(ENABLE_LLVM BOOL "If LLVM should be used for compilation" DEFAULT ON)
|
||||
|
||||
if(SKIP_LLVM)
|
||||
if(NOT ENABLE_LLVM)
|
||||
return()
|
||||
endif()
|
||||
|
||||
@@ -11,45 +11,90 @@ else()
|
||||
endif()
|
||||
|
||||
optionx(LLVM_VERSION STRING "The version of LLVM to use" DEFAULT ${DEFAULT_LLVM_VERSION})
|
||||
parse_semver(${LLVM_VERSION} LLVM)
|
||||
|
||||
string(REGEX MATCH "([0-9]+)\\.([0-9]+)\\.([0-9]+)" USE_LLVM_VERSION ${LLVM_VERSION})
|
||||
if(USE_LLVM_VERSION)
|
||||
set(LLVM_VERSION_MAJOR ${CMAKE_MATCH_1})
|
||||
set(LLVM_VERSION_MINOR ${CMAKE_MATCH_2})
|
||||
set(LLVM_VERSION_PATCH ${CMAKE_MATCH_3})
|
||||
endif()
|
||||
|
||||
set(LLVM_PATHS)
|
||||
|
||||
if(APPLE)
|
||||
execute_process(
|
||||
COMMAND brew --prefix llvm@${LLVM_VERSION_MAJOR}
|
||||
OUTPUT_VARIABLE DEFAULT_LLVM_PREFIX
|
||||
COMMAND brew --prefix
|
||||
OUTPUT_VARIABLE HOMEBREW_PREFIX
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
ERROR_QUIET
|
||||
)
|
||||
if(NOT DEFAULT_LLVM_PREFIX)
|
||||
set(DEFAULT_LLVM_PREFIX /opt/homebrew/opt/llvm)
|
||||
|
||||
if(NOT HOMEBREW_PREFIX)
|
||||
if(CMAKE_SYSTEM_PROCESSOR MATCHES "arm64|ARM64|aarch64|AARCH64")
|
||||
set(HOMEBREW_PREFIX /opt/homebrew)
|
||||
else()
|
||||
set(HOMEBREW_PREFIX /usr/local)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
list(APPEND LLVM_PATHS ${HOMEBREW_PREFIX}/opt/llvm/bin)
|
||||
|
||||
if(USE_LLVM_VERSION)
|
||||
list(APPEND LLVM_PATHS ${HOMEBREW_PREFIX}/opt/llvm@${LLVM_VERSION_MAJOR}/bin)
|
||||
endif()
|
||||
elseif(NOT WIN32)
|
||||
set(DEFAULT_LLVM_PREFIX /usr/lib/llvm-${LLVM_VERSION_MAJOR})
|
||||
else()
|
||||
set(DEFAULT_LLVM_PREFIX /usr/lib)
|
||||
endif()
|
||||
|
||||
optionx(LLVM_PREFIX FILEPATH "The path to the LLVM installation" DEFAULT ${DEFAULT_LLVM_PREFIX})
|
||||
set(LLVM_PATH ${LLVM_PREFIX}/bin)
|
||||
if(UNIX)
|
||||
list(APPEND LLVM_PATHS /usr/lib/llvm/bin)
|
||||
|
||||
if(USE_LLVM_VERSION)
|
||||
list(APPEND LLVM_PATHS
|
||||
/usr/lib/llvm-${LLVM_VERSION_MAJOR}.${LLVM_VERSION_MINOR}.${LLVM_VERSION_PATCH}/bin
|
||||
/usr/lib/llvm-${LLVM_VERSION_MAJOR}.${LLVM_VERSION_MINOR}/bin
|
||||
/usr/lib/llvm-${LLVM_VERSION_MAJOR}/bin
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
macro(find_llvm_command variable command)
|
||||
set(commands ${command})
|
||||
|
||||
if(USE_LLVM_VERSION)
|
||||
list(APPEND commands
|
||||
${command}-${LLVM_VERSION_MAJOR}.${LLVM_VERSION_MINOR}.${LLVM_VERSION_PATCH}
|
||||
${command}-${LLVM_VERSION_MAJOR}.${LLVM_VERSION_MINOR}
|
||||
${command}-${LLVM_VERSION_MAJOR}
|
||||
)
|
||||
endif()
|
||||
|
||||
macro(find_llvm_command VARIABLE COMMAND)
|
||||
find_command(
|
||||
VARIABLE ${VARIABLE}
|
||||
COMMAND ${COMMAND} ${COMMAND}-${LLVM_VERSION_MAJOR}
|
||||
PATHS ${LLVM_PATH}
|
||||
VARIABLE ${variable}
|
||||
VERSION_VARIABLE LLVM_VERSION
|
||||
COMMAND ${commands}
|
||||
PATHS ${LLVM_PATHS}
|
||||
VERSION ${LLVM_VERSION}
|
||||
)
|
||||
list(APPEND CMAKE_ARGS -D${VARIABLE}=${${VARIABLE}})
|
||||
list(APPEND CMAKE_ARGS -D${variable}=${${variable}})
|
||||
endmacro()
|
||||
|
||||
macro(find_llvm_command_no_version VARIABLE COMMAND)
|
||||
macro(find_llvm_command_no_version variable command)
|
||||
set(commands ${command})
|
||||
|
||||
if(USE_LLVM_VERSION)
|
||||
list(APPEND commands
|
||||
${command}-${LLVM_VERSION_MAJOR}.${LLVM_VERSION_MINOR}.${LLVM_VERSION_PATCH}
|
||||
${command}-${LLVM_VERSION_MAJOR}.${LLVM_VERSION_MINOR}
|
||||
${command}-${LLVM_VERSION_MAJOR}
|
||||
)
|
||||
endif()
|
||||
|
||||
find_command(
|
||||
VARIABLE ${VARIABLE}
|
||||
COMMAND ${COMMAND} ${COMMAND}-${LLVM_VERSION_MAJOR}
|
||||
PATHS ${LLVM_PATH}
|
||||
REQUIRED ON
|
||||
VARIABLE ${variable}
|
||||
VERSION_VARIABLE LLVM_VERSION
|
||||
COMMAND ${commands}
|
||||
PATHS ${LLVM_PATHS}
|
||||
)
|
||||
list(APPEND CMAKE_ARGS -D${VARIABLE}=${${VARIABLE}})
|
||||
list(APPEND CMAKE_ARGS -D${variable}=${${variable}})
|
||||
endmacro()
|
||||
|
||||
if(WIN32)
|
||||
@@ -69,3 +114,8 @@ else()
|
||||
find_llvm_command(CMAKE_DSYMUTIL dsymutil)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(ENABLE_ANALYSIS)
|
||||
find_llvm_command(CLANG_FORMAT_PROGRAM clang-format)
|
||||
find_llvm_command(CLANG_TIDY_PROGRAM clang-tidy)
|
||||
endif()
|
||||
|
||||
@@ -2,7 +2,7 @@ option(WEBKIT_VERSION "The version of WebKit to use")
|
||||
option(WEBKIT_LOCAL "If a local version of WebKit should be used instead of downloading")
|
||||
|
||||
if(NOT WEBKIT_VERSION)
|
||||
set(WEBKIT_VERSION 4a2db3254a9535949a5d5380eb58cf0f77c8e15a)
|
||||
set(WEBKIT_VERSION 0a0a3838e5fab36b579df26620237bb62ed6d950)
|
||||
endif()
|
||||
|
||||
if(WEBKIT_LOCAL)
|
||||
|
||||
262
docs/api/color.md
Normal file
262
docs/api/color.md
Normal file
@@ -0,0 +1,262 @@
|
||||
`Bun.color(input, outputFormat?)` leverages Bun's CSS parser to parse, normalize, and convert colors from user input to a variety of output formats, including:
|
||||
|
||||
| Format | Example |
|
||||
| ------------ | -------------------------------- |
|
||||
| `"css"` | `"red"` |
|
||||
| `"ansi"` | `"\x1b[38;2;255;0;0m"` |
|
||||
| `"ansi-16"` | `"\x1b[38;5;\tm"` |
|
||||
| `"ansi-256"` | `"\x1b[38;5;196m"` |
|
||||
| `"ansi-16m"` | `"\x1b[38;2;255;0;0m"` |
|
||||
| `"number"` | `0x1a2b3c` |
|
||||
| `"rgb"` | `"rgb(255, 99, 71)"` |
|
||||
| `"rgba"` | `"rgba(255, 99, 71, 0.5)"` |
|
||||
| `"hsl"` | `"hsl(120, 50%, 50%)"` |
|
||||
| `"hex"` | `"#1a2b3c"` |
|
||||
| `"HEX"` | `"#1A2B3C"` |
|
||||
| `"{rgb}"` | `{ r: 255, g: 99, b: 71 }` |
|
||||
| `"{rgba}"` | `{ r: 255, g: 99, b: 71, a: 1 }` |
|
||||
| `"[rgb]"` | `[ 255, 99, 71 ]` |
|
||||
| `"[rgba]"` | `[ 255, 99, 71, 255]` |
|
||||
|
||||
There are many different ways to use this API:
|
||||
|
||||
- Validate and normalize colors to persist in a database (`number` is the most database-friendly)
|
||||
- Convert colors to different formats
|
||||
- Colorful logging beyond the 16 colors many use today (use `ansi` if you don't want to figure out what the user's terminal supports, otherwise use `ansi-16`, `ansi-256`, or `ansi-16m` for how many colors the terminal supports)
|
||||
- Format colors for use in CSS injected into HTML
|
||||
- Get the `r`, `g`, `b`, and `a` color components as JavaScript objects or numbers from a CSS color string
|
||||
|
||||
You can think of this as an alternative to the popular npm packages [`color`](https://github.com/Qix-/color) and [`tinycolor2`](https://github.com/bgrins/TinyColor) except with full support for parsing CSS color strings and zero dependencies built directly into Bun.
|
||||
|
||||
### Flexible input
|
||||
|
||||
You can pass in any of the following:
|
||||
|
||||
- Standard CSS color names like `"red"`
|
||||
- Numbers like `0xff0000`
|
||||
- Hex strings like `"#f00"`
|
||||
- RGB strings like `"rgb(255, 0, 0)"`
|
||||
- RGBA strings like `"rgba(255, 0, 0, 1)"`
|
||||
- HSL strings like `"hsl(0, 100%, 50%)"`
|
||||
- HSLA strings like `"hsla(0, 100%, 50%, 1)"`
|
||||
- RGB objects like `{ r: 255, g: 0, b: 0 }`
|
||||
- RGBA objects like `{ r: 255, g: 0, b: 0, a: 1 }`
|
||||
- RGB arrays like `[255, 0, 0]`
|
||||
- RGBA arrays like `[255, 0, 0, 255]`
|
||||
- LAB strings like `"lab(50% 50% 50%)"`
|
||||
- ... anything else that CSS can parse as a single color value
|
||||
|
||||
### Format colors as CSS
|
||||
|
||||
The `"css"` format outputs valid CSS for use in stylesheets, inline styles, CSS variables, css-in-js, etc. It returns the most compact representation of the color as a string.
|
||||
|
||||
```ts
|
||||
Bun.color("red", "css"); // "red"
|
||||
Bun.color(0xff0000, "css"); // "#f000"
|
||||
Bun.color("#f00", "css"); // "red"
|
||||
Bun.color("#ff0000", "css"); // "red"
|
||||
Bun.color("rgb(255, 0, 0)", "css"); // "red"
|
||||
Bun.color("rgba(255, 0, 0, 1)", "css"); // "red"
|
||||
Bun.color("hsl(0, 100%, 50%)", "css"); // "red"
|
||||
Bun.color("hsla(0, 100%, 50%, 1)", "css"); // "red"
|
||||
Bun.color({ r: 255, g: 0, b: 0 }, "css"); // "red"
|
||||
Bun.color({ r: 255, g: 0, b: 0, a: 1 }, "css"); // "red"
|
||||
Bun.color([255, 0, 0], "css"); // "red"
|
||||
Bun.color([255, 0, 0, 255], "css"); // "red"
|
||||
```
|
||||
|
||||
If the input is unknown or fails to parse, `Bun.color` returns `null`.
|
||||
|
||||
### Format colors as ANSI (for terminals)
|
||||
|
||||
The `"ansi"` format outputs ANSI escape codes for use in terminals to make text colorful.
|
||||
|
||||
```ts
|
||||
Bun.color("red", "ansi"); // "\u001b[38;2;255;0;0m"
|
||||
Bun.color(0xff0000, "ansi"); // "\u001b[38;2;255;0;0m"
|
||||
Bun.color("#f00", "ansi"); // "\u001b[38;2;255;0;0m"
|
||||
Bun.color("#ff0000", "ansi"); // "\u001b[38;2;255;0;0m"
|
||||
Bun.color("rgb(255, 0, 0)", "ansi"); // "\u001b[38;2;255;0;0m"
|
||||
Bun.color("rgba(255, 0, 0, 1)", "ansi"); // "\u001b[38;2;255;0;0m"
|
||||
Bun.color("hsl(0, 100%, 50%)", "ansi"); // "\u001b[38;2;255;0;0m"
|
||||
Bun.color("hsla(0, 100%, 50%, 1)", "ansi"); // "\u001b[38;2;255;0;0m"
|
||||
Bun.color({ r: 255, g: 0, b: 0 }, "ansi"); // "\u001b[38;2;255;0;0m"
|
||||
Bun.color({ r: 255, g: 0, b: 0, a: 1 }, "ansi"); // "\u001b[38;2;255;0;0m"
|
||||
Bun.color([255, 0, 0], "ansi"); // "\u001b[38;2;255;0;0m"
|
||||
Bun.color([255, 0, 0, 255], "ansi"); // "\u001b[38;2;255;0;0m"
|
||||
```
|
||||
|
||||
This gets the color depth of stdout and automatically chooses one of `"ansi-16m"`, `"ansi-256"`, `"ansi-16"` based on the environment variables. If stdout doesn't support any form of ANSI color, it returns an empty string. As with the rest of Bun's color API, if the input is unknown or fails to parse, it returns `null`.
|
||||
|
||||
#### 24-bit ANSI colors (`ansi-16m`)
|
||||
|
||||
The `"ansi-16m"` format outputs 24-bit ANSI colors for use in terminals to make text colorful. 24-bit color means you can display 16 million colors on supported terminals, and requires a modern terminal that supports it.
|
||||
|
||||
This converts the input color to RGBA, and then outputs that as an ANSI color.
|
||||
|
||||
```ts
|
||||
Bun.color("red", "ansi-16m"); // "\x1b[38;2;255;0;0m"
|
||||
Bun.color(0xff0000, "ansi-16m"); // "\x1b[38;2;255;0;0m"
|
||||
Bun.color("#f00", "ansi-16m"); // "\x1b[38;2;255;0;0m"
|
||||
Bun.color("#ff0000", "ansi-16m"); // "\x1b[38;2;255;0;0m"
|
||||
```
|
||||
|
||||
#### 256 ANSI colors (`ansi-256`)
|
||||
|
||||
The `"ansi-256"` format approximates the input color to the nearest of the 256 ANSI colors supported by some terminals.
|
||||
|
||||
```ts
|
||||
Bun.color("red", "ansi-256"); // "\u001b[38;5;196m"
|
||||
Bun.color(0xff0000, "ansi-256"); // "\u001b[38;5;196m"
|
||||
Bun.color("#f00", "ansi-256"); // "\u001b[38;5;196m"
|
||||
Bun.color("#ff0000", "ansi-256"); // "\u001b[38;5;196m"
|
||||
```
|
||||
|
||||
To convert from RGBA to one of the 256 ANSI colors, we ported the algorithm that [`tmux` uses](https://github.com/tmux/tmux/blob/dae2868d1227b95fd076fb4a5efa6256c7245943/colour.c#L44-L55).
|
||||
|
||||
#### 16 ANSI colors (`ansi-16`)
|
||||
|
||||
The `"ansi-16"` format approximates the input color to the nearest of the 16 ANSI colors supported by most terminals.
|
||||
|
||||
```ts
|
||||
Bun.color("red", "ansi-16"); // "\u001b[38;5;\tm"
|
||||
Bun.color(0xff0000, "ansi-16"); // "\u001b[38;5;\tm"
|
||||
Bun.color("#f00", "ansi-16"); // "\u001b[38;5;\tm"
|
||||
Bun.color("#ff0000", "ansi-16"); // "\u001b[38;5;\tm"
|
||||
```
|
||||
|
||||
This works by first converting the input to a 24-bit RGB color space, then to `ansi-256`, and then we convert that to the nearest 16 ANSI color.
|
||||
|
||||
### Format colors as numbers
|
||||
|
||||
The `"number"` format outputs a 24-bit number for use in databases, configuration, or any other use case where a compact representation of the color is desired.
|
||||
|
||||
```ts
|
||||
Bun.color("red", "number"); // 16711680
|
||||
Bun.color(0xff0000, "number"); // 16711680
|
||||
Bun.color({ r: 255, g: 0, b: 0 }, "number"); // 16711680
|
||||
Bun.color([255, 0, 0], "number"); // 16711680
|
||||
Bun.color("rgb(255, 0, 0)", "number"); // 16711680
|
||||
Bun.color("rgba(255, 0, 0, 1)", "number"); // 16711680
|
||||
Bun.color("hsl(0, 100%, 50%)", "number"); // 16711680
|
||||
Bun.color("hsla(0, 100%, 50%, 1)", "number"); // 16711680
|
||||
```
|
||||
|
||||
### Get the red, green, blue, and alpha channels
|
||||
|
||||
You can use the `"{rgba}"`, `"{rgb}"`, `"[rgba]"` and `"[rgb]"` formats to get the red, green, blue, and alpha channels as objects or arrays.
|
||||
|
||||
#### `{rgba}` object
|
||||
|
||||
The `"{rgba}"` format outputs an object with the red, green, blue, and alpha channels.
|
||||
|
||||
```ts
|
||||
type RGBAObject = {
|
||||
// 0 - 255
|
||||
r: number;
|
||||
// 0 - 255
|
||||
g: number;
|
||||
// 0 - 255
|
||||
b: number;
|
||||
// 0 - 1
|
||||
a: number;
|
||||
};
|
||||
```
|
||||
|
||||
Example:
|
||||
|
||||
```ts
|
||||
Bun.color("hsl(0, 0%, 50%)", "{rgba}"); // { r: 128, g: 128, b: 128, a: 1 }
|
||||
Bun.color("red", "{rgba}"); // { r: 255, g: 0, b: 0, a: 1 }
|
||||
Bun.color(0xff0000, "{rgba}"); // { r: 255, g: 0, b: 0, a: 1 }
|
||||
Bun.color({ r: 255, g: 0, b: 0 }, "{rgba}"); // { r: 255, g: 0, b: 0, a: 1 }
|
||||
Bun.color([255, 0, 0], "{rgba}"); // { r: 255, g: 0, b: 0, a: 1 }
|
||||
```
|
||||
|
||||
To behave similarly to CSS, the `a` channel is a decimal number between `0` and `1`.
|
||||
|
||||
The `"{rgb}"` format is similar, but it doesn't include the alpha channel.
|
||||
|
||||
```ts
|
||||
Bun.color("hsl(0, 0%, 50%)", "{rgb}"); // { r: 128, g: 128, b: 128 }
|
||||
Bun.color("red", "{rgb}"); // { r: 255, g: 0, b: 0 }
|
||||
Bun.color(0xff0000, "{rgb}"); // { r: 255, g: 0, b: 0 }
|
||||
Bun.color({ r: 255, g: 0, b: 0 }, "{rgb}"); // { r: 255, g: 0, b: 0 }
|
||||
Bun.color([255, 0, 0], "{rgb}"); // { r: 255, g: 0, b: 0 }
|
||||
```
|
||||
|
||||
#### `[rgba]` array
|
||||
|
||||
The `"[rgba]"` format outputs an array with the red, green, blue, and alpha channels.
|
||||
|
||||
```ts
|
||||
// All values are 0 - 255
|
||||
type RGBAArray = [number, number, number, number];
|
||||
```
|
||||
|
||||
Example:
|
||||
|
||||
```ts
|
||||
Bun.color("hsl(0, 0%, 50%)", "[rgba]"); // [128, 128, 128, 255]
|
||||
Bun.color("red", "[rgba]"); // [255, 0, 0, 255]
|
||||
Bun.color(0xff0000, "[rgba]"); // [255, 0, 0, 255]
|
||||
Bun.color({ r: 255, g: 0, b: 0 }, "[rgba]"); // [255, 0, 0, 255]
|
||||
Bun.color([255, 0, 0], "[rgba]"); // [255, 0, 0, 255]
|
||||
```
|
||||
|
||||
Unlike the `"{rgba}"` format, the alpha channel is an integer between `0` and `255`. This is useful for typed arrays where each channel must be the same underlying type.
|
||||
|
||||
The `"[rgb]"` format is similar, but it doesn't include the alpha channel.
|
||||
|
||||
```ts
|
||||
Bun.color("hsl(0, 0%, 50%)", "[rgb]"); // [128, 128, 128]
|
||||
Bun.color("red", "[rgb]"); // [255, 0, 0]
|
||||
Bun.color(0xff0000, "[rgb]"); // [255, 0, 0]
|
||||
Bun.color({ r: 255, g: 0, b: 0 }, "[rgb]"); // [255, 0, 0]
|
||||
Bun.color([255, 0, 0], "[rgb]"); // [255, 0, 0]
|
||||
```
|
||||
|
||||
### Format colors as hex strings
|
||||
|
||||
The `"hex"` format outputs a lowercase hex string for use in CSS or other contexts.
|
||||
|
||||
```ts
|
||||
Bun.color("hsl(0, 0%, 50%)", "hex"); // "#808080"
|
||||
Bun.color("red", "hex"); // "#ff0000"
|
||||
Bun.color(0xff0000, "hex"); // "#ff0000"
|
||||
Bun.color({ r: 255, g: 0, b: 0 }, "hex"); // "#ff0000"
|
||||
Bun.color([255, 0, 0], "hex"); // "#ff0000"
|
||||
```
|
||||
|
||||
The `"HEX"` format is similar, but it outputs a hex string with uppercase letters instead of lowercase letters.
|
||||
|
||||
```ts
|
||||
Bun.color("hsl(0, 0%, 50%)", "HEX"); // "#808080"
|
||||
Bun.color("red", "HEX"); // "#FF0000"
|
||||
Bun.color(0xff0000, "HEX"); // "#FF0000"
|
||||
Bun.color({ r: 255, g: 0, b: 0 }, "HEX"); // "#FF0000"
|
||||
Bun.color([255, 0, 0], "HEX"); // "#FF0000"
|
||||
```
|
||||
|
||||
### Bundle-time client-side color formatting
|
||||
|
||||
Like many of Bun's APIs, you can use macros to invoke `Bun.color` at bundle-time for use in client-side JavaScript builds:
|
||||
|
||||
```ts#client-side.ts
|
||||
import { color } from "bun" with { type: "macro" };
|
||||
|
||||
console.log(color("#f00", "css"));
|
||||
```
|
||||
|
||||
Then, build the client-side code:
|
||||
|
||||
```sh
|
||||
bun build ./client-side.ts
|
||||
```
|
||||
|
||||
This will output the following to `client-side.js`:
|
||||
|
||||
```js
|
||||
// client-side.ts
|
||||
console.log("red");
|
||||
```
|
||||
@@ -206,4 +206,42 @@ console.log(arr);
|
||||
// => Uint8Array(32) [ 185, 77, 39, 185, 147, ... ]
|
||||
```
|
||||
|
||||
<!-- Bun.sha; -->
|
||||
### HMAC in `Bun.CryptoHasher`
|
||||
|
||||
`Bun.CryptoHasher` can be used to compute HMAC digests. To do so, pass the key to the constructor.
|
||||
|
||||
```ts
|
||||
const hasher = new Bun.CryptoHasher("sha256", "secret-key");
|
||||
hasher.update("hello world");
|
||||
console.log(hasher.digest("hex"));
|
||||
// => "095d5a21fe6d0646db223fdf3de6436bb8dfb2fab0b51677ecf6441fcf5f2a67"
|
||||
```
|
||||
|
||||
When using HMAC, a more limited set of algorithms are supported:
|
||||
|
||||
- `"blake2b512"`
|
||||
- `"md5"`
|
||||
- `"sha1"`
|
||||
- `"sha224"`
|
||||
- `"sha256"`
|
||||
- `"sha384"`
|
||||
- `"sha512-224"`
|
||||
- `"sha512-256"`
|
||||
- `"sha512"`
|
||||
|
||||
Unlike the non-HMAC `Bun.CryptoHasher`, the HMAC `Bun.CryptoHasher` instance is not reset after `.digest()` is called, and attempting to use the same instance again will throw an error.
|
||||
|
||||
Other methods like `.copy()` and `.update()` are supported (as long as it's before `.digest()`), but methods like `.digest()` that finalize the hasher are not.
|
||||
|
||||
```ts
|
||||
const hasher = new Bun.CryptoHasher("sha256", "secret-key");
|
||||
hasher.update("hello world");
|
||||
|
||||
const copy = hasher.copy();
|
||||
copy.update("!");
|
||||
console.log(copy.digest("hex"));
|
||||
// => "3840176c3d8923f59ac402b7550404b28ab11cb0ef1fa199130a5c37864b5497"
|
||||
|
||||
console.log(hasher.digest("hex"));
|
||||
// => "095d5a21fe6d0646db223fdf3de6436bb8dfb2fab0b51677ecf6441fcf5f2a67"
|
||||
```
|
||||
|
||||
@@ -100,12 +100,30 @@ When deploying to production, we recommend the following:
|
||||
bun build --compile --minify --sourcemap ./path/to/my/app.ts --outfile myapp
|
||||
```
|
||||
|
||||
**What do these flags do?**
|
||||
### Bytecode compilation
|
||||
|
||||
To improve startup time, enable bytecode compilation:
|
||||
|
||||
```sh
|
||||
bun build --compile --minify --sourcemap --bytecode ./path/to/my/app.ts --outfile myapp
|
||||
```
|
||||
|
||||
Using bytecode compilation, `tsc` starts 2x faster:
|
||||
|
||||
{% image src="https://github.com/user-attachments/assets/dc8913db-01d2-48f8-a8ef-ac4e984f9763" width="689" /%}
|
||||
|
||||
Bytecode compilation moves parsing overhead for large input files from runtime to bundle time. Your app starts faster, in exchange for making the `bun build` command a little slower. It doesn't obscure source code.
|
||||
|
||||
**Experimental:** Bytecode compilation is an experimental feature introduced in Bun v1.1.30. Only `cjs` format is supported (which means no top-level-await). Let us know if you run into any issues!
|
||||
|
||||
### What do these flags do?
|
||||
|
||||
The `--minify` argument optimizes the size of the transpiled output code. If you have a large application, this can save megabytes of space. For smaller applications, it might still improve start time a little.
|
||||
|
||||
The `--sourcemap` argument embeds a sourcemap compressed with zstd, so that errors & stacktraces point to their original locations instead of the transpiled location. Bun will automatically decompress & resolve the sourcemap when an error occurs.
|
||||
|
||||
The `--bytecode` argument enables bytecode compilation. Every time you run JavaScript code in Bun, JavaScriptCore (the engine) will compile your source code into bytecode. We can move this parsing work from runtime to bundle time, saving you startup time.
|
||||
|
||||
## Worker
|
||||
|
||||
To use workers in a standalone executable, add the worker's entrypoint to the CLI arguments:
|
||||
|
||||
@@ -330,6 +330,8 @@ Depending on the target, Bun will apply different module resolution rules and op
|
||||
|
||||
If any entrypoints contains a Bun shebang (`#!/usr/bin/env bun`) the bundler will default to `target: "bun"` instead of `"browser"`.
|
||||
|
||||
When using `target: "bun"` and `format: "cjs"` together, the `// @bun @bun-cjs` pragma is added and the CommonJS wrapper function is not compatible with Node.js.
|
||||
|
||||
---
|
||||
|
||||
- `node`
|
||||
@@ -341,7 +343,11 @@ Depending on the target, Bun will apply different module resolution rules and op
|
||||
|
||||
Specifies the module format to be used in the generated bundles.
|
||||
|
||||
Currently the bundler only supports one module format: `"esm"`. Support for `"cjs"` and `"iife"` are planned.
|
||||
Bun defaults to `"esm"`, and provides experimental support for `"cjs"` and `"iife"`.
|
||||
|
||||
#### `format: "esm"` - ES Module
|
||||
|
||||
This is the default format, which supports ES Module syntax including top-level `await`, import.meta, and more.
|
||||
|
||||
{% codetabs %}
|
||||
|
||||
@@ -359,44 +365,31 @@ $ bun build ./index.tsx --outdir ./out --format esm
|
||||
|
||||
{% /codetabs %}
|
||||
|
||||
<!-- ### `bundling`
|
||||
To use ES Module syntax in browsers, set `format` to `"esm"` and make sure your `<script type="module">` tag has `type="module"` set.
|
||||
|
||||
Whether to enable bundling.
|
||||
#### `format: "cjs"` - CommonJS
|
||||
|
||||
{% codetabs group="a" %}
|
||||
To build a CommonJS module, set `format` to `"cjs"`. When choosing `"cjs"`, the default target changes from `"browser"` (esm) to `"node"` (cjs). CommonJS modules transpiled with `format: "cjs", target: "node"` can be executed in both Bun and Node.js (assuming the APIs in use are supported by both).
|
||||
|
||||
{% codetabs %}
|
||||
|
||||
```ts#JavaScript
|
||||
await Bun.build({
|
||||
entrypoints: ['./index.tsx'],
|
||||
outdir: './out',
|
||||
bundling: true, // default
|
||||
format: "cjs",
|
||||
})
|
||||
```
|
||||
|
||||
```bash#CLI
|
||||
# bundling is enabled by default
|
||||
$ bun build ./index.tsx --outdir ./out
|
||||
$ bun build ./index.tsx --outdir ./out --format cjs
|
||||
```
|
||||
|
||||
{% /codetabs %}
|
||||
|
||||
Set to `false` to disable bundling. Instead, files will be transpiled and individually written to `outdir`.
|
||||
#### `format: "iife"` - IIFE
|
||||
|
||||
{% codetabs group="a" %}
|
||||
|
||||
```ts#JavaScript
|
||||
await Bun.build({
|
||||
entrypoints: ['./index.tsx'],
|
||||
outdir: './out',
|
||||
bundling: false,
|
||||
})
|
||||
```
|
||||
|
||||
```bash#CLI
|
||||
$ bun build ./index.tsx --outdir ./out --no-bundling
|
||||
```
|
||||
|
||||
{% /codetabs %} -->
|
||||
TODO: document IIFE once we support globalNames.
|
||||
|
||||
### `splitting`
|
||||
|
||||
@@ -758,7 +751,7 @@ $ bun build ./index.tsx --outdir ./out --external '*'
|
||||
|
||||
### `packages`
|
||||
|
||||
Control whatever package dependencies are included to bundle or not. Possible values: `bundle` (default), `external`. Bun threats any import which path do not start with `.`, `..` or `/` as package.
|
||||
Control whatever package dependencies are included to bundle or not. Possible values: `bundle` (default), `external`. Bun treats any import which path do not start with `.`, `..` or `/` as package.
|
||||
|
||||
{% codetabs group="a" %}
|
||||
|
||||
@@ -1097,6 +1090,62 @@ $ bun build ./index.tsx --outdir ./out --loader .png:dataurl --loader .txt:file
|
||||
|
||||
{% /codetabs %}
|
||||
|
||||
### `banner`
|
||||
|
||||
A banner to be added to the final bundle, this can be a directive like "use client" for react or a comment block such as a license for the code.
|
||||
|
||||
{% codetabs %}
|
||||
|
||||
```ts#JavaScript
|
||||
await Bun.build({
|
||||
entrypoints: ['./index.tsx'],
|
||||
outdir: './out',
|
||||
banner: '"use client";'
|
||||
})
|
||||
```
|
||||
|
||||
```bash#CLI
|
||||
$ bun build ./index.tsx --outdir ./out --banner "\"use client\";"
|
||||
```
|
||||
|
||||
### `footer`
|
||||
|
||||
A footer to be added to the final bundle, this can be something like a comment block for a license or just a fun easter egg.
|
||||
|
||||
{% codetabs %}
|
||||
|
||||
```ts#JavaScript
|
||||
await Bun.build({
|
||||
entrypoints: ['./index.tsx'],
|
||||
outdir: './out',
|
||||
footer: '// built with love in SF'
|
||||
})
|
||||
```
|
||||
|
||||
```bash#CLI
|
||||
$ bun build ./index.tsx --outdir ./out --footer="// built with love in SF"
|
||||
```
|
||||
|
||||
{% /codetabs %}
|
||||
|
||||
### `experimentalCss`
|
||||
|
||||
Whether to enable _experimental_ support for bundling CSS files. Defaults to `false`.
|
||||
|
||||
This supports bundling CSS files imported from JS, as well as CSS entrypoints.
|
||||
|
||||
{% codetabs group="a" %}
|
||||
|
||||
```ts#JavaScript
|
||||
const result = await Bun.build({
|
||||
entrypoints: ["./index.ts"],
|
||||
experimentalCss: true,
|
||||
});
|
||||
// => { success: boolean, outputs: BuildArtifact[], logs: BuildMessage[] }
|
||||
```
|
||||
|
||||
{% /codetabs %}
|
||||
|
||||
## Outputs
|
||||
|
||||
The `Bun.build` function returns a `Promise<BuildOutput>`, defined as:
|
||||
@@ -1138,7 +1187,7 @@ Each artifact also contains the following properties:
|
||||
---
|
||||
|
||||
- `kind`
|
||||
- What kind of build output this file is. A build generates bundled entrypoints, code-split "chunks", sourcemaps, and copied assets (like images).
|
||||
- What kind of build output this file is. A build generates bundled entrypoints, code-split "chunks", sourcemaps, bytecode, and copied assets (like images).
|
||||
|
||||
---
|
||||
|
||||
@@ -1203,6 +1252,26 @@ BuildArtifact (entry-point) {
|
||||
|
||||
{% /codetabs %}
|
||||
|
||||
### Bytecode
|
||||
|
||||
The `bytecode: boolean` option can be used to generate bytecode for any JavaScript/TypeScript entrypoints. This can greatly improve startup times for large applications. Only supported for `"cjs"` format, only supports `"target": "bun"` and dependent on a matching version of Bun. This adds a corresponding `.jsc` file for each entrypoint.
|
||||
|
||||
{% codetabs %}
|
||||
|
||||
```ts#JavaScript
|
||||
await Bun.build({
|
||||
entrypoints: ["./index.tsx"],
|
||||
outdir: "./out",
|
||||
bytecode: true,
|
||||
})
|
||||
```
|
||||
|
||||
```bash#CLI
|
||||
$ bun build ./index.tsx --outdir ./out --bytecode
|
||||
```
|
||||
|
||||
{% /codetabs %}
|
||||
|
||||
### Executables
|
||||
|
||||
Bun supports "compiling" a JavaScript/TypeScript entrypoint into a standalone executable. This executable contains a copy of the Bun binary.
|
||||
@@ -1266,33 +1335,104 @@ interface Bun {
|
||||
build(options: BuildOptions): Promise<BuildOutput>;
|
||||
}
|
||||
|
||||
interface BuildOptions {
|
||||
entrypoints: string[]; // required
|
||||
outdir?: string; // default: no write (in-memory only)
|
||||
format?: "esm"; // later: "cjs" | "iife"
|
||||
target?: "browser" | "bun" | "node"; // "browser"
|
||||
splitting?: boolean; // true
|
||||
plugins?: BunPlugin[]; // [] // See https://bun.sh/docs/bundler/plugins
|
||||
loader?: { [k in string]: Loader }; // See https://bun.sh/docs/bundler/loaders
|
||||
manifest?: boolean; // false
|
||||
external?: string[]; // []
|
||||
sourcemap?: "none" | "inline" | "linked" | "external" | "linked" | boolean; // "none"
|
||||
root?: string; // computed from entrypoints
|
||||
interface BuildConfig {
|
||||
entrypoints: string[]; // list of file path
|
||||
outdir?: string; // output directory
|
||||
target?: Target; // default: "browser"
|
||||
/**
|
||||
* Output module format. Top-level await is only supported for `"esm"`.
|
||||
*
|
||||
* Can be:
|
||||
* - `"esm"`
|
||||
* - `"cjs"` (**experimental**)
|
||||
* - `"iife"` (**experimental**)
|
||||
*
|
||||
* @default "esm"
|
||||
*/
|
||||
format?: /**
|
||||
|
||||
* ECMAScript Module format
|
||||
*/
|
||||
| "esm"
|
||||
/**
|
||||
* CommonJS format
|
||||
* **Experimental**
|
||||
*/
|
||||
| "cjs"
|
||||
/**
|
||||
* IIFE format
|
||||
* **Experimental**
|
||||
*/
|
||||
| "iife";
|
||||
naming?:
|
||||
| string
|
||||
| {
|
||||
entry?: string; // '[dir]/[name].[ext]'
|
||||
chunk?: string; // '[name]-[hash].[ext]'
|
||||
asset?: string; // '[name]-[hash].[ext]'
|
||||
};
|
||||
publicPath?: string; // e.g. http://mydomain.com/
|
||||
chunk?: string;
|
||||
entry?: string;
|
||||
asset?: string;
|
||||
}; // | string;
|
||||
root?: string; // project root
|
||||
splitting?: boolean; // default true, enable code splitting
|
||||
plugins?: BunPlugin[];
|
||||
// manifest?: boolean; // whether to return manifest
|
||||
external?: string[];
|
||||
packages?: "bundle" | "external";
|
||||
publicPath?: string;
|
||||
define?: Record<string, string>;
|
||||
// origin?: string; // e.g. http://mydomain.com
|
||||
loader?: { [k in string]: Loader };
|
||||
sourcemap?: "none" | "linked" | "inline" | "external" | "linked"; // default: "none", true -> "inline"
|
||||
/**
|
||||
* package.json `exports` conditions used when resolving imports
|
||||
*
|
||||
* Equivalent to `--conditions` in `bun build` or `bun run`.
|
||||
*
|
||||
* https://nodejs.org/api/packages.html#exports
|
||||
*/
|
||||
conditions?: Array<string> | string;
|
||||
minify?:
|
||||
| boolean // false
|
||||
| boolean
|
||||
| {
|
||||
identifiers?: boolean;
|
||||
whitespace?: boolean;
|
||||
syntax?: boolean;
|
||||
identifiers?: boolean;
|
||||
};
|
||||
/**
|
||||
* Ignore dead code elimination/tree-shaking annotations such as @__PURE__ and package.json
|
||||
* "sideEffects" fields. This should only be used as a temporary workaround for incorrect
|
||||
* annotations in libraries.
|
||||
*/
|
||||
ignoreDCEAnnotations?: boolean;
|
||||
/**
|
||||
* Force emitting @__PURE__ annotations even if minify.whitespace is true.
|
||||
*/
|
||||
emitDCEAnnotations?: boolean;
|
||||
// treeshaking?: boolean;
|
||||
|
||||
// jsx?:
|
||||
// | "automatic"
|
||||
// | "classic"
|
||||
// | /* later: "preserve" */ {
|
||||
// runtime?: "automatic" | "classic"; // later: "preserve"
|
||||
// /** Only works when runtime=classic */
|
||||
// factory?: string; // default: "React.createElement"
|
||||
// /** Only works when runtime=classic */
|
||||
// fragment?: string; // default: "React.Fragment"
|
||||
// /** Only works when runtime=automatic */
|
||||
// importSource?: string; // default: "react"
|
||||
// };
|
||||
|
||||
/**
|
||||
* Generate bytecode for the output. This can dramatically improve cold
|
||||
* start times, but will make the final output larger and slightly increase
|
||||
* memory usage.
|
||||
*
|
||||
* Bytecode is currently only supported for CommonJS (`format: "cjs"`).
|
||||
*
|
||||
* Must be `target: "bun"`
|
||||
* @default false
|
||||
*/
|
||||
bytecode?: boolean;
|
||||
}
|
||||
|
||||
interface BuildOutput {
|
||||
@@ -1304,9 +1444,9 @@ interface BuildOutput {
|
||||
interface BuildArtifact extends Blob {
|
||||
path: string;
|
||||
loader: Loader;
|
||||
hash?: string;
|
||||
kind: "entry-point" | "chunk" | "asset" | "sourcemap";
|
||||
sourcemap?: BuildArtifact;
|
||||
hash: string | null;
|
||||
kind: "entry-point" | "chunk" | "asset" | "sourcemap" | "bytecode";
|
||||
sourcemap: BuildArtifact | null;
|
||||
}
|
||||
|
||||
type Loader =
|
||||
|
||||
@@ -59,7 +59,7 @@ In Bun's CLI, simple boolean flags like `--minify` do not accept an argument. Ot
|
||||
|
||||
- `--format`
|
||||
- `--format`
|
||||
- Bun only supports `"esm"` currently but other module formats are planned. esbuild defaults to `"iife"`.
|
||||
- Bun supports `"esm"` and `"cjs"` currently, but more module formats are planned. esbuild defaults to `"iife"`.
|
||||
|
||||
---
|
||||
|
||||
@@ -154,8 +154,14 @@ In Bun's CLI, simple boolean flags like `--minify` do not accept an argument. Ot
|
||||
---
|
||||
|
||||
- `--banner`
|
||||
- n/a
|
||||
- Not supported
|
||||
- `--banner`
|
||||
- Only applies to js bundles
|
||||
|
||||
---
|
||||
|
||||
- `--footer`
|
||||
- `--footer`
|
||||
- Only applies to js bundles
|
||||
|
||||
---
|
||||
|
||||
@@ -195,12 +201,6 @@ In Bun's CLI, simple boolean flags like `--minify` do not accept an argument. Ot
|
||||
|
||||
---
|
||||
|
||||
- `--footer`
|
||||
- n/a
|
||||
- Not supported
|
||||
|
||||
---
|
||||
|
||||
- `--global-name`
|
||||
- n/a
|
||||
- Not applicable, Bun does not support `iife` output at this time
|
||||
|
||||
@@ -1,5 +1,22 @@
|
||||
The `bun pm` command group provides a set of utilities for working with Bun's package manager.
|
||||
|
||||
## pack
|
||||
|
||||
To create a tarball of the current workspace:
|
||||
|
||||
```bash
|
||||
$ bun pm pack
|
||||
```
|
||||
|
||||
Options for the `pack` command:
|
||||
|
||||
- `--dry-run`: Perform all tasks except writing the tarball to disk.
|
||||
- `--destination`: Specify the directory where the tarball will be saved.
|
||||
- `--ignore-scripts`: Skip running pre/postpack and prepare scripts.
|
||||
- `--gzip-level`: Set a custom compression level for gzip, ranging from 0 to 9 (default is 9).
|
||||
|
||||
## bin
|
||||
|
||||
To print the path to the `bin` directory for the local project:
|
||||
|
||||
```bash
|
||||
@@ -14,6 +31,8 @@ $ bun pm bin -g
|
||||
<$HOME>/.bun/bin
|
||||
```
|
||||
|
||||
## ls
|
||||
|
||||
To print a list of installed dependencies in the current project and their resolved versions, excluding their dependencies.
|
||||
|
||||
```bash
|
||||
@@ -45,6 +64,36 @@ $ bun pm ls --all
|
||||
├── ...
|
||||
```
|
||||
|
||||
## whoami
|
||||
|
||||
Print your npm username. Requires you to be logged in (`bunx npm login`) with credentials in either `bunfig.toml` or `.npmrc`:
|
||||
|
||||
```bash
|
||||
$ bun pm whoami
|
||||
```
|
||||
|
||||
## hash
|
||||
|
||||
To generate and print the hash of the current lockfile:
|
||||
|
||||
```bash
|
||||
$ bun pm hash
|
||||
```
|
||||
|
||||
To print the string used to hash the lockfile:
|
||||
|
||||
```bash
|
||||
$ bun pm hash-string
|
||||
```
|
||||
|
||||
To print the hash stored in the current lockfile:
|
||||
|
||||
```bash
|
||||
$ bun pm hash-print
|
||||
```
|
||||
|
||||
## cache
|
||||
|
||||
To print the path to Bun's global module cache:
|
||||
|
||||
```bash
|
||||
@@ -57,16 +106,45 @@ To clear Bun's global module cache:
|
||||
$ bun pm cache rm
|
||||
```
|
||||
|
||||
## List global installs
|
||||
## migrate
|
||||
|
||||
To list all globally installed packages:
|
||||
To migrate another package manager's lockfile without installing anything:
|
||||
|
||||
```bash
|
||||
$ bun pm ls -g
|
||||
$ bun pm migrate
|
||||
```
|
||||
|
||||
To list all globally installed packages, including nth-order dependencies:
|
||||
## untrusted
|
||||
|
||||
To print current untrusted dependencies with scripts:
|
||||
|
||||
```bash
|
||||
$ bun pm ls -g --all
|
||||
$ bun pm untrusted
|
||||
|
||||
./node_modules/@biomejs/biome @1.8.3
|
||||
» [postinstall]: node scripts/postinstall.js
|
||||
|
||||
These dependencies had their lifecycle scripts blocked during install.
|
||||
```
|
||||
|
||||
## trust
|
||||
|
||||
To run scripts for untrusted dependencies and add to `trustedDependencies`:
|
||||
|
||||
```bash
|
||||
$ bun pm trust <names>
|
||||
```
|
||||
|
||||
Options for the `trust` command:
|
||||
|
||||
- `--all`: Trust all untrusted dependencies.
|
||||
|
||||
## default-trusted
|
||||
|
||||
To print the default trusted dependencies list:
|
||||
|
||||
```bash
|
||||
$ bun pm default-trusted
|
||||
```
|
||||
|
||||
see the current list on GitHub [here](https://github.com/oven-sh/bun/blob/main/src/install/default-trusted-dependencies.txt)
|
||||
|
||||
107
docs/cli/publish.md
Normal file
107
docs/cli/publish.md
Normal file
@@ -0,0 +1,107 @@
|
||||
Use `bun publish` to publish a package to the npm registry.
|
||||
|
||||
`bun publish` will automatically pack your package into a tarball, strip workspace protocols from the `package.json` (resolving versions if necessary), and publish to the registry specified in your configuration files. Both `bunfig.toml` and `.npmrc` files are supported.
|
||||
|
||||
```sh
|
||||
## Publishing the package from the current working directory
|
||||
$ bun publish
|
||||
|
||||
## Output
|
||||
bun publish v1.1.30 (ca7428e9)
|
||||
|
||||
packed 203B package.json
|
||||
packed 224B README.md
|
||||
packed 30B index.ts
|
||||
packed 0.64KB tsconfig.json
|
||||
|
||||
Total files: 4
|
||||
Shasum: 79e2b4377b63f4de38dc7ea6e5e9dbee08311a69
|
||||
Integrity: sha512-6QSNlDdSwyG/+[...]X6wXHriDWr6fA==
|
||||
Unpacked size: 1.1KB
|
||||
Packed size: 0.76KB
|
||||
Tag: latest
|
||||
Access: default
|
||||
Registry: http://localhost:4873/
|
||||
|
||||
+ publish-1@1.0.0
|
||||
```
|
||||
|
||||
Alternatively, you can pack and publish your package separately by using `bun pm pack` followed by `bun publish` with the path to the output tarball.
|
||||
|
||||
```sh
|
||||
$ bun pm pack
|
||||
...
|
||||
$ bun publish ./package.tgz
|
||||
```
|
||||
|
||||
{% callout %}
|
||||
**Note** - `bun publish` will not run lifecycle scripts (`prepublishOnly/prepack/prepare/postpack/publish/postpublish`) if a tarball path is provided. Scripts will only be run if the package is packed by `bun publish`.
|
||||
{% /callout %}
|
||||
|
||||
### `--access`
|
||||
|
||||
The `--access` flag can be used to set the access level of the package being published. The access level can be one of `public` or `restricted`. Unscoped packages are always public, and attempting to publish an unscoped package with `--access restricted` will result in an error.
|
||||
|
||||
```sh
|
||||
$ bun publish --access public
|
||||
```
|
||||
|
||||
`--access` can also be set in the `publishConfig` field of your `package.json`.
|
||||
|
||||
```json
|
||||
{
|
||||
"publishConfig": {
|
||||
"access": "restricted"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### `--tag`
|
||||
|
||||
Set the tag of the package version being published. By default, the tag is `latest`. The initial version of a package is always given the `latest` tag in addition to the specified tag.
|
||||
|
||||
```sh
|
||||
$ bun publish --tag alpha
|
||||
```
|
||||
|
||||
`--tag` can also be set in the `publishConfig` field of your `package.json`.
|
||||
|
||||
```json
|
||||
{
|
||||
"publishConfig": {
|
||||
"tag": "next"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### `--dry-run`
|
||||
|
||||
The `--dry-run` flag can be used to simulate the publish process without actually publishing the package. This is useful for verifying the contents of the published package without actually publishing the package.
|
||||
|
||||
```sh
|
||||
$ bun publish --dry-run
|
||||
```
|
||||
|
||||
### `--auth-type`
|
||||
|
||||
If you have 2FA enabled for your npm account, `bun publish` will prompt you for a one-time password. This can be done through a browser or the CLI. The `--auth-type` flag can be used to tell the npm registry which method you prefer. The possible values are `web` and `legacy`, with `web` being the default.
|
||||
|
||||
```sh
|
||||
$ bun publish --auth-type legacy
|
||||
...
|
||||
This operation requires a one-time password.
|
||||
Enter OTP: 123456
|
||||
...
|
||||
```
|
||||
|
||||
### `--otp`
|
||||
|
||||
Provide a one-time password directly to the CLI. If the password is valid, this will skip the extra prompt for a one-time password before publishing. Example usage:
|
||||
|
||||
```sh
|
||||
$ bun publish --otp 123456
|
||||
```
|
||||
|
||||
### `--gzip-level`
|
||||
|
||||
Specify the level of gzip compression to use when packing the package. Only applies to `bun publish` without a tarball path argument. Values range from `0` to `9` (default is `9`).
|
||||
@@ -17,7 +17,7 @@ If you are seeing one of the following errors, you are probably trying to use a
|
||||
|
||||
---
|
||||
|
||||
To tell Bun to allow lifecycle scripts for a particular package, add the package to `trustedDependencies` in your package.json.
|
||||
To allow Bun to execute lifecycle scripts for a specific package, add the package to `trustedDependencies` in your package.json file. You can do this automatically by running the command `bun pm trust <pkg>`.
|
||||
|
||||
{% callout %}
|
||||
Note that this only allows lifecycle scripts for the specific package listed in `trustedDependencies`, _not_ the dependencies of that dependency!
|
||||
|
||||
@@ -16,7 +16,7 @@ Add the following to your local or global `.gitattributes` file:
|
||||
*.lockb binary diff=lockb
|
||||
```
|
||||
|
||||
Then add the following to you local git config with:
|
||||
Then add the following to your local git config with:
|
||||
|
||||
```sh
|
||||
$ git config diff.lockb.textconv bun
|
||||
|
||||
@@ -41,7 +41,7 @@ In the root `package.json`, the `"workspaces"` key is used to indicate which sub
|
||||
**Glob support** — Bun supports full glob syntax in `"workspaces"` (see [here](https://bun.sh/docs/api/glob#supported-glob-patterns) for a comprehensive list of supported syntax), _except_ for exclusions (e.g. `!**/excluded/**`), which are not implemented yet.
|
||||
{% /callout %}
|
||||
|
||||
Each workspace has it's own `package.json` When referencing other packages in the monorepo, use `"workspace:*"` as the version field in your `package.json`.
|
||||
Each workspace has it's own `package.json`. When referencing other packages in the monorepo, semver or workspace protocols (e.g. `workspace:*`) can be used as the version field in your `package.json`.
|
||||
|
||||
```json
|
||||
{
|
||||
@@ -53,10 +53,6 @@ Each workspace has it's own `package.json` When referencing other packages in th
|
||||
}
|
||||
```
|
||||
|
||||
{% callout %}
|
||||
**Version support** — Bun supports simple `workspace:*` versions in `"dependencies"`. Full version syntax (e.g. `workspace:^*`) is not yet supported.
|
||||
{% /callout %}
|
||||
|
||||
Workspaces have a couple major benefits.
|
||||
|
||||
- **Code can be split into logical parts.** If one package relies on another, you can simply add it as a dependency in `package.json`. If package `b` depends on `a`, `bun install` will install your local `packages/a` directory into `node_modules` instead of downloading it from the npm registry.
|
||||
|
||||
@@ -164,6 +164,9 @@ export default {
|
||||
page("cli/update", "`bun update`", {
|
||||
description: "Update your project's dependencies.",
|
||||
}),
|
||||
page("cli/publish", "`bun publish`", {
|
||||
description: "Publish your package to an npm registry.",
|
||||
}),
|
||||
page("cli/outdated", "`bun outdated`", {
|
||||
description: "Check for outdated dependencies.",
|
||||
}),
|
||||
@@ -374,6 +377,10 @@ export default {
|
||||
description: `Bun's native Semver implementation is 20x faster than the popular \`node-semver\` package.`,
|
||||
}), // "`Semver`"),
|
||||
|
||||
page("api/color", "Color", {
|
||||
description: `Bun's color function leverages Bun's CSS parser for parsing, normalizing, and converting colors from user input to a variety of output formats.`,
|
||||
}), // "`Color`"),
|
||||
|
||||
// divider("Dev Server"),
|
||||
// page("bun-dev", "Vanilla"),
|
||||
// page("dev/css", "CSS"),
|
||||
|
||||
@@ -76,6 +76,12 @@ test("wat", async () => {
|
||||
}, 500); // test must run in <500ms
|
||||
```
|
||||
|
||||
In `bun:test`, test timeouts throw an uncatchable exception to force the test to stop running and fail. We also kill any child processes that were spawned in the test to avoid leaving behind zombie processes lurking in the background.
|
||||
|
||||
### 🧟 Zombie process killer
|
||||
|
||||
When a test times out and processes spawned in the test via `Bun.spawn`, `Bun.spawnSync`, or `node:child_process` are not killed, they will be automatically killed and a message will be logged to the console.
|
||||
|
||||
## `test.skip`
|
||||
|
||||
Skip individual tests with `test.skip`. These tests will not be run.
|
||||
@@ -324,6 +330,7 @@ Bun implements the following matchers. Full Jest compatibility is on the roadmap
|
||||
- [`.toContainAllValues()`](https://jest-extended.jestcommunity.dev/docs/matchers/Object#tocontainallvaluesvalues)
|
||||
|
||||
---
|
||||
|
||||
- ✅
|
||||
- [`.toContainAnyValues()`](https://jest-extended.jestcommunity.dev/docs/matchers/Object#tocontainanyvaluesvalues)
|
||||
|
||||
|
||||
35
package.json
35
package.json
@@ -21,7 +21,10 @@
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1",
|
||||
"source-map-js": "^1.2.0",
|
||||
"typescript": "^5.4.5"
|
||||
"typescript": "^5.4.5",
|
||||
"caniuse-lite": "^1.0.30001620",
|
||||
"autoprefixer": "^10.4.19",
|
||||
"@mdn/browser-compat-data": "~5.5.28"
|
||||
},
|
||||
"resolutions": {
|
||||
"bun-types": "workspace:packages/bun-types"
|
||||
@@ -40,6 +43,7 @@
|
||||
"build:release:local": "bun ./scripts/build.mjs -GNinja -DCMAKE_BUILD_TYPE=Release -DWEBKIT_LOCAL=ON -B build/release",
|
||||
"build:release:with_logs": "cmake . -DCMAKE_BUILD_TYPE=Release -DENABLE_LOGS=true -GNinja -Bbuild-release && ninja -Cbuild-release",
|
||||
"build:debug-zig-release": "cmake . -DCMAKE_BUILD_TYPE=Release -DZIG_OPTIMIZE=Debug -GNinja -Bbuild-debug-zig-release && ninja -Cbuild-debug-zig-release",
|
||||
"css-properties": "bun run src/css/properties/generate_properties.ts",
|
||||
"bump": "bun ./scripts/bump.ts",
|
||||
"typecheck": "tsc --noEmit && cd test && bun run typecheck",
|
||||
"fmt": "bun run prettier",
|
||||
@@ -55,19 +59,20 @@
|
||||
"zig:check": "bun run zig build check --summary new",
|
||||
"zig:check-all": "bun run zig build check-all --summary new",
|
||||
"zig:check-windows": "bun run zig build check-windows --summary new",
|
||||
"cmake": "bun ./scripts/build.mjs -DCMAKE_BUILD_TYPE=Debug -B build/debug",
|
||||
"clang-format": "bun run cmake --target clang-format",
|
||||
"clang-format:check": "bun run cmake --target clang-format-check",
|
||||
"clang-format:diff": "bun run cmake --target clang-format-diff",
|
||||
"clang-tidy": "bun run cmake --target clang-tidy",
|
||||
"clang-tidy:check": "bun run cmake --target clang-tidy-check",
|
||||
"clang-tidy:diff": "bun run cmake --target clang-tidy-diff",
|
||||
"zig-format": "bun run cmake --target zig-format",
|
||||
"zig-format:check": "bun run cmake --target zig-format-check",
|
||||
"zig-format:diff": "bun run cmake --target zig-format-diff",
|
||||
"prettier": "bun run cmake --target prettier",
|
||||
"prettier:check": "bun run cmake --target prettier-check",
|
||||
"prettier:extra": "bun run cmake --target prettier-extra",
|
||||
"prettier:diff": "bun run cmake --target prettier-diff"
|
||||
"analysis": "bun ./scripts/build.mjs -DCMAKE_BUILD_TYPE=Debug -DENABLE_ANALYSIS=ON -DENABLE_CCACHE=OFF -B build/analysis",
|
||||
"analysis:no-llvm": "bun run analysis -DENABLE_LLVM=OFF",
|
||||
"clang-format": "bun run analysis --target clang-format",
|
||||
"clang-format:check": "bun run analysis --target clang-format-check",
|
||||
"clang-format:diff": "bun run analysis --target clang-format-diff",
|
||||
"clang-tidy": "bun run analysis --target clang-tidy",
|
||||
"clang-tidy:check": "bun run analysis --target clang-tidy-check",
|
||||
"clang-tidy:diff": "bun run analysis --target clang-tidy-diff",
|
||||
"zig-format": "bun run analysis:no-llvm --target zig-format",
|
||||
"zig-format:check": "bun run analysis:no-llvm --target zig-format-check",
|
||||
"zig-format:diff": "bun run analysis:no-llvm --target zig-format-diff",
|
||||
"prettier": "bun run analysis:no-llvm --target prettier",
|
||||
"prettier:check": "bun run analysis:no-llvm --target prettier-check",
|
||||
"prettier:extra": "bun run analysis:no-llvm --target prettier-extra",
|
||||
"prettier:diff": "bun run analysis:no-llvm --target prettier-diff"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
bin/bun-profile
|
||||
bin/*.o
|
||||
*.o
|
||||
*.a
|
||||
@@ -1,4 +0,0 @@
|
||||
bin/bun-profile
|
||||
bin/*.o
|
||||
*.o
|
||||
*.a
|
||||
@@ -1,3 +0,0 @@
|
||||
# `bun-plugin-css`
|
||||
|
||||
Not implemented.
|
||||
@@ -1 +0,0 @@
|
||||
throw new Error("Not implemented.");
|
||||
@@ -1,10 +0,0 @@
|
||||
{
|
||||
"name": "bun-plugin-css",
|
||||
"version": "0.0.1-alpha.0",
|
||||
"module": "index.ts",
|
||||
"type": "module",
|
||||
"files": [
|
||||
"index.ts",
|
||||
"package.json"
|
||||
]
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
# `bun-plugin-lightningcss`
|
||||
|
||||
Not implemented.
|
||||
@@ -1 +0,0 @@
|
||||
throw new Error("Not implemented.");
|
||||
@@ -1,10 +0,0 @@
|
||||
{
|
||||
"name": "bun-plugin-lightningcss",
|
||||
"version": "0.0.1-alpha.0",
|
||||
"module": "index.ts",
|
||||
"type": "module",
|
||||
"files": [
|
||||
"index.ts",
|
||||
"package.json"
|
||||
]
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
# `bun-plugin-mdx`
|
||||
|
||||
Not implemented.
|
||||
@@ -1 +0,0 @@
|
||||
throw new Error("Not implemented.");
|
||||
@@ -1,10 +0,0 @@
|
||||
{
|
||||
"name": "bun-plugin-mdx",
|
||||
"version": "0.0.1-alpha.0",
|
||||
"module": "index.ts",
|
||||
"type": "module",
|
||||
"files": [
|
||||
"index.ts",
|
||||
"package.json"
|
||||
]
|
||||
}
|
||||
169
packages/bun-plugin-server-components/.gitignore
vendored
169
packages/bun-plugin-server-components/.gitignore
vendored
@@ -1,169 +0,0 @@
|
||||
# Based on https://raw.githubusercontent.com/github/gitignore/main/Node.gitignore
|
||||
|
||||
# Logs
|
||||
|
||||
logs
|
||||
_.log
|
||||
npm-debug.log_
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
lerna-debug.log*
|
||||
.pnpm-debug.log*
|
||||
|
||||
# Diagnostic reports (https://nodejs.org/api/report.html)
|
||||
|
||||
report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json
|
||||
|
||||
# Runtime data
|
||||
|
||||
pids
|
||||
_.pid
|
||||
_.seed
|
||||
\*.pid.lock
|
||||
|
||||
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||
|
||||
lib-cov
|
||||
|
||||
# Coverage directory used by tools like istanbul
|
||||
|
||||
coverage
|
||||
\*.lcov
|
||||
|
||||
# nyc test coverage
|
||||
|
||||
.nyc_output
|
||||
|
||||
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
|
||||
|
||||
.grunt
|
||||
|
||||
# Bower dependency directory (https://bower.io/)
|
||||
|
||||
bower_components
|
||||
|
||||
# node-waf configuration
|
||||
|
||||
.lock-wscript
|
||||
|
||||
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
||||
|
||||
build/Release
|
||||
|
||||
# Dependency directories
|
||||
|
||||
node_modules/
|
||||
jspm_packages/
|
||||
|
||||
# Snowpack dependency directory (https://snowpack.dev/)
|
||||
|
||||
web_modules/
|
||||
|
||||
# TypeScript cache
|
||||
|
||||
\*.tsbuildinfo
|
||||
|
||||
# Optional npm cache directory
|
||||
|
||||
.npm
|
||||
|
||||
# Optional eslint cache
|
||||
|
||||
.eslintcache
|
||||
|
||||
# Optional stylelint cache
|
||||
|
||||
.stylelintcache
|
||||
|
||||
# Microbundle cache
|
||||
|
||||
.rpt2_cache/
|
||||
.rts2_cache_cjs/
|
||||
.rts2_cache_es/
|
||||
.rts2_cache_umd/
|
||||
|
||||
# Optional REPL history
|
||||
|
||||
.node_repl_history
|
||||
|
||||
# Output of 'npm pack'
|
||||
|
||||
\*.tgz
|
||||
|
||||
# Yarn Integrity file
|
||||
|
||||
.yarn-integrity
|
||||
|
||||
# dotenv environment variable files
|
||||
|
||||
.env
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
.env.local
|
||||
|
||||
# parcel-bundler cache (https://parceljs.org/)
|
||||
|
||||
.cache
|
||||
.parcel-cache
|
||||
|
||||
# Next.js build output
|
||||
|
||||
.next
|
||||
out
|
||||
|
||||
# Nuxt.js build / generate output
|
||||
|
||||
.nuxt
|
||||
dist
|
||||
|
||||
# Gatsby files
|
||||
|
||||
.cache/
|
||||
|
||||
# Comment in the public line in if your project uses Gatsby and not Next.js
|
||||
|
||||
# https://nextjs.org/blog/next-9-1#public-directory-support
|
||||
|
||||
# public
|
||||
|
||||
# vuepress build output
|
||||
|
||||
.vuepress/dist
|
||||
|
||||
# vuepress v2.x temp and cache directory
|
||||
|
||||
.temp
|
||||
.cache
|
||||
|
||||
# Docusaurus cache and generated files
|
||||
|
||||
.docusaurus
|
||||
|
||||
# Serverless directories
|
||||
|
||||
.serverless/
|
||||
|
||||
# FuseBox cache
|
||||
|
||||
.fusebox/
|
||||
|
||||
# DynamoDB Local files
|
||||
|
||||
.dynamodb/
|
||||
|
||||
# TernJS port file
|
||||
|
||||
.tern-port
|
||||
|
||||
# Stores VSCode versions used for testing VSCode extensions
|
||||
|
||||
.vscode-test
|
||||
|
||||
# yarn v2
|
||||
|
||||
.yarn/cache
|
||||
.yarn/unplugged
|
||||
.yarn/build-state.yml
|
||||
.yarn/install-state.gz
|
||||
.pnp.\*
|
||||
@@ -1,149 +0,0 @@
|
||||
# `bun-plugin-server-components`
|
||||
|
||||
The official Bun plugin for **server components**.
|
||||
|
||||
## Installation
|
||||
|
||||
```sh
|
||||
bun add bun-plugin-server-components -d
|
||||
```
|
||||
|
||||
## Context
|
||||
|
||||
Server components are a new abstraction for building web applications. They look similar to standard React/JSX components, but render exclusively on the server. They differ from classic "client components" in a few ways:
|
||||
|
||||
1. They can be `async`.
|
||||
2. Their implementation can run privileged code like database queries. Normally this would be unsafe, because the source code of client components are typically bundled and sent to the client, where they can be inspected and reverse-engineered. Server components are never sent to the client, so they can run privileged code safely.
|
||||
3. They _cannot_ contain stateful hooks like `useState` or `useEffect`.
|
||||
|
||||
Server components require a deep integration with the bundler to work. To understand why, we need a bit of background on how server components work.
|
||||
|
||||
### How server components work
|
||||
|
||||
Imagine you have a server component that looks like this:
|
||||
|
||||
```tsx
|
||||
// index.tsx
|
||||
import { Component } from "./Component";
|
||||
export default async function HomePage() {
|
||||
return (
|
||||
<div>
|
||||
<Component />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
This file imports a client component called `Component`.
|
||||
|
||||
```ts
|
||||
// ./Component.tsx
|
||||
"use client";
|
||||
|
||||
export function Component() {
|
||||
return <div>Hello world</div>;
|
||||
}
|
||||
```
|
||||
|
||||
To run this component we need to generate two builds.
|
||||
|
||||
> Here the term "build" refers to a typical bundling step—the act of converting a set of entrypoints into a set of bundles.
|
||||
|
||||
1. The first is our "server component build". It contains all the code we need to render `HomePage` to a component tree. When an incoming `Request` comes in, we can use React's built-in tools to convert this tree into a "virtual DOM stream" that we can return as a `Response`.
|
||||
2. The second is our "client build". It contains the bundled versions of all client components that were referenced by our server components.
|
||||
|
||||
The browser hits the server and gets back the "virtual DOM stream". The virtual DOM stream will contain references to client components, which will be loaded from the client bundle. React provides a built-in utility (`createFromFetch`)that accepts the VDOM stream, dynamically loads the necessary client components, and returns a renderable component.
|
||||
|
||||
```ts
|
||||
import { createRoot } from "react-dom/client";
|
||||
import { createFromFetch } from "react-server-dom-webpack/client.browser";
|
||||
|
||||
const stream = fetch("/", { headers: { Accept: "text/x-component" } });
|
||||
const data = createFromFetch(stream);
|
||||
|
||||
const root = createRoot(document);
|
||||
root.render(<App />);
|
||||
```
|
||||
|
||||
### Server-side rendering
|
||||
|
||||
One potentially confusing aspect of server components is that they "return" virtual DOM. From the perspective of a server component, client components are black boxes.
|
||||
|
||||
If we want to do server-side rendering, we need to render our server component to VDOM, _then_ render the VDOM to plain HTML. These are two distinct steps. The second step requires a _third build_, we we'll call the "SSR build". Like the "client build", this build will bundle all the client components. Unlike the "client build", those bundles will be intended for consumption on the server; in bundler terms, the build's `"target"` will be`"bun"` (or perhaps `"node"`).
|
||||
|
||||
### Bundling server components
|
||||
|
||||
That's a high-level overview of how server components work. The important takeaway is that we need to generate totally separate bundles for server and client components.
|
||||
|
||||
But it's not just a simple matter of running two separate bundling scripts. The true "entrypoints" of our application are the server components. Over the course of bundling our server components, we will discover some files containing the `"use client"` directive; these files then become the entrypoints for our "client build", which will require a totally separate build configuration from the server build.
|
||||
|
||||
The goal of this plugin is to hide the complexty of this multi-stage build from the user.
|
||||
|
||||
## Usage
|
||||
|
||||
To use this plugin:
|
||||
|
||||
```ts
|
||||
import ServerComponentsPlugin from "bun-plugin-server-components";
|
||||
|
||||
await Bun.build({
|
||||
entrypoints: ["./index.tsx"], // server component files
|
||||
plugins: [
|
||||
ServerComponentsPlugin({
|
||||
// plugin configuration
|
||||
}),
|
||||
],
|
||||
// other configuration
|
||||
});
|
||||
```
|
||||
|
||||
The `"entrypoints"` you pass into `Bun.build()` should be your _server components_. Bun's bundler will automatically detect any files containing the `"use client"` directive, and will use those files as entrypoints for the "client build" and "SSR build". The bundler configuration for these builds can be provided `client` and `ssr` keys respectively.
|
||||
|
||||
```ts
|
||||
import ServerComponentsPlugin from "bun-plugin-server-components";
|
||||
|
||||
await Bun.build({
|
||||
entrypoints: ["./index.tsx"], // server component files
|
||||
outdir: "./build",
|
||||
manifest: true,
|
||||
plugins: [ServerComponentsPlugin({
|
||||
client: {
|
||||
entrypoints: [], // optional - additional client entrypoints
|
||||
outdir: "./build/client", // default: inherits from the main build
|
||||
target: "browser",
|
||||
plugins: [/* */],
|
||||
}
|
||||
ssr: {
|
||||
entrypoints: [], // optional - additional SSR entrypoints
|
||||
outdir: "./build/client", // default: inherits from the main build
|
||||
target: "bun", // this is default
|
||||
plugins: [/* */],
|
||||
}
|
||||
})],
|
||||
});
|
||||
```
|
||||
|
||||
The result of `Bun.build()` will contain additional manifests for the SSR and client builds.
|
||||
|
||||
```ts
|
||||
const result = await Bun.build({
|
||||
// config
|
||||
plugins: [
|
||||
ServerComponentsPlugin({
|
||||
/* config */
|
||||
}),
|
||||
],
|
||||
});
|
||||
|
||||
// standard manifest
|
||||
// for the top-level (server components) build
|
||||
result.manifest;
|
||||
|
||||
// manifest for client build
|
||||
result.clientManifest;
|
||||
|
||||
// manifest for client build
|
||||
result.ssrManifest;
|
||||
```
|
||||
|
||||
Once the build is complete, use the manifests to implement your RSC server.
|
||||
Binary file not shown.
@@ -1,10 +0,0 @@
|
||||
import { BunPlugin, BuildConfig } from "bun";
|
||||
|
||||
function Plugin(config: { client?: BuildConfig; ssr?: BuildConfig }): BunPlugin {
|
||||
return {
|
||||
name: "bun-plugin-server-components",
|
||||
SECRET_SERVER_COMPONENTS_INTERNALS: config,
|
||||
} as any;
|
||||
}
|
||||
|
||||
export default Plugin;
|
||||
@@ -1,28 +0,0 @@
|
||||
{
|
||||
"name": "bun-plugin-server-components",
|
||||
"version": "0.0.1-alpha.0",
|
||||
"module": "index.ts",
|
||||
"type": "module",
|
||||
"types": "index.ts",
|
||||
"exports": {
|
||||
".": {
|
||||
"import": "./index.ts",
|
||||
"require": "./index.ts",
|
||||
"default": "./index.js"
|
||||
},
|
||||
"./package.json": "./package.json"
|
||||
},
|
||||
"files": [
|
||||
"index.ts",
|
||||
"tsconfig.json",
|
||||
"package.json",
|
||||
"modules.d.ts"
|
||||
],
|
||||
"devDependencies": {
|
||||
"@types/js-yaml": "^4.0.5"
|
||||
},
|
||||
"dependencies": {
|
||||
"bun-types": "canary",
|
||||
"js-yaml": "^4.1.0"
|
||||
}
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"lib": ["ESNext"],
|
||||
"module": "esnext",
|
||||
"target": "esnext",
|
||||
"moduleResolution": "bundler",
|
||||
"moduleDetection": "force",
|
||||
"allowImportingTsExtensions": true,
|
||||
"noEmit": true,
|
||||
"composite": true,
|
||||
"strict": true,
|
||||
"downlevelIteration": true,
|
||||
"skipLibCheck": true,
|
||||
"jsx": "react-jsx",
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"allowJs": true,
|
||||
"types": [
|
||||
"bun-types" // add Bun global
|
||||
]
|
||||
},
|
||||
"include": ["**/*.ts", "modules.d.ts"]
|
||||
}
|
||||
177
packages/bun-types/bun.d.ts
vendored
177
packages/bun-types/bun.d.ts
vendored
@@ -1497,13 +1497,35 @@ declare module "bun" {
|
||||
kind: ImportKind;
|
||||
}
|
||||
|
||||
type ModuleFormat = "esm"; // later: "cjs", "iife"
|
||||
|
||||
interface BuildConfig {
|
||||
entrypoints: string[]; // list of file path
|
||||
outdir?: string; // output directory
|
||||
target?: Target; // default: "browser"
|
||||
format?: ModuleFormat; // later: "cjs", "iife"
|
||||
/**
|
||||
* Output module format. Top-level await is only supported for `"esm"`.
|
||||
*
|
||||
* Can be:
|
||||
* - `"esm"`
|
||||
* - `"cjs"` (**experimental**)
|
||||
* - `"iife"` (**experimental**)
|
||||
*
|
||||
* @default "esm"
|
||||
*/
|
||||
format?: /**
|
||||
|
||||
* ECMAScript Module format
|
||||
*/
|
||||
| "esm"
|
||||
/**
|
||||
* CommonJS format
|
||||
* **Experimental**
|
||||
*/
|
||||
| "cjs"
|
||||
/**
|
||||
* IIFE format
|
||||
* **Experimental**
|
||||
*/
|
||||
| "iife";
|
||||
naming?:
|
||||
| string
|
||||
| {
|
||||
@@ -1561,6 +1583,35 @@ declare module "bun" {
|
||||
// /** Only works when runtime=automatic */
|
||||
// importSource?: string; // default: "react"
|
||||
// };
|
||||
|
||||
/**
|
||||
* Generate bytecode for the output. This can dramatically improve cold
|
||||
* start times, but will make the final output larger and slightly increase
|
||||
* memory usage.
|
||||
*
|
||||
* Bytecode is currently only supported for CommonJS (`format: "cjs"`).
|
||||
*
|
||||
* Must be `target: "bun"`
|
||||
* @default false
|
||||
*/
|
||||
bytecode?: boolean;
|
||||
/**
|
||||
* Add a banner to the bundled code such as "use client";
|
||||
*/
|
||||
banner?: string;
|
||||
/**
|
||||
* Add a footer to the bundled code such as a comment block like
|
||||
*
|
||||
* `// made with bun!`
|
||||
*/
|
||||
footer?: string;
|
||||
|
||||
/**
|
||||
* **Experimental**
|
||||
*
|
||||
* Enable CSS support.
|
||||
*/
|
||||
experimentalCss?: boolean;
|
||||
}
|
||||
|
||||
namespace Password {
|
||||
@@ -1781,7 +1832,7 @@ declare module "bun" {
|
||||
path: string;
|
||||
loader: Loader;
|
||||
hash: string | null;
|
||||
kind: "entry-point" | "chunk" | "asset" | "sourcemap";
|
||||
kind: "entry-point" | "chunk" | "asset" | "sourcemap" | "bytecode";
|
||||
sourcemap: BuildArtifact | null;
|
||||
}
|
||||
|
||||
@@ -2282,7 +2333,7 @@ declare module "bun" {
|
||||
*/
|
||||
development?: boolean;
|
||||
|
||||
error?: (this: Server, request: ErrorLike) => Response | Promise<Response> | undefined | Promise<undefined>;
|
||||
error?: (this: Server, error: ErrorLike) => Response | Promise<Response> | undefined | Promise<undefined>;
|
||||
|
||||
/**
|
||||
* Uniquely identify a server instance with an ID
|
||||
@@ -3029,6 +3080,87 @@ declare module "bun" {
|
||||
|
||||
type StringLike = string | { toString(): string };
|
||||
|
||||
type ColorInput =
|
||||
| { r: number; g: number; b: number; a?: number }
|
||||
| [number, number, number]
|
||||
| [number, number, number, number]
|
||||
| Uint8Array
|
||||
| Uint8ClampedArray
|
||||
| Float32Array
|
||||
| Float64Array
|
||||
| string
|
||||
| number
|
||||
| { toString(): string };
|
||||
|
||||
function color(
|
||||
input: ColorInput,
|
||||
outputFormat?: /**
|
||||
* True color ANSI color string, for use in terminals
|
||||
* @example \x1b[38;2;100;200;200m
|
||||
*/
|
||||
| "ansi"
|
||||
/**
|
||||
* 256 color ANSI color string, for use in terminals which don't support true color
|
||||
*
|
||||
* Tries to match closest 24-bit color to 256 color palette
|
||||
*/
|
||||
| "ansi256"
|
||||
/**
|
||||
* Lowercase hex color string without alpha
|
||||
* @example #aabb11
|
||||
*/
|
||||
| "hex"
|
||||
/**
|
||||
* RGB color string without alpha
|
||||
* rgb(100, 200, 200)
|
||||
*/
|
||||
| "rgb"
|
||||
/**
|
||||
* RGB color string with alpha
|
||||
* rgba(100, 200, 200, 0.5)
|
||||
*/
|
||||
| "rgba"
|
||||
| "hsl"
|
||||
| "lab"
|
||||
| "css"
|
||||
| "lab"
|
||||
| "HEX",
|
||||
): string | null;
|
||||
|
||||
function color(
|
||||
input: ColorInput,
|
||||
/**
|
||||
* An array of numbers representing the RGB color
|
||||
* @example [100, 200, 200]
|
||||
*/
|
||||
outputFormat: "[rgb]",
|
||||
): [number, number, number] | null;
|
||||
function color(
|
||||
input: ColorInput,
|
||||
/**
|
||||
* An array of numbers representing the RGBA color
|
||||
* @example [100, 200, 200, 255]
|
||||
*/
|
||||
outputFormat: "[rgba]",
|
||||
): [number, number, number, number] | null;
|
||||
function color(
|
||||
input: ColorInput,
|
||||
/**
|
||||
* An object representing the RGB color
|
||||
* @example { r: 100, g: 200, b: 200 }
|
||||
*/
|
||||
outputFormat: "{rgb}",
|
||||
): { r: number; g: number; b: number } | null;
|
||||
function color(
|
||||
input: ColorInput,
|
||||
/**
|
||||
* An object representing the RGBA color
|
||||
* @example { r: 100, g: 200, b: 200, a: 0.5 }
|
||||
*/
|
||||
outputFormat: "{rgba}",
|
||||
): { r: number; g: number; b: number; a: number } | null;
|
||||
function color(input: ColorInput, outputFormat: "number"): number | null;
|
||||
|
||||
interface Semver {
|
||||
/**
|
||||
* Test if the version satisfies the range. Stringifies both arguments. Returns `true` or `false`.
|
||||
@@ -3264,8 +3396,9 @@ declare module "bun" {
|
||||
* Create a new hasher
|
||||
*
|
||||
* @param algorithm The algorithm to use. See {@link algorithms} for a list of supported algorithms
|
||||
* @param hmacKey Optional key for HMAC. Must be a string or `TypedArray`. If not provided, the hasher will be a non-HMAC hasher.
|
||||
*/
|
||||
constructor(algorithm: SupportedCryptoAlgorithms);
|
||||
constructor(algorithm: SupportedCryptoAlgorithms, hmacKey?: string | NodeJS.TypedArray);
|
||||
|
||||
/**
|
||||
* Update the hash with data
|
||||
@@ -4615,6 +4748,32 @@ declare module "bun" {
|
||||
* @default cmds[0]
|
||||
*/
|
||||
argv0?: string;
|
||||
|
||||
/**
|
||||
* An {@link AbortSignal} that can be used to abort the subprocess.
|
||||
*
|
||||
* This is useful for aborting a subprocess when some other part of the
|
||||
* program is aborted, such as a `fetch` response.
|
||||
*
|
||||
* Internally, this works by calling `subprocess.kill(1)`.
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* const controller = new AbortController();
|
||||
* const { signal } = controller;
|
||||
* const start = performance.now();
|
||||
* const subprocess = Bun.spawn({
|
||||
* cmd: ["sleep", "100"],
|
||||
* signal,
|
||||
* });
|
||||
* await Bun.sleep(1);
|
||||
* controller.abort();
|
||||
* await subprocess.exited;
|
||||
* const end = performance.now();
|
||||
* console.log(end - start); // 1ms instead of 101ms
|
||||
* ```
|
||||
*/
|
||||
signal?: AbortSignal;
|
||||
}
|
||||
|
||||
type OptionsToSubprocess<Opts extends OptionsObject> =
|
||||
@@ -5118,6 +5277,12 @@ declare module "bun" {
|
||||
*/
|
||||
const version: string;
|
||||
|
||||
/**
|
||||
* The current version of Bun with the shortened commit sha of the build
|
||||
* @example "v1.1.30 (d09df1af)"
|
||||
*/
|
||||
const version_with_sha: string;
|
||||
|
||||
/**
|
||||
* The git sha at the time the currently-running version of Bun was compiled
|
||||
* @example
|
||||
|
||||
@@ -3645,7 +3645,7 @@ CKA_SERIAL_NUMBER MULTILINE_OCTAL
|
||||
\002\006\040\006\005\026\160\002
|
||||
END
|
||||
CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
|
||||
CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
|
||||
CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
|
||||
CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
|
||||
CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
|
||||
|
||||
@@ -7252,7 +7252,7 @@ CKA_SERIAL_NUMBER MULTILINE_OCTAL
|
||||
\002\010\136\303\267\246\103\177\244\340
|
||||
END
|
||||
CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
|
||||
CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
|
||||
CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
|
||||
CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
|
||||
CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
|
||||
|
||||
@@ -17020,8 +17020,14 @@ CKA_VALUE MULTILINE_OCTAL
|
||||
\155\015\277\173\327\222
|
||||
END
|
||||
CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE
|
||||
CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE
|
||||
CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE
|
||||
# For Server Distrust After: Sun Jun 30 00:00:00 2024
|
||||
CKA_NSS_SERVER_DISTRUST_AFTER MULTILINE_OCTAL
|
||||
\062\064\060\066\063\060\060\060\060\060\060\060\132
|
||||
END
|
||||
# For Email Distrust After: Sun Jun 30 00:00:00 2024
|
||||
CKA_NSS_EMAIL_DISTRUST_AFTER MULTILINE_OCTAL
|
||||
\062\064\060\066\063\060\060\060\060\060\060\060\132
|
||||
END
|
||||
|
||||
# Trust for "GLOBALTRUST 2020"
|
||||
# Issuer: CN=GLOBALTRUST 2020,O=e-commerce monitoring GmbH,C=AT
|
||||
@@ -25483,3 +25489,761 @@ CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
|
||||
CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
|
||||
CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
|
||||
|
||||
#
|
||||
# Certificate "TWCA CYBER Root CA"
|
||||
#
|
||||
# Issuer: CN=TWCA CYBER Root CA,OU=Root CA,O=TAIWAN-CA,C=TW
|
||||
# Serial Number:40:01:34:8c:c2:00:00:00:00:00:00:00:01:3c:f2:c6
|
||||
# Subject: CN=TWCA CYBER Root CA,OU=Root CA,O=TAIWAN-CA,C=TW
|
||||
# Not Valid Before: Tue Nov 22 06:54:29 2022
|
||||
# Not Valid After : Fri Nov 22 15:59:59 2047
|
||||
# Fingerprint (SHA-256): 3F:63:BB:28:14:BE:17:4E:C8:B6:43:9C:F0:8D:6D:56:F0:B7:C4:05:88:3A:56:48:A3:34:42:4D:6B:3E:C5:58
|
||||
# Fingerprint (SHA1): F6:B1:1C:1A:83:38:E9:7B:DB:B3:A8:C8:33:24:E0:2D:9C:7F:26:66
|
||||
CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
|
||||
CKA_TOKEN CK_BBOOL CK_TRUE
|
||||
CKA_PRIVATE CK_BBOOL CK_FALSE
|
||||
CKA_MODIFIABLE CK_BBOOL CK_FALSE
|
||||
CKA_LABEL UTF8 "TWCA CYBER Root CA"
|
||||
CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
|
||||
CKA_SUBJECT MULTILINE_OCTAL
|
||||
\060\120\061\013\060\011\006\003\125\004\006\023\002\124\127\061
|
||||
\022\060\020\006\003\125\004\012\023\011\124\101\111\127\101\116
|
||||
\055\103\101\061\020\060\016\006\003\125\004\013\023\007\122\157
|
||||
\157\164\040\103\101\061\033\060\031\006\003\125\004\003\023\022
|
||||
\124\127\103\101\040\103\131\102\105\122\040\122\157\157\164\040
|
||||
\103\101
|
||||
END
|
||||
CKA_ID UTF8 "0"
|
||||
CKA_ISSUER MULTILINE_OCTAL
|
||||
\060\120\061\013\060\011\006\003\125\004\006\023\002\124\127\061
|
||||
\022\060\020\006\003\125\004\012\023\011\124\101\111\127\101\116
|
||||
\055\103\101\061\020\060\016\006\003\125\004\013\023\007\122\157
|
||||
\157\164\040\103\101\061\033\060\031\006\003\125\004\003\023\022
|
||||
\124\127\103\101\040\103\131\102\105\122\040\122\157\157\164\040
|
||||
\103\101
|
||||
END
|
||||
CKA_SERIAL_NUMBER MULTILINE_OCTAL
|
||||
\002\020\100\001\064\214\302\000\000\000\000\000\000\000\001\074
|
||||
\362\306
|
||||
END
|
||||
CKA_VALUE MULTILINE_OCTAL
|
||||
\060\202\005\215\060\202\003\165\240\003\002\001\002\002\020\100
|
||||
\001\064\214\302\000\000\000\000\000\000\000\001\074\362\306\060
|
||||
\015\006\011\052\206\110\206\367\015\001\001\014\005\000\060\120
|
||||
\061\013\060\011\006\003\125\004\006\023\002\124\127\061\022\060
|
||||
\020\006\003\125\004\012\023\011\124\101\111\127\101\116\055\103
|
||||
\101\061\020\060\016\006\003\125\004\013\023\007\122\157\157\164
|
||||
\040\103\101\061\033\060\031\006\003\125\004\003\023\022\124\127
|
||||
\103\101\040\103\131\102\105\122\040\122\157\157\164\040\103\101
|
||||
\060\036\027\015\062\062\061\061\062\062\060\066\065\064\062\071
|
||||
\132\027\015\064\067\061\061\062\062\061\065\065\071\065\071\132
|
||||
\060\120\061\013\060\011\006\003\125\004\006\023\002\124\127\061
|
||||
\022\060\020\006\003\125\004\012\023\011\124\101\111\127\101\116
|
||||
\055\103\101\061\020\060\016\006\003\125\004\013\023\007\122\157
|
||||
\157\164\040\103\101\061\033\060\031\006\003\125\004\003\023\022
|
||||
\124\127\103\101\040\103\131\102\105\122\040\122\157\157\164\040
|
||||
\103\101\060\202\002\042\060\015\006\011\052\206\110\206\367\015
|
||||
\001\001\001\005\000\003\202\002\017\000\060\202\002\012\002\202
|
||||
\002\001\000\306\370\312\036\331\011\040\176\035\154\116\316\217
|
||||
\343\107\063\104\234\307\311\151\252\072\133\170\356\160\322\222
|
||||
\370\004\263\122\122\035\147\162\050\241\337\213\135\225\012\376
|
||||
\352\315\355\367\051\316\360\157\177\254\315\075\357\263\034\105
|
||||
\152\367\050\220\361\141\127\305\014\304\243\120\135\336\324\265
|
||||
\313\031\312\200\271\165\316\051\316\322\205\042\354\002\143\314
|
||||
\104\060\040\332\352\221\133\126\346\035\034\325\235\146\307\077
|
||||
\337\206\312\113\123\304\331\215\262\035\352\370\334\047\123\243
|
||||
\107\341\141\314\175\265\260\370\356\163\221\305\316\163\157\316
|
||||
\356\020\037\032\006\317\351\047\140\305\117\031\344\353\316\042
|
||||
\046\105\327\140\231\335\316\117\067\340\177\347\143\255\260\270
|
||||
\131\270\320\006\150\065\140\323\066\256\161\103\004\361\151\145
|
||||
\170\174\363\037\363\312\050\237\132\040\225\146\264\315\267\356
|
||||
\217\170\244\105\030\351\046\057\215\233\051\050\261\244\267\072
|
||||
\155\271\324\034\070\162\105\130\261\136\353\360\050\233\267\202
|
||||
\312\375\317\326\063\017\237\373\227\236\261\034\234\236\352\137
|
||||
\136\333\252\335\124\351\060\041\050\155\216\171\363\165\222\214
|
||||
\046\376\334\305\366\303\260\337\104\131\103\243\266\003\050\366
|
||||
\010\060\252\015\063\341\357\234\251\007\042\343\131\133\100\217
|
||||
\332\210\267\151\010\250\267\043\056\104\011\131\067\133\307\343
|
||||
\027\362\042\353\156\071\122\305\336\124\247\230\311\113\040\225
|
||||
\334\106\211\137\264\022\371\205\051\216\353\310\047\025\040\300
|
||||
\113\324\314\174\014\154\064\014\046\233\046\061\246\074\247\366
|
||||
\331\320\113\242\144\377\073\231\101\162\301\340\160\227\361\044
|
||||
\273\053\304\164\042\261\254\153\042\062\044\323\170\052\300\300
|
||||
\241\057\361\122\005\311\077\357\166\146\342\105\330\015\075\255
|
||||
\225\310\307\211\046\310\017\256\247\003\056\373\301\137\372\040
|
||||
\341\160\255\260\145\040\067\063\140\260\325\257\327\014\034\302
|
||||
\220\160\327\112\030\274\176\001\260\260\353\025\036\104\006\315
|
||||
\244\117\350\014\321\303\040\020\341\124\145\236\266\121\320\032
|
||||
\166\153\102\132\130\166\064\352\267\067\031\256\056\165\371\226
|
||||
\345\301\131\367\224\127\051\045\215\072\114\253\115\232\101\320
|
||||
\137\046\003\002\003\001\000\001\243\143\060\141\060\016\006\003
|
||||
\125\035\017\001\001\377\004\004\003\002\001\006\060\017\006\003
|
||||
\125\035\023\001\001\377\004\005\060\003\001\001\377\060\037\006
|
||||
\003\125\035\043\004\030\060\026\200\024\235\205\141\024\174\301
|
||||
\142\157\227\150\344\117\067\100\341\255\340\015\126\067\060\035
|
||||
\006\003\125\035\016\004\026\004\024\235\205\141\024\174\301\142
|
||||
\157\227\150\344\117\067\100\341\255\340\015\126\067\060\015\006
|
||||
\011\052\206\110\206\367\015\001\001\014\005\000\003\202\002\001
|
||||
\000\144\217\172\304\142\016\265\210\314\270\307\206\016\241\112
|
||||
\026\315\160\013\267\247\205\013\263\166\266\017\247\377\010\213
|
||||
\013\045\317\250\324\203\165\052\270\226\210\266\373\337\055\055
|
||||
\264\151\123\041\065\127\326\211\115\163\277\151\217\160\243\141
|
||||
\314\232\333\036\232\340\040\370\154\273\233\042\235\135\204\061
|
||||
\232\054\212\335\152\241\327\050\151\312\376\166\125\172\106\147
|
||||
\353\314\103\210\026\242\003\326\271\027\370\031\154\155\043\002
|
||||
\177\361\137\320\012\051\043\073\321\252\012\355\251\027\046\124
|
||||
\012\115\302\245\115\370\305\375\270\201\317\053\054\170\243\147
|
||||
\114\251\007\232\363\337\136\373\174\365\211\315\164\227\141\020
|
||||
\152\007\053\201\132\322\216\267\347\040\321\040\156\044\250\204
|
||||
\047\241\127\254\252\125\130\057\334\331\312\372\150\004\236\355
|
||||
\104\044\371\164\100\073\043\063\253\203\132\030\046\102\266\155
|
||||
\124\265\026\140\060\154\261\240\370\270\101\240\135\111\111\322
|
||||
\145\005\072\352\376\235\141\274\206\331\277\336\323\272\072\261
|
||||
\177\176\222\064\216\311\000\156\334\230\275\334\354\200\005\255
|
||||
\002\075\337\145\355\013\003\367\367\026\204\004\061\272\223\224
|
||||
\330\362\022\370\212\343\277\102\257\247\324\315\021\027\026\310
|
||||
\102\035\024\250\102\366\322\100\206\240\117\043\312\226\105\126
|
||||
\140\006\315\267\125\001\246\001\224\145\376\156\005\011\272\264
|
||||
\244\252\342\357\130\276\275\047\126\330\357\163\161\133\104\063
|
||||
\362\232\162\352\260\136\076\156\251\122\133\354\160\155\265\207
|
||||
\217\067\136\074\214\234\316\344\360\316\014\147\101\314\316\366
|
||||
\200\253\116\314\114\126\365\301\141\131\223\264\076\246\332\270
|
||||
\067\022\237\052\062\343\213\270\041\354\303\053\145\014\357\042
|
||||
\336\210\051\073\114\327\372\376\267\341\107\276\234\076\076\203
|
||||
\373\121\135\365\150\367\056\041\205\334\277\361\132\342\174\327
|
||||
\305\344\203\301\152\353\272\200\132\336\134\055\160\166\370\310
|
||||
\345\207\207\312\240\235\241\345\042\022\047\017\104\075\035\154
|
||||
\352\324\302\213\057\157\171\253\177\120\246\304\031\247\241\172
|
||||
\267\226\371\301\037\142\132\242\103\007\100\136\046\306\254\355
|
||||
\256\160\026\305\252\312\162\212\115\260\317\001\213\003\077\156
|
||||
\327
|
||||
END
|
||||
CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE
|
||||
CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE
|
||||
CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE
|
||||
|
||||
# Trust for "TWCA CYBER Root CA"
|
||||
# Issuer: CN=TWCA CYBER Root CA,OU=Root CA,O=TAIWAN-CA,C=TW
|
||||
# Serial Number:40:01:34:8c:c2:00:00:00:00:00:00:00:01:3c:f2:c6
|
||||
# Subject: CN=TWCA CYBER Root CA,OU=Root CA,O=TAIWAN-CA,C=TW
|
||||
# Not Valid Before: Tue Nov 22 06:54:29 2022
|
||||
# Not Valid After : Fri Nov 22 15:59:59 2047
|
||||
# Fingerprint (SHA-256): 3F:63:BB:28:14:BE:17:4E:C8:B6:43:9C:F0:8D:6D:56:F0:B7:C4:05:88:3A:56:48:A3:34:42:4D:6B:3E:C5:58
|
||||
# Fingerprint (SHA1): F6:B1:1C:1A:83:38:E9:7B:DB:B3:A8:C8:33:24:E0:2D:9C:7F:26:66
|
||||
CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
|
||||
CKA_TOKEN CK_BBOOL CK_TRUE
|
||||
CKA_PRIVATE CK_BBOOL CK_FALSE
|
||||
CKA_MODIFIABLE CK_BBOOL CK_FALSE
|
||||
CKA_LABEL UTF8 "TWCA CYBER Root CA"
|
||||
CKA_CERT_SHA1_HASH MULTILINE_OCTAL
|
||||
\366\261\034\032\203\070\351\173\333\263\250\310\063\044\340\055
|
||||
\234\177\046\146
|
||||
END
|
||||
CKA_CERT_MD5_HASH MULTILINE_OCTAL
|
||||
\013\063\240\227\122\225\324\251\375\273\333\156\243\125\133\121
|
||||
END
|
||||
CKA_ISSUER MULTILINE_OCTAL
|
||||
\060\120\061\013\060\011\006\003\125\004\006\023\002\124\127\061
|
||||
\022\060\020\006\003\125\004\012\023\011\124\101\111\127\101\116
|
||||
\055\103\101\061\020\060\016\006\003\125\004\013\023\007\122\157
|
||||
\157\164\040\103\101\061\033\060\031\006\003\125\004\003\023\022
|
||||
\124\127\103\101\040\103\131\102\105\122\040\122\157\157\164\040
|
||||
\103\101
|
||||
END
|
||||
CKA_SERIAL_NUMBER MULTILINE_OCTAL
|
||||
\002\020\100\001\064\214\302\000\000\000\000\000\000\000\001\074
|
||||
\362\306
|
||||
END
|
||||
CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
|
||||
CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
|
||||
CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
|
||||
CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
|
||||
|
||||
#
|
||||
# Certificate "TWCA Global Root CA G2"
|
||||
#
|
||||
# Issuer: CN=TWCA Global Root CA G2,OU=Root CA,O=TAIWAN-CA,C=TW
|
||||
# Serial Number:40:01:34:8c:c2:00:00:00:00:00:00:00:01:97:58:f4
|
||||
# Subject: CN=TWCA Global Root CA G2,OU=Root CA,O=TAIWAN-CA,C=TW
|
||||
# Not Valid Before: Tue Nov 22 06:42:21 2022
|
||||
# Not Valid After : Fri Nov 22 15:59:59 2047
|
||||
# Fingerprint (SHA-256): 3A:00:72:D4:9F:FC:04:E9:96:C5:9A:EB:75:99:1D:3C:34:0F:36:15:D6:FD:4D:CE:90:AC:0B:3D:88:EA:D4:F4
|
||||
# Fingerprint (SHA1): 73:FE:92:2F:83:63:91:FF:C8:C6:C4:DA:D6:20:2F:6B:07:2E:7F:1B
|
||||
CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
|
||||
CKA_TOKEN CK_BBOOL CK_TRUE
|
||||
CKA_PRIVATE CK_BBOOL CK_FALSE
|
||||
CKA_MODIFIABLE CK_BBOOL CK_FALSE
|
||||
CKA_LABEL UTF8 "TWCA Global Root CA G2"
|
||||
CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
|
||||
CKA_SUBJECT MULTILINE_OCTAL
|
||||
\060\124\061\013\060\011\006\003\125\004\006\023\002\124\127\061
|
||||
\022\060\020\006\003\125\004\012\023\011\124\101\111\127\101\116
|
||||
\055\103\101\061\020\060\016\006\003\125\004\013\023\007\122\157
|
||||
\157\164\040\103\101\061\037\060\035\006\003\125\004\003\023\026
|
||||
\124\127\103\101\040\107\154\157\142\141\154\040\122\157\157\164
|
||||
\040\103\101\040\107\062
|
||||
END
|
||||
CKA_ID UTF8 "0"
|
||||
CKA_ISSUER MULTILINE_OCTAL
|
||||
\060\124\061\013\060\011\006\003\125\004\006\023\002\124\127\061
|
||||
\022\060\020\006\003\125\004\012\023\011\124\101\111\127\101\116
|
||||
\055\103\101\061\020\060\016\006\003\125\004\013\023\007\122\157
|
||||
\157\164\040\103\101\061\037\060\035\006\003\125\004\003\023\026
|
||||
\124\127\103\101\040\107\154\157\142\141\154\040\122\157\157\164
|
||||
\040\103\101\040\107\062
|
||||
END
|
||||
CKA_SERIAL_NUMBER MULTILINE_OCTAL
|
||||
\002\020\100\001\064\214\302\000\000\000\000\000\000\000\001\227
|
||||
\130\364
|
||||
END
|
||||
CKA_VALUE MULTILINE_OCTAL
|
||||
\060\202\005\225\060\202\003\175\240\003\002\001\002\002\020\100
|
||||
\001\064\214\302\000\000\000\000\000\000\000\001\227\130\364\060
|
||||
\015\006\011\052\206\110\206\367\015\001\001\014\005\000\060\124
|
||||
\061\013\060\011\006\003\125\004\006\023\002\124\127\061\022\060
|
||||
\020\006\003\125\004\012\023\011\124\101\111\127\101\116\055\103
|
||||
\101\061\020\060\016\006\003\125\004\013\023\007\122\157\157\164
|
||||
\040\103\101\061\037\060\035\006\003\125\004\003\023\026\124\127
|
||||
\103\101\040\107\154\157\142\141\154\040\122\157\157\164\040\103
|
||||
\101\040\107\062\060\036\027\015\062\062\061\061\062\062\060\066
|
||||
\064\062\062\061\132\027\015\064\067\061\061\062\062\061\065\065
|
||||
\071\065\071\132\060\124\061\013\060\011\006\003\125\004\006\023
|
||||
\002\124\127\061\022\060\020\006\003\125\004\012\023\011\124\101
|
||||
\111\127\101\116\055\103\101\061\020\060\016\006\003\125\004\013
|
||||
\023\007\122\157\157\164\040\103\101\061\037\060\035\006\003\125
|
||||
\004\003\023\026\124\127\103\101\040\107\154\157\142\141\154\040
|
||||
\122\157\157\164\040\103\101\040\107\062\060\202\002\042\060\015
|
||||
\006\011\052\206\110\206\367\015\001\001\001\005\000\003\202\002
|
||||
\017\000\060\202\002\012\002\202\002\001\000\252\016\325\040\222
|
||||
\001\255\202\371\014\010\221\064\153\212\026\320\106\026\377\003
|
||||
\270\330\215\352\223\064\373\377\053\275\375\156\252\334\233\362
|
||||
\206\201\125\365\211\034\304\215\165\152\130\170\221\023\036\002
|
||||
\023\160\075\357\276\012\347\000\217\270\061\345\164\305\060\276
|
||||
\377\175\326\231\345\302\102\243\317\041\326\263\010\177\221\325
|
||||
\141\346\242\225\020\015\357\136\227\013\111\070\325\042\260\327
|
||||
\213\131\157\237\065\233\177\322\221\314\172\177\273\240\237\336
|
||||
\125\063\366\113\215\012\352\175\011\300\171\334\275\104\342\376
|
||||
\034\347\144\041\050\317\004\112\342\264\277\206\171\052\273\016
|
||||
\223\311\217\136\254\060\071\122\220\007\271\352\234\046\102\024
|
||||
\304\147\106\376\321\032\150\241\076\120\031\243\046\012\047\051
|
||||
\220\302\366\264\353\163\232\170\036\341\230\364\145\014\065\041
|
||||
\006\370\013\336\142\345\115\301\263\135\331\271\372\141\227\052
|
||||
\343\352\307\104\125\044\222\376\022\247\077\304\167\340\055\002
|
||||
\201\007\325\373\175\346\020\236\072\264\250\357\354\373\120\352
|
||||
\065\317\314\176\273\102\271\104\154\122\351\277\052\162\037\077
|
||||
\336\233\160\351\334\132\305\073\273\277\360\131\205\257\057\301
|
||||
\260\024\171\005\254\165\237\045\365\021\047\006\140\041\307\155
|
||||
\145\276\250\211\234\345\254\106\337\370\135\104\003\215\140\275
|
||||
\367\261\015\314\057\357\101\124\057\356\153\225\271\116\174\064
|
||||
\337\073\371\167\235\175\315\007\075\034\006\063\022\200\354\162
|
||||
\234\362\055\202\332\325\073\304\307\371\004\303\144\002\174\365
|
||||
\065\140\247\264\106\051\056\033\357\245\130\200\056\172\211\121
|
||||
\070\066\074\375\241\167\270\200\060\320\212\336\215\247\064\046
|
||||
\354\043\273\030\125\030\066\105\356\355\001\006\252\115\277\144
|
||||
\014\312\230\227\032\061\002\146\370\170\150\133\210\337\011\250
|
||||
\347\233\372\064\155\160\034\041\255\010\213\362\241\266\254\166
|
||||
\152\277\361\200\045\000\276\074\036\115\256\271\074\266\225\143
|
||||
\275\153\176\107\022\220\125\105\021\215\354\027\037\301\276\047
|
||||
\201\223\127\143\151\000\046\167\213\303\131\345\173\321\015\104
|
||||
\362\250\360\367\205\232\005\367\302\056\160\232\223\205\330\225
|
||||
\220\061\220\124\246\354\013\237\067\105\017\002\003\001\000\001
|
||||
\243\143\060\141\060\016\006\003\125\035\017\001\001\377\004\004
|
||||
\003\002\001\006\060\017\006\003\125\035\023\001\001\377\004\005
|
||||
\060\003\001\001\377\060\037\006\003\125\035\043\004\030\060\026
|
||||
\200\024\222\214\324\066\321\133\107\123\304\161\015\204\335\144
|
||||
\052\365\066\144\100\347\060\035\006\003\125\035\016\004\026\004
|
||||
\024\222\214\324\066\321\133\107\123\304\161\015\204\335\144\052
|
||||
\365\066\144\100\347\060\015\006\011\052\206\110\206\367\015\001
|
||||
\001\014\005\000\003\202\002\001\000\045\374\113\332\220\264\332
|
||||
\165\347\101\072\201\321\246\376\240\152\363\030\161\142\152\044
|
||||
\010\213\251\172\115\311\125\316\317\020\050\056\004\031\226\005
|
||||
\317\135\002\040\052\073\263\125\077\001\315\102\315\262\167\355
|
||||
\377\165\363\174\167\333\226\245\317\214\147\006\364\244\233\162
|
||||
\366\041\111\011\230\243\062\136\167\132\143\011\357\142\103\227
|
||||
\002\070\265\352\074\030\120\150\374\131\133\331\171\324\361\344
|
||||
\126\110\023\126\330\323\161\013\136\170\224\070\021\105\372\005
|
||||
\027\365\016\165\036\142\122\141\106\272\056\031\255\206\264\210
|
||||
\017\261\120\346\100\000\064\032\225\235\223\340\121\371\324\125
|
||||
\106\351\225\074\045\206\056\227\327\001\061\030\104\354\034\140
|
||||
\351\175\151\257\062\370\227\100\045\044\266\215\032\125\074\305
|
||||
\267\367\274\006\122\073\161\060\160\076\161\027\176\361\146\004
|
||||
\136\135\274\212\061\103\246\222\035\173\124\322\245\066\213\157
|
||||
\215\326\136\332\324\303\056\035\337\071\125\140\202\060\236\047
|
||||
\377\216\200\335\143\114\246\125\065\330\320\063\251\200\155\076
|
||||
\136\235\314\250\147\200\146\372\231\127\014\122\312\031\165\260
|
||||
\070\065\125\052\201\305\214\036\126\327\137\220\362\040\330\332
|
||||
\340\146\161\351\262\170\253\147\271\044\156\153\066\162\374\157
|
||||
\215\375\177\162\071\050\147\122\221\005\037\127\145\322\243\247
|
||||
\015\141\372\241\347\325\065\106\225\311\006\207\366\060\354\062
|
||||
\121\251\254\126\300\041\116\243\024\164\005\072\274\343\277\155
|
||||
\075\116\077\136\245\244\155\051\277\204\121\165\123\216\206\032
|
||||
\365\121\160\052\015\034\116\100\341\375\243\343\245\053\147\220
|
||||
\222\307\154\256\205\277\072\233\027\025\312\234\052\223\324\115
|
||||
\071\015\274\040\010\243\215\210\154\011\015\214\256\104\041\115
|
||||
\311\161\354\330\046\327\027\236\055\021\030\074\243\042\175\270
|
||||
\047\124\277\150\310\073\102\314\217\136\116\347\334\302\305\372
|
||||
\152\104\017\215\126\210\172\337\211\204\154\240\263\076\075\361
|
||||
\145\000\011\210\352\052\353\100\316\263\135\254\062\027\256\301
|
||||
\233\351\320\301\365\111\224\335\247\316\174\132\007\353\256\040
|
||||
\234\027\060\222\151\223\162\363\232\133\161\233\376\152\337\172
|
||||
\060\151\216\263\056\333\017\054\335
|
||||
END
|
||||
CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE
|
||||
CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE
|
||||
CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE
|
||||
|
||||
# Trust for "TWCA Global Root CA G2"
|
||||
# Issuer: CN=TWCA Global Root CA G2,OU=Root CA,O=TAIWAN-CA,C=TW
|
||||
# Serial Number:40:01:34:8c:c2:00:00:00:00:00:00:00:01:97:58:f4
|
||||
# Subject: CN=TWCA Global Root CA G2,OU=Root CA,O=TAIWAN-CA,C=TW
|
||||
# Not Valid Before: Tue Nov 22 06:42:21 2022
|
||||
# Not Valid After : Fri Nov 22 15:59:59 2047
|
||||
# Fingerprint (SHA-256): 3A:00:72:D4:9F:FC:04:E9:96:C5:9A:EB:75:99:1D:3C:34:0F:36:15:D6:FD:4D:CE:90:AC:0B:3D:88:EA:D4:F4
|
||||
# Fingerprint (SHA1): 73:FE:92:2F:83:63:91:FF:C8:C6:C4:DA:D6:20:2F:6B:07:2E:7F:1B
|
||||
CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
|
||||
CKA_TOKEN CK_BBOOL CK_TRUE
|
||||
CKA_PRIVATE CK_BBOOL CK_FALSE
|
||||
CKA_MODIFIABLE CK_BBOOL CK_FALSE
|
||||
CKA_LABEL UTF8 "TWCA Global Root CA G2"
|
||||
CKA_CERT_SHA1_HASH MULTILINE_OCTAL
|
||||
\163\376\222\057\203\143\221\377\310\306\304\332\326\040\057\153
|
||||
\007\056\177\033
|
||||
END
|
||||
CKA_CERT_MD5_HASH MULTILINE_OCTAL
|
||||
\023\215\135\372\031\265\346\253\144\173\020\164\160\032\043\056
|
||||
END
|
||||
CKA_ISSUER MULTILINE_OCTAL
|
||||
\060\124\061\013\060\011\006\003\125\004\006\023\002\124\127\061
|
||||
\022\060\020\006\003\125\004\012\023\011\124\101\111\127\101\116
|
||||
\055\103\101\061\020\060\016\006\003\125\004\013\023\007\122\157
|
||||
\157\164\040\103\101\061\037\060\035\006\003\125\004\003\023\026
|
||||
\124\127\103\101\040\107\154\157\142\141\154\040\122\157\157\164
|
||||
\040\103\101\040\107\062
|
||||
END
|
||||
CKA_SERIAL_NUMBER MULTILINE_OCTAL
|
||||
\002\020\100\001\064\214\302\000\000\000\000\000\000\000\001\227
|
||||
\130\364
|
||||
END
|
||||
CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
|
||||
CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
|
||||
CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
|
||||
CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
|
||||
|
||||
#
|
||||
# Certificate "SecureSign Root CA12"
|
||||
#
|
||||
# Issuer: CN=SecureSign Root CA12,O="Cybertrust Japan Co., Ltd.",C=JP
|
||||
# Serial Number:66:f9:c7:c1:af:ec:c2:51:b4:ed:53:97:e6:e6:82:c3:2b:1c:90:16
|
||||
# Subject: CN=SecureSign Root CA12,O="Cybertrust Japan Co., Ltd.",C=JP
|
||||
# Not Valid Before: Wed Apr 08 05:36:46 2020
|
||||
# Not Valid After : Sun Apr 08 05:36:46 2040
|
||||
# Fingerprint (SHA-256): 3F:03:4B:B5:70:4D:44:B2:D0:85:45:A0:20:57:DE:93:EB:F3:90:5F:CE:72:1A:CB:C7:30:C0:6D:DA:EE:90:4E
|
||||
# Fingerprint (SHA1): 7A:22:1E:3D:DE:1B:06:AC:9E:C8:47:70:16:8E:3C:E5:F7:6B:06:F4
|
||||
CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
|
||||
CKA_TOKEN CK_BBOOL CK_TRUE
|
||||
CKA_PRIVATE CK_BBOOL CK_FALSE
|
||||
CKA_MODIFIABLE CK_BBOOL CK_FALSE
|
||||
CKA_LABEL UTF8 "SecureSign Root CA12"
|
||||
CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
|
||||
CKA_SUBJECT MULTILINE_OCTAL
|
||||
\060\121\061\013\060\011\006\003\125\004\006\023\002\112\120\061
|
||||
\043\060\041\006\003\125\004\012\023\032\103\171\142\145\162\164
|
||||
\162\165\163\164\040\112\141\160\141\156\040\103\157\056\054\040
|
||||
\114\164\144\056\061\035\060\033\006\003\125\004\003\023\024\123
|
||||
\145\143\165\162\145\123\151\147\156\040\122\157\157\164\040\103
|
||||
\101\061\062
|
||||
END
|
||||
CKA_ID UTF8 "0"
|
||||
CKA_ISSUER MULTILINE_OCTAL
|
||||
\060\121\061\013\060\011\006\003\125\004\006\023\002\112\120\061
|
||||
\043\060\041\006\003\125\004\012\023\032\103\171\142\145\162\164
|
||||
\162\165\163\164\040\112\141\160\141\156\040\103\157\056\054\040
|
||||
\114\164\144\056\061\035\060\033\006\003\125\004\003\023\024\123
|
||||
\145\143\165\162\145\123\151\147\156\040\122\157\157\164\040\103
|
||||
\101\061\062
|
||||
END
|
||||
CKA_SERIAL_NUMBER MULTILINE_OCTAL
|
||||
\002\024\146\371\307\301\257\354\302\121\264\355\123\227\346\346
|
||||
\202\303\053\034\220\026
|
||||
END
|
||||
CKA_VALUE MULTILINE_OCTAL
|
||||
\060\202\003\162\060\202\002\132\240\003\002\001\002\002\024\146
|
||||
\371\307\301\257\354\302\121\264\355\123\227\346\346\202\303\053
|
||||
\034\220\026\060\015\006\011\052\206\110\206\367\015\001\001\013
|
||||
\005\000\060\121\061\013\060\011\006\003\125\004\006\023\002\112
|
||||
\120\061\043\060\041\006\003\125\004\012\023\032\103\171\142\145
|
||||
\162\164\162\165\163\164\040\112\141\160\141\156\040\103\157\056
|
||||
\054\040\114\164\144\056\061\035\060\033\006\003\125\004\003\023
|
||||
\024\123\145\143\165\162\145\123\151\147\156\040\122\157\157\164
|
||||
\040\103\101\061\062\060\036\027\015\062\060\060\064\060\070\060
|
||||
\065\063\066\064\066\132\027\015\064\060\060\064\060\070\060\065
|
||||
\063\066\064\066\132\060\121\061\013\060\011\006\003\125\004\006
|
||||
\023\002\112\120\061\043\060\041\006\003\125\004\012\023\032\103
|
||||
\171\142\145\162\164\162\165\163\164\040\112\141\160\141\156\040
|
||||
\103\157\056\054\040\114\164\144\056\061\035\060\033\006\003\125
|
||||
\004\003\023\024\123\145\143\165\162\145\123\151\147\156\040\122
|
||||
\157\157\164\040\103\101\061\062\060\202\001\042\060\015\006\011
|
||||
\052\206\110\206\367\015\001\001\001\005\000\003\202\001\017\000
|
||||
\060\202\001\012\002\202\001\001\000\272\071\301\067\172\150\105
|
||||
\053\024\264\353\344\023\353\127\165\043\115\217\044\055\026\350
|
||||
\256\216\311\175\244\127\073\052\166\045\063\203\154\352\062\212
|
||||
\224\233\116\074\226\344\375\121\277\231\311\223\176\277\371\255
|
||||
\247\262\110\053\007\034\047\365\114\274\160\022\167\244\205\124
|
||||
\265\375\220\172\344\243\344\121\130\003\315\020\171\171\356\153
|
||||
\223\037\144\216\153\144\253\243\023\343\161\376\175\253\234\335
|
||||
\047\123\067\263\252\030\302\131\046\354\133\037\322\346\145\174
|
||||
\357\223\275\330\130\134\013\300\343\145\157\074\307\312\131\343
|
||||
\376\156\137\254\203\276\375\135\045\116\052\051\073\326\013\253
|
||||
\027\062\170\244\341\076\224\106\276\142\156\233\336\106\250\261
|
||||
\026\347\205\156\364\010\100\105\021\240\236\124\104\204\367\330
|
||||
\066\316\365\120\107\334\054\060\233\356\300\365\226\322\376\011
|
||||
\206\307\006\131\256\117\256\216\021\230\173\363\013\122\252\142
|
||||
\046\252\041\337\216\045\063\171\227\026\111\215\365\076\325\107
|
||||
\237\067\061\111\063\162\005\115\014\266\125\214\361\127\217\212
|
||||
\207\321\255\305\021\022\071\240\255\002\003\001\000\001\243\102
|
||||
\060\100\060\017\006\003\125\035\023\001\001\377\004\005\060\003
|
||||
\001\001\377\060\016\006\003\125\035\017\001\001\377\004\004\003
|
||||
\002\001\006\060\035\006\003\125\035\016\004\026\004\024\127\064
|
||||
\363\164\317\004\113\325\045\346\361\100\266\054\114\331\055\351
|
||||
\240\255\060\015\006\011\052\206\110\206\367\015\001\001\013\005
|
||||
\000\003\202\001\001\000\076\273\333\027\026\322\362\024\001\040
|
||||
\054\070\203\113\255\276\312\205\172\232\266\233\153\246\341\374
|
||||
\245\072\254\255\264\050\072\257\327\001\203\111\053\143\242\335
|
||||
\232\144\016\230\134\157\335\216\273\212\124\042\055\112\023\363
|
||||
\256\100\103\333\117\221\267\206\032\354\000\264\101\201\244\117
|
||||
\372\152\213\210\263\166\010\162\052\111\100\303\323\303\205\211
|
||||
\230\020\245\235\157\031\267\273\317\172\145\125\333\067\353\074
|
||||
\212\162\062\227\036\232\051\076\255\215\346\243\033\155\365\165
|
||||
\032\346\260\150\271\133\242\356\151\107\047\065\241\206\231\200
|
||||
\363\063\113\341\153\244\046\303\357\164\131\154\172\242\144\266
|
||||
\036\104\303\120\340\017\071\075\251\063\361\245\363\322\275\142
|
||||
\204\254\216\034\251\315\132\275\067\073\156\012\042\264\364\025
|
||||
\347\221\130\305\072\104\323\225\050\331\300\145\351\162\312\320
|
||||
\017\275\037\263\025\331\251\343\244\107\011\236\340\313\067\373
|
||||
\375\275\227\325\276\030\032\151\242\071\201\331\032\365\253\177
|
||||
\310\343\342\147\013\235\364\014\352\124\337\322\262\257\261\042
|
||||
\361\040\337\274\104\034
|
||||
END
|
||||
CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE
|
||||
CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE
|
||||
CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE
|
||||
|
||||
# Trust for "SecureSign Root CA12"
|
||||
# Issuer: CN=SecureSign Root CA12,O="Cybertrust Japan Co., Ltd.",C=JP
|
||||
# Serial Number:66:f9:c7:c1:af:ec:c2:51:b4:ed:53:97:e6:e6:82:c3:2b:1c:90:16
|
||||
# Subject: CN=SecureSign Root CA12,O="Cybertrust Japan Co., Ltd.",C=JP
|
||||
# Not Valid Before: Wed Apr 08 05:36:46 2020
|
||||
# Not Valid After : Sun Apr 08 05:36:46 2040
|
||||
# Fingerprint (SHA-256): 3F:03:4B:B5:70:4D:44:B2:D0:85:45:A0:20:57:DE:93:EB:F3:90:5F:CE:72:1A:CB:C7:30:C0:6D:DA:EE:90:4E
|
||||
# Fingerprint (SHA1): 7A:22:1E:3D:DE:1B:06:AC:9E:C8:47:70:16:8E:3C:E5:F7:6B:06:F4
|
||||
CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
|
||||
CKA_TOKEN CK_BBOOL CK_TRUE
|
||||
CKA_PRIVATE CK_BBOOL CK_FALSE
|
||||
CKA_MODIFIABLE CK_BBOOL CK_FALSE
|
||||
CKA_LABEL UTF8 "SecureSign Root CA12"
|
||||
CKA_CERT_SHA1_HASH MULTILINE_OCTAL
|
||||
\172\042\036\075\336\033\006\254\236\310\107\160\026\216\074\345
|
||||
\367\153\006\364
|
||||
END
|
||||
CKA_CERT_MD5_HASH MULTILINE_OCTAL
|
||||
\306\211\312\144\102\233\142\010\111\013\036\177\351\007\075\350
|
||||
END
|
||||
CKA_ISSUER MULTILINE_OCTAL
|
||||
\060\121\061\013\060\011\006\003\125\004\006\023\002\112\120\061
|
||||
\043\060\041\006\003\125\004\012\023\032\103\171\142\145\162\164
|
||||
\162\165\163\164\040\112\141\160\141\156\040\103\157\056\054\040
|
||||
\114\164\144\056\061\035\060\033\006\003\125\004\003\023\024\123
|
||||
\145\143\165\162\145\123\151\147\156\040\122\157\157\164\040\103
|
||||
\101\061\062
|
||||
END
|
||||
CKA_SERIAL_NUMBER MULTILINE_OCTAL
|
||||
\002\024\146\371\307\301\257\354\302\121\264\355\123\227\346\346
|
||||
\202\303\053\034\220\026
|
||||
END
|
||||
CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
|
||||
CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
|
||||
CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
|
||||
CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
|
||||
|
||||
#
|
||||
# Certificate "SecureSign Root CA14"
|
||||
#
|
||||
# Issuer: CN=SecureSign Root CA14,O="Cybertrust Japan Co., Ltd.",C=JP
|
||||
# Serial Number:64:db:5a:0c:20:4e:e8:d7:29:77:c8:50:27:a2:5a:27:dd:2d:f2:cb
|
||||
# Subject: CN=SecureSign Root CA14,O="Cybertrust Japan Co., Ltd.",C=JP
|
||||
# Not Valid Before: Wed Apr 08 07:06:19 2020
|
||||
# Not Valid After : Sat Apr 08 07:06:19 2045
|
||||
# Fingerprint (SHA-256): 4B:00:9C:10:34:49:4F:9A:B5:6B:BA:3B:A1:D6:27:31:FC:4D:20:D8:95:5A:DC:EC:10:A9:25:60:72:61:E3:38
|
||||
# Fingerprint (SHA1): DD:50:C0:F7:79:B3:64:2E:74:A2:B8:9D:9F:D3:40:DD:BB:F0:F2:4F
|
||||
CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
|
||||
CKA_TOKEN CK_BBOOL CK_TRUE
|
||||
CKA_PRIVATE CK_BBOOL CK_FALSE
|
||||
CKA_MODIFIABLE CK_BBOOL CK_FALSE
|
||||
CKA_LABEL UTF8 "SecureSign Root CA14"
|
||||
CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
|
||||
CKA_SUBJECT MULTILINE_OCTAL
|
||||
\060\121\061\013\060\011\006\003\125\004\006\023\002\112\120\061
|
||||
\043\060\041\006\003\125\004\012\023\032\103\171\142\145\162\164
|
||||
\162\165\163\164\040\112\141\160\141\156\040\103\157\056\054\040
|
||||
\114\164\144\056\061\035\060\033\006\003\125\004\003\023\024\123
|
||||
\145\143\165\162\145\123\151\147\156\040\122\157\157\164\040\103
|
||||
\101\061\064
|
||||
END
|
||||
CKA_ID UTF8 "0"
|
||||
CKA_ISSUER MULTILINE_OCTAL
|
||||
\060\121\061\013\060\011\006\003\125\004\006\023\002\112\120\061
|
||||
\043\060\041\006\003\125\004\012\023\032\103\171\142\145\162\164
|
||||
\162\165\163\164\040\112\141\160\141\156\040\103\157\056\054\040
|
||||
\114\164\144\056\061\035\060\033\006\003\125\004\003\023\024\123
|
||||
\145\143\165\162\145\123\151\147\156\040\122\157\157\164\040\103
|
||||
\101\061\064
|
||||
END
|
||||
CKA_SERIAL_NUMBER MULTILINE_OCTAL
|
||||
\002\024\144\333\132\014\040\116\350\327\051\167\310\120\047\242
|
||||
\132\047\335\055\362\313
|
||||
END
|
||||
CKA_VALUE MULTILINE_OCTAL
|
||||
\060\202\005\162\060\202\003\132\240\003\002\001\002\002\024\144
|
||||
\333\132\014\040\116\350\327\051\167\310\120\047\242\132\047\335
|
||||
\055\362\313\060\015\006\011\052\206\110\206\367\015\001\001\014
|
||||
\005\000\060\121\061\013\060\011\006\003\125\004\006\023\002\112
|
||||
\120\061\043\060\041\006\003\125\004\012\023\032\103\171\142\145
|
||||
\162\164\162\165\163\164\040\112\141\160\141\156\040\103\157\056
|
||||
\054\040\114\164\144\056\061\035\060\033\006\003\125\004\003\023
|
||||
\024\123\145\143\165\162\145\123\151\147\156\040\122\157\157\164
|
||||
\040\103\101\061\064\060\036\027\015\062\060\060\064\060\070\060
|
||||
\067\060\066\061\071\132\027\015\064\065\060\064\060\070\060\067
|
||||
\060\066\061\071\132\060\121\061\013\060\011\006\003\125\004\006
|
||||
\023\002\112\120\061\043\060\041\006\003\125\004\012\023\032\103
|
||||
\171\142\145\162\164\162\165\163\164\040\112\141\160\141\156\040
|
||||
\103\157\056\054\040\114\164\144\056\061\035\060\033\006\003\125
|
||||
\004\003\023\024\123\145\143\165\162\145\123\151\147\156\040\122
|
||||
\157\157\164\040\103\101\061\064\060\202\002\042\060\015\006\011
|
||||
\052\206\110\206\367\015\001\001\001\005\000\003\202\002\017\000
|
||||
\060\202\002\012\002\202\002\001\000\305\322\172\241\326\212\277
|
||||
\026\061\320\230\321\072\224\374\132\270\156\042\301\142\367\247
|
||||
\012\047\357\120\366\056\261\236\150\022\360\154\044\143\071\361
|
||||
\360\337\020\306\336\267\122\040\325\122\133\102\231\236\363\240
|
||||
\276\122\037\137\314\147\155\247\056\120\242\301\227\215\266\370
|
||||
\225\365\260\272\334\235\340\276\313\337\367\070\362\107\365\246
|
||||
\232\222\225\052\142\131\120\013\242\261\065\347\145\262\141\262
|
||||
\352\222\161\151\344\051\360\117\201\201\004\074\262\245\133\324
|
||||
\305\250\131\147\173\125\034\111\253\172\235\302\347\163\115\357
|
||||
\315\011\302\304\127\022\333\001\016\043\171\011\007\073\242\350
|
||||
\374\212\317\217\300\106\044\234\070\047\340\203\235\033\240\277
|
||||
\170\025\020\353\206\116\012\132\375\337\332\054\202\176\356\312
|
||||
\366\051\341\372\161\241\367\210\150\234\234\360\215\276\017\111
|
||||
\221\330\352\072\371\375\320\150\161\333\351\265\053\116\202\222
|
||||
\157\146\037\340\360\334\114\354\312\321\352\272\164\006\371\263
|
||||
\204\220\224\321\137\216\163\031\020\135\002\345\160\245\300\020
|
||||
\320\020\174\157\305\130\111\264\260\156\232\332\175\225\365\314
|
||||
\332\002\257\270\054\175\171\217\276\103\361\371\050\050\215\011
|
||||
\103\370\010\335\153\310\213\054\044\261\215\122\007\275\170\233
|
||||
\313\312\150\262\244\335\014\114\171\140\306\231\321\223\361\060
|
||||
\032\007\323\256\042\302\352\316\361\204\011\314\340\024\156\177
|
||||
\077\176\322\202\205\254\334\251\026\116\205\240\140\313\366\234
|
||||
\327\310\263\216\355\306\233\230\165\015\125\350\137\345\225\213
|
||||
\002\244\256\103\051\050\021\244\346\022\060\001\113\165\153\036
|
||||
\146\235\171\057\245\166\057\035\100\264\155\311\175\171\010\354
|
||||
\321\152\266\135\052\262\245\146\275\153\205\364\164\126\303\365
|
||||
\347\165\122\050\054\245\377\146\107\245\324\376\376\236\124\277
|
||||
\145\176\001\326\060\217\245\066\234\242\120\034\356\070\200\001
|
||||
\110\306\307\164\364\306\254\303\100\111\026\141\164\054\257\214
|
||||
\157\065\355\173\030\000\133\066\074\234\120\015\312\222\063\020
|
||||
\361\046\111\155\337\165\044\067\202\042\327\350\226\375\025\113
|
||||
\002\226\076\007\162\225\176\253\075\114\056\327\312\360\337\340
|
||||
\130\077\055\057\004\232\070\243\001\002\003\001\000\001\243\102
|
||||
\060\100\060\017\006\003\125\035\023\001\001\377\004\005\060\003
|
||||
\001\001\377\060\016\006\003\125\035\017\001\001\377\004\004\003
|
||||
\002\001\006\060\035\006\003\125\035\016\004\026\004\024\006\223
|
||||
\243\012\136\050\151\067\252\141\035\353\353\374\055\157\043\344
|
||||
\363\240\060\015\006\011\052\206\110\206\367\015\001\001\014\005
|
||||
\000\003\202\002\001\000\226\200\162\011\006\176\234\314\223\004
|
||||
\026\273\240\072\215\222\116\267\021\032\012\161\161\020\315\004
|
||||
\255\177\245\105\120\020\146\116\112\101\242\003\331\021\117\172
|
||||
\067\271\113\342\306\217\062\146\165\045\373\353\316\077\003\051
|
||||
\046\215\270\026\035\366\037\063\156\110\346\350\370\127\262\033
|
||||
\171\337\073\207\012\342\144\272\000\312\154\357\176\320\043\353
|
||||
\170\217\377\144\233\064\067\237\065\145\242\244\000\075\022\043
|
||||
\226\130\135\312\143\207\306\243\007\210\115\347\151\166\212\123
|
||||
\315\361\117\354\102\362\223\343\231\244\067\074\207\270\142\333
|
||||
\360\354\037\067\077\067\137\103\314\121\235\265\360\227\302\267
|
||||
\205\152\150\013\104\036\345\121\356\223\316\113\156\206\301\322
|
||||
\014\044\131\066\032\237\054\221\217\343\030\333\224\225\012\355
|
||||
\221\252\016\231\334\226\123\343\141\203\306\026\272\043\272\334
|
||||
\335\176\032\306\173\102\266\331\132\005\334\232\137\325\337\270
|
||||
\332\107\175\332\070\333\254\071\325\036\153\154\052\027\214\141
|
||||
\315\261\155\162\001\303\303\040\000\142\150\026\061\325\166\252
|
||||
\206\273\016\252\236\306\371\360\331\370\015\041\002\344\305\050
|
||||
\026\131\021\271\331\151\163\052\222\170\270\222\127\233\010\362
|
||||
\072\345\057\225\260\130\267\153\040\024\155\024\357\012\274\176
|
||||
\330\125\330\210\332\057\372\031\245\373\213\340\177\071\365\162
|
||||
\053\205\304\054\254\357\031\105\222\114\263\141\007\334\115\037
|
||||
\156\322\201\023\134\232\363\022\147\203\317\233\077\213\237\235
|
||||
\244\271\250\226\003\172\305\356\040\336\063\332\057\236\032\172
|
||||
\164\036\341\356\314\132\072\004\335\263\032\004\250\024\143\254
|
||||
\267\107\022\203\232\154\365\346\351\025\025\221\032\204\031\016
|
||||
\224\104\347\022\216\045\133\200\147\031\334\143\223\020\013\145
|
||||
\056\212\372\011\232\116\332\206\050\175\252\141\065\330\016\247
|
||||
\050\032\273\122\340\170\370\154\272\154\260\156\271\207\136\351
|
||||
\231\065\067\361\075\144\053\251\240\064\223\317\143\057\325\201
|
||||
\337\256\143\047\245\036\116\215\334\051\170\131\370\371\241\040
|
||||
\214\247\046\100\156\202\162\315\170\262\310\217\074\036\163\347
|
||||
\301\037\277\317\316\245\052\233\333\104\144\062\240\273\177\134
|
||||
\045\023\110\265\177\222
|
||||
END
|
||||
CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE
|
||||
CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE
|
||||
CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE
|
||||
|
||||
# Trust for "SecureSign Root CA14"
|
||||
# Issuer: CN=SecureSign Root CA14,O="Cybertrust Japan Co., Ltd.",C=JP
|
||||
# Serial Number:64:db:5a:0c:20:4e:e8:d7:29:77:c8:50:27:a2:5a:27:dd:2d:f2:cb
|
||||
# Subject: CN=SecureSign Root CA14,O="Cybertrust Japan Co., Ltd.",C=JP
|
||||
# Not Valid Before: Wed Apr 08 07:06:19 2020
|
||||
# Not Valid After : Sat Apr 08 07:06:19 2045
|
||||
# Fingerprint (SHA-256): 4B:00:9C:10:34:49:4F:9A:B5:6B:BA:3B:A1:D6:27:31:FC:4D:20:D8:95:5A:DC:EC:10:A9:25:60:72:61:E3:38
|
||||
# Fingerprint (SHA1): DD:50:C0:F7:79:B3:64:2E:74:A2:B8:9D:9F:D3:40:DD:BB:F0:F2:4F
|
||||
CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
|
||||
CKA_TOKEN CK_BBOOL CK_TRUE
|
||||
CKA_PRIVATE CK_BBOOL CK_FALSE
|
||||
CKA_MODIFIABLE CK_BBOOL CK_FALSE
|
||||
CKA_LABEL UTF8 "SecureSign Root CA14"
|
||||
CKA_CERT_SHA1_HASH MULTILINE_OCTAL
|
||||
\335\120\300\367\171\263\144\056\164\242\270\235\237\323\100\335
|
||||
\273\360\362\117
|
||||
END
|
||||
CKA_CERT_MD5_HASH MULTILINE_OCTAL
|
||||
\161\015\162\372\222\031\145\136\211\004\254\026\063\360\274\325
|
||||
END
|
||||
CKA_ISSUER MULTILINE_OCTAL
|
||||
\060\121\061\013\060\011\006\003\125\004\006\023\002\112\120\061
|
||||
\043\060\041\006\003\125\004\012\023\032\103\171\142\145\162\164
|
||||
\162\165\163\164\040\112\141\160\141\156\040\103\157\056\054\040
|
||||
\114\164\144\056\061\035\060\033\006\003\125\004\003\023\024\123
|
||||
\145\143\165\162\145\123\151\147\156\040\122\157\157\164\040\103
|
||||
\101\061\064
|
||||
END
|
||||
CKA_SERIAL_NUMBER MULTILINE_OCTAL
|
||||
\002\024\144\333\132\014\040\116\350\327\051\167\310\120\047\242
|
||||
\132\047\335\055\362\313
|
||||
END
|
||||
CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
|
||||
CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
|
||||
CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
|
||||
CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
|
||||
|
||||
#
|
||||
# Certificate "SecureSign Root CA15"
|
||||
#
|
||||
# Issuer: CN=SecureSign Root CA15,O="Cybertrust Japan Co., Ltd.",C=JP
|
||||
# Serial Number:16:15:c7:c3:d8:49:a7:be:69:0c:8a:88:ed:f0:70:f9:dd:b7:3e:87
|
||||
# Subject: CN=SecureSign Root CA15,O="Cybertrust Japan Co., Ltd.",C=JP
|
||||
# Not Valid Before: Wed Apr 08 08:32:56 2020
|
||||
# Not Valid After : Sat Apr 08 08:32:56 2045
|
||||
# Fingerprint (SHA-256): E7:78:F0:F0:95:FE:84:37:29:CD:1A:00:82:17:9E:53:14:A9:C2:91:44:28:05:E1:FB:1D:8F:B6:B8:88:6C:3A
|
||||
# Fingerprint (SHA1): CB:BA:83:C8:C1:5A:5D:F1:F9:73:6F:CA:D7:EF:28:13:06:4A:07:7D
|
||||
CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
|
||||
CKA_TOKEN CK_BBOOL CK_TRUE
|
||||
CKA_PRIVATE CK_BBOOL CK_FALSE
|
||||
CKA_MODIFIABLE CK_BBOOL CK_FALSE
|
||||
CKA_LABEL UTF8 "SecureSign Root CA15"
|
||||
CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
|
||||
CKA_SUBJECT MULTILINE_OCTAL
|
||||
\060\121\061\013\060\011\006\003\125\004\006\023\002\112\120\061
|
||||
\043\060\041\006\003\125\004\012\023\032\103\171\142\145\162\164
|
||||
\162\165\163\164\040\112\141\160\141\156\040\103\157\056\054\040
|
||||
\114\164\144\056\061\035\060\033\006\003\125\004\003\023\024\123
|
||||
\145\143\165\162\145\123\151\147\156\040\122\157\157\164\040\103
|
||||
\101\061\065
|
||||
END
|
||||
CKA_ID UTF8 "0"
|
||||
CKA_ISSUER MULTILINE_OCTAL
|
||||
\060\121\061\013\060\011\006\003\125\004\006\023\002\112\120\061
|
||||
\043\060\041\006\003\125\004\012\023\032\103\171\142\145\162\164
|
||||
\162\165\163\164\040\112\141\160\141\156\040\103\157\056\054\040
|
||||
\114\164\144\056\061\035\060\033\006\003\125\004\003\023\024\123
|
||||
\145\143\165\162\145\123\151\147\156\040\122\157\157\164\040\103
|
||||
\101\061\065
|
||||
END
|
||||
CKA_SERIAL_NUMBER MULTILINE_OCTAL
|
||||
\002\024\026\025\307\303\330\111\247\276\151\014\212\210\355\360
|
||||
\160\371\335\267\076\207
|
||||
END
|
||||
CKA_VALUE MULTILINE_OCTAL
|
||||
\060\202\002\043\060\202\001\251\240\003\002\001\002\002\024\026
|
||||
\025\307\303\330\111\247\276\151\014\212\210\355\360\160\371\335
|
||||
\267\076\207\060\012\006\010\052\206\110\316\075\004\003\003\060
|
||||
\121\061\013\060\011\006\003\125\004\006\023\002\112\120\061\043
|
||||
\060\041\006\003\125\004\012\023\032\103\171\142\145\162\164\162
|
||||
\165\163\164\040\112\141\160\141\156\040\103\157\056\054\040\114
|
||||
\164\144\056\061\035\060\033\006\003\125\004\003\023\024\123\145
|
||||
\143\165\162\145\123\151\147\156\040\122\157\157\164\040\103\101
|
||||
\061\065\060\036\027\015\062\060\060\064\060\070\060\070\063\062
|
||||
\065\066\132\027\015\064\065\060\064\060\070\060\070\063\062\065
|
||||
\066\132\060\121\061\013\060\011\006\003\125\004\006\023\002\112
|
||||
\120\061\043\060\041\006\003\125\004\012\023\032\103\171\142\145
|
||||
\162\164\162\165\163\164\040\112\141\160\141\156\040\103\157\056
|
||||
\054\040\114\164\144\056\061\035\060\033\006\003\125\004\003\023
|
||||
\024\123\145\143\165\162\145\123\151\147\156\040\122\157\157\164
|
||||
\040\103\101\061\065\060\166\060\020\006\007\052\206\110\316\075
|
||||
\002\001\006\005\053\201\004\000\042\003\142\000\004\013\120\164
|
||||
\215\144\062\231\231\263\322\140\010\270\042\216\106\164\054\170
|
||||
\300\053\104\055\155\137\035\311\256\113\122\040\203\075\270\024
|
||||
\155\123\207\140\236\137\154\205\333\006\024\225\340\307\050\377
|
||||
\235\137\344\252\361\263\213\155\355\117\057\113\311\112\224\221
|
||||
\144\165\376\001\354\301\330\353\172\224\170\126\030\103\137\153
|
||||
\201\313\366\274\332\264\014\266\051\223\010\151\217\243\102\060
|
||||
\100\060\017\006\003\125\035\023\001\001\377\004\005\060\003\001
|
||||
\001\377\060\016\006\003\125\035\017\001\001\377\004\004\003\002
|
||||
\001\006\060\035\006\003\125\035\016\004\026\004\024\353\101\310
|
||||
\256\374\325\236\121\110\365\275\213\364\207\040\223\101\053\323
|
||||
\364\060\012\006\010\052\206\110\316\075\004\003\003\003\150\000
|
||||
\060\145\002\061\000\331\056\211\176\136\116\244\021\007\275\131
|
||||
\302\007\336\253\062\070\123\052\106\104\006\027\172\316\121\351
|
||||
\340\377\146\055\011\116\340\117\364\005\321\205\366\065\140\334
|
||||
\365\162\263\106\175\002\060\104\230\106\032\202\205\036\141\151
|
||||
\211\113\007\113\146\265\236\252\272\240\036\101\331\001\164\072
|
||||
\156\105\072\211\200\031\173\062\230\125\143\253\353\143\156\223
|
||||
\155\253\033\011\140\061\116
|
||||
END
|
||||
CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE
|
||||
CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE
|
||||
CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE
|
||||
|
||||
# Trust for "SecureSign Root CA15"
|
||||
# Issuer: CN=SecureSign Root CA15,O="Cybertrust Japan Co., Ltd.",C=JP
|
||||
# Serial Number:16:15:c7:c3:d8:49:a7:be:69:0c:8a:88:ed:f0:70:f9:dd:b7:3e:87
|
||||
# Subject: CN=SecureSign Root CA15,O="Cybertrust Japan Co., Ltd.",C=JP
|
||||
# Not Valid Before: Wed Apr 08 08:32:56 2020
|
||||
# Not Valid After : Sat Apr 08 08:32:56 2045
|
||||
# Fingerprint (SHA-256): E7:78:F0:F0:95:FE:84:37:29:CD:1A:00:82:17:9E:53:14:A9:C2:91:44:28:05:E1:FB:1D:8F:B6:B8:88:6C:3A
|
||||
# Fingerprint (SHA1): CB:BA:83:C8:C1:5A:5D:F1:F9:73:6F:CA:D7:EF:28:13:06:4A:07:7D
|
||||
CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
|
||||
CKA_TOKEN CK_BBOOL CK_TRUE
|
||||
CKA_PRIVATE CK_BBOOL CK_FALSE
|
||||
CKA_MODIFIABLE CK_BBOOL CK_FALSE
|
||||
CKA_LABEL UTF8 "SecureSign Root CA15"
|
||||
CKA_CERT_SHA1_HASH MULTILINE_OCTAL
|
||||
\313\272\203\310\301\132\135\361\371\163\157\312\327\357\050\023
|
||||
\006\112\007\175
|
||||
END
|
||||
CKA_CERT_MD5_HASH MULTILINE_OCTAL
|
||||
\023\060\374\304\142\246\251\336\265\301\150\257\265\322\061\107
|
||||
END
|
||||
CKA_ISSUER MULTILINE_OCTAL
|
||||
\060\121\061\013\060\011\006\003\125\004\006\023\002\112\120\061
|
||||
\043\060\041\006\003\125\004\012\023\032\103\171\142\145\162\164
|
||||
\162\165\163\164\040\112\141\160\141\156\040\103\157\056\054\040
|
||||
\114\164\144\056\061\035\060\033\006\003\125\004\003\023\024\123
|
||||
\145\143\165\162\145\123\151\147\156\040\122\157\157\164\040\103
|
||||
\101\061\065
|
||||
END
|
||||
CKA_SERIAL_NUMBER MULTILINE_OCTAL
|
||||
\002\024\026\025\307\303\330\111\247\276\151\014\212\210\355\360
|
||||
\160\371\335\267\076\207
|
||||
END
|
||||
CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
|
||||
CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
|
||||
CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
|
||||
CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
|
||||
|
||||
@@ -3614,4 +3614,101 @@ static struct us_cert_string_t root_certs[] = {
|
||||
"fKR7w4l1M+E7qUW/Runpod3JIha3RxEL2Jq68cgLcFBTApFwhVmpHqTm6iMxoAACMQD94viz\n"
|
||||
"rxa5HnPEluPBMBnYfubDl94cT7iJLzPrSA8Z94dGXSaQpYXFuXqUPoeovQA=\n"
|
||||
"-----END CERTIFICATE-----",.len=917},
|
||||
|
||||
/* TWCA CYBER Root CA */
|
||||
{.str="-----BEGIN CERTIFICATE-----\n"
|
||||
"MIIFjTCCA3WgAwIBAgIQQAE0jMIAAAAAAAAAATzyxjANBgkqhkiG9w0BAQwFADBQMQswCQYD\n"
|
||||
"VQQGEwJUVzESMBAGA1UEChMJVEFJV0FOLUNBMRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQD\n"
|
||||
"ExJUV0NBIENZQkVSIFJvb3QgQ0EwHhcNMjIxMTIyMDY1NDI5WhcNNDcxMTIyMTU1OTU5WjBQ\n"
|
||||
"MQswCQYDVQQGEwJUVzESMBAGA1UEChMJVEFJV0FOLUNBMRAwDgYDVQQLEwdSb290IENBMRsw\n"
|
||||
"GQYDVQQDExJUV0NBIENZQkVSIFJvb3QgQ0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK\n"
|
||||
"AoICAQDG+Moe2Qkgfh1sTs6P40czRJzHyWmqOlt47nDSkvgEs1JSHWdyKKHfi12VCv7qze33\n"
|
||||
"Kc7wb3+szT3vsxxFavcokPFhV8UMxKNQXd7UtcsZyoC5dc4pztKFIuwCY8xEMCDa6pFbVuYd\n"
|
||||
"HNWdZsc/34bKS1PE2Y2yHer43CdTo0fhYcx9tbD47nORxc5zb87uEB8aBs/pJ2DFTxnk684i\n"
|
||||
"JkXXYJndzk834H/nY62wuFm40AZoNWDTNq5xQwTxaWV4fPMf88oon1oglWa0zbfuj3ikRRjp\n"
|
||||
"Ji+NmykosaS3Om251Bw4ckVYsV7r8Cibt4LK/c/WMw+f+5eesRycnupfXtuq3VTpMCEobY55\n"
|
||||
"83WSjCb+3MX2w7DfRFlDo7YDKPYIMKoNM+HvnKkHIuNZW0CP2oi3aQiotyMuRAlZN1vH4xfy\n"
|
||||
"IutuOVLF3lSnmMlLIJXcRolftBL5hSmO68gnFSDAS9TMfAxsNAwmmyYxpjyn9tnQS6Jk/zuZ\n"
|
||||
"QXLB4HCX8SS7K8R0IrGsayIyJNN4KsDAoS/xUgXJP+92ZuJF2A09rZXIx4kmyA+upwMu+8Ff\n"
|
||||
"+iDhcK2wZSA3M2Cw1a/XDBzCkHDXShi8fgGwsOsVHkQGzaRP6AzRwyAQ4VRlnrZR0Bp2a0Ja\n"
|
||||
"WHY06rc3Ga4udfmW5cFZ95RXKSWNOkyrTZpB0F8mAwIDAQABo2MwYTAOBgNVHQ8BAf8EBAMC\n"
|
||||
"AQYwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBSdhWEUfMFib5do5E83QOGt4A1WNzAd\n"
|
||||
"BgNVHQ4EFgQUnYVhFHzBYm+XaORPN0DhreANVjcwDQYJKoZIhvcNAQEMBQADggIBAGSPesRi\n"
|
||||
"DrWIzLjHhg6hShbNcAu3p4ULs3a2D6f/CIsLJc+o1IN1KriWiLb73y0ttGlTITVX1olNc79p\n"
|
||||
"j3CjYcya2x6a4CD4bLubIp1dhDGaLIrdaqHXKGnK/nZVekZn68xDiBaiA9a5F/gZbG0jAn/x\n"
|
||||
"X9AKKSM70aoK7akXJlQKTcKlTfjF/biBzysseKNnTKkHmvPfXvt89YnNdJdhEGoHK4Fa0o63\n"
|
||||
"5yDRIG4kqIQnoVesqlVYL9zZyvpoBJ7tRCT5dEA7IzOrg1oYJkK2bVS1FmAwbLGg+LhBoF1J\n"
|
||||
"SdJlBTrq/p1hvIbZv97Tujqxf36SNI7JAG7cmL3c7IAFrQI932XtCwP39xaEBDG6k5TY8hL4\n"
|
||||
"iuO/Qq+n1M0RFxbIQh0UqEL20kCGoE8jypZFVmAGzbdVAaYBlGX+bgUJurSkquLvWL69J1bY\n"
|
||||
"73NxW0Qz8ppy6rBePm6pUlvscG21h483XjyMnM7k8M4MZ0HMzvaAq07MTFb1wWFZk7Q+ptq4\n"
|
||||
"NxKfKjLji7gh7MMrZQzvIt6IKTtM1/r+t+FHvpw+PoP7UV31aPcuIYXcv/Fa4nzXxeSDwWrr\n"
|
||||
"uoBa3lwtcHb4yOWHh8qgnaHlIhInD0Q9HWzq1MKLL295q39QpsQZp6F6t5b5wR9iWqJDB0Be\n"
|
||||
"Jsas7a5wFsWqynKKTbDPAYsDP27X\n"
|
||||
"-----END CERTIFICATE-----",.len=1980},
|
||||
|
||||
/* SecureSign Root CA12 */
|
||||
{.str="-----BEGIN CERTIFICATE-----\n"
|
||||
"MIIDcjCCAlqgAwIBAgIUZvnHwa/swlG07VOX5uaCwysckBYwDQYJKoZIhvcNAQELBQAwUTEL\n"
|
||||
"MAkGA1UEBhMCSlAxIzAhBgNVBAoTGkN5YmVydHJ1c3QgSmFwYW4gQ28uLCBMdGQuMR0wGwYD\n"
|
||||
"VQQDExRTZWN1cmVTaWduIFJvb3QgQ0ExMjAeFw0yMDA0MDgwNTM2NDZaFw00MDA0MDgwNTM2\n"
|
||||
"NDZaMFExCzAJBgNVBAYTAkpQMSMwIQYDVQQKExpDeWJlcnRydXN0IEphcGFuIENvLiwgTHRk\n"
|
||||
"LjEdMBsGA1UEAxMUU2VjdXJlU2lnbiBSb290IENBMTIwggEiMA0GCSqGSIb3DQEBAQUAA4IB\n"
|
||||
"DwAwggEKAoIBAQC6OcE3emhFKxS06+QT61d1I02PJC0W6K6OyX2kVzsqdiUzg2zqMoqUm048\n"
|
||||
"luT9Ub+ZyZN+v/mtp7JIKwccJ/VMvHASd6SFVLX9kHrko+RRWAPNEHl57muTH2SOa2SroxPj\n"
|
||||
"cf59q5zdJ1M3s6oYwlkm7Fsf0uZlfO+TvdhYXAvA42VvPMfKWeP+bl+sg779XSVOKik71gur\n"
|
||||
"FzJ4pOE+lEa+Ym6b3kaosRbnhW70CEBFEaCeVESE99g2zvVQR9wsMJvuwPWW0v4JhscGWa5P\n"
|
||||
"ro4RmHvzC1KqYiaqId+OJTN5lxZJjfU+1UefNzFJM3IFTQy2VYzxV4+Kh9GtxRESOaCtAgMB\n"
|
||||
"AAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRXNPN0\n"
|
||||
"zwRL1SXm8UC2LEzZLemgrTANBgkqhkiG9w0BAQsFAAOCAQEAPrvbFxbS8hQBICw4g0utvsqF\n"
|
||||
"epq2m2um4fylOqyttCg6r9cBg0krY6LdmmQOmFxv3Y67ilQiLUoT865AQ9tPkbeGGuwAtEGB\n"
|
||||
"pE/6aouIs3YIcipJQMPTw4WJmBClnW8Zt7vPemVV2zfrPIpyMpcemik+rY3moxtt9XUa5rBo\n"
|
||||
"uVui7mlHJzWhhpmA8zNL4WukJsPvdFlseqJkth5Ew1DgDzk9qTPxpfPSvWKErI4cqc1avTc7\n"
|
||||
"bgoitPQV55FYxTpE05Uo2cBl6XLK0A+9H7MV2anjpEcJnuDLN/v9vZfVvhgaaaI5gdka9at/\n"
|
||||
"yOPiZwud9AzqVN/Ssq+xIvEg37xEHA==\n"
|
||||
"-----END CERTIFICATE-----",.len=1254},
|
||||
|
||||
/* SecureSign Root CA14 */
|
||||
{.str="-----BEGIN CERTIFICATE-----\n"
|
||||
"MIIFcjCCA1qgAwIBAgIUZNtaDCBO6Ncpd8hQJ6JaJ90t8sswDQYJKoZIhvcNAQEMBQAwUTEL\n"
|
||||
"MAkGA1UEBhMCSlAxIzAhBgNVBAoTGkN5YmVydHJ1c3QgSmFwYW4gQ28uLCBMdGQuMR0wGwYD\n"
|
||||
"VQQDExRTZWN1cmVTaWduIFJvb3QgQ0ExNDAeFw0yMDA0MDgwNzA2MTlaFw00NTA0MDgwNzA2\n"
|
||||
"MTlaMFExCzAJBgNVBAYTAkpQMSMwIQYDVQQKExpDeWJlcnRydXN0IEphcGFuIENvLiwgTHRk\n"
|
||||
"LjEdMBsGA1UEAxMUU2VjdXJlU2lnbiBSb290IENBMTQwggIiMA0GCSqGSIb3DQEBAQUAA4IC\n"
|
||||
"DwAwggIKAoICAQDF0nqh1oq/FjHQmNE6lPxauG4iwWL3pwon71D2LrGeaBLwbCRjOfHw3xDG\n"
|
||||
"3rdSINVSW0KZnvOgvlIfX8xnbacuUKLBl422+JX1sLrcneC+y9/3OPJH9aaakpUqYllQC6Kx\n"
|
||||
"NedlsmGy6pJxaeQp8E+BgQQ8sqVb1MWoWWd7VRxJq3qdwudzTe/NCcLEVxLbAQ4jeQkHO6Lo\n"
|
||||
"/IrPj8BGJJw4J+CDnRugv3gVEOuGTgpa/d/aLIJ+7sr2KeH6caH3iGicnPCNvg9JkdjqOvn9\n"
|
||||
"0Ghx2+m1K06Ckm9mH+Dw3EzsytHqunQG+bOEkJTRX45zGRBdAuVwpcAQ0BB8b8VYSbSwbpra\n"
|
||||
"fZX1zNoCr7gsfXmPvkPx+SgojQlD+Ajda8iLLCSxjVIHvXiby8posqTdDEx5YMaZ0ZPxMBoH\n"
|
||||
"064iwurO8YQJzOAUbn8/ftKChazcqRZOhaBgy/ac18izju3Gm5h1DVXoX+WViwKkrkMpKBGk\n"
|
||||
"5hIwAUt1ax5mnXkvpXYvHUC0bcl9eQjs0Wq2XSqypWa9a4X0dFbD9ed1Uigspf9mR6XU/v6e\n"
|
||||
"VL9lfgHWMI+lNpyiUBzuOIABSMbHdPTGrMNASRZhdCyvjG817XsYAFs2PJxQDcqSMxDxJklt\n"
|
||||
"33UkN4Ii1+iW/RVLApY+B3KVfqs9TC7XyvDf4Fg/LS8EmjijAQIDAQABo0IwQDAPBgNVHRMB\n"
|
||||
"Af8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUBpOjCl4oaTeqYR3r6/wtbyPk\n"
|
||||
"86AwDQYJKoZIhvcNAQEMBQADggIBAJaAcgkGfpzMkwQWu6A6jZJOtxEaCnFxEM0ErX+lRVAQ\n"
|
||||
"Zk5KQaID2RFPeje5S+LGjzJmdSX7684/AykmjbgWHfYfM25I5uj4V7Ibed87hwriZLoAymzv\n"
|
||||
"ftAj63iP/2SbNDefNWWipAA9EiOWWF3KY4fGoweITedpdopTzfFP7ELyk+OZpDc8h7hi2/Ds\n"
|
||||
"Hzc/N19DzFGdtfCXwreFamgLRB7lUe6TzktuhsHSDCRZNhqfLJGP4xjblJUK7ZGqDpncllPj\n"
|
||||
"YYPGFrojutzdfhrGe0K22VoF3Jpf1d+42kd92jjbrDnVHmtsKheMYc2xbXIBw8MgAGJoFjHV\n"
|
||||
"dqqGuw6qnsb58Nn4DSEC5MUoFlkRudlpcyqSeLiSV5sI8jrlL5WwWLdrIBRtFO8KvH7YVdiI\n"
|
||||
"2i/6GaX7i+B/OfVyK4XELKzvGUWSTLNhB9xNH27SgRNcmvMSZ4PPmz+Ln52kuaiWA3rF7iDe\n"
|
||||
"M9ovnhp6dB7h7sxaOgTdsxoEqBRjrLdHEoOabPXm6RUVkRqEGQ6UROcSjiVbgGcZ3GOTEAtl\n"
|
||||
"Lor6CZpO2oYofaphNdgOpygau1LgePhsumywbrmHXumZNTfxPWQrqaA0k89jL9WB365jJ6Ue\n"
|
||||
"To3cKXhZ+PmhIIynJkBugnLNeLLIjzwec+fBH7/PzqUqm9tEZDKgu39cJRNItX+S\n"
|
||||
"-----END CERTIFICATE-----",.len=1943},
|
||||
|
||||
/* SecureSign Root CA15 */
|
||||
{.str="-----BEGIN CERTIFICATE-----\n"
|
||||
"MIICIzCCAamgAwIBAgIUFhXHw9hJp75pDIqI7fBw+d23PocwCgYIKoZIzj0EAwMwUTELMAkG\n"
|
||||
"A1UEBhMCSlAxIzAhBgNVBAoTGkN5YmVydHJ1c3QgSmFwYW4gQ28uLCBMdGQuMR0wGwYDVQQD\n"
|
||||
"ExRTZWN1cmVTaWduIFJvb3QgQ0ExNTAeFw0yMDA0MDgwODMyNTZaFw00NTA0MDgwODMyNTZa\n"
|
||||
"MFExCzAJBgNVBAYTAkpQMSMwIQYDVQQKExpDeWJlcnRydXN0IEphcGFuIENvLiwgTHRkLjEd\n"
|
||||
"MBsGA1UEAxMUU2VjdXJlU2lnbiBSb290IENBMTUwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQL\n"
|
||||
"UHSNZDKZmbPSYAi4Io5GdCx4wCtELW1fHcmuS1Iggz24FG1Th2CeX2yF2wYUleDHKP+dX+Sq\n"
|
||||
"8bOLbe1PL0vJSpSRZHX+AezB2Ot6lHhWGENfa4HL9rzatAy2KZMIaY+jQjBAMA8GA1UdEwEB\n"
|
||||
"/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTrQciu/NWeUUj1vYv0hyCTQSvT\n"
|
||||
"9DAKBggqhkjOPQQDAwNoADBlAjEA2S6Jfl5OpBEHvVnCB96rMjhTKkZEBhd6zlHp4P9mLQlO\n"
|
||||
"4E/0BdGF9jVg3PVys0Z9AjBEmEYagoUeYWmJSwdLZrWeqrqgHkHZAXQ6bkU6iYAZezKYVWOr\n"
|
||||
"62Nuk22rGwlgMU4=\n"
|
||||
"-----END CERTIFICATE-----",.len=800},
|
||||
};
|
||||
|
||||
58
patches/libarchive/archive_write_add_filter_gzip.c.patch
Normal file
58
patches/libarchive/archive_write_add_filter_gzip.c.patch
Normal file
@@ -0,0 +1,58 @@
|
||||
--- a/libarchive/archive_write_add_filter_gzip.c
|
||||
+++ b/libarchive/archive_write_add_filter_gzip.c
|
||||
@@ -58,6 +58,7 @@ archive_write_set_compression_gzip(struct archive *a)
|
||||
struct private_data {
|
||||
int compression_level;
|
||||
int timestamp;
|
||||
+ unsigned char os;
|
||||
#ifdef HAVE_ZLIB_H
|
||||
z_stream stream;
|
||||
int64_t total_in;
|
||||
@@ -106,6 +107,7 @@ archive_write_add_filter_gzip(struct archive *_a)
|
||||
archive_set_error(&a->archive, ENOMEM, "Out of memory");
|
||||
return (ARCHIVE_FATAL);
|
||||
}
|
||||
+ data->os = 3; /* default Unix */
|
||||
f->data = data;
|
||||
f->open = &archive_compressor_gzip_open;
|
||||
f->options = &archive_compressor_gzip_options;
|
||||
@@ -166,6 +168,30 @@ archive_compressor_gzip_options(struct archive_write_filter *f, const char *key,
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
+ if (strcmp(key, "os") == 0) {
|
||||
+ if (value == NULL)
|
||||
+ return (ARCHIVE_WARN);
|
||||
+
|
||||
+ if (strcmp(value, "FAT") == 0) data->os = 0;
|
||||
+ else if (strcmp(value, "Amiga") == 0) data->os = 1;
|
||||
+ else if (strcmp(value, "VMS") == 0 || strcmp(value, "OpenVMS") == 0) data->os = 2;
|
||||
+ else if (strcmp(value, "Unix") == 0) data->os = 3;
|
||||
+ else if (strcmp(value, "VM") == 0 || strcmp(value, "VM/CMS") == 0) data->os = 4;
|
||||
+ else if (strcmp(value, "Atari TOS") == 0) data->os = 5;
|
||||
+ else if (strcmp(value, "HPFS") == 0) data->os = 6;
|
||||
+ else if (strcmp(value, "Macintosh") == 0) data->os = 7;
|
||||
+ else if (strcmp(value, "Z-System") == 0) data->os = 8;
|
||||
+ else if (strcmp(value, "CP/M") == 0) data->os = 9;
|
||||
+ else if (strcmp(value, "TOPS-20") == 0) data->os = 10;
|
||||
+ else if (strcmp(value, "NTFS") == 0) data->os = 11;
|
||||
+ else if (strcmp(value, "QDOS") == 0) data->os = 12;
|
||||
+ else if (strcmp(value, "Acorn RISCOS") == 0) data->os = 13;
|
||||
+ else if (strcmp(value, "Unknown") == 0) data->os = 255;
|
||||
+ else return (ARCHIVE_WARN);
|
||||
+
|
||||
+ return (ARCHIVE_OK);
|
||||
+ }
|
||||
+
|
||||
/* Note: The "warn" return is just to inform the options
|
||||
* supervisor that we didn't handle it. It will generate
|
||||
* a suitable error if no one used this option. */
|
||||
@@ -226,7 +252,7 @@ archive_compressor_gzip_open(struct archive_write_filter *f)
|
||||
data->compressed[8] = 4;
|
||||
else
|
||||
data->compressed[8] = 0;
|
||||
- data->compressed[9] = 3; /* OS=Unix */
|
||||
+ data->compressed[9] = data->os;
|
||||
data->stream.next_out += 10;
|
||||
data->stream.avail_out -= 10;
|
||||
|
||||
537
scripts/bootstrap.sh
Executable file
537
scripts/bootstrap.sh
Executable file
@@ -0,0 +1,537 @@
|
||||
#!/bin/sh
|
||||
|
||||
# A script to setup a machine to build or test Bun.
|
||||
# This should work on macOS and Linux, with support for most Linux distros.
|
||||
|
||||
pid=$$
|
||||
|
||||
print() {
|
||||
echo "$*"
|
||||
}
|
||||
|
||||
error() {
|
||||
echo "error: $*" >&2
|
||||
kill -s TERM "$pid"
|
||||
exit 1
|
||||
}
|
||||
|
||||
execute() {
|
||||
print "$ $*"
|
||||
if ! $*; then
|
||||
error "Command failed: $*"
|
||||
fi
|
||||
}
|
||||
|
||||
execute_non_root() {
|
||||
if [ "$sudo" = "1" ]; then
|
||||
execute sudo -u "$user" $*
|
||||
else
|
||||
execute $*
|
||||
fi
|
||||
}
|
||||
|
||||
which() {
|
||||
command -v "$1"
|
||||
}
|
||||
|
||||
require() {
|
||||
path="$(which "$1")"
|
||||
if ! [ -f "$path" ]; then
|
||||
error "Command \"$1\" is required, but is not installed."
|
||||
fi
|
||||
echo "$path"
|
||||
}
|
||||
|
||||
fetch() {
|
||||
curl=$(which curl)
|
||||
if [ -f "$curl" ]; then
|
||||
execute "$curl" -fsSL "$1"
|
||||
else
|
||||
wget=$(which wget)
|
||||
if [ -f "$wget" ]; then
|
||||
execute "$wget" -qO- "$1"
|
||||
else
|
||||
error "Command \"curl\" or \"wget\" is required, but is not installed."
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
compare_version() {
|
||||
if [ "$1" = "$2" ]; then
|
||||
echo "0"
|
||||
elif [ "$1" = "$(echo -e "$1\n$2" | sort -V | head -n1)" ]; then
|
||||
echo "-1"
|
||||
else
|
||||
echo "1"
|
||||
fi
|
||||
}
|
||||
|
||||
move_to_bin() {
|
||||
bin="$1"
|
||||
|
||||
if ! [ -d "$bin" ]; then
|
||||
error "Could not find directory: \"$bin\""
|
||||
fi
|
||||
|
||||
mv $bin/* /usr/bin/
|
||||
}
|
||||
|
||||
check_system() {
|
||||
uname="$(require uname)"
|
||||
|
||||
os="$($uname -s)"
|
||||
case "$os" in
|
||||
Linux*) os="linux" ;;
|
||||
Darwin*) os="darwin" ;;
|
||||
CYGWIN* | MINGW32* | MSYS* | MINGW*) os="windows" ;;
|
||||
*) error "Unsupported operating system: $os" ;;
|
||||
esac
|
||||
|
||||
arch="$($uname -m)"
|
||||
case "$arch" in
|
||||
x86_64 | x64 | amd64) arch="x64" ;;
|
||||
aarch64 | arm64) arch="aarch64" ;;
|
||||
*) error "Unsupported architecture: $arch" ;;
|
||||
esac
|
||||
|
||||
if [ "$os" = "darwin" ]; then
|
||||
sw_vers="$(which sw_vers)"
|
||||
if [ -f "$sw_vers" ]; then
|
||||
distro="$($sw_vers -productName)"
|
||||
release="$($sw_vers -productVersion)"
|
||||
fi
|
||||
|
||||
if [ "$arch" = "x64" ]; then
|
||||
sysctl="$(which sysctl)"
|
||||
if [ -f "$sysctl" ] && [ "$($sysctl -n sysctl.proc_translated 2>/dev/null)" = "1" ]; then
|
||||
arch="aarch64"
|
||||
rosetta="1"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$os" = "linux" ] && [ -f /etc/os-release ]; then
|
||||
. /etc/os-release
|
||||
if [ -n "$NAME" ]; then
|
||||
distro="$NAME"
|
||||
elif [ -n "$ID" ]; then
|
||||
distro="$ID"
|
||||
fi
|
||||
if [ -n "$VERSION_ID" ]; then
|
||||
release="$VERSION_ID"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$os" = "linux" ]; then
|
||||
rpm="$(which rpm)"
|
||||
if [ -f "$rpm" ]; then
|
||||
glibc="$($rpm -q glibc --queryformat '%{VERSION}\n')"
|
||||
else
|
||||
ldd="$(which ldd)"
|
||||
awk="$(which awk)"
|
||||
if [ -f "$ldd" ] && [ -f "$awk" ]; then
|
||||
glibc="$($ldd --version | $awk 'NR==1{print $NF}')"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$os" = "darwin" ]; then
|
||||
brew="$(which brew)"
|
||||
if ! [ -f "$brew" ]; then
|
||||
install_brew
|
||||
fi
|
||||
brew="$(require brew)"
|
||||
pm="brew"
|
||||
fi
|
||||
|
||||
if [ "$os" = "linux" ]; then
|
||||
apt="$(which apt-get)"
|
||||
if [ -f "$apt" ]; then
|
||||
pm="apt"
|
||||
else
|
||||
dnf="$(which dnf)"
|
||||
if [ -f "$dnf" ]; then
|
||||
pm="dnf"
|
||||
else
|
||||
yum="$(which yum)"
|
||||
if [ -f "$yum" ]; then
|
||||
pm="yum"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -z "$pm" ]; then
|
||||
error "No package manager found. (apt, dnf, yum)"
|
||||
fi
|
||||
fi
|
||||
|
||||
whoami="$(which whoami)"
|
||||
if [ -f "$whoami" ]; then
|
||||
user="$($whoami)"
|
||||
elif [ -n "$USER" ]; then
|
||||
user="$USER"
|
||||
else
|
||||
error "Could not determine the current user, set \$USER or ensure the \"whoami\" command is installed."
|
||||
fi
|
||||
|
||||
id="$(which id)"
|
||||
if [ -f "$id" ] && [ "$($id -u)" = "0" ]; then
|
||||
sudo=1
|
||||
elif [ "$EUID" = "0" ]; then
|
||||
sudo=1
|
||||
fi
|
||||
|
||||
print "System information:"
|
||||
if [ -n "$distro" ]; then
|
||||
print "| Distro: $distro $release"
|
||||
fi
|
||||
print "| Operating system: $os"
|
||||
print "| Architecture: $arch"
|
||||
if [ -n "$rosetta" ]; then
|
||||
print "| Rosetta: true"
|
||||
fi
|
||||
if [ -n "$glibc" ]; then
|
||||
print "| Glibc: $glibc"
|
||||
fi
|
||||
print "| Package manager: $pm"
|
||||
print "| User: $user"
|
||||
if [ -n "$sudo" ]; then
|
||||
print "| Sudo: true"
|
||||
fi
|
||||
}
|
||||
|
||||
package_manager() {
|
||||
case "$pm" in
|
||||
apt) execute "$apt" $* ;;
|
||||
dnf) execute "$dnf" $* ;;
|
||||
yum) execute "$yum" $* ;;
|
||||
brew) execute_non_root \
|
||||
HOMEBREW_NO_INSTALL_CLEANUP=1 \
|
||||
HOMEBREW_NO_AUTO_UPDATE=1 \
|
||||
HOMEBREW_NO_ANALYTICS=1 \
|
||||
"$brew" $* ;;
|
||||
*) error "Unsupported package manager: $pm" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
update_packages() {
|
||||
case "$pm" in
|
||||
apt) execute "$apt" update ;;
|
||||
esac
|
||||
}
|
||||
|
||||
check_package() {
|
||||
case "$pm" in
|
||||
apt) command="apt-cache policy $1" ;;
|
||||
dnf) command="$dnf info $1" ;;
|
||||
yum) command="$yum info $1" ;;
|
||||
brew) command="$brew info $1" ;;
|
||||
*) error "Unsupported package manager: $pm" ;;
|
||||
esac
|
||||
|
||||
$command
|
||||
}
|
||||
|
||||
install_packages() {
|
||||
case "$pm" in
|
||||
apt) args="install --yes --no-install-recommends" ;;
|
||||
dnf) args="install --assumeyes --nodocs --noautoremove --allowerasing" ;;
|
||||
yum) args="install -y" ;;
|
||||
brew) args="install --force" ;;
|
||||
*) error "Unsupported package manager: $pm" ;;
|
||||
esac
|
||||
|
||||
package_manager "$args" "$@"
|
||||
}
|
||||
|
||||
install_brew() {
|
||||
fetch "https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh" \
|
||||
| exec_non_root NONINTERACTIVE=1 bash
|
||||
}
|
||||
|
||||
install_common_software() {
|
||||
case "$pm" in
|
||||
apt) install_packages \
|
||||
apt-transport-https \
|
||||
software-properties-common ;;
|
||||
dnf) install_packages \
|
||||
dnf-plugins-core ;;
|
||||
esac
|
||||
|
||||
install_packages \
|
||||
ca-certificates \
|
||||
curl \
|
||||
bash \
|
||||
gnupg \
|
||||
git \
|
||||
unzip \
|
||||
tar \
|
||||
zip
|
||||
|
||||
install_nodejs
|
||||
install_bun
|
||||
}
|
||||
|
||||
install_nodejs() {
|
||||
version="${1:-"22"}"
|
||||
|
||||
if ! [ "$(compare_version "$glibc" "2.27")" = "1" ]; then
|
||||
version="16"
|
||||
fi
|
||||
|
||||
case "$pm" in
|
||||
dnf | yum) fetch "https://rpm.nodesource.com/setup_$version.x" | bash ;;
|
||||
apt) fetch "https://deb.nodesource.com/setup_$version.x" | bash ;;
|
||||
esac
|
||||
|
||||
install_packages nodejs
|
||||
}
|
||||
|
||||
install_bun() {
|
||||
bash="$(require bash)"
|
||||
version="${1:-"latest"}"
|
||||
|
||||
if [ "$version" = "latest" ]; then
|
||||
fetch "https://bun.sh/install" | "$bash"
|
||||
else
|
||||
fetch "https://bun.sh/install" | "$bash" -s "$version"
|
||||
fi
|
||||
|
||||
move_to_bin "$HOME/.bun/bin"
|
||||
}
|
||||
|
||||
install_build_essentials() {
|
||||
case "$pm" in
|
||||
apt) install_packages \
|
||||
build-essential \
|
||||
ccache \
|
||||
xz-utils ;;
|
||||
dnf | yum) install_packages \
|
||||
gcc-c++ \
|
||||
xz ;;
|
||||
esac
|
||||
|
||||
install_packages \
|
||||
make \
|
||||
cmake \
|
||||
ninja-build \
|
||||
pkg-config \
|
||||
python3 \
|
||||
libtool \
|
||||
ruby \
|
||||
perl \
|
||||
golang
|
||||
|
||||
install_llvm
|
||||
install_rust
|
||||
install_docker
|
||||
}
|
||||
|
||||
install_llvm() {
|
||||
version="${1:-"16"}"
|
||||
|
||||
case "$pm" in
|
||||
apt) fetch "https://apt.llvm.org/llvm.sh" | bash -s -- "$version" all ;;
|
||||
esac
|
||||
}
|
||||
|
||||
install_rust() {
|
||||
fetch "https://sh.rustup.rs" | sh -s -- -y
|
||||
move_to_bin "$HOME/.cargo/bin"
|
||||
}
|
||||
|
||||
install_docker() {
|
||||
fetch "https://get.docker.com" | sh
|
||||
}
|
||||
|
||||
install_ci_dependencies() {
|
||||
install_tailscale
|
||||
install_buildkite
|
||||
}
|
||||
|
||||
install_tailscale() {
|
||||
fetch "https://tailscale.com/install.sh" | sh
|
||||
}
|
||||
|
||||
install_buildkite() {
|
||||
case "$os" in
|
||||
linux) install_buildkite_linux ;;
|
||||
darwin) install_packages \
|
||||
buildkite/buildkite/buildkite-agent ;;
|
||||
esac
|
||||
}
|
||||
|
||||
install_buildkite_linux() {
|
||||
home_dir="/var/lib/buildkite-agent"
|
||||
config_dir="/etc/buildkite-agent"
|
||||
config_file="$config_dir/buildkite-agent.cfg"
|
||||
|
||||
getent="$(require getent)"
|
||||
if [ -z "$("$getent" passwd buildkite-agent)" ]; then
|
||||
useradd="$(require useradd)"
|
||||
execute "$useradd" buildkite-agent \
|
||||
--system \
|
||||
--no-create-home \
|
||||
--home-dir "$home_dir"
|
||||
fi
|
||||
|
||||
if [ -n "$("$getent" group docker)" ]; then
|
||||
usermod="$(require usermod)"
|
||||
execute "$usermod" -aG docker buildkite-agent
|
||||
fi
|
||||
|
||||
if ! [ -d "$home_dir" ]; then
|
||||
execute mkdir -p "$home_dir"
|
||||
fi
|
||||
|
||||
if ! [ -d "$config_dir" ]; then
|
||||
execute mkdir -p "$config_dir"
|
||||
fi
|
||||
|
||||
if ! [ -f "$config_file" ]; then
|
||||
cat << EOF > "$config_file"
|
||||
# This is generated by scripts/bootstrap.sh
|
||||
# https://buildkite.com/docs/agent/v3/configuration
|
||||
token="xxx"
|
||||
|
||||
name="%hostname-%pid"
|
||||
spawn=1
|
||||
tags="os=$os,arch=$arch,distro=$distro,release=$release,glibc=$glibc"
|
||||
|
||||
build-path="$home_dir"
|
||||
git-mirrors-path="$home_dir/git"
|
||||
job-log-path="$home_dir/logs"
|
||||
plugins-path="$config_dir/plugins"
|
||||
hooks-path="$config_dir/hooks"
|
||||
|
||||
no-ssh-keyscan=true
|
||||
cancel-grace-period=3600000 # 1 hour
|
||||
enable-job-log-tmpfile=true
|
||||
experiment="normalised-upload-paths,resolve-commit-after-checkout,agent-api"
|
||||
EOF
|
||||
fi
|
||||
|
||||
agent="$(which buildkite-agent)"
|
||||
if ! [ -f "$agent" ]; then
|
||||
bash="$(require bash)"
|
||||
fetch "https://raw.githubusercontent.com/buildkite/agent/main/install.sh" | "$bash"
|
||||
|
||||
out_dir="$HOME/.buildkite-agent"
|
||||
move_to_bin "$out_dir/bin"
|
||||
execute rm -rf "$out_dir"
|
||||
fi
|
||||
|
||||
agent="$(require buildkite-agent)"
|
||||
systemctl="$(which systemctl)"
|
||||
if [ -f "$systemctl" ]; then
|
||||
service_file="/etc/systemd/system/buildkite-agent.service"
|
||||
if ! [ -f "$service_file" ]; then
|
||||
cat << EOF > "$service_file"
|
||||
# This is generated by scripts/bootstrap.sh
|
||||
# https://buildkite.com/docs/agent/v3/configuration
|
||||
|
||||
[Unit]
|
||||
Description=Buildkite Agent
|
||||
Documentation=https://buildkite.com/agent
|
||||
After=syslog.target
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
User=buildkite-agent
|
||||
Environment=HOME=$home_dir
|
||||
ExecStart=$agent start
|
||||
RestartSec=5
|
||||
Restart=on-failure
|
||||
RestartForceExitStatus=SIGPIPE
|
||||
TimeoutStartSec=10
|
||||
TimeoutStopSec=0
|
||||
KillMode=process
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOF
|
||||
fi
|
||||
fi
|
||||
|
||||
execute chown -R buildkite-agent:buildkite-agent "$home_dir"
|
||||
execute chown -R buildkite-agent:buildkite-agent "$config_dir"
|
||||
}
|
||||
|
||||
install_chrome_dependencies() {
|
||||
# https://github.com/puppeteer/puppeteer/blob/main/docs/troubleshooting.md#chrome-doesnt-launch-on-linux
|
||||
# https://github.com/puppeteer/puppeteer/blob/main/docs/troubleshooting.md#running-puppeteer-in-the-cloud
|
||||
case "$pm" in
|
||||
apt) install_packages \
|
||||
fonts-liberation \
|
||||
libatk-bridge2.0-0 \
|
||||
libatk1.0-0 \
|
||||
libc6 \
|
||||
libcairo2 \
|
||||
libcups2 \
|
||||
libdbus-1-3 \
|
||||
libexpat1 \
|
||||
libfontconfig1 \
|
||||
libgbm1 \
|
||||
libgcc1 \
|
||||
libglib2.0-0 \
|
||||
libgtk-3-0 \
|
||||
libnspr4 \
|
||||
libnss3 \
|
||||
libpango-1.0-0 \
|
||||
libpangocairo-1.0-0 \
|
||||
libstdc++6 \
|
||||
libx11-6 \
|
||||
libx11-xcb1 \
|
||||
libxcb1 \
|
||||
libxcomposite1 \
|
||||
libxcursor1 \
|
||||
libxdamage1 \
|
||||
libxext6 \
|
||||
libxfixes3 \
|
||||
libxi6 \
|
||||
libxrandr2 \
|
||||
libxrender1 \
|
||||
libxss1 \
|
||||
libxtst6 \
|
||||
xdg-utils
|
||||
|
||||
# Fixes issue in newer version of Ubuntu:
|
||||
# Package 'libasound2' has no installation candidate
|
||||
if [ "$(check_package "libasound2t64")" ]; then
|
||||
install_packages libasound2t64
|
||||
else
|
||||
install_packages libasound2
|
||||
fi
|
||||
;;
|
||||
dnf | yum) install_packages \
|
||||
alsa-lib \
|
||||
atk \
|
||||
cups-libs \
|
||||
gtk3 \
|
||||
ipa-gothic-fonts \
|
||||
libXcomposite \
|
||||
libXcursor \
|
||||
libXdamage \
|
||||
libXext \
|
||||
libXi \
|
||||
libXrandr \
|
||||
libXScrnSaver \
|
||||
libXtst \
|
||||
pango \
|
||||
xorg-x11-fonts-100dpi \
|
||||
xorg-x11-fonts-75dpi \
|
||||
xorg-x11-fonts-cyrillic \
|
||||
xorg-x11-fonts-misc \
|
||||
xorg-x11-fonts-Type1 \
|
||||
xorg-x11-utils
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
check_system
|
||||
update_packages
|
||||
install_common_software
|
||||
install_build_essentials
|
||||
install_chrome_dependencies
|
||||
install_ci_dependencies
|
||||
@@ -172,23 +172,16 @@ const string = bun.string;
|
||||
pub const BunInfo = struct {
|
||||
bun_version: string,
|
||||
platform: Analytics.GenerateHeader.GeneratePlatform.Platform,
|
||||
framework: string = "",
|
||||
framework_version: string = "",
|
||||
|
||||
const Analytics = @import("./analytics/analytics_thread.zig");
|
||||
const JSON = bun.JSON;
|
||||
const JSAst = bun.JSAst;
|
||||
pub fn generate(comptime Bundler: type, bundler: Bundler, allocator: std.mem.Allocator) !JSAst.Expr {
|
||||
var info = BunInfo{
|
||||
pub fn generate(comptime Bundler: type, _: Bundler, allocator: std.mem.Allocator) !JSAst.Expr {
|
||||
const info = BunInfo{
|
||||
.bun_version = Global.package_json_version,
|
||||
.platform = Analytics.GenerateHeader.GeneratePlatform.forOS(),
|
||||
};
|
||||
|
||||
if (bundler.options.framework) |framework| {
|
||||
info.framework = framework.package;
|
||||
info.framework_version = framework.version;
|
||||
}
|
||||
|
||||
return try JSON.toAST(allocator, BunInfo, info);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -75,8 +75,10 @@ pub const StandaloneModuleGraph = struct {
|
||||
name: Schema.StringPointer = .{},
|
||||
contents: Schema.StringPointer = .{},
|
||||
sourcemap: Schema.StringPointer = .{},
|
||||
bytecode: Schema.StringPointer = .{},
|
||||
encoding: Encoding = .latin1,
|
||||
loader: bun.options.Loader = .file,
|
||||
module_format: ModuleFormat = .none,
|
||||
};
|
||||
|
||||
pub const Encoding = enum(u8) {
|
||||
@@ -88,6 +90,12 @@ pub const StandaloneModuleGraph = struct {
|
||||
utf8 = 2,
|
||||
};
|
||||
|
||||
pub const ModuleFormat = enum(u8) {
|
||||
none = 0,
|
||||
esm = 1,
|
||||
cjs = 2,
|
||||
};
|
||||
|
||||
pub const File = struct {
|
||||
name: []const u8 = "",
|
||||
loader: bun.options.Loader,
|
||||
@@ -96,6 +104,8 @@ pub const StandaloneModuleGraph = struct {
|
||||
cached_blob: ?*bun.JSC.WebCore.Blob = null,
|
||||
encoding: Encoding = .binary,
|
||||
wtf_string: bun.String = bun.String.empty,
|
||||
bytecode: []u8 = "",
|
||||
module_format: ModuleFormat = .none,
|
||||
|
||||
pub fn lessThanByIndex(ctx: []const File, lhs_i: u32, rhs_i: u32) bool {
|
||||
const lhs = ctx[lhs_i];
|
||||
@@ -225,7 +235,7 @@ pub const StandaloneModuleGraph = struct {
|
||||
};
|
||||
|
||||
const modules_list_bytes = sliceTo(raw_bytes, offsets.modules_ptr);
|
||||
const modules_list = std.mem.bytesAsSlice(CompiledModuleGraphFile, modules_list_bytes);
|
||||
const modules_list: []align(1) const CompiledModuleGraphFile = std.mem.bytesAsSlice(CompiledModuleGraphFile, modules_list_bytes);
|
||||
|
||||
if (offsets.entry_point_id > modules_list.len) {
|
||||
return error.@"Corrupted module graph: entry point ID is greater than module list count";
|
||||
@@ -246,6 +256,8 @@ pub const StandaloneModuleGraph = struct {
|
||||
} }
|
||||
else
|
||||
.none,
|
||||
.bytecode = if (module.bytecode.length > 0) @constCast(sliceTo(raw_bytes, module.bytecode)) else &.{},
|
||||
.module_format = module.module_format,
|
||||
},
|
||||
);
|
||||
}
|
||||
@@ -271,14 +283,14 @@ pub const StandaloneModuleGraph = struct {
|
||||
return bytes[ptr.offset..][0..ptr.length :0];
|
||||
}
|
||||
|
||||
pub fn toBytes(allocator: std.mem.Allocator, prefix: []const u8, output_files: []const bun.options.OutputFile) ![]u8 {
|
||||
pub fn toBytes(allocator: std.mem.Allocator, prefix: []const u8, output_files: []const bun.options.OutputFile, output_format: bun.options.Format) ![]u8 {
|
||||
var serialize_trace = bun.tracy.traceNamed(@src(), "StandaloneModuleGraph.serialize");
|
||||
defer serialize_trace.end();
|
||||
|
||||
var entry_point_id: ?usize = null;
|
||||
var string_builder = bun.StringBuilder{};
|
||||
var module_count: usize = 0;
|
||||
for (output_files, 0..) |output_file, i| {
|
||||
for (output_files) |output_file| {
|
||||
string_builder.countZ(output_file.dest_path);
|
||||
string_builder.countZ(prefix);
|
||||
if (output_file.value == .buffer) {
|
||||
@@ -288,10 +300,13 @@ pub const StandaloneModuleGraph = struct {
|
||||
// the exact amount is not possible without allocating as it
|
||||
// involves a JSON parser.
|
||||
string_builder.cap += output_file.value.buffer.bytes.len * 2;
|
||||
} else if (output_file.output_kind == .bytecode) {
|
||||
// Allocate up to 256 byte alignment for bytecode
|
||||
string_builder.cap += (output_file.value.buffer.bytes.len + 255) / 256 * 256 + 256;
|
||||
} else {
|
||||
if (entry_point_id == null) {
|
||||
if (output_file.output_kind == .@"entry-point") {
|
||||
entry_point_id = i;
|
||||
entry_point_id = module_count;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -320,7 +335,7 @@ pub const StandaloneModuleGraph = struct {
|
||||
defer source_map_arena.deinit();
|
||||
|
||||
for (output_files) |output_file| {
|
||||
if (output_file.output_kind == .sourcemap) {
|
||||
if (!output_file.output_kind.isFileInStandaloneMode()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -330,6 +345,23 @@ pub const StandaloneModuleGraph = struct {
|
||||
|
||||
const dest_path = bun.strings.removeLeadingDotSlash(output_file.dest_path);
|
||||
|
||||
const bytecode: StringPointer = brk: {
|
||||
if (output_file.bytecode_index != std.math.maxInt(u32)) {
|
||||
// Use up to 256 byte alignment for bytecode
|
||||
// Not aligning it correctly will cause a runtime assertion error, or a segfault.
|
||||
const bytecode = output_files[output_file.bytecode_index].value.buffer.bytes;
|
||||
const aligned = std.mem.alignInSlice(string_builder.writable(), 128).?;
|
||||
@memcpy(aligned[0..bytecode.len], bytecode[0..bytecode.len]);
|
||||
const unaligned_space = aligned[bytecode.len..];
|
||||
const offset = @intFromPtr(aligned.ptr) - @intFromPtr(string_builder.ptr.?);
|
||||
const len = bytecode.len + @min(unaligned_space.len, 128);
|
||||
string_builder.len += len;
|
||||
break :brk StringPointer{ .offset = @truncate(offset), .length = @truncate(len) };
|
||||
} else {
|
||||
break :brk .{};
|
||||
}
|
||||
};
|
||||
|
||||
var module = CompiledModuleGraphFile{
|
||||
.name = string_builder.fmtAppendCountZ("{s}{s}", .{
|
||||
prefix,
|
||||
@@ -341,7 +373,14 @@ pub const StandaloneModuleGraph = struct {
|
||||
.js, .jsx, .ts, .tsx => .latin1,
|
||||
else => .binary,
|
||||
},
|
||||
.module_format = if (output_file.loader.isJavaScriptLike()) switch (output_format) {
|
||||
.cjs => .cjs,
|
||||
.esm => .esm,
|
||||
else => .none,
|
||||
} else .none,
|
||||
.bytecode = bytecode,
|
||||
};
|
||||
|
||||
if (output_file.source_map_index != std.math.maxInt(u32)) {
|
||||
defer source_map_header_list.clearRetainingCapacity();
|
||||
defer source_map_string_list.clearRetainingCapacity();
|
||||
@@ -619,8 +658,9 @@ pub const StandaloneModuleGraph = struct {
|
||||
module_prefix: []const u8,
|
||||
outfile: []const u8,
|
||||
env: *bun.DotEnv.Loader,
|
||||
output_format: bun.options.Format,
|
||||
) !void {
|
||||
const bytes = try toBytes(allocator, module_prefix, output_files);
|
||||
const bytes = try toBytes(allocator, module_prefix, output_files, output_format);
|
||||
if (bytes.len == 0) return;
|
||||
|
||||
const fd = inject(
|
||||
@@ -999,7 +1039,7 @@ pub const StandaloneModuleGraph = struct {
|
||||
bun.JSAst.Expr.Data.Store.reset();
|
||||
bun.JSAst.Stmt.Data.Store.reset();
|
||||
}
|
||||
var json = bun.JSON.ParseJSON(&json_src, &log, arena, false) catch
|
||||
var json = bun.JSON.parse(&json_src, &log, arena, false) catch
|
||||
return error.InvalidSourceMap;
|
||||
|
||||
const mappings_str = json.get("mappings") orelse
|
||||
|
||||
@@ -79,41 +79,44 @@ pub fn isCI() bool {
|
||||
|
||||
/// This answers, "What parts of bun are people actually using?"
|
||||
pub const Features = struct {
|
||||
/// Set right before JSC::initialize is called
|
||||
pub var jsc: usize = 0;
|
||||
pub var builtin_modules = std.enums.EnumSet(bun.JSC.HardcodedModule).initEmpty();
|
||||
|
||||
pub var @"Bun.stderr": usize = 0;
|
||||
pub var @"Bun.stdin": usize = 0;
|
||||
pub var @"Bun.stdout": usize = 0;
|
||||
pub var WebSocket: usize = 0;
|
||||
pub var abort_signal: usize = 0;
|
||||
pub var binlinks: usize = 0;
|
||||
pub var bunfig: usize = 0;
|
||||
pub var define: usize = 0;
|
||||
pub var dotenv: usize = 0;
|
||||
pub var external: usize = 0;
|
||||
pub var extracted_packages: usize = 0;
|
||||
/// Incremented for each call to `fetch`
|
||||
pub var fetch: usize = 0;
|
||||
pub var filesystem_router: usize = 0;
|
||||
pub var git_dependencies: usize = 0;
|
||||
pub var html_rewriter: usize = 0;
|
||||
pub var http_server: usize = 0;
|
||||
pub var https_server: usize = 0;
|
||||
/// Set right before JSC::initialize is called
|
||||
pub var jsc: usize = 0;
|
||||
/// Set when kit.DevServer is initialized
|
||||
pub var kit_dev: usize = 0;
|
||||
pub var lifecycle_scripts: usize = 0;
|
||||
pub var loaders: usize = 0;
|
||||
pub var lockfile_migration_from_package_lock: usize = 0;
|
||||
pub var macros: usize = 0;
|
||||
pub var no_avx2: usize = 0;
|
||||
pub var no_avx: usize = 0;
|
||||
pub var shell: usize = 0;
|
||||
pub var spawn: usize = 0;
|
||||
pub var standalone_shell: usize = 0;
|
||||
pub var transpiler_cache: usize = 0;
|
||||
pub var tsconfig_paths: usize = 0;
|
||||
pub var tsconfig: usize = 0;
|
||||
pub var virtual_modules: usize = 0;
|
||||
pub var WebSocket: usize = 0;
|
||||
pub var no_avx: usize = 0;
|
||||
pub var no_avx2: usize = 0;
|
||||
pub var binlinks: usize = 0;
|
||||
pub var builtin_modules = std.enums.EnumSet(bun.JSC.HardcodedModule).initEmpty();
|
||||
pub var standalone_executable: usize = 0;
|
||||
pub var standalone_shell: usize = 0;
|
||||
/// Set when invoking a todo panic
|
||||
pub var todo_panic: usize = 0;
|
||||
pub var transpiler_cache: usize = 0;
|
||||
pub var tsconfig: usize = 0;
|
||||
pub var tsconfig_paths: usize = 0;
|
||||
pub var virtual_modules: usize = 0;
|
||||
pub var workers_spawned: usize = 0;
|
||||
pub var workers_terminated: usize = 0;
|
||||
|
||||
|
||||
@@ -1671,12 +1671,6 @@ pub const Api = struct {
|
||||
/// extension_order
|
||||
extension_order: []const []const u8,
|
||||
|
||||
/// framework
|
||||
framework: ?FrameworkConfig = null,
|
||||
|
||||
/// router
|
||||
router: ?RouteConfig = null,
|
||||
|
||||
/// no_summary
|
||||
no_summary: ?bool = null,
|
||||
|
||||
@@ -1755,9 +1749,7 @@ pub const Api = struct {
|
||||
15 => {
|
||||
this.target = try reader.readValue(Target);
|
||||
},
|
||||
16 => {
|
||||
this.serve = try reader.readValue(bool);
|
||||
},
|
||||
16 => {},
|
||||
17 => {
|
||||
this.env_files = try reader.readArray([]const u8);
|
||||
},
|
||||
|
||||
@@ -31,7 +31,6 @@ pub const RefCtx = struct {
|
||||
|
||||
/// In some parts of Bun, we have many different IDs pointing to different things.
|
||||
/// It's easy for them to get mixed up, so we use this type to make sure we don't.
|
||||
///
|
||||
pub const Index = packed struct(u32) {
|
||||
value: Int,
|
||||
|
||||
@@ -48,6 +47,9 @@ pub const Index = packed struct(u32) {
|
||||
pub const invalid = Index{ .value = std.math.maxInt(Int) };
|
||||
pub const runtime = Index{ .value = 0 };
|
||||
|
||||
pub const bake_server_data = Index{ .value = 1 };
|
||||
pub const bake_client_data = Index{ .value = 2 };
|
||||
|
||||
pub const Int = u32;
|
||||
|
||||
pub inline fn source(num: anytype) Index {
|
||||
@@ -111,7 +113,7 @@ pub const Ref = packed struct(u64) {
|
||||
allocated_name,
|
||||
source_contents_slice,
|
||||
symbol,
|
||||
} = .invalid,
|
||||
},
|
||||
|
||||
source_index: Int = 0,
|
||||
|
||||
@@ -229,6 +231,8 @@ pub const Ref = packed struct(u64) {
|
||||
*const std.ArrayList(js_ast.Symbol) => symbol_table.items,
|
||||
*std.ArrayList(js_ast.Symbol) => symbol_table.items,
|
||||
[]js_ast.Symbol => symbol_table,
|
||||
*js_ast.Symbol.Map => return symbol_table.get(ref) orelse
|
||||
unreachable, // ref must exist within symbol table
|
||||
else => |T| @compileError("Unsupported type to Ref.getSymbol: " ++ @typeName(T)),
|
||||
};
|
||||
return &resolved_symbol_table[ref.innerIndex()];
|
||||
|
||||
@@ -41,11 +41,17 @@ pub fn BabyList(comptime Type: type) type {
|
||||
return l.swapRemove(index);
|
||||
}
|
||||
|
||||
pub fn sortAsc(
|
||||
this: *@This(),
|
||||
) void {
|
||||
bun.strings.sortAsc(this.slice());
|
||||
}
|
||||
|
||||
pub fn contains(this: @This(), item: []const Type) bool {
|
||||
return this.len > 0 and @intFromPtr(item.ptr) >= @intFromPtr(this.ptr) and @intFromPtr(item.ptr) < @intFromPtr(this.ptr) + this.len;
|
||||
}
|
||||
|
||||
pub inline fn initConst(items: []const Type) ListType {
|
||||
pub fn initConst(items: []const Type) callconv(bun.callconv_inline) ListType {
|
||||
@setRuntimeSafety(false);
|
||||
return ListType{
|
||||
// Remove the const qualifier from the items
|
||||
@@ -77,8 +83,17 @@ pub fn BabyList(comptime Type: type) type {
|
||||
};
|
||||
}
|
||||
|
||||
fn assertValidDeepClone(comptime T: type) void {
|
||||
return switch (T) {
|
||||
bun.JSAst.Expr, bun.JSAst.G.Property, bun.css.ImportConditions => {},
|
||||
else => {
|
||||
@compileError("Unsupported type for BabyList.deepClone(): " ++ @typeName(Type));
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
pub fn deepClone(this: @This(), allocator: std.mem.Allocator) !@This() {
|
||||
if (comptime Type != bun.JSAst.Expr and Type != bun.JSAst.G.Property) @compileError("Unsupported type for BabyList.deepClone()");
|
||||
assertValidDeepClone(Type);
|
||||
var list_ = try initCapacity(allocator, this.len);
|
||||
for (this.slice()) |item| {
|
||||
list_.appendAssumeCapacity(try item.deepClone(allocator));
|
||||
@@ -87,6 +102,17 @@ pub fn BabyList(comptime Type: type) type {
|
||||
return list_;
|
||||
}
|
||||
|
||||
/// Same as `deepClone` but doesn't return an error
|
||||
pub fn deepClone2(this: @This(), allocator: std.mem.Allocator) @This() {
|
||||
assertValidDeepClone(Type);
|
||||
var list_ = initCapacity(allocator, this.len) catch bun.outOfMemory();
|
||||
for (this.slice()) |item| {
|
||||
list_.appendAssumeCapacity(item.deepClone(allocator));
|
||||
}
|
||||
|
||||
return list_;
|
||||
}
|
||||
|
||||
pub fn clearRetainingCapacity(this: *@This()) void {
|
||||
this.len = 0;
|
||||
}
|
||||
@@ -204,24 +230,24 @@ pub fn BabyList(comptime Type: type) type {
|
||||
};
|
||||
}
|
||||
|
||||
pub inline fn first(this: ListType) ?*Type {
|
||||
pub fn first(this: ListType) callconv(bun.callconv_inline) ?*Type {
|
||||
return if (this.len > 0) this.ptr[0] else @as(?*Type, null);
|
||||
}
|
||||
|
||||
pub inline fn last(this: ListType) ?*Type {
|
||||
pub fn last(this: ListType) callconv(bun.callconv_inline) ?*Type {
|
||||
return if (this.len > 0) &this.ptr[this.len - 1] else @as(?*Type, null);
|
||||
}
|
||||
|
||||
pub inline fn first_(this: ListType) Type {
|
||||
pub fn first_(this: ListType) callconv(bun.callconv_inline) Type {
|
||||
return this.ptr[0];
|
||||
}
|
||||
|
||||
pub inline fn at(this: ListType, index: usize) *const Type {
|
||||
pub fn at(this: ListType, index: usize) callconv(bun.callconv_inline) *const Type {
|
||||
bun.assert(index < this.len);
|
||||
return &this.ptr[index];
|
||||
}
|
||||
|
||||
pub inline fn mut(this: ListType, index: usize) *Type {
|
||||
pub fn mut(this: ListType, index: usize) callconv(bun.callconv_inline) *Type {
|
||||
bun.assert(index < this.len);
|
||||
return &this.ptr[index];
|
||||
}
|
||||
@@ -236,7 +262,7 @@ pub fn BabyList(comptime Type: type) type {
|
||||
};
|
||||
}
|
||||
|
||||
pub inline fn @"[0]"(this: ListType) Type {
|
||||
pub fn @"[0]"(this: ListType) callconv(bun.callconv_inline) Type {
|
||||
return this.ptr[0];
|
||||
}
|
||||
const OOM = error{OutOfMemory};
|
||||
@@ -259,7 +285,7 @@ pub fn BabyList(comptime Type: type) type {
|
||||
this.update(list__);
|
||||
}
|
||||
|
||||
pub inline fn slice(this: ListType) []Type {
|
||||
pub fn slice(this: ListType) callconv(bun.callconv_inline) []Type {
|
||||
@setRuntimeSafety(false);
|
||||
return this.ptr[0..this.len];
|
||||
}
|
||||
@@ -273,6 +299,7 @@ pub fn BabyList(comptime Type: type) type {
|
||||
this.update(list_);
|
||||
return this.len - initial;
|
||||
}
|
||||
|
||||
pub fn writeLatin1(this: *@This(), allocator: std.mem.Allocator, str: []const u8) !u32 {
|
||||
if (comptime Type != u8)
|
||||
@compileError("Unsupported for type " ++ @typeName(Type));
|
||||
@@ -282,6 +309,7 @@ pub fn BabyList(comptime Type: type) type {
|
||||
this.update(new);
|
||||
return this.len - initial;
|
||||
}
|
||||
|
||||
pub fn writeUTF16(this: *@This(), allocator: std.mem.Allocator, str: []const u16) !u32 {
|
||||
if (comptime Type != u8)
|
||||
@compileError("Unsupported for type " ++ @typeName(Type));
|
||||
|
||||
@@ -1,9 +1,33 @@
|
||||
#include "KitDevGlobalObject.h"
|
||||
#include "BakeDevGlobalObject.h"
|
||||
#include "JSNextTickQueue.h"
|
||||
#include "JavaScriptCore/GlobalObjectMethodTable.h"
|
||||
#include "JavaScriptCore/JSInternalPromise.h"
|
||||
#include "ProcessIdentifier.h"
|
||||
#include "headers-handwritten.h"
|
||||
|
||||
namespace Kit {
|
||||
namespace Bake {
|
||||
|
||||
extern "C" void BakeInitProcessIdentifier() {
|
||||
// assert is on main thread
|
||||
WebCore::Process::identifier();
|
||||
}
|
||||
|
||||
JSC::JSInternalPromise *
|
||||
moduleLoaderImportModule(JSC::JSGlobalObject *jsGlobalObject,
|
||||
JSC::JSModuleLoader *, JSC::JSString *moduleNameValue,
|
||||
JSC::JSValue parameters,
|
||||
const JSC::SourceOrigin &sourceOrigin) {
|
||||
// TODO: forward this to the runtime?
|
||||
JSC::VM &vm = jsGlobalObject->vm();
|
||||
auto err = JSC::createTypeError(
|
||||
jsGlobalObject,
|
||||
WTF::makeString(
|
||||
"Dynamic import should have been replaced with a hook into the module runtime"_s));
|
||||
auto *promise = JSC::JSInternalPromise::create(
|
||||
vm, jsGlobalObject->internalPromiseStructure());
|
||||
promise->reject(jsGlobalObject, err);
|
||||
return promise;
|
||||
}
|
||||
|
||||
#define INHERIT_HOOK_METHOD(name) \
|
||||
Zig::GlobalObject::s_globalObjectMethodTable.name
|
||||
@@ -15,7 +39,7 @@ const JSC::GlobalObjectMethodTable DevGlobalObject::s_globalObjectMethodTable =
|
||||
INHERIT_HOOK_METHOD(javaScriptRuntimeFlags),
|
||||
INHERIT_HOOK_METHOD(queueMicrotaskToEventLoop),
|
||||
INHERIT_HOOK_METHOD(shouldInterruptScriptBeforeTimeout),
|
||||
INHERIT_HOOK_METHOD(moduleLoaderImportModule),
|
||||
moduleLoaderImportModule,
|
||||
INHERIT_HOOK_METHOD(moduleLoaderResolve),
|
||||
INHERIT_HOOK_METHOD(moduleLoaderFetch),
|
||||
INHERIT_HOOK_METHOD(moduleLoaderCreateImportMetaProperties),
|
||||
@@ -50,8 +74,8 @@ void DevGlobalObject::finishCreation(JSC::VM &vm) {
|
||||
extern "C" BunVirtualMachine *Bun__getVM();
|
||||
|
||||
// A lot of this function is taken from 'Zig__GlobalObject__create'
|
||||
extern "C" DevGlobalObject *KitCreateDevGlobal(DevServer *owner,
|
||||
void *console) {
|
||||
extern "C" DevGlobalObject *BakeCreateDevGlobal(DevServer *owner,
|
||||
void *console) {
|
||||
JSC::VM &vm = JSC::VM::create(JSC::HeapType::Large).leakRef();
|
||||
vm.heap.acquireAccess();
|
||||
JSC::JSLockHolder locker(vm);
|
||||
@@ -72,18 +96,19 @@ extern "C" DevGlobalObject *KitCreateDevGlobal(DevServer *owner,
|
||||
global->setConsole(console);
|
||||
global->setStackTraceLimit(10); // Node.js defaults to 10
|
||||
|
||||
// TODO: it segfaults! process.nextTick is scoped out for now i guess!
|
||||
// vm.setOnComputeErrorInfo(computeErrorInfoWrapper);
|
||||
vm.setOnEachMicrotaskTick([global](JSC::VM &vm) -> void {
|
||||
if (auto nextTickQueue = global->m_nextTickQueue.get()) {
|
||||
global->resetOnEachMicrotaskTick();
|
||||
Bun::JSNextTickQueue *queue =
|
||||
jsCast<Bun::JSNextTickQueue *>(nextTickQueue);
|
||||
queue->drain(vm, global);
|
||||
return;
|
||||
}
|
||||
});
|
||||
// vm.setOnEachMicrotaskTick([global](JSC::VM &vm) -> void {
|
||||
// if (auto nextTickQueue = global->m_nextTickQueue.get()) {
|
||||
// global->resetOnEachMicrotaskTick();
|
||||
// // Bun::JSNextTickQueue *queue =
|
||||
// // jsCast<Bun::JSNextTickQueue *>(nextTickQueue);
|
||||
// // queue->drain(vm, global);
|
||||
// return;
|
||||
// }
|
||||
// });
|
||||
|
||||
return global;
|
||||
}
|
||||
|
||||
}; // namespace Kit
|
||||
}; // namespace Bake
|
||||
@@ -2,7 +2,7 @@
|
||||
#include "root.h"
|
||||
#include "ZigGlobalObject.h"
|
||||
|
||||
namespace Kit {
|
||||
namespace Bake {
|
||||
|
||||
struct DevServer; // DevServer.zig
|
||||
struct Route; // DevServer.zig
|
||||
@@ -18,10 +18,10 @@ public:
|
||||
return nullptr;
|
||||
return WebCore::subspaceForImpl<DevGlobalObject, WebCore::UseCustomHeapCellType::Yes>(
|
||||
vm,
|
||||
[](auto& spaces) { return spaces.m_clientSubspaceForKitGlobalScope.get(); },
|
||||
[](auto& spaces, auto&& space) { spaces.m_clientSubspaceForKitGlobalScope = std::forward<decltype(space)>(space); },
|
||||
[](auto& spaces) { return spaces.m_subspaceForKitGlobalScope.get(); },
|
||||
[](auto& spaces, auto&& space) { spaces.m_subspaceForKitGlobalScope = std::forward<decltype(space)>(space); },
|
||||
[](auto& spaces) { return spaces.m_clientSubspaceForBakeGlobalScope.get(); },
|
||||
[](auto& spaces, auto&& space) { spaces.m_clientSubspaceForBakeGlobalScope = std::forward<decltype(space)>(space); },
|
||||
[](auto& spaces) { return spaces.m_subspaceForBakeGlobalScope.get(); },
|
||||
[](auto& spaces, auto&& space) { spaces.m_subspaceForBakeGlobalScope = std::forward<decltype(space)>(space); },
|
||||
[](auto& server) -> JSC::HeapCellType& { return server.m_heapCellTypeForJSWorkerGlobalScope; });
|
||||
}
|
||||
|
||||
@@ -37,6 +37,7 @@ public:
|
||||
};
|
||||
|
||||
// Zig API
|
||||
extern "C" void KitInitProcessIdentifier();
|
||||
extern "C" DevGlobalObject* KitCreateDevGlobal(DevServer* owner, void* console);
|
||||
|
||||
}; // namespace Kit
|
||||
79
src/bake/BakeDevSourceProvider.cpp
Normal file
79
src/bake/BakeDevSourceProvider.cpp
Normal file
@@ -0,0 +1,79 @@
|
||||
// clang-format off
|
||||
#include "BakeDevSourceProvider.h"
|
||||
#include "BakeDevGlobalObject.h"
|
||||
#include "JavaScriptCore/Completion.h"
|
||||
#include "JavaScriptCore/Identifier.h"
|
||||
#include "JavaScriptCore/JSCJSValue.h"
|
||||
#include "JavaScriptCore/JSCast.h"
|
||||
#include "JavaScriptCore/JSLock.h"
|
||||
#include "JavaScriptCore/JSMap.h"
|
||||
#include "JavaScriptCore/JSModuleLoader.h"
|
||||
#include "JavaScriptCore/JSString.h"
|
||||
#include "JavaScriptCore/JSModuleNamespaceObject.h"
|
||||
|
||||
namespace Bake {
|
||||
|
||||
extern "C" LoadServerCodeResult BakeLoadInitialServerCode(DevGlobalObject* global, BunString source) {
|
||||
JSC::VM& vm = global->vm();
|
||||
auto scope = DECLARE_THROW_SCOPE(vm);
|
||||
|
||||
String string = "bake://server.js"_s;
|
||||
JSC::SourceOrigin origin = JSC::SourceOrigin(WTF::URL(string));
|
||||
JSC::SourceCode sourceCode = JSC::SourceCode(DevSourceProvider::create(
|
||||
source.toWTFString(),
|
||||
origin,
|
||||
WTFMove(string),
|
||||
WTF::TextPosition(),
|
||||
JSC::SourceProviderSourceType::Module
|
||||
));
|
||||
|
||||
JSC::JSString* key = JSC::jsString(vm, string);
|
||||
global->moduleLoader()->provideFetch(global, key, sourceCode);
|
||||
RETURN_IF_EXCEPTION(scope, {});
|
||||
|
||||
JSC::JSInternalPromise* internalPromise = global->moduleLoader()->loadAndEvaluateModule(global, key, JSC::jsUndefined(), JSC::jsUndefined());
|
||||
RETURN_IF_EXCEPTION(scope, {});
|
||||
|
||||
return { internalPromise, key };
|
||||
}
|
||||
|
||||
extern "C" JSC::EncodedJSValue BakeLoadServerHmrPatch(DevGlobalObject* global, BunString source) {
|
||||
JSC::VM&vm=global->vm();
|
||||
auto scope = DECLARE_THROW_SCOPE(vm);
|
||||
|
||||
String string = "bake://server.patch.js"_s;
|
||||
JSC::SourceOrigin origin = JSC::SourceOrigin(WTF::URL(string));
|
||||
JSC::SourceCode sourceCode = JSC::SourceCode(DevSourceProvider::create(
|
||||
source.toWTFString(),
|
||||
origin,
|
||||
WTFMove(string),
|
||||
WTF::TextPosition(),
|
||||
JSC::SourceProviderSourceType::Program
|
||||
));
|
||||
|
||||
JSC::JSValue result = vm.interpreter.executeProgram(sourceCode, global, global);
|
||||
RETURN_IF_EXCEPTION(scope, JSC::JSValue::encode({}));
|
||||
|
||||
RELEASE_ASSERT(result);
|
||||
return JSC::JSValue::encode(result);
|
||||
}
|
||||
|
||||
extern "C" JSC::EncodedJSValue BakeGetRequestHandlerFromModule(
|
||||
DevGlobalObject* global,
|
||||
JSC::JSString* key
|
||||
) {
|
||||
JSC::VM&vm = global->vm();
|
||||
JSC::JSMap* map = JSC::jsCast<JSC::JSMap*>(
|
||||
global->moduleLoader()->getDirect(
|
||||
vm, JSC::Identifier::fromString(global->vm(), "registry"_s)
|
||||
));
|
||||
JSC::JSValue entry = map->get(global, key);
|
||||
ASSERT(entry.isObject()); // should have called BakeLoadServerCode and wait for that promise
|
||||
JSC::JSValue module = entry.getObject()->get(global, JSC::Identifier::fromString(global->vm(), "module"_s));
|
||||
ASSERT(module.isCell());
|
||||
JSC::JSModuleNamespaceObject* namespaceObject = global->moduleLoader()->getModuleNamespaceObject(global, module);
|
||||
ASSERT(namespaceObject);
|
||||
return JSC::JSValue::encode(namespaceObject->get(global, vm.propertyNames->defaultKeyword));
|
||||
}
|
||||
|
||||
} // namespace Bake
|
||||
@@ -1,30 +1,30 @@
|
||||
#pragma once
|
||||
#include "root.h"
|
||||
#include "headers-handwritten.h"
|
||||
#include "KitDevGlobalObject.h"
|
||||
#include "BakeDevGlobalObject.h"
|
||||
#include "JavaScriptCore/SourceOrigin.h"
|
||||
|
||||
namespace Kit {
|
||||
namespace Bake {
|
||||
|
||||
struct LoadServerCodeResult {
|
||||
JSC::JSInternalPromise* promise;
|
||||
JSC::JSString* key;
|
||||
};
|
||||
|
||||
class KitSourceProvider final : public JSC::StringSourceProvider {
|
||||
class DevSourceProvider final : public JSC::StringSourceProvider {
|
||||
public:
|
||||
static Ref<KitSourceProvider> create(
|
||||
static Ref<DevSourceProvider> create(
|
||||
const String& source,
|
||||
const JSC::SourceOrigin& sourceOrigin,
|
||||
String&& sourceURL,
|
||||
const TextPosition& startPosition,
|
||||
JSC::SourceProviderSourceType sourceType
|
||||
) {
|
||||
return adoptRef(*new KitSourceProvider(source, sourceOrigin, WTFMove(sourceURL), startPosition, sourceType));
|
||||
return adoptRef(*new DevSourceProvider(source, sourceOrigin, WTFMove(sourceURL), startPosition, sourceType));
|
||||
}
|
||||
|
||||
private:
|
||||
KitSourceProvider(
|
||||
DevSourceProvider(
|
||||
const String& source,
|
||||
const JSC::SourceOrigin& sourceOrigin,
|
||||
String&& sourceURL,
|
||||
@@ -41,7 +41,8 @@ private:
|
||||
};
|
||||
|
||||
// Zig API
|
||||
extern "C" LoadServerCodeResult KitLoadServerCode(DevGlobalObject* global, BunString source);
|
||||
extern "C" JSC::EncodedJSValue KitGetRequestHandlerFromModule(DevGlobalObject* global, JSC::JSString* encodedModule);
|
||||
extern "C" LoadServerCodeResult BakeLoadInitialServerCode(DevGlobalObject* global, BunString source);
|
||||
extern "C" JSC::EncodedJSValue BakeLoadServerHmrPatch(DevGlobalObject* global, BunString source);
|
||||
extern "C" JSC::EncodedJSValue BakeGetRequestHandlerFromModule(DevGlobalObject* global, JSC::JSString* encodedModule);
|
||||
|
||||
} // namespace Kit
|
||||
} // namespace Bake
|
||||
2476
src/bake/DevServer.zig
Normal file
2476
src/bake/DevServer.zig
Normal file
File diff suppressed because it is too large
Load Diff
234
src/bake/bake.d.ts
vendored
Normal file
234
src/bake/bake.d.ts
vendored
Normal file
@@ -0,0 +1,234 @@
|
||||
declare module "bun" {
|
||||
declare function wipDevServerExpectHugeBreakingChanges(options: Bake.Options): never;
|
||||
|
||||
declare namespace Bake {
|
||||
interface Options {
|
||||
/**
|
||||
* Bun provides built-in support for using React as a framework by
|
||||
* passing 'react-server-components' as the framework name.
|
||||
*
|
||||
* Has external dependencies:
|
||||
* ```
|
||||
* bun i react@experimental react-dom@experimental react-server-dom-webpack@experimental react-refresh@experimental
|
||||
* ```
|
||||
*/
|
||||
framework: Framework | "react-server-components";
|
||||
|
||||
/**
|
||||
* Route patterns must be statically known.
|
||||
* TODO: Static at dev-server start is bad and this API must be revisited
|
||||
*/
|
||||
routes: Record<RoutePattern, RouteOptions>;
|
||||
|
||||
// TODO: many other options
|
||||
}
|
||||
|
||||
/**
|
||||
* A "Framework" in our eyes is simply a set of bundler options that a
|
||||
* framework author would set in order to integrate framework code with the
|
||||
* application. Many of the configuration options are paths, which are
|
||||
* resolved as import specifiers. The first thing the bundler does is
|
||||
* ensure that all import specifiers are fully resolved.
|
||||
*/
|
||||
interface Framework {
|
||||
/**
|
||||
* This file is the true entrypoint of the server application. This module
|
||||
* must `export default` a fetch function, which takes a request and the
|
||||
* bundled route module, and returns a response. See `ServerEntryPoint`
|
||||
*
|
||||
* When `serverComponents` is configured, this can access the component
|
||||
* manifest using the special 'bun:bake/server' import:
|
||||
*
|
||||
* import { serverManifest } from 'bun:bake/server'
|
||||
*/
|
||||
serverEntryPoint: ImportSource;
|
||||
/**
|
||||
* This file is the true entrypoint of the client application.
|
||||
*
|
||||
* When `serverComponents` is configured, this can access the component
|
||||
* manifest using the special 'bun:bake/client' import:
|
||||
*
|
||||
* import { clientManifest } from 'bun:bake/client'
|
||||
*/
|
||||
clientEntryPoint: ImportSource;
|
||||
/**
|
||||
* Add extra modules
|
||||
*/
|
||||
builtInModules: Record<string, BuiltInModule>;
|
||||
/**
|
||||
* Bun offers integration for React's Server Components with an
|
||||
* interface that is generic enough to adapt to any framework.
|
||||
*/
|
||||
serverComponents?: ServerComponentsOptions | undefined;
|
||||
/**
|
||||
* While it is unlikely that Fast Refresh is useful outside of
|
||||
* React, it can be enabled regardless.
|
||||
*/
|
||||
reactFastRefresh?: ReactFastRefreshOptions | true | undefined;
|
||||
}
|
||||
|
||||
type BuiltInModule = { code: string } | { path: string };
|
||||
|
||||
/**
|
||||
* A high-level overview of what server components means exists
|
||||
* in the React Docs: https://react.dev/reference/rsc/server-components
|
||||
*
|
||||
* When enabled, files with "use server" and "use client" directives will get
|
||||
* special processing according to this object, in combination with the
|
||||
* framework-specified entry points for server rendering and browser
|
||||
* interactivity.
|
||||
*/
|
||||
interface ServerComponentsOptions {
|
||||
/**
|
||||
* If you are unsure what to set this to for a custom server components
|
||||
* framework, choose 'false'.
|
||||
*
|
||||
* When set `true`, when bundling "use client" components for SSR, these
|
||||
* files will be placed in a separate bundling graph where `conditions` does
|
||||
* not include `react-server`.
|
||||
*
|
||||
* The built in framework config for React enables this flag so that server
|
||||
* components and client components, utilize their own versions of React,
|
||||
* despite running in the same process. This facilitates different aspects
|
||||
* of the server and client react runtimes, such as `async` components only
|
||||
* being available on the server.
|
||||
*
|
||||
* To cross from the server graph to the SSR graph, use the bun_bake_graph
|
||||
* import attribute:
|
||||
*
|
||||
* import * as ReactDOM from 'react-dom/server' with { bun_bake_graph: 'ssr' };
|
||||
*
|
||||
* Since these models are so subtley different, there is no default value
|
||||
* provided for this.
|
||||
*/
|
||||
separateSSRGraph: boolean;
|
||||
/** Server components runtime for the server */
|
||||
serverRuntimeImportSource: ImportSource;
|
||||
/**
|
||||
* When server code imports client code, a stub module is generated,
|
||||
* where every export calls this export from `serverRuntimeImportSource`.
|
||||
* This is used to implement client components on the server.
|
||||
*
|
||||
* The call is given three arguments:
|
||||
*
|
||||
* export const ClientComp = registerClientReference(
|
||||
* // A function which may be passed through, it throws an error
|
||||
* function () { throw new Error('Cannot call client-component on the server') },
|
||||
*
|
||||
* // The file path. In production, these use hashed strings for
|
||||
* // compactness and code privacy.
|
||||
* "src/components/Client.tsx",
|
||||
*
|
||||
* // The instance id. This is not guaranteed to match the export
|
||||
* // name the user has given.
|
||||
* "ClientComp",
|
||||
* );
|
||||
*
|
||||
* Additionally, the bundler will assemble a component manifest to be used
|
||||
* during rendering.
|
||||
*/
|
||||
serverRegisterClientReferenceExport: string | undefined;
|
||||
}
|
||||
|
||||
/** Customize the React Fast Refresh transform. */
|
||||
interface ReactFastRefreshOptions {
|
||||
/** @default "react-refresh/runtime" */
|
||||
importSource: ImportSource | undefined;
|
||||
}
|
||||
|
||||
/// Will be resolved from the point of view of the framework user's project root
|
||||
/// Examples: `react-dom`, `./entry_point.tsx`, `/absolute/path.js`
|
||||
type ImportSource = string;
|
||||
|
||||
interface ServerEntryPoint {
|
||||
/**
|
||||
* The framework implementation decides and enforces the shape
|
||||
* of the route module. Bun passes it as an opaque value.
|
||||
*/
|
||||
default: (request: Request, routeModule: unknown, routeMetadata: RouteMetadata) => Response;
|
||||
}
|
||||
|
||||
interface ClientEntryPoint {
|
||||
/**
|
||||
* Called when server-side code is changed. This can be used to fetch a
|
||||
* non-html version of the updated page to perform a faster reload.
|
||||
*
|
||||
* Tree-shaken away in production builds.
|
||||
*/
|
||||
onServerSideReload?: () => void;
|
||||
}
|
||||
|
||||
interface RouteMetadata {
|
||||
/** A list of css files that the route will need to be styled */
|
||||
styles: string[];
|
||||
/** A list of js files that the route will need to be interactive */
|
||||
scripts: string[];
|
||||
}
|
||||
}
|
||||
|
||||
// declare class Bake {
|
||||
// constructor(options: Bake.Options);
|
||||
// }
|
||||
}
|
||||
|
||||
declare module "bun:bake/server" {
|
||||
// NOTE: The format of these manifests will likely be customizable in the future.
|
||||
|
||||
/**
|
||||
* Entries in this manifest can be loaded by using dynamic `await import()` or
|
||||
* `require`. The bundler always ensures that all modules are ready on the server.
|
||||
*/
|
||||
declare const clientManifest: ReactClientManifest;
|
||||
/**
|
||||
* This follows the requirements for React's Server Components manifest, which
|
||||
* does not actually include usable module specifiers. Calling `import()` on
|
||||
* these specifiers wont work, but they will work client-side. Use
|
||||
* `clientManifest` on the server for SSR.
|
||||
*/
|
||||
declare const serverManifest: ReactServerManifest;
|
||||
|
||||
/** (insert teaser trailer) */
|
||||
declare const actionManifest: never;
|
||||
}
|
||||
|
||||
declare module "bun:bake/client" {
|
||||
/**
|
||||
* Entries in this manifest can be loaded by using dynamic `await import()` or
|
||||
* `require`. The bundler currently ensures that all modules are ready.
|
||||
*/
|
||||
declare const clientManifest: ReactClientManifest;
|
||||
}
|
||||
|
||||
declare interface ReactClientManifest {
|
||||
[id: string]: {
|
||||
[name: string]: {
|
||||
/** Valid specifier to import */
|
||||
specifier: string;
|
||||
/** Export name */
|
||||
name: string;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
declare interface ReactServerManifest {
|
||||
/**
|
||||
* Concatenation of the component file ID and the instance id with '#'
|
||||
* Example: 'components/Navbar.tsx#default' (dev) or 'l2#a' (prod/minified)
|
||||
*
|
||||
* The component file ID and the instance id are both passed to `registerClientReference`
|
||||
*/
|
||||
[combinedComponentId: string]: {
|
||||
/**
|
||||
* The `id` in ReactClientManifest.
|
||||
* Correlates but is not required to be the filename
|
||||
*/
|
||||
id: string;
|
||||
/**
|
||||
* The `name` in ReactServerManifest
|
||||
* Correlates but is not required to be the export name
|
||||
*/
|
||||
name: string;
|
||||
/** Currently not implemented; always an empty array */
|
||||
chunks: [];
|
||||
};
|
||||
}
|
||||
66
src/bake/bake.private.d.ts
vendored
Normal file
66
src/bake/bake.private.d.ts
vendored
Normal file
@@ -0,0 +1,66 @@
|
||||
type Id = string;
|
||||
|
||||
/** Index with same usage as `IncrementalGraph(.client).Index` */
|
||||
type FileIndex = number;
|
||||
|
||||
interface Config {
|
||||
// Server + Client
|
||||
main: Id;
|
||||
|
||||
// Server
|
||||
separateSSRGraph?: true;
|
||||
|
||||
// Client
|
||||
/** If available, this is the Id of `react-refresh/runtime` */
|
||||
refresh?: Id;
|
||||
/**
|
||||
* A list of "roots" that the client is aware of. This includes
|
||||
* the framework entry point, as well as every client component.
|
||||
*/
|
||||
roots: FileIndex[];
|
||||
}
|
||||
|
||||
/**
|
||||
* All modules for the initial bundle.
|
||||
*/
|
||||
declare const input_graph: Record<string, ModuleLoadFunction>;
|
||||
|
||||
declare const config: Config;
|
||||
|
||||
/**
|
||||
* The runtime is bundled for server and client, which influences
|
||||
* how hmr connection should be established, as well if there is
|
||||
* a window to visually display errors with.
|
||||
*/
|
||||
declare const side: "client" | "server";
|
||||
|
||||
/*
|
||||
* This variable becomes the default export. Kit uses this
|
||||
* interface as opposed to a WebSocket connection.
|
||||
*/
|
||||
declare var server_exports: {
|
||||
handleRequest: (req: Request, meta: HandleRequestMeta, id: Id) => any;
|
||||
registerUpdate: (modules: any) => void;
|
||||
};
|
||||
|
||||
interface HandleRequestMeta {
|
||||
// url for script tag
|
||||
clientEntryPoint: string;
|
||||
}
|
||||
|
||||
/*
|
||||
* If you are running a debug build of Bun. These debug builds should provide
|
||||
* helpful information to someone working on the bundler itself.
|
||||
*/
|
||||
declare const IS_BUN_DEVELOPMENT: any;
|
||||
|
||||
// shims for experimental react types
|
||||
declare module "react" {
|
||||
export function use<T>(promise: Promise<T>): T;
|
||||
}
|
||||
declare module "react-server-dom-webpack/client.browser" {
|
||||
export function createFromReadableStream<T = any>(readable: ReadableStream, manifest?: any): Promise<T>;
|
||||
}
|
||||
declare module "react-server-dom-webpack/server.browser" {
|
||||
export function renderToReadableStream<T = any>(element: JSX.Element, manifest: any): ReadableStream;
|
||||
}
|
||||
392
src/bake/bake.zig
Normal file
392
src/bake/bake.zig
Normal file
@@ -0,0 +1,392 @@
|
||||
//! Bake is Bun's toolkit for building client+server web applications. It
|
||||
//! combines `Bun.build` and `Bun.serve`, providing a hot-reloading development
|
||||
//! server, server components, and other integrations. Instead of taking the
|
||||
//! role as a framework, Bake is tool for frameworks to build on top of.
|
||||
|
||||
/// Temporary function to invoke dev server via JavaScript. Will be
|
||||
/// replaced with a user-facing API. Refs the event loop forever.
|
||||
pub fn jsWipDevServer(global: *JSC.JSGlobalObject, callframe: *JSC.CallFrame) JSValue {
|
||||
if (!bun.FeatureFlags.bake) return .undefined;
|
||||
|
||||
BakeInitProcessIdentifier();
|
||||
|
||||
bun.Output.warn(
|
||||
\\Be advised that Bun Bake is highly experimental, and its API
|
||||
\\will have breaking changes. Join the <magenta>#bake<r> Discord
|
||||
\\channel to help us find bugs: <blue>https://bun.sh/discord<r>
|
||||
\\
|
||||
\\
|
||||
, .{});
|
||||
bun.Output.flush();
|
||||
|
||||
const options = devServerOptionsFromJs(global, callframe.argument(0)) catch {
|
||||
if (!global.hasException())
|
||||
global.throwInvalidArguments("invalid arguments", .{});
|
||||
return .zero;
|
||||
};
|
||||
|
||||
// TODO: this should inherit the current VM, running on the main thread.
|
||||
const t = std.Thread.spawn(.{}, wipDevServer, .{options}) catch @panic("Failed to start");
|
||||
t.detach();
|
||||
|
||||
{
|
||||
var futex = std.atomic.Value(u32).init(0);
|
||||
while (true) std.Thread.Futex.wait(&futex, 0);
|
||||
}
|
||||
}
|
||||
|
||||
extern fn BakeInitProcessIdentifier() void;
|
||||
|
||||
/// A "Framework" in our eyes is simply set of bundler options that a framework
|
||||
/// author would set in order to integrate the framework with the application.
|
||||
///
|
||||
/// Full documentation on these fields is located in the TypeScript definitions.
|
||||
pub const Framework = struct {
|
||||
entry_client: ?[]const u8 = null,
|
||||
entry_server: ?[]const u8 = null,
|
||||
|
||||
server_components: ?ServerComponents = null,
|
||||
react_fast_refresh: ?ReactFastRefresh = null,
|
||||
|
||||
built_in_modules: bun.StringArrayHashMapUnmanaged(BuiltInModule) = .{},
|
||||
|
||||
/// Bun provides built-in support for using React as a framework.
|
||||
/// Depends on externally provided React
|
||||
///
|
||||
/// $ bun i react@experimental react-dom@experimental react-server-dom-webpack@experimental react-refresh@experimental
|
||||
pub fn react() Framework {
|
||||
return .{
|
||||
.server_components = .{
|
||||
.separate_ssr_graph = true,
|
||||
.server_runtime_import = "react-server-dom-webpack/server",
|
||||
.client_runtime_import = "react-server-dom-webpack/client",
|
||||
},
|
||||
.react_fast_refresh = .{},
|
||||
.entry_client = "bun-framework-rsc/client.tsx",
|
||||
.entry_server = "bun-framework-rsc/server.tsx",
|
||||
.built_in_modules = bun.StringArrayHashMapUnmanaged(BuiltInModule).init(bun.default_allocator, &.{
|
||||
"bun-framework-rsc/client.tsx",
|
||||
"bun-framework-rsc/server.tsx",
|
||||
"bun-framework-rsc/ssr.tsx",
|
||||
}, if (Environment.embed_code) &.{
|
||||
.{ .code = @embedFile("./bun-framework-rsc/client.tsx") },
|
||||
.{ .code = @embedFile("./bun-framework-rsc/server.tsx") },
|
||||
.{ .code = @embedFile("./bun-framework-rsc/ssr.tsx") },
|
||||
} else &.{
|
||||
.{ .code = bun.runtimeEmbedFile(.src, "bake/bun-framework-rsc/client.tsx") },
|
||||
.{ .code = bun.runtimeEmbedFile(.src, "bake/bun-framework-rsc/server.tsx") },
|
||||
.{ .code = bun.runtimeEmbedFile(.src, "bake/bun-framework-rsc/ssr.tsx") },
|
||||
}) catch bun.outOfMemory(),
|
||||
};
|
||||
}
|
||||
|
||||
const BuiltInModule = union(enum) {
|
||||
import: []const u8,
|
||||
code: []const u8,
|
||||
};
|
||||
|
||||
const ServerComponents = struct {
|
||||
separate_ssr_graph: bool = false,
|
||||
server_runtime_import: []const u8,
|
||||
client_runtime_import: []const u8,
|
||||
server_register_client_reference: []const u8 = "registerClientReference",
|
||||
server_register_server_reference: []const u8 = "registerServerReference",
|
||||
client_register_server_reference: []const u8 = "registerServerReference",
|
||||
};
|
||||
|
||||
const ReactFastRefresh = struct {
|
||||
import_source: []const u8 = "react-refresh/runtime",
|
||||
};
|
||||
|
||||
/// Given a Framework configuration, this returns another one with all modules resolved.
|
||||
///
|
||||
/// All resolution errors will happen before returning error.ModuleNotFound
|
||||
/// Details written into `r.log`
|
||||
pub fn resolve(f: Framework, server: *bun.resolver.Resolver, client: *bun.resolver.Resolver) !Framework {
|
||||
var clone = f;
|
||||
var had_errors: bool = false;
|
||||
|
||||
if (clone.entry_client) |*path| f.resolveHelper(client, path, &had_errors);
|
||||
if (clone.entry_server) |*path| f.resolveHelper(server, path, &had_errors);
|
||||
|
||||
if (clone.react_fast_refresh) |*react_fast_refresh| {
|
||||
f.resolveHelper(client, &react_fast_refresh.import_source, &had_errors);
|
||||
}
|
||||
|
||||
if (clone.server_components) |*sc| {
|
||||
f.resolveHelper(server, &sc.server_runtime_import, &had_errors);
|
||||
f.resolveHelper(client, &sc.client_runtime_import, &had_errors);
|
||||
}
|
||||
|
||||
if (had_errors) return error.ModuleNotFound;
|
||||
|
||||
return clone;
|
||||
}
|
||||
|
||||
inline fn resolveHelper(f: *const Framework, r: *bun.resolver.Resolver, path: *[]const u8, had_errors: *bool) void {
|
||||
if (f.built_in_modules.get(path.*)) |mod| {
|
||||
switch (mod) {
|
||||
.import => |p| path.* = p,
|
||||
.code => {},
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
var result = r.resolve(r.fs.top_level_dir, path.*, .stmt) catch |err| {
|
||||
bun.Output.err(err, "Failed to resolve '{s}' for framework", .{path.*});
|
||||
had_errors.* = true;
|
||||
|
||||
return;
|
||||
};
|
||||
path.* = result.path().?.text; // TODO: what is the lifetime of this string
|
||||
}
|
||||
|
||||
// TODO: This function always leaks memory.
|
||||
// `Framework` has no way to specify what is allocated, nor should it.
|
||||
fn fromJS(opts: JSValue, global: *JSC.JSGlobalObject) !Framework {
|
||||
if (opts.isString()) {
|
||||
const str = opts.toBunString(global);
|
||||
defer str.deref();
|
||||
if (str.eqlComptime("react-server-components")) {
|
||||
return Framework.react();
|
||||
}
|
||||
}
|
||||
|
||||
if (!opts.isObject()) {
|
||||
global.throwInvalidArguments("Framework must be an object", .{});
|
||||
return error.JSError;
|
||||
}
|
||||
return .{
|
||||
.entry_server = brk: {
|
||||
const prop: JSValue = opts.get(global, "serverEntryPoint") orelse {
|
||||
if (!global.hasException())
|
||||
global.throwInvalidArguments("Missing 'framework.serverEntryPoint'", .{});
|
||||
return error.JSError;
|
||||
};
|
||||
const str = prop.toBunString(global);
|
||||
defer str.deref();
|
||||
|
||||
if (global.hasException())
|
||||
return error.JSError;
|
||||
|
||||
// Leak
|
||||
break :brk str.toUTF8(bun.default_allocator).slice();
|
||||
},
|
||||
.entry_client = brk: {
|
||||
const prop: JSValue = opts.get(global, "clientEntryPoint") orelse {
|
||||
if (!global.hasException())
|
||||
global.throwInvalidArguments("Missing 'framework.clientEntryPoint'", .{});
|
||||
return error.JSError;
|
||||
};
|
||||
const str = prop.toBunString(global);
|
||||
defer str.deref();
|
||||
|
||||
if (global.hasException())
|
||||
return error.JSError;
|
||||
|
||||
// Leak
|
||||
break :brk str.toUTF8(bun.default_allocator).slice();
|
||||
},
|
||||
.react_fast_refresh = brk: {
|
||||
const rfr: JSValue = opts.get(global, "reactFastRefresh") orelse {
|
||||
if (global.hasException())
|
||||
return error.JSError;
|
||||
break :brk null;
|
||||
};
|
||||
if (rfr == .true) break :brk .{};
|
||||
if (rfr == .false or rfr == .null or rfr == .undefined) break :brk null;
|
||||
if (!rfr.isObject()) {
|
||||
global.throwInvalidArguments("'framework.reactFastRefresh' must be an object or 'true'", .{});
|
||||
return error.JSError;
|
||||
}
|
||||
// in addition to here, this import isnt actually wired up to js_parser where the default is hardcoded.
|
||||
bun.todoPanic(@src(), "custom react-fast-refresh import source", .{});
|
||||
},
|
||||
.server_components = sc: {
|
||||
const rfr: JSValue = opts.get(global, "serverComponents") orelse {
|
||||
if (global.hasException())
|
||||
return error.JSError;
|
||||
break :sc null;
|
||||
};
|
||||
if (rfr == .null or rfr == .undefined) break :sc null;
|
||||
|
||||
break :sc .{
|
||||
.client_runtime_import = "",
|
||||
.separate_ssr_graph = brk: {
|
||||
const prop: JSValue = opts.get(global, "separateSSRGraph") orelse {
|
||||
if (!global.hasException())
|
||||
global.throwInvalidArguments("Missing 'framework.serverComponents.separateSSRGraph'", .{});
|
||||
return error.JSError;
|
||||
};
|
||||
if (prop == .true) break :brk true;
|
||||
if (prop == .false) break :brk false;
|
||||
global.throwInvalidArguments("'framework.serverComponents.separateSSRGraph' must be a boolean", .{});
|
||||
return error.JSError;
|
||||
},
|
||||
.server_runtime_import = brk: {
|
||||
const prop: JSValue = opts.get(global, "serverRuntimeImportSource") orelse {
|
||||
if (!global.hasException())
|
||||
global.throwInvalidArguments("Missing 'framework.serverComponents.serverRuntimeImportSource'", .{});
|
||||
return error.JSError;
|
||||
};
|
||||
const str = prop.toBunString(global);
|
||||
defer str.deref();
|
||||
|
||||
if (global.hasException())
|
||||
return error.JSError;
|
||||
|
||||
// Leak
|
||||
break :brk str.toUTF8(bun.default_allocator).slice();
|
||||
},
|
||||
.server_register_client_reference = brk: {
|
||||
const prop: JSValue = opts.get(global, "serverRegisterClientReferenceExport") orelse {
|
||||
if (!global.hasException())
|
||||
global.throwInvalidArguments("Missing 'framework.serverComponents.serverRegisterClientReferenceExport'", .{});
|
||||
return error.JSError;
|
||||
};
|
||||
const str = prop.toBunString(global);
|
||||
defer str.deref();
|
||||
|
||||
if (global.hasException())
|
||||
return error.JSError;
|
||||
|
||||
// Leak
|
||||
break :brk str.toUTF8(bun.default_allocator).slice();
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
// TODO: this function leaks memory and bad error handling, but that is OK since
|
||||
// this API is not finalized.
|
||||
fn devServerOptionsFromJs(global: *JSC.JSGlobalObject, options: JSValue) !DevServer.Options {
|
||||
if (!options.isObject()) return error.Invalid;
|
||||
const routes_js = try options.getArray(global, "routes") orelse return error.Invalid;
|
||||
|
||||
const len = routes_js.getLength(global);
|
||||
const routes = try bun.default_allocator.alloc(DevServer.Route, len);
|
||||
|
||||
var it = routes_js.arrayIterator(global);
|
||||
var i: usize = 0;
|
||||
while (it.next()) |route| : (i += 1) {
|
||||
if (!route.isObject()) return error.Invalid;
|
||||
|
||||
const pattern_js = route.get(global, "pattern") orelse return error.Invalid;
|
||||
if (!pattern_js.isString()) return error.Invalid;
|
||||
const entry_point_js = route.get(global, "entrypoint") orelse return error.Invalid;
|
||||
if (!entry_point_js.isString()) return error.Invalid;
|
||||
|
||||
const pattern = pattern_js.toBunString(global).toUTF8(bun.default_allocator);
|
||||
defer pattern.deinit();
|
||||
// TODO: this dupe is stupid
|
||||
const pattern_z = try bun.default_allocator.dupeZ(u8, pattern.slice());
|
||||
const entry_point = entry_point_js.toBunString(global).toUTF8(bun.default_allocator).slice(); // leak
|
||||
|
||||
routes[i] = .{
|
||||
.pattern = pattern_z,
|
||||
.entry_point = entry_point,
|
||||
};
|
||||
}
|
||||
|
||||
const framework_js = options.get(global, "framework") orelse {
|
||||
return error.Invalid;
|
||||
};
|
||||
const framework = try Framework.fromJS(framework_js, global);
|
||||
return .{
|
||||
.cwd = bun.getcwdAlloc(bun.default_allocator) catch bun.outOfMemory(),
|
||||
.routes = routes,
|
||||
.framework = framework,
|
||||
};
|
||||
}
|
||||
|
||||
export fn Bun__getTemporaryDevServer(global: *JSC.JSGlobalObject) JSValue {
|
||||
if (!bun.FeatureFlags.bake) return .undefined;
|
||||
return JSC.JSFunction.create(global, "wipDevServer", bun.JSC.toJSHostFunction(jsWipDevServer), 0, .{});
|
||||
}
|
||||
|
||||
pub fn wipDevServer(options: DevServer.Options) noreturn {
|
||||
bun.Output.Source.configureNamedThread("Dev Server");
|
||||
|
||||
const dev = DevServer.init(options) catch |err| switch (err) {
|
||||
error.FrameworkInitialization => bun.Global.exit(1),
|
||||
else => {
|
||||
bun.handleErrorReturnTrace(err, @errorReturnTrace());
|
||||
bun.Output.panic("Failed to init DevServer: {}", .{err});
|
||||
},
|
||||
};
|
||||
dev.runLoopForever();
|
||||
}
|
||||
|
||||
pub fn getHmrRuntime(mode: Side) []const u8 {
|
||||
return if (Environment.embed_code)
|
||||
switch (mode) {
|
||||
.client => @embedFile("bake-codegen/bake.client.js"),
|
||||
.server => @embedFile("bake-codegen/bake.server.js"),
|
||||
}
|
||||
else switch (mode) {
|
||||
inline else => |m| bun.runtimeEmbedFile(.codegen, "bake." ++ @tagName(m) ++ ".js"),
|
||||
};
|
||||
}
|
||||
|
||||
pub const Mode = enum { production, development };
|
||||
pub const Side = enum { client, server };
|
||||
/// TODO: Rename this to Graph
|
||||
pub const Renderer = enum(u2) {
|
||||
client,
|
||||
server,
|
||||
/// Only used when Framework has .server_components.separate_ssr_graph set
|
||||
ssr,
|
||||
};
|
||||
|
||||
pub fn addImportMetaDefines(
|
||||
allocator: std.mem.Allocator,
|
||||
define: *bun.options.Define,
|
||||
mode: Mode,
|
||||
side: Side,
|
||||
) !void {
|
||||
const Define = bun.options.Define;
|
||||
|
||||
// The following are from Vite: https://vitejs.dev/guide/env-and-mode
|
||||
// TODO: MODE, BASE_URL
|
||||
try define.insert(
|
||||
allocator,
|
||||
"import.meta.env.DEV",
|
||||
Define.Data.initBoolean(mode == .development),
|
||||
);
|
||||
try define.insert(
|
||||
allocator,
|
||||
"import.meta.env.PROD",
|
||||
Define.Data.initBoolean(mode == .production),
|
||||
);
|
||||
try define.insert(
|
||||
allocator,
|
||||
"import.meta.env.SSR",
|
||||
Define.Data.initBoolean(side == .server),
|
||||
);
|
||||
}
|
||||
|
||||
pub const server_virtual_source: bun.logger.Source = .{
|
||||
.path = bun.fs.Path.initForKitBuiltIn("bun", "bake/server"),
|
||||
.key_path = bun.fs.Path.initForKitBuiltIn("bun", "bake/server"),
|
||||
.contents = "", // Virtual
|
||||
.index = bun.JSAst.Index.bake_server_data,
|
||||
};
|
||||
|
||||
pub const client_virtual_source: bun.logger.Source = .{
|
||||
.path = bun.fs.Path.initForKitBuiltIn("bun", "bake/client"),
|
||||
.key_path = bun.fs.Path.initForKitBuiltIn("bun", "bake/client"),
|
||||
.contents = "", // Virtual
|
||||
.index = bun.JSAst.Index.bake_client_data,
|
||||
};
|
||||
|
||||
pub const DevServer = @import("./DevServer.zig");
|
||||
|
||||
const std = @import("std");
|
||||
|
||||
const bun = @import("root").bun;
|
||||
const Environment = bun.Environment;
|
||||
|
||||
const JSC = bun.JSC;
|
||||
const JSValue = JSC.JSValue;
|
||||
41
src/bake/bun-framework-rsc/client.tsx
Normal file
41
src/bake/bun-framework-rsc/client.tsx
Normal file
@@ -0,0 +1,41 @@
|
||||
/// <reference lib="dom" />
|
||||
import { use } from "react";
|
||||
import { hydrateRoot } from "react-dom/client";
|
||||
import { createFromReadableStream } from "react-server-dom-webpack/client.browser";
|
||||
|
||||
function assertionFailed(msg: string) {
|
||||
throw new Error(`Assertion Failure: ${msg}. This is a bug in Bun's React integration`);
|
||||
}
|
||||
|
||||
// Client-side entry point expects an RSC payload. In development, let's fail
|
||||
// loudly if this is somehow missing.
|
||||
const initialPayload = document.getElementById("rsc_payload");
|
||||
if (import.meta.env.DEV) {
|
||||
if (!initialPayload) assertionFailed("Missing #rsc_payload in HTML response");
|
||||
}
|
||||
|
||||
// React takes in a ReadableStream with the payload.
|
||||
let promise = createFromReadableStream(new Response(initialPayload!.innerText).body!);
|
||||
initialPayload!.remove();
|
||||
|
||||
const Async = () => use(promise);
|
||||
const root = hydrateRoot(document, <Async />, {
|
||||
// handle `onUncaughtError` here
|
||||
});
|
||||
|
||||
export async function onServerSideReload() {
|
||||
const response = await fetch(location.href, {
|
||||
headers: {
|
||||
Accept: "text/x-component",
|
||||
},
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
||||
}
|
||||
|
||||
promise = createFromReadableStream(response.body!);
|
||||
root.render(<Async />);
|
||||
}
|
||||
|
||||
globalThis.onServerSideReload = onServerSideReload;
|
||||
71
src/bake/bun-framework-rsc/server.tsx
Normal file
71
src/bake/bun-framework-rsc/server.tsx
Normal file
@@ -0,0 +1,71 @@
|
||||
import type { Bake } from "bun";
|
||||
import { renderToReadableStream } from "react-server-dom-webpack/server.browser";
|
||||
import { renderToHtml } from "bun-framework-rsc/ssr.tsx" with { bunBakeGraph: "ssr" };
|
||||
import { serverManifest } from "bun:bake/server";
|
||||
|
||||
// `server.tsx` exports a function to be used for handling user routes. It takes
|
||||
// in the Request object, the route's module, and extra route metadata.
|
||||
export default async function (request: Request, route: any, meta: Bake.RouteMetadata): Promise<Response> {
|
||||
// TODO: be able to signal to Bake that Accept may include this, so that
|
||||
// static pages can be pre-rendered both as RSC payload + HTML.
|
||||
|
||||
// The framework generally has two rendering modes.
|
||||
// - Standard browser navigation
|
||||
// - Client-side navigation
|
||||
//
|
||||
// For React, this means we will always perform `renderToReadableStream` to
|
||||
// generate the RSC payload, but only generate HTML for the former of these
|
||||
// rendering modes. This is signaled by `client.tsx` via the `Accept` header.
|
||||
const skipSSR = request.headers.get("Accept")?.includes("text/x-component");
|
||||
|
||||
const Route = route.default;
|
||||
const page = (
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>Bun + React Server Components</title>
|
||||
{meta.styles.map(url => (
|
||||
<link key={url} rel="stylesheet" href={url} />
|
||||
))}
|
||||
</head>
|
||||
<body>
|
||||
<Route />
|
||||
</body>
|
||||
</html>
|
||||
);
|
||||
|
||||
// This renders Server Components to a ReadableStream "RSC Payload"
|
||||
const rscPayload = renderToReadableStream(page, serverManifest);
|
||||
if (skipSSR) {
|
||||
return new Response(rscPayload, {
|
||||
status: 200,
|
||||
headers: { "Content-Type": "text/x-component" },
|
||||
});
|
||||
}
|
||||
|
||||
// One straem is used to render SSR. The second is embedded into the html for browser hydration.
|
||||
// Note: This approach does not stream the response.
|
||||
const [rscPayload1, rscPayload2] = rscPayload.tee();
|
||||
const rscPayloadBuffer = Bun.readableStreamToText(rscPayload1);
|
||||
const rw = new HTMLRewriter();
|
||||
rw.on("body", {
|
||||
element(element) {
|
||||
element.onEndTag(async end => {
|
||||
end.before(
|
||||
`<script id="rsc_payload" type="json">${await rscPayloadBuffer}</script>` +
|
||||
meta.scripts.map(url => `<script src=${JSON.stringify(url)}></script>`).join(""),
|
||||
{ html: true },
|
||||
);
|
||||
});
|
||||
},
|
||||
});
|
||||
// TODO: readableStreamToText is needed due to https://github.com/oven-sh/bun/issues/14216
|
||||
const output = await Bun.readableStreamToText(await renderToHtml(rscPayload2));
|
||||
return rw.transform(
|
||||
new Response(output, {
|
||||
headers: {
|
||||
"Content-Type": "text/html; charset=utf8",
|
||||
},
|
||||
}),
|
||||
);
|
||||
}
|
||||
16
src/bake/bun-framework-rsc/ssr.tsx
Normal file
16
src/bake/bun-framework-rsc/ssr.tsx
Normal file
@@ -0,0 +1,16 @@
|
||||
// This file is loaded in the SSR graph, meaning the `react-server` condition is
|
||||
// no longer set. This means we can import client components, using `react-dom`
|
||||
// to perform SSR from the RSC payload.
|
||||
import { use } from "react";
|
||||
import { createFromReadableStream } from "react-server-dom-webpack/client.browser";
|
||||
import { renderToReadableStream } from "react-dom/server";
|
||||
import { clientManifest } from "bun:bake/server";
|
||||
|
||||
export function renderToHtml(rscPayload: ReadableStream): Promise<ReadableStream> {
|
||||
const promise = createFromReadableStream(rscPayload, {
|
||||
moduleMap: clientManifest,
|
||||
moduleLoading: { prefix: "" },
|
||||
});
|
||||
const Async = () => use(promise);
|
||||
return renderToReadableStream(<Async />);
|
||||
}
|
||||
@@ -9,10 +9,21 @@
|
||||
}
|
||||
|
||||
main {
|
||||
font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
|
||||
font-family:
|
||||
system-ui,
|
||||
-apple-system,
|
||||
BlinkMacSystemFont,
|
||||
"Segoe UI",
|
||||
Roboto,
|
||||
Oxygen,
|
||||
Ubuntu,
|
||||
Cantarell,
|
||||
"Open Sans",
|
||||
"Helvetica Neue",
|
||||
sans-serif;
|
||||
}
|
||||
|
||||
.error {
|
||||
padding: 1rem;
|
||||
background-color: rgba(255, 0, 0, 0.2);
|
||||
}
|
||||
background-color: rgba(255, 169, 169, 0.9);
|
||||
}
|
||||
@@ -4,7 +4,7 @@ import { css } from "../macros" with { type: "macro" };
|
||||
var root!: HTMLElement;
|
||||
var mount;
|
||||
|
||||
if (mode === "client") {
|
||||
if (side === "client") {
|
||||
mount = function mount() {
|
||||
const wrap = document.createElement("bun-hmr");
|
||||
wrap.setAttribute(
|
||||
@@ -26,5 +26,8 @@ if (mode === "client") {
|
||||
export function showErrorOverlay(e) {
|
||||
mount();
|
||||
console.error(e);
|
||||
root.innerHTML = `<div class='error'><h1>oh no, a client side error happened:</h1><pre><code>${e?.message ? `${e?.name ?? e?.constructor?.name ?? "Error"}: ${e.message}\n` : JSON.stringify(e)}${e?.message ? e?.stack : ""}</code></pre></div>`;
|
||||
root.innerHTML = `<div class='error'><h1>Client-side Runtime Error</h1><pre><code>${e?.message ? `${e?.name ?? e?.constructor?.name ?? "Error"}: ${e.message}\n` : JSON.stringify(e)}${e?.message ? e?.stack : ""}</code></pre><button class='dismiss'>x</button></div>`;
|
||||
root.querySelector(".dismiss")!.addEventListener("click", () => {
|
||||
root.innerHTML = "";
|
||||
});
|
||||
}
|
||||
35
src/bake/client/reader.ts
Normal file
35
src/bake/client/reader.ts
Normal file
@@ -0,0 +1,35 @@
|
||||
import { td } from "../text-decoder";
|
||||
|
||||
export class DataViewReader {
|
||||
view: DataView;
|
||||
cursor: number;
|
||||
|
||||
constructor(view: DataView, cursor: number = 0) {
|
||||
this.view = view;
|
||||
this.cursor = cursor;
|
||||
}
|
||||
|
||||
u32() {
|
||||
const value = this.view.getUint32(this.cursor, true);
|
||||
this.cursor += 4;
|
||||
return value;
|
||||
}
|
||||
|
||||
u16() {
|
||||
const value = this.view.getUint16(this.cursor, true);
|
||||
this.cursor += 2;
|
||||
return value;
|
||||
}
|
||||
|
||||
u8() {
|
||||
const value = this.view.getUint8(this.cursor);
|
||||
this.cursor += 1;
|
||||
return value;
|
||||
}
|
||||
|
||||
string(byteLength: number) {
|
||||
const str = td.decode(this.view.buffer.slice(this.cursor, this.cursor + byteLength));
|
||||
this.cursor += byteLength;
|
||||
return str;
|
||||
}
|
||||
}
|
||||
6
src/bake/client/route.ts
Normal file
6
src/bake/client/route.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
export function routeMatch(routeId: number, routePattern: string) {
|
||||
console.log(`routeMatch(${routeId}, ${routePattern})`);
|
||||
// TODO: pattern parsing
|
||||
// TODO: use routeId to cache the current route to avoid reparsing text we dont care about
|
||||
return routePattern === location.pathname;
|
||||
}
|
||||
15
src/bake/error.template.html
Normal file
15
src/bake/error.template.html
Normal file
@@ -0,0 +1,15 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>{[page_title]s}</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<script id="bun_error_payload" type="text/bun-error-payload">
|
||||
{[error_payload]s}
|
||||
</script>
|
||||
<script src="/_bun/error.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
173
src/bake/hmr-module.ts
Normal file
173
src/bake/hmr-module.ts
Normal file
@@ -0,0 +1,173 @@
|
||||
import * as runtimeHelpers from "../runtime.bun.js";
|
||||
|
||||
let refreshRuntime: any;
|
||||
const registry = new Map<Id, HotModule>();
|
||||
|
||||
export type ModuleLoadFunction = (module: HotModule) => void;
|
||||
export type ExportsCallbackFunction = (new_exports: any) => void;
|
||||
|
||||
export const enum State {
|
||||
Loading,
|
||||
Boundary,
|
||||
Error,
|
||||
}
|
||||
|
||||
export const enum LoadModuleType {
|
||||
AssertPresent,
|
||||
UserDynamic,
|
||||
}
|
||||
|
||||
/**
|
||||
* This object is passed as the CommonJS "module", but has a bunch of
|
||||
* non-standard properties that are used for implementing hot-module
|
||||
* reloading. It is unacceptable to depend on these properties, and
|
||||
* it will not be considered a breaking change.
|
||||
*/
|
||||
export class HotModule<E = any> {
|
||||
id: Id;
|
||||
exports: E = {} as E;
|
||||
|
||||
_state = State.Loading;
|
||||
_ext_exports = undefined;
|
||||
__esModule = false;
|
||||
_import_meta: ImportMeta | undefined = undefined;
|
||||
_cached_failure: any = undefined;
|
||||
// modules that import THIS module
|
||||
_deps: Map<HotModule, ExportsCallbackFunction | undefined> = new Map();
|
||||
|
||||
constructor(id: Id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
require(id: Id, onReload?: ExportsCallbackFunction) {
|
||||
const mod = loadModule(id, LoadModuleType.UserDynamic);
|
||||
mod._deps.set(this, onReload);
|
||||
return mod.exports;
|
||||
}
|
||||
|
||||
importSync(id: Id, onReload?: ExportsCallbackFunction) {
|
||||
const mod = loadModule(id, LoadModuleType.AssertPresent);
|
||||
// insert into the map if not present
|
||||
mod._deps.set(this, onReload);
|
||||
const { exports, __esModule } = mod;
|
||||
return __esModule ? exports : (mod._ext_exports ??= { ...exports, default: exports });
|
||||
}
|
||||
|
||||
async dynamicImport(specifier: string, opts?: ImportCallOptions) {
|
||||
const mod = loadModule(specifier, LoadModuleType.UserDynamic);
|
||||
// insert into the map if not present
|
||||
mod._deps.set(this, mod._deps.get(this));
|
||||
const { exports, __esModule } = mod;
|
||||
return __esModule ? exports : (mod._ext_exports ??= { ...exports, default: exports });
|
||||
}
|
||||
|
||||
importMeta() {
|
||||
return (this._import_meta ??= initImportMeta(this));
|
||||
}
|
||||
|
||||
/** Server-only */
|
||||
declare importBuiltin: (id: string) => any;
|
||||
}
|
||||
|
||||
if (side === "server") {
|
||||
HotModule.prototype.importBuiltin = function (id: string) {
|
||||
return import.meta.require(id);
|
||||
};
|
||||
}
|
||||
|
||||
function initImportMeta(m: HotModule): ImportMeta {
|
||||
throw new Error("TODO: import meta object");
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a module by ID. Use `type` to specify if the module is supposed to be
|
||||
* present, or is something a user is able to dynamically specify.
|
||||
*/
|
||||
export function loadModule<T = any>(key: Id, type: LoadModuleType): HotModule<T> {
|
||||
let module = registry.get(key);
|
||||
if (module) {
|
||||
// Preserve failures until they are re-saved.
|
||||
if (module._state == State.Error) throw module._cached_failure;
|
||||
|
||||
return module;
|
||||
}
|
||||
module = new HotModule(key);
|
||||
const load = input_graph[key];
|
||||
if (!load) {
|
||||
if (type == LoadModuleType.AssertPresent) {
|
||||
throw new Error(
|
||||
`Failed to load bundled module '${key}'. This is not a dynamic import, and therefore is a bug in Bun Kit's bundler.`,
|
||||
);
|
||||
} else {
|
||||
throw new Error(
|
||||
`Failed to resolve dynamic import '${key}'. In Bun Kit, all imports must be statically known at compile time so that the bundler can trace everything.`,
|
||||
);
|
||||
}
|
||||
}
|
||||
try {
|
||||
registry.set(key, module);
|
||||
load(module);
|
||||
} catch (err) {
|
||||
module._cached_failure = err;
|
||||
module._state = State.Error;
|
||||
throw err;
|
||||
}
|
||||
return module;
|
||||
}
|
||||
|
||||
export function replaceModule(key: Id, load: ModuleLoadFunction) {
|
||||
const module = registry.get(key);
|
||||
if (module) {
|
||||
module.exports = {};
|
||||
load(module);
|
||||
const { exports } = module;
|
||||
for (const updater of module._deps.values()) {
|
||||
updater?.(exports);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function replaceModules(modules: any) {
|
||||
for (const k in modules) {
|
||||
input_graph[k] = modules[k];
|
||||
}
|
||||
for (const k in modules) {
|
||||
try {
|
||||
replaceModule(k, modules[k]);
|
||||
} catch (err) {
|
||||
// TODO: overlay for client
|
||||
console.error(err);
|
||||
}
|
||||
}
|
||||
if (side === "client" && refreshRuntime) {
|
||||
refreshRuntime.performReactRefresh(window);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
const runtime = new HotModule("bun:wrap");
|
||||
runtime.exports = runtimeHelpers;
|
||||
runtime.__esModule = true;
|
||||
registry.set("bun:wrap", runtime);
|
||||
}
|
||||
|
||||
if (side === "client") {
|
||||
const { refresh } = config;
|
||||
if (refresh) {
|
||||
refreshRuntime = loadModule(refresh, LoadModuleType.AssertPresent).exports;
|
||||
refreshRuntime.injectIntoGlobalHook(window);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Remove this after `react-server-dom-bun` is uploaded
|
||||
globalThis.__webpack_require__ = (id: string) => {
|
||||
if (side == "server" && config.separateSSRGraph && !id.startsWith("ssr:")) {
|
||||
return loadModule("ssr:" + id, LoadModuleType.UserDynamic).exports;
|
||||
} else {
|
||||
return loadModule(id, LoadModuleType.UserDynamic).exports;
|
||||
}
|
||||
};
|
||||
|
||||
runtimeHelpers.__name(HotModule.prototype.importSync, "<HMR runtime> importSync");
|
||||
runtimeHelpers.__name(HotModule.prototype.require, "<HMR runtime> require");
|
||||
runtimeHelpers.__name(loadModule, "<HMR runtime> loadModule");
|
||||
66
src/bake/hmr-protocol.md
Normal file
66
src/bake/hmr-protocol.md
Normal file
@@ -0,0 +1,66 @@
|
||||
# Kit's WebSocket Protocol
|
||||
|
||||
This format is only intended for communication for the browser build of
|
||||
`hmr-runtime.ts` <-> `DevServer.zig`. Server-side HMR is implemented using a
|
||||
different interface. This document is aimed for contributors to these
|
||||
two components; Any other use-case is unsupported.
|
||||
|
||||
Every message is to use `.binary`/`ArrayBuffer` transport mode. The first byte
|
||||
indicates a Message ID, with the length being inferred by the payload size.
|
||||
|
||||
All integers are in little-endian
|
||||
|
||||
## Client->Server messages
|
||||
|
||||
### `v`
|
||||
|
||||
Subscribe to visualizer packets (`v`)
|
||||
|
||||
## Server->Client messages
|
||||
|
||||
### `V`
|
||||
|
||||
Version payload. Sent on connection startup. The client should issue a hard-reload
|
||||
when it does not match the embedded version.
|
||||
|
||||
Example:
|
||||
|
||||
```
|
||||
V1.1.30-canary.37+117e1b388
|
||||
```
|
||||
|
||||
### `(`
|
||||
|
||||
Hot-module-reloading patch. The entire payload is UTF-8 Encoded JavaScript Payload.
|
||||
|
||||
### `R`
|
||||
|
||||
Server-side code has reloaded. Client should either refetch the route or perform a hard reload.
|
||||
|
||||
- `u32` Number of updated routes
|
||||
- For each route:
|
||||
- `u32` Route ID
|
||||
- `u16` Length of route name.
|
||||
- `[n]u8` Route name in UTF-8 encoded text.
|
||||
|
||||
### `v`
|
||||
|
||||
Payload for `incremental_visualizer.html`. This can be accessed via `/_bun/incremental_visualizer`.
|
||||
|
||||
- `u32`: Number of files in client graph
|
||||
- For each file in client graph
|
||||
- `u32`: Length of name. If zero then no other fields are provided.
|
||||
- `[n]u8`: File path in UTF-8 encoded text
|
||||
- `u8`: If file is stale, set 1
|
||||
- `u8`: If file is in server graph, set 1
|
||||
- `u8`: If file is in ssr graph, set 1
|
||||
- `u8`: If file is a server-side route root, set 1
|
||||
- `u8`: If file is a server-side component boundary file, set 1
|
||||
- `u32`: Number of files in the server graph
|
||||
- For each file in server graph, repeat the same parser for the clienr graph
|
||||
- `u32`: Number of client edges. For each,
|
||||
- `u32`: File index of the dependency file
|
||||
- `u32`: File index of the imported file
|
||||
- `u32`: Number of server edges. For each,
|
||||
- `u32`: File index of the dependency file
|
||||
- `u32`: File index of the imported file
|
||||
116
src/bake/hmr-runtime-client.ts
Normal file
116
src/bake/hmr-runtime-client.ts
Normal file
@@ -0,0 +1,116 @@
|
||||
// This file is the entrypoint to the hot-module-reloading runtime
|
||||
// In the browser, this uses a WebSocket to communicate with the bundler.
|
||||
import { loadModule, LoadModuleType, replaceModules } from "./hmr-module";
|
||||
import { showErrorOverlay } from "./client/overlay";
|
||||
import { Bake } from "bun";
|
||||
import { int } from "./macros" with { type: "macro" };
|
||||
import { td } from "./text-decoder";
|
||||
import { DataViewReader } from "./client/reader";
|
||||
import { routeMatch } from "./client/route";
|
||||
|
||||
if (typeof IS_BUN_DEVELOPMENT !== "boolean") {
|
||||
throw new Error("DCE is configured incorrectly");
|
||||
}
|
||||
|
||||
async function performRouteReload() {
|
||||
console.info("[Bun] Server-side code changed, reloading!");
|
||||
if (onServerSideReload) {
|
||||
try {
|
||||
await onServerSideReload();
|
||||
return;
|
||||
} catch (err) {
|
||||
console.error("Failed to perform Server-side reload.");
|
||||
console.error(err);
|
||||
console.error("The page will hard-reload now.");
|
||||
if (IS_BUN_DEVELOPMENT) {
|
||||
return showErrorOverlay(err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback for when reloading fails or is not implemented by the framework is
|
||||
// to hard-reload.
|
||||
location.reload();
|
||||
}
|
||||
|
||||
try {
|
||||
const main = loadModule<Bake.ClientEntryPoint>(config.main, LoadModuleType.AssertPresent);
|
||||
|
||||
var { onServerSideReload, ...rest } = main.exports;
|
||||
if (Object.keys(rest).length > 0) {
|
||||
console.warn(
|
||||
`Framework client entry point (${config.main}) exported unknown properties, found: ${Object.keys(rest).join(", ")}`,
|
||||
);
|
||||
}
|
||||
|
||||
const enum SocketState {
|
||||
Connecting,
|
||||
Connected,
|
||||
}
|
||||
|
||||
let state = SocketState.Connecting;
|
||||
|
||||
function initHmrWebSocket() {
|
||||
const ws = new WebSocket("/_bun/hmr");
|
||||
ws.binaryType = "arraybuffer";
|
||||
ws.onopen = ev => {
|
||||
console.log("HMR socket open!");
|
||||
state = SocketState.Connected;
|
||||
};
|
||||
ws.onmessage = (ev: MessageEvent<string | ArrayBuffer>) => {
|
||||
const { data } = ev;
|
||||
if (typeof data === "string") return data;
|
||||
const view = new DataView(data);
|
||||
// See hmr-protocol.md
|
||||
switch (view.getUint8(0)) {
|
||||
case int("V"): {
|
||||
console.log("VERSION", data);
|
||||
break;
|
||||
}
|
||||
case int("("): {
|
||||
const code = td.decode(data);
|
||||
const modules = (0, eval)(code);
|
||||
replaceModules(modules);
|
||||
break;
|
||||
}
|
||||
case int("R"): {
|
||||
const reader = new DataViewReader(view, 1);
|
||||
let routeCount = reader.u32();
|
||||
|
||||
while (routeCount > 0) {
|
||||
routeCount -= 1;
|
||||
const routeId = reader.u32();
|
||||
const routePattern = reader.string(reader.u16());
|
||||
if (routeMatch(routeId, routePattern)) {
|
||||
performRouteReload();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
if (IS_BUN_DEVELOPMENT) {
|
||||
return showErrorOverlay(
|
||||
new Error("Unknown WebSocket Payload ID: " + String.fromCharCode(view.getUint8(0))),
|
||||
);
|
||||
}
|
||||
location.reload();
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
ws.onclose = ev => {
|
||||
// TODO: visual feedback in overlay.ts
|
||||
// TODO: reconnection
|
||||
};
|
||||
ws.onerror = ev => {
|
||||
console.error(ev);
|
||||
};
|
||||
}
|
||||
|
||||
initHmrWebSocket();
|
||||
} catch (e) {
|
||||
if (side !== "client") throw e;
|
||||
showErrorOverlay(e);
|
||||
}
|
||||
36
src/bake/hmr-runtime-server.ts
Normal file
36
src/bake/hmr-runtime-server.ts
Normal file
@@ -0,0 +1,36 @@
|
||||
// This file is the entrypoint to the hot-module-reloading runtime.
|
||||
// On the server, communication is facilitated using the default
|
||||
// export, which is assigned via `server_exports`.
|
||||
import type { Bake } from "bun";
|
||||
import { loadModule, LoadModuleType, replaceModules } from "./hmr-module";
|
||||
|
||||
if (typeof IS_BUN_DEVELOPMENT !== "boolean") {
|
||||
throw new Error("DCE is configured incorrectly");
|
||||
}
|
||||
|
||||
// Server Side
|
||||
server_exports = {
|
||||
async handleRequest(req, { clientEntryPoint }, requested_id) {
|
||||
const serverRenderer = loadModule<Bake.ServerEntryPoint>(config.main, LoadModuleType.AssertPresent).exports.default;
|
||||
|
||||
if (!serverRenderer) {
|
||||
throw new Error('Framework server entrypoint is missing a "default" export.');
|
||||
}
|
||||
if (typeof serverRenderer !== "function") {
|
||||
throw new Error('Framework server entrypoint\'s "default" export is not a function.');
|
||||
}
|
||||
|
||||
const response = await serverRenderer(req, loadModule(requested_id, LoadModuleType.AssertPresent).exports, {
|
||||
styles: [],
|
||||
scripts: [clientEntryPoint],
|
||||
});
|
||||
|
||||
if (!(response instanceof Response)) {
|
||||
throw new Error(`Server-side request handler was expected to return a Response object.`);
|
||||
}
|
||||
|
||||
// TODO: support streaming
|
||||
return await response.text();
|
||||
},
|
||||
registerUpdate: replaceModules,
|
||||
};
|
||||
326
src/bake/incremental_visualizer.html
Normal file
326
src/bake/incremental_visualizer.html
Normal file
@@ -0,0 +1,326 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>IncrementalGraph Visualization</title>
|
||||
<script type="text/javascript" src="https://unpkg.com/vis-network/standalone/umd/vis-network.min.js"></script>
|
||||
<style>
|
||||
html,
|
||||
body {
|
||||
background-color: #1e1e2e;
|
||||
color: #cdd6f4;
|
||||
font-family: sans-serif;
|
||||
}
|
||||
|
||||
#network {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
}
|
||||
|
||||
h1 {
|
||||
position: fixed;
|
||||
top: 1rem;
|
||||
left: 1rem;
|
||||
pointer-events: none;
|
||||
font-size: 1rem;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#stat {
|
||||
font-weight: normal;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1>IncrementalGraph Visualization <span id="stat"></span></h1>
|
||||
<div id="network"></div>
|
||||
|
||||
<script>
|
||||
const c = {
|
||||
// derived from mocha theme on https://catppuccin.com/palette
|
||||
red: '#f38ba8',
|
||||
green: '#a6e3a1',
|
||||
mauve: '#cba6f7',
|
||||
gray: '#7f849c',
|
||||
orange: '#fab387',
|
||||
sky: '#89dceb',
|
||||
blue: '#89b4fa',
|
||||
yellow: '#f9e2af',
|
||||
};
|
||||
const ws = new WebSocket(location.origin + "/_bun/hmr");
|
||||
|
||||
ws.binaryType = "arraybuffer"; // We are expecting binary data
|
||||
|
||||
ws.onopen = function () {
|
||||
ws.send(new Uint8Array([118])); // Send 'v' byte to initiate connection
|
||||
};
|
||||
|
||||
// Store nodes and edges
|
||||
let clientFiles = [];
|
||||
let serverFiles = [];
|
||||
let clientEdges = [];
|
||||
let serverEdges = [];
|
||||
let currentEdgeIds = new Set();
|
||||
let isFirst = true;
|
||||
|
||||
// When a message is received
|
||||
ws.onmessage = function (event) {
|
||||
const buffer = new Uint8Array(event.data);
|
||||
|
||||
// Only process messages starting with 'v' (ASCII code 118)
|
||||
if (buffer[0] !== 118) return;
|
||||
console.log('Got Event');
|
||||
|
||||
let offset = 1; // Skip the 'v' byte
|
||||
|
||||
// Parse client files
|
||||
const clientFileCount = readUint32(buffer, offset);
|
||||
offset += 4;
|
||||
|
||||
clientFiles = parseFiles(buffer, clientFileCount, offset);
|
||||
offset = clientFiles.offset;
|
||||
clientFiles = clientFiles.files;
|
||||
|
||||
// Parse server files
|
||||
const serverFileCount = readUint32(buffer, offset);
|
||||
offset += 4;
|
||||
|
||||
serverFiles = parseFiles(buffer, serverFileCount, offset);
|
||||
offset = serverFiles.offset;
|
||||
serverFiles = serverFiles.files;
|
||||
|
||||
// Parse client edges
|
||||
const clientEdgeCount = readUint32(buffer, offset);
|
||||
offset += 4;
|
||||
clientEdges = parseEdges(buffer, clientEdgeCount, offset);
|
||||
offset = clientEdges.offset;
|
||||
clientEdges = clientEdges.edges;
|
||||
|
||||
// Parse server edges
|
||||
const serverEdgeCount = readUint32(buffer, offset);
|
||||
offset += 4;
|
||||
serverEdges = parseEdges(buffer, serverEdgeCount, offset);
|
||||
offset = serverEdges.offset;
|
||||
serverEdges = serverEdges.edges;
|
||||
|
||||
// Update the graph visualization
|
||||
updateGraph();
|
||||
};
|
||||
|
||||
// Helper to read 4-byte unsigned int
|
||||
function readUint32(buffer, offset) {
|
||||
return buffer[offset] |
|
||||
(buffer[offset + 1] << 8) |
|
||||
(buffer[offset + 2] << 16) |
|
||||
(buffer[offset + 3] << 24);
|
||||
}
|
||||
|
||||
function basename(path) {
|
||||
return path.slice(path.lastIndexOf('/') + 1)
|
||||
}
|
||||
|
||||
// Parse the files from the buffer
|
||||
function parseFiles(buffer, count, offset) {
|
||||
const files = [];
|
||||
|
||||
for (let i = 0; i < count; i++) {
|
||||
const nameLength = readUint32(buffer, offset);
|
||||
offset += 4;
|
||||
|
||||
// If the name length is 0, it's a deleted file
|
||||
if (nameLength === 0) {
|
||||
files.push({ id: i, deleted: true });
|
||||
continue;
|
||||
}
|
||||
|
||||
const nameBytes = buffer.slice(offset, offset + nameLength);
|
||||
const name = new TextDecoder().decode(nameBytes);
|
||||
offset += nameLength;
|
||||
|
||||
const isStale = buffer[offset++] === 1;
|
||||
const isServer = buffer[offset++] === 1;
|
||||
const isSSR = buffer[offset++] === 1;
|
||||
const isRoute = buffer[offset++] === 1;
|
||||
const isFramework = buffer[offset++] === 1;
|
||||
const isBoundary = buffer[offset++] === 1;
|
||||
|
||||
files.push({
|
||||
id: i,
|
||||
name,
|
||||
isStale,
|
||||
isServer,
|
||||
isSSR,
|
||||
isRoute,
|
||||
isFramework,
|
||||
isBoundary
|
||||
});
|
||||
}
|
||||
|
||||
return { files, offset };
|
||||
}
|
||||
|
||||
// Parse the edges from the buffer
|
||||
function parseEdges(buffer, count, offset) {
|
||||
const edges = [];
|
||||
for (let i = 0; i < count; i++) {
|
||||
const from = readUint32(buffer, offset);
|
||||
offset += 4;
|
||||
const to = readUint32(buffer, offset);
|
||||
offset += 4;
|
||||
edges.push({ from, to });
|
||||
}
|
||||
return { edges, offset };
|
||||
}
|
||||
|
||||
// Initialize Vis.js network
|
||||
const nodes = new vis.DataSet();
|
||||
const edges = new vis.DataSet();
|
||||
|
||||
const container = document.getElementById("network");
|
||||
const data = { nodes, edges };
|
||||
const options = {};
|
||||
const network = new vis.Network(container, data, options);
|
||||
|
||||
// Helper function to add or update nodes in the graph
|
||||
function updateNode(id, file, group) {
|
||||
const label = basename(file.name);
|
||||
const color = file.name.includes('/node_modules/')
|
||||
? c.gray
|
||||
: file.isStale
|
||||
? c.red
|
||||
: file.isBoundary
|
||||
? c.orange
|
||||
: group === 'client'
|
||||
? c.mauve
|
||||
: file.isRoute
|
||||
? c.blue
|
||||
: file.isSSR ? file.isServer ? c.yellow : c.green : c.sky;
|
||||
const props = {
|
||||
id,
|
||||
label,
|
||||
shape: 'dot',
|
||||
color: color,
|
||||
borderWidth: file.isRoute ? 3 : 1,
|
||||
group,
|
||||
font: file.name.includes('/node_modules/')
|
||||
? '10px sans-serif #cdd6f488' : '20px sans-serif #cdd6f4',
|
||||
}
|
||||
if (nodes.get(id)) {
|
||||
nodes.update(props);
|
||||
} else {
|
||||
nodes.add(props);
|
||||
}
|
||||
}
|
||||
|
||||
// Helper function to remove a node by ID
|
||||
function removeNode(id) {
|
||||
nodes.remove({ id });
|
||||
}
|
||||
|
||||
// Helper function to add or update edges in the graph
|
||||
const edgeProps = { arrows: 'to' };
|
||||
function updateEdge(id, from, to, variant) {
|
||||
const prop = variant === 'normal'
|
||||
? { id, from, to, arrows: 'to' }
|
||||
: variant === 'client'
|
||||
? { id, from, to, arrows: 'to,from', color: '#ffffff99', width: 2, label: '[use client]' }
|
||||
: { id, from, to };
|
||||
if (edges.get(id)) {
|
||||
edges.update(prop);
|
||||
} else {
|
||||
edges.add(prop);
|
||||
}
|
||||
}
|
||||
|
||||
// Helper to remove all edges of a node
|
||||
function removeEdges(nodeId) {
|
||||
const edgesToRemove = edges.get({
|
||||
filter: (edge) => edge.from === nodeId || edge.to === nodeId,
|
||||
});
|
||||
edges.remove(edgesToRemove.map(e => e.id));
|
||||
}
|
||||
|
||||
// Function to update the entire graph when new data is received
|
||||
function updateGraph() {
|
||||
const newEdgeIds = new Set(); // Track new edges
|
||||
|
||||
const boundaries = new Map();
|
||||
|
||||
// Update server files
|
||||
serverFiles.forEach((file, index) => {
|
||||
const id = `S_${index}`;
|
||||
if (file.deleted) {
|
||||
removeNode(id);
|
||||
removeEdges(id);
|
||||
} else {
|
||||
updateNode(id, file, 'server');
|
||||
}
|
||||
|
||||
if (file.isBoundary) {
|
||||
boundaries.set(file.name, { server: index, client: -1 });
|
||||
}
|
||||
});
|
||||
|
||||
// Update client files
|
||||
clientFiles.forEach((file, index) => {
|
||||
const id = `C_${index}`;
|
||||
if (file.deleted) {
|
||||
removeNode(id);
|
||||
removeEdges(id);
|
||||
return;
|
||||
}
|
||||
updateNode(id, file, 'client');
|
||||
const b = boundaries.get(file.name);
|
||||
if (b) {
|
||||
b.client = index;
|
||||
}
|
||||
});
|
||||
|
||||
// Update client edges
|
||||
clientEdges.forEach((edge, index) => {
|
||||
const id = `C_edge_${index}`;
|
||||
updateEdge(id, `C_${edge.from}`, `C_${edge.to}`, 'normal');
|
||||
newEdgeIds.add(id); // Track this edge
|
||||
});
|
||||
|
||||
// Update server edges
|
||||
serverEdges.forEach((edge, index) => {
|
||||
const id = `S_edge_${index}`;
|
||||
updateEdge(id, `S_${edge.from}`, `S_${edge.to}`, 'normal');
|
||||
newEdgeIds.add(id); // Track this edge
|
||||
});
|
||||
|
||||
boundaries.forEach(({ server, client }) => {
|
||||
if (client === -1) return;
|
||||
const id = `S_edge_bound_${server}_${client}`;
|
||||
updateEdge(id, `S_${server}`, `C_${client}`, 'client');
|
||||
newEdgeIds.add(id); // Track this edge
|
||||
});
|
||||
|
||||
// Remove edges that are no longer present
|
||||
currentEdgeIds.forEach((id) => {
|
||||
if (!newEdgeIds.has(id)) {
|
||||
edges.remove(id);
|
||||
}
|
||||
});
|
||||
|
||||
// Update the currentEdgeIds set to the new one
|
||||
currentEdgeIds = newEdgeIds;
|
||||
|
||||
if (isFirst) {
|
||||
network.stabilize();
|
||||
isFirst = false;
|
||||
}
|
||||
|
||||
document.getElementById('stat').innerText = `(server: ${serverFiles.length} files, ${serverEdges.length} edges; client: ${clientFiles.length} files, ${clientEdges.length} edges; ${boundaries.size} boundaries)`;
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -9,3 +9,8 @@ export function css(file: string, is_development: boolean): string {
|
||||
}
|
||||
return contents;
|
||||
}
|
||||
|
||||
export function int(char: string): number {
|
||||
if (char.length !== 1) throw new Error("Must be one char long");
|
||||
return char.charCodeAt(0);
|
||||
}
|
||||
3
src/bake/package.json
Normal file
3
src/bake/package.json
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"sideEffects": false
|
||||
}
|
||||
1
src/bake/text-decoder.ts
Normal file
1
src/bake/text-decoder.ts
Normal file
@@ -0,0 +1 @@
|
||||
export const td = new TextDecoder();
|
||||
@@ -13,6 +13,9 @@
|
||||
"esModuleInterop": true,
|
||||
"skipLibCheck": true,
|
||||
"jsx": "react-jsx",
|
||||
"paths": {
|
||||
"bun-framework-rsc/*": ["./bun-framework-rsc/*"]
|
||||
}
|
||||
},
|
||||
"include": ["./hmr-runtime-types.d.ts", "*.ts"]
|
||||
}
|
||||
"include": ["**/*.ts", "**/*.tsx"]
|
||||
}
|
||||
62
src/bitflags.zig
Normal file
62
src/bitflags.zig
Normal file
@@ -0,0 +1,62 @@
|
||||
const std = @import("std");
|
||||
|
||||
pub fn Bitflags(comptime T: type) type {
|
||||
const tyinfo = @typeInfo(T);
|
||||
const IntType = tyinfo.Struct.backing_integer.?;
|
||||
|
||||
return struct {
|
||||
pub inline fn empty() T {
|
||||
return @bitCast(@as(IntType, 0));
|
||||
}
|
||||
|
||||
pub inline fn intersects(lhs: T, rhs: T) bool {
|
||||
return asBits(lhs) & asBits(rhs) != 0;
|
||||
}
|
||||
|
||||
pub inline fn fromName(comptime name: []const u8) T {
|
||||
var this: T = .{};
|
||||
@field(this, name) = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
pub inline fn fromNames(comptime names: []const []const u8) T {
|
||||
var this: T = .{};
|
||||
inline for (names) |name| {
|
||||
@field(this, name) = true;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
pub fn bitwiseOr(lhs: T, rhs: T) T {
|
||||
return @bitCast(@as(IntType, @bitCast(lhs)) | @as(IntType, @bitCast(rhs)));
|
||||
}
|
||||
|
||||
pub fn bitwiseAnd(lhs: T, rhs: T) T {
|
||||
return @bitCast(@as(IntType, asBits(lhs) & asBits(rhs)));
|
||||
}
|
||||
|
||||
pub inline fn insert(this: *T, other: T) void {
|
||||
this.* = bitwiseOr(this.*, other);
|
||||
}
|
||||
|
||||
pub fn contains(lhs: T, rhs: T) bool {
|
||||
return @as(IntType, @bitCast(lhs)) & @as(IntType, @bitCast(rhs)) != 0;
|
||||
}
|
||||
|
||||
pub inline fn asBits(this: T) IntType {
|
||||
return @as(IntType, @bitCast(this));
|
||||
}
|
||||
|
||||
pub fn isEmpty(this: T) bool {
|
||||
return asBits(this) == 0;
|
||||
}
|
||||
|
||||
pub fn eq(lhs: T, rhs: T) bool {
|
||||
return asBits(lhs) == asBits(rhs);
|
||||
}
|
||||
|
||||
pub fn neq(lhs: T, rhs: T) bool {
|
||||
return asBits(lhs) != asBits(rhs);
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -112,7 +112,7 @@ pub const BuildMessage = struct {
|
||||
_: *JSC.CallFrame,
|
||||
) JSC.JSValue {
|
||||
var object = JSC.JSValue.createEmptyObject(globalThis, 4);
|
||||
object.put(globalThis, ZigString.static("name"), ZigString.init("BuildMessage").toJS(globalThis));
|
||||
object.put(globalThis, ZigString.static("name"), bun.String.static("BuildMessage").toJS(globalThis));
|
||||
object.put(globalThis, ZigString.static("position"), this.getPosition(globalThis));
|
||||
object.put(globalThis, ZigString.static("message"), this.getMessage(globalThis));
|
||||
object.put(globalThis, ZigString.static("level"), this.getLevel(globalThis));
|
||||
|
||||
@@ -1138,13 +1138,18 @@ pub const Formatter = struct {
|
||||
.Symbol => .Symbol,
|
||||
.BooleanObject => .Boolean,
|
||||
.JSFunction => .Function,
|
||||
.JSWeakMap, JSValue.JSType.JSMap => .Map,
|
||||
.JSMapIterator => .MapIterator,
|
||||
.JSSetIterator => .SetIterator,
|
||||
.JSWeakSet, JSValue.JSType.JSSet => .Set,
|
||||
.WeakMap, JSValue.JSType.Map => .Map,
|
||||
.MapIterator => .MapIterator,
|
||||
.SetIterator => .SetIterator,
|
||||
.WeakSet, JSValue.JSType.Set => .Set,
|
||||
.JSDate => .JSON,
|
||||
.JSPromise => .Promise,
|
||||
|
||||
.WrapForValidIterator,
|
||||
.RegExpStringIterator,
|
||||
.JSArrayIterator,
|
||||
.Iterator,
|
||||
.IteratorHelper,
|
||||
.Object,
|
||||
.FinalObject,
|
||||
.ModuleNamespaceObject,
|
||||
@@ -1778,7 +1783,7 @@ pub const Formatter = struct {
|
||||
|
||||
writer.print(
|
||||
comptime Output.prettyFmt("<r><green>{s}<r><d>:<r> ", enable_ansi_colors),
|
||||
.{JSPrinter.formatJSONString(key.slice())},
|
||||
.{bun.fmt.formatJSONString(key.slice())},
|
||||
);
|
||||
}
|
||||
} else if (Environment.isDebug and is_private_symbol) {
|
||||
@@ -2433,7 +2438,7 @@ pub const Formatter = struct {
|
||||
this.quote_strings = true;
|
||||
defer this.quote_strings = prev_quote_strings;
|
||||
|
||||
const map_name = if (value.jsType() == .JSWeakMap) "WeakMap" else "Map";
|
||||
const map_name = if (value.jsType() == .WeakMap) "WeakMap" else "Map";
|
||||
|
||||
if (length == 0) {
|
||||
return writer.print("{s} {{}}", .{map_name});
|
||||
@@ -2541,7 +2546,7 @@ pub const Formatter = struct {
|
||||
this.writeIndent(Writer, writer_) catch {};
|
||||
}
|
||||
|
||||
const set_name = if (value.jsType() == .JSWeakSet) "WeakSet" else "Set";
|
||||
const set_name = if (value.jsType() == .WeakSet) "WeakSet" else "Set";
|
||||
|
||||
if (length == 0) {
|
||||
return writer.print("{s} {{}}", .{set_name});
|
||||
|
||||
@@ -142,7 +142,7 @@ pub const ResolveMessage = struct {
|
||||
_: *JSC.CallFrame,
|
||||
) JSC.JSValue {
|
||||
var object = JSC.JSValue.createEmptyObject(globalThis, 7);
|
||||
object.put(globalThis, ZigString.static("name"), ZigString.init("ResolveMessage").toJS(globalThis));
|
||||
object.put(globalThis, ZigString.static("name"), bun.String.static("ResolveMessage").toJS(globalThis));
|
||||
object.put(globalThis, ZigString.static("position"), this.getPosition(globalThis));
|
||||
object.put(globalThis, ZigString.static("message"), this.getMessage(globalThis));
|
||||
object.put(globalThis, ZigString.static("level"), this.getLevel(globalThis));
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
/// Version 4: TypeScript enums are properly handled + more constant folding
|
||||
/// Version 5: `require.main === module` no longer marks a module as CJS
|
||||
/// Version 6: `use strict` is preserved in CommonJS modules when at the top of the file
|
||||
const expected_version = 6;
|
||||
/// Version 7: Several bundler changes that are likely to impact the runtime as well.
|
||||
const expected_version = 7;
|
||||
|
||||
const bun = @import("root").bun;
|
||||
const std = @import("std");
|
||||
|
||||
@@ -42,6 +42,7 @@ pub const BunObject = struct {
|
||||
pub const shellEscape = toJSCallback(Bun.shellEscape);
|
||||
pub const createParsedShellScript = toJSCallback(bun.shell.ParsedShellScript.createParsedShellScript);
|
||||
pub const createShellInterpreter = toJSCallback(bun.shell.Interpreter.createShellInterpreter);
|
||||
pub const color = bun.css.CssColor.jsFunctionColor;
|
||||
// --- Callbacks ---
|
||||
|
||||
// --- Getters ---
|
||||
@@ -60,7 +61,6 @@ pub const BunObject = struct {
|
||||
pub const Glob = toJSGetter(Bun.getGlobConstructor);
|
||||
pub const Transpiler = toJSGetter(Bun.getTranspilerConstructor);
|
||||
pub const argv = toJSGetter(Bun.getArgv);
|
||||
pub const assetPrefix = toJSGetter(Bun.getAssetPrefix);
|
||||
pub const cwd = toJSGetter(Bun.getCWD);
|
||||
pub const enableANSIColors = toJSGetter(Bun.enableANSIColors);
|
||||
pub const hash = toJSGetter(Bun.getHashObject);
|
||||
@@ -120,7 +120,6 @@ pub const BunObject = struct {
|
||||
@export(BunObject.Glob, .{ .name = getterName("Glob") });
|
||||
@export(BunObject.Transpiler, .{ .name = getterName("Transpiler") });
|
||||
@export(BunObject.argv, .{ .name = getterName("argv") });
|
||||
@export(BunObject.assetPrefix, .{ .name = getterName("assetPrefix") });
|
||||
@export(BunObject.cwd, .{ .name = getterName("cwd") });
|
||||
@export(BunObject.enableANSIColors, .{ .name = getterName("enableANSIColors") });
|
||||
@export(BunObject.hash, .{ .name = getterName("hash") });
|
||||
@@ -136,12 +135,13 @@ pub const BunObject = struct {
|
||||
// --- Getters --
|
||||
|
||||
// -- Callbacks --
|
||||
@export(BunObject.createParsedShellScript, .{ .name = callbackName("createParsedShellScript") });
|
||||
@export(BunObject.createShellInterpreter, .{ .name = callbackName("createShellInterpreter") });
|
||||
@export(BunObject.allocUnsafe, .{ .name = callbackName("allocUnsafe") });
|
||||
@export(BunObject.braces, .{ .name = callbackName("braces") });
|
||||
@export(BunObject.build, .{ .name = callbackName("build") });
|
||||
@export(BunObject.color, .{ .name = callbackName("color") });
|
||||
@export(BunObject.connect, .{ .name = callbackName("connect") });
|
||||
@export(BunObject.createParsedShellScript, .{ .name = callbackName("createParsedShellScript") });
|
||||
@export(BunObject.createShellInterpreter, .{ .name = callbackName("createShellInterpreter") });
|
||||
@export(BunObject.deflateSync, .{ .name = callbackName("deflateSync") });
|
||||
@export(BunObject.file, .{ .name = callbackName("file") });
|
||||
@export(BunObject.gc, .{ .name = callbackName("gc") });
|
||||
@@ -152,7 +152,6 @@ pub const BunObject = struct {
|
||||
@export(BunObject.inflateSync, .{ .name = callbackName("inflateSync") });
|
||||
@export(BunObject.jest, .{ .name = callbackName("jest") });
|
||||
@export(BunObject.listen, .{ .name = callbackName("listen") });
|
||||
@export(BunObject.udpSocket, .{ .name = callbackName("udpSocket") });
|
||||
@export(BunObject.mmap, .{ .name = callbackName("mmap") });
|
||||
@export(BunObject.nanoseconds, .{ .name = callbackName("nanoseconds") });
|
||||
@export(BunObject.openInEditor, .{ .name = callbackName("openInEditor") });
|
||||
@@ -161,14 +160,15 @@ pub const BunObject = struct {
|
||||
@export(BunObject.resolveSync, .{ .name = callbackName("resolveSync") });
|
||||
@export(BunObject.serve, .{ .name = callbackName("serve") });
|
||||
@export(BunObject.sha, .{ .name = callbackName("sha") });
|
||||
@export(BunObject.shellEscape, .{ .name = callbackName("shellEscape") });
|
||||
@export(BunObject.shrink, .{ .name = callbackName("shrink") });
|
||||
@export(BunObject.sleepSync, .{ .name = callbackName("sleepSync") });
|
||||
@export(BunObject.spawn, .{ .name = callbackName("spawn") });
|
||||
@export(BunObject.spawnSync, .{ .name = callbackName("spawnSync") });
|
||||
@export(BunObject.stringWidth, .{ .name = callbackName("stringWidth") });
|
||||
@export(BunObject.udpSocket, .{ .name = callbackName("udpSocket") });
|
||||
@export(BunObject.which, .{ .name = callbackName("which") });
|
||||
@export(BunObject.write, .{ .name = callbackName("write") });
|
||||
@export(BunObject.stringWidth, .{ .name = callbackName("stringWidth") });
|
||||
@export(BunObject.shellEscape, .{ .name = callbackName("shellEscape") });
|
||||
// -- Callbacks --
|
||||
}
|
||||
};
|
||||
@@ -252,161 +252,13 @@ const zlib = @import("../../zlib.zig");
|
||||
const Which = @import("../../which.zig");
|
||||
const ErrorableString = JSC.ErrorableString;
|
||||
const is_bindgen = JSC.is_bindgen;
|
||||
const max_addressible_memory = std.math.maxInt(u56);
|
||||
const max_addressable_memory = std.math.maxInt(u56);
|
||||
const glob = @import("../../glob.zig");
|
||||
const Async = bun.Async;
|
||||
const SemverObject = @import("../../install/semver.zig").SemverObject;
|
||||
const Braces = @import("../../shell/braces.zig");
|
||||
const Shell = @import("../../shell/shell.zig");
|
||||
|
||||
threadlocal var css_imports_list_strings: [512]ZigString = undefined;
|
||||
threadlocal var css_imports_list: [512]Api.StringPointer = undefined;
|
||||
threadlocal var css_imports_list_tail: u16 = 0;
|
||||
threadlocal var css_imports_buf: std.ArrayList(u8) = undefined;
|
||||
threadlocal var css_imports_buf_loaded: bool = false;
|
||||
|
||||
threadlocal var routes_list_strings: [1024]ZigString = undefined;
|
||||
|
||||
pub fn onImportCSS(
|
||||
resolve_result: *const Resolver.Result,
|
||||
import_record: *ImportRecord,
|
||||
origin: URL,
|
||||
) void {
|
||||
if (!css_imports_buf_loaded) {
|
||||
css_imports_buf = std.ArrayList(u8).initCapacity(
|
||||
VirtualMachine.get().allocator,
|
||||
import_record.path.text.len,
|
||||
) catch unreachable;
|
||||
css_imports_buf_loaded = true;
|
||||
}
|
||||
|
||||
const writer = css_imports_buf.writer();
|
||||
const offset = css_imports_buf.items.len;
|
||||
css_imports_list[css_imports_list_tail] = .{
|
||||
.offset = @as(u32, @truncate(offset)),
|
||||
.length = 0,
|
||||
};
|
||||
getPublicPath(resolve_result.path_pair.primary.text, origin, @TypeOf(writer), writer);
|
||||
const length = css_imports_buf.items.len - offset;
|
||||
css_imports_list[css_imports_list_tail].length = @as(u32, @truncate(length));
|
||||
css_imports_list_tail += 1;
|
||||
}
|
||||
|
||||
pub fn flushCSSImports() void {
|
||||
if (css_imports_buf_loaded) {
|
||||
css_imports_buf.clearRetainingCapacity();
|
||||
css_imports_list_tail = 0;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn getCSSImports() []ZigString {
|
||||
const tail = css_imports_list_tail;
|
||||
for (0..tail) |i| {
|
||||
ZigString.fromStringPointer(css_imports_list[i], css_imports_buf.items, &css_imports_list_strings[i]);
|
||||
}
|
||||
return css_imports_list_strings[0..tail];
|
||||
}
|
||||
|
||||
const ShellTask = struct {
|
||||
arena: std.heap.Arena,
|
||||
script: std.ArrayList(u8),
|
||||
interpreter: Shell.InterpreterSync,
|
||||
|
||||
pub const AsyncShellTask = JSC.ConcurrentPromiseTask(ShellTask);
|
||||
};
|
||||
|
||||
pub fn shell(
|
||||
globalThis: *JSC.JSGlobalObject,
|
||||
callframe: *JSC.CallFrame,
|
||||
) JSC.JSValue {
|
||||
const Interpreter = @import("../../shell/interpreter.zig").Interpreter;
|
||||
|
||||
// var allocator = globalThis.bunVM().allocator;
|
||||
const allocator = getAllocator(globalThis);
|
||||
var arena = bun.ArenaAllocator.init(allocator);
|
||||
|
||||
const arguments_ = callframe.arguments(8);
|
||||
var arguments = JSC.Node.ArgumentsSlice.init(globalThis.bunVM(), arguments_.slice());
|
||||
const string_args = arguments.nextEat() orelse {
|
||||
globalThis.throw("shell: expected 2 arguments, got 0", .{});
|
||||
return .undefined;
|
||||
};
|
||||
|
||||
const template_args_js = arguments.nextEat() orelse {
|
||||
globalThis.throw("shell: expected 2 arguments, got 0", .{});
|
||||
return .undefined;
|
||||
};
|
||||
var template_args = template_args_js.arrayIterator(globalThis);
|
||||
var jsobjs = std.ArrayList(JSValue).init(arena.allocator());
|
||||
var script = std.ArrayList(u8).init(arena.allocator());
|
||||
|
||||
if (!(bun.shell.shellCmdFromJS(globalThis, string_args, &template_args, &jsobjs, &script) catch {
|
||||
if (!globalThis.hasException())
|
||||
globalThis.throwOutOfMemory();
|
||||
return JSValue.undefined;
|
||||
})) {
|
||||
return .undefined;
|
||||
}
|
||||
|
||||
if (globalThis.hasException()) {
|
||||
arena.deinit();
|
||||
return .undefined;
|
||||
}
|
||||
|
||||
const lex_result = brk: {
|
||||
if (bun.strings.isAllASCII(script.items[0..])) {
|
||||
var lexer = Shell.LexerAscii.new(arena.allocator(), script.items[0..]);
|
||||
lexer.lex() catch |err| {
|
||||
globalThis.throwError(err, "failed to lex shell");
|
||||
return JSValue.undefined;
|
||||
};
|
||||
break :brk lexer.get_result();
|
||||
}
|
||||
var lexer = Shell.LexerUnicode.new(arena.allocator(), script.items[0..]);
|
||||
lexer.lex() catch |err| {
|
||||
globalThis.throwError(err, "failed to lex shell");
|
||||
return JSValue.undefined;
|
||||
};
|
||||
break :brk lexer.get_result();
|
||||
};
|
||||
|
||||
var parser = Shell.Parser.new(arena.allocator(), lex_result, jsobjs.items[0..]) catch |err| {
|
||||
globalThis.throwError(err, "failed to create shell parser");
|
||||
return JSValue.undefined;
|
||||
};
|
||||
|
||||
const script_ast = parser.parse() catch |err| {
|
||||
globalThis.throwError(err, "failed to parse shell");
|
||||
return JSValue.undefined;
|
||||
};
|
||||
|
||||
const script_heap = arena.allocator().create(Shell.AST.Script) catch {
|
||||
globalThis.throwOutOfMemory();
|
||||
return JSValue.undefined;
|
||||
};
|
||||
|
||||
script_heap.* = script_ast;
|
||||
|
||||
const interpreter = Interpreter.init(
|
||||
globalThis,
|
||||
allocator,
|
||||
&arena,
|
||||
script_heap,
|
||||
jsobjs.items[0..],
|
||||
) catch {
|
||||
arena.deinit();
|
||||
return .false;
|
||||
};
|
||||
_ = interpreter; // autofix
|
||||
|
||||
// return interpreter;
|
||||
return .undefined;
|
||||
|
||||
// return interpreter.start(globalThis) catch {
|
||||
// return .false;
|
||||
// };
|
||||
}
|
||||
|
||||
pub fn shellEscape(
|
||||
globalThis: *JSC.JSGlobalObject,
|
||||
callframe: *JSC.CallFrame,
|
||||
@@ -477,11 +329,11 @@ pub fn braces(
|
||||
if (arguments.nextEat()) |opts_val| {
|
||||
if (opts_val.isObject()) {
|
||||
if (comptime bun.Environment.allow_assert) {
|
||||
if (opts_val.getOwnTruthy(globalThis, "tokenize")) |tokenize_val| {
|
||||
if (opts_val.getTruthy(globalThis, "tokenize")) |tokenize_val| {
|
||||
tokenize = if (tokenize_val.isBoolean()) tokenize_val.asBoolean() else false;
|
||||
}
|
||||
|
||||
if (opts_val.getOwnTruthy(globalThis, "parse")) |tokenize_val| {
|
||||
if (opts_val.getTruthy(globalThis, "parse")) |tokenize_val| {
|
||||
parse = if (tokenize_val.isBoolean()) tokenize_val.asBoolean() else false;
|
||||
}
|
||||
}
|
||||
@@ -609,11 +461,11 @@ pub fn which(
|
||||
|
||||
if (arguments.nextEat()) |arg| {
|
||||
if (!arg.isEmptyOrUndefinedOrNull() and arg.isObject()) {
|
||||
if (arg.getOwn(globalThis, "PATH")) |str_| {
|
||||
if (arg.get(globalThis, "PATH")) |str_| {
|
||||
path_str = str_.toSlice(globalThis, globalThis.bunVM().allocator);
|
||||
}
|
||||
|
||||
if (arg.getOwn(globalThis, "cwd")) |str_| {
|
||||
if (arg.get(globalThis, "cwd")) |str_| {
|
||||
cwd_str = str_.toSlice(globalThis, globalThis.bunVM().allocator);
|
||||
}
|
||||
}
|
||||
@@ -662,7 +514,7 @@ pub fn inspect(
|
||||
const arg1 = arguments[1];
|
||||
|
||||
if (arg1.isObject()) {
|
||||
if (arg1.getOwnTruthy(globalThis, "depth")) |opt| {
|
||||
if (arg1.getTruthy(globalThis, "depth")) |opt| {
|
||||
if (opt.isInt32()) {
|
||||
const arg = opt.toInt32();
|
||||
if (arg < 0) {
|
||||
@@ -900,13 +752,6 @@ pub fn getMain(
|
||||
return ZigString.init(vm.main).toJS(globalThis);
|
||||
}
|
||||
|
||||
pub fn getAssetPrefix(
|
||||
globalThis: *JSC.JSGlobalObject,
|
||||
_: *JSC.JSObject,
|
||||
) JSC.JSValue {
|
||||
return ZigString.init(VirtualMachine.get().bundler.options.routes.asset_prefix_path).toJS(globalThis);
|
||||
}
|
||||
|
||||
pub fn getArgv(
|
||||
globalThis: *JSC.JSGlobalObject,
|
||||
_: *JSC.JSObject,
|
||||
@@ -934,7 +779,7 @@ pub fn openInEditor(
|
||||
|
||||
if (arguments.nextEat()) |opts| {
|
||||
if (!opts.isUndefinedOrNull()) {
|
||||
if (opts.getOwnTruthy(globalThis, "editor")) |editor_val| {
|
||||
if (opts.getTruthy(globalThis, "editor")) |editor_val| {
|
||||
var sliced = editor_val.toSlice(globalThis, arguments.arena.allocator());
|
||||
const prev_name = edit.name;
|
||||
|
||||
@@ -954,11 +799,11 @@ pub fn openInEditor(
|
||||
}
|
||||
}
|
||||
|
||||
if (opts.getOwnTruthy(globalThis, "line")) |line_| {
|
||||
if (opts.getTruthy(globalThis, "line")) |line_| {
|
||||
line = line_.toSlice(globalThis, arguments.arena.allocator()).slice();
|
||||
}
|
||||
|
||||
if (opts.getOwnTruthy(globalThis, "column")) |column_| {
|
||||
if (opts.getTruthy(globalThis, "column")) |column_| {
|
||||
column = column_.toSlice(globalThis, arguments.arena.allocator()).slice();
|
||||
}
|
||||
}
|
||||
@@ -992,7 +837,7 @@ pub fn getPublicPath(to: string, origin: URL, comptime Writer: type, writer: Wri
|
||||
to,
|
||||
VirtualMachine.get().bundler.fs.top_level_dir,
|
||||
origin,
|
||||
VirtualMachine.get().bundler.options.routes.asset_prefix_path,
|
||||
"",
|
||||
comptime Writer,
|
||||
writer,
|
||||
.loose,
|
||||
@@ -1284,22 +1129,6 @@ export fn Bun__resolveSyncWithSource(
|
||||
};
|
||||
}
|
||||
|
||||
pub fn getPublicPathJS(globalObject: *JSC.JSGlobalObject, callframe: *JSC.CallFrame) JSC.JSValue {
|
||||
const arguments = callframe.arguments(1).slice();
|
||||
if (arguments.len < 1) {
|
||||
return bun.String.empty.toJS(globalObject);
|
||||
}
|
||||
var public_path_temp_str: bun.PathBuffer = undefined;
|
||||
|
||||
const to = arguments[0].toSlice(globalObject, bun.default_allocator);
|
||||
defer to.deinit();
|
||||
var stream = std.io.fixedBufferStream(&public_path_temp_str);
|
||||
var writer = stream.writer();
|
||||
getPublicPath(to.slice(), VirtualMachine.get().origin, @TypeOf(&writer), &writer);
|
||||
|
||||
return ZigString.init(stream.buffer[0..stream.pos]).toJS(globalObject);
|
||||
}
|
||||
|
||||
extern fn dump_zone_malloc_stats() void;
|
||||
|
||||
fn dump_mimalloc(globalObject: *JSC.JSGlobalObject, _: *JSC.CallFrame) JSC.JSValue {
|
||||
@@ -1361,6 +1190,58 @@ pub const Crypto = struct {
|
||||
const Hashers = @import("../../sha.zig");
|
||||
|
||||
const BoringSSL = bun.BoringSSL;
|
||||
pub const HMAC = struct {
|
||||
ctx: BoringSSL.HMAC_CTX,
|
||||
algorithm: EVP.Algorithm,
|
||||
|
||||
pub usingnamespace bun.New(@This());
|
||||
|
||||
pub fn init(algorithm: EVP.Algorithm, key: []const u8) ?*HMAC {
|
||||
var ctx: BoringSSL.HMAC_CTX = undefined;
|
||||
BoringSSL.HMAC_CTX_init(&ctx);
|
||||
if (BoringSSL.HMAC_Init_ex(&ctx, key.ptr, @intCast(key.len), algorithm.md(), null) != 1) {
|
||||
BoringSSL.HMAC_CTX_cleanup(&ctx);
|
||||
return null;
|
||||
}
|
||||
return HMAC.new(.{
|
||||
.ctx = ctx,
|
||||
.algorithm = algorithm,
|
||||
});
|
||||
}
|
||||
|
||||
pub fn update(this: *HMAC, data: []const u8) void {
|
||||
_ = BoringSSL.HMAC_Update(&this.ctx, data.ptr, data.len);
|
||||
}
|
||||
|
||||
pub fn size(this: *const HMAC) usize {
|
||||
return BoringSSL.HMAC_size(&this.ctx);
|
||||
}
|
||||
|
||||
pub fn copy(this: *HMAC) !*HMAC {
|
||||
var ctx: BoringSSL.HMAC_CTX = undefined;
|
||||
BoringSSL.HMAC_CTX_init(&ctx);
|
||||
if (BoringSSL.HMAC_CTX_copy(&ctx, &this.ctx) != 1) {
|
||||
BoringSSL.HMAC_CTX_cleanup(&ctx);
|
||||
return error.BoringSSLError;
|
||||
}
|
||||
return HMAC.new(.{
|
||||
.ctx = ctx,
|
||||
.algorithm = this.algorithm,
|
||||
});
|
||||
}
|
||||
|
||||
pub fn final(this: *HMAC, out: []u8) []u8 {
|
||||
var outlen: c_uint = undefined;
|
||||
_ = BoringSSL.HMAC_Final(&this.ctx, out.ptr, &outlen);
|
||||
return out[0..outlen];
|
||||
}
|
||||
|
||||
pub fn deinit(this: *HMAC) void {
|
||||
BoringSSL.HMAC_CTX_cleanup(&this.ctx);
|
||||
this.destroy();
|
||||
}
|
||||
};
|
||||
|
||||
pub const EVP = struct {
|
||||
ctx: BoringSSL.EVP_MD_CTX = undefined,
|
||||
md: *const BoringSSL.EVP_MD = undefined,
|
||||
@@ -1830,7 +1711,7 @@ pub const Crypto = struct {
|
||||
|
||||
pub fn fromJS(globalObject: *JSC.JSGlobalObject, value: JSC.JSValue) ?Value {
|
||||
if (value.isObject()) {
|
||||
if (value.getOwnTruthy(globalObject, "algorithm")) |algorithm_value| {
|
||||
if (value.getTruthy(globalObject, "algorithm")) |algorithm_value| {
|
||||
if (!algorithm_value.isString()) {
|
||||
globalObject.throwInvalidArgumentType("hash", "algorithm", "string");
|
||||
return null;
|
||||
@@ -1847,7 +1728,7 @@ pub const Crypto = struct {
|
||||
.bcrypt = PasswordObject.Algorithm.Value.bcrpyt_default,
|
||||
};
|
||||
|
||||
if (value.getOwnTruthy(globalObject, "cost")) |rounds_value| {
|
||||
if (value.getTruthy(globalObject, "cost")) |rounds_value| {
|
||||
if (!rounds_value.isNumber()) {
|
||||
globalObject.throwInvalidArgumentType("hash", "cost", "number");
|
||||
return null;
|
||||
@@ -1868,7 +1749,7 @@ pub const Crypto = struct {
|
||||
inline .argon2id, .argon2d, .argon2i => |tag| {
|
||||
var argon = Algorithm.Argon2Params{};
|
||||
|
||||
if (value.getOwnTruthy(globalObject, "timeCost")) |time_value| {
|
||||
if (value.getTruthy(globalObject, "timeCost")) |time_value| {
|
||||
if (!time_value.isNumber()) {
|
||||
globalObject.throwInvalidArgumentType("hash", "timeCost", "number");
|
||||
return null;
|
||||
@@ -1884,7 +1765,7 @@ pub const Crypto = struct {
|
||||
argon.time_cost = @as(u32, @intCast(time_cost));
|
||||
}
|
||||
|
||||
if (value.getOwnTruthy(globalObject, "memoryCost")) |memory_value| {
|
||||
if (value.getTruthy(globalObject, "memoryCost")) |memory_value| {
|
||||
if (!memory_value.isNumber()) {
|
||||
globalObject.throwInvalidArgumentType("hash", "memoryCost", "number");
|
||||
return null;
|
||||
@@ -2604,6 +2485,9 @@ pub const Crypto = struct {
|
||||
};
|
||||
|
||||
pub const CryptoHasher = union(enum) {
|
||||
// HMAC_CTX contains 3 EVP_CTX, so let's store it as a pointer.
|
||||
hmac: ?*HMAC,
|
||||
|
||||
evp: EVP,
|
||||
zig: CryptoHasherZig,
|
||||
|
||||
@@ -2615,12 +2499,20 @@ pub const Crypto = struct {
|
||||
pub const digest = JSC.wrapInstanceMethod(CryptoHasher, "digest_", false);
|
||||
pub const hash = JSC.wrapStaticMethod(CryptoHasher, "hash_", false);
|
||||
|
||||
fn throwHmacConsumed(globalThis: *JSC.JSGlobalObject) void {
|
||||
globalThis.throw("HMAC has been consumed and is no longer usable", .{});
|
||||
}
|
||||
|
||||
pub fn getByteLength(
|
||||
this: *CryptoHasher,
|
||||
_: *JSC.JSGlobalObject,
|
||||
globalThis: *JSC.JSGlobalObject,
|
||||
) JSC.JSValue {
|
||||
return JSC.JSValue.jsNumber(switch (this.*) {
|
||||
.evp => |*inner| inner.size(),
|
||||
.hmac => |inner| if (inner) |hmac| hmac.size() else {
|
||||
throwHmacConsumed(globalThis);
|
||||
return JSC.JSValue.zero;
|
||||
},
|
||||
.zig => |*inner| inner.digest_length,
|
||||
});
|
||||
}
|
||||
@@ -2630,7 +2522,11 @@ pub const Crypto = struct {
|
||||
globalObject: *JSC.JSGlobalObject,
|
||||
) JSC.JSValue {
|
||||
return switch (this.*) {
|
||||
inline else => |*inner| ZigString.fromUTF8(bun.asByteSlice(@tagName(inner.algorithm))).toJS(globalObject),
|
||||
inline .evp, .zig => |*inner| ZigString.fromUTF8(bun.asByteSlice(@tagName(inner.algorithm))).toJS(globalObject),
|
||||
.hmac => |inner| if (inner) |hmac| ZigString.fromUTF8(bun.asByteSlice(@tagName(hmac.algorithm))).toJS(globalObject) else {
|
||||
throwHmacConsumed(globalObject);
|
||||
return JSC.JSValue.zero;
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
@@ -2740,6 +2636,7 @@ pub const Crypto = struct {
|
||||
}
|
||||
}
|
||||
|
||||
// Bun.CryptoHasher(algorithm, hmacKey?: string | Buffer)
|
||||
pub fn constructor(globalThis: *JSC.JSGlobalObject, callframe: *JSC.CallFrame) ?*CryptoHasher {
|
||||
const arguments = callframe.arguments(2);
|
||||
if (arguments.len == 0) {
|
||||
@@ -2760,13 +2657,54 @@ pub const Crypto = struct {
|
||||
return null;
|
||||
}
|
||||
|
||||
var this: CryptoHasher = undefined;
|
||||
const evp = EVP.byName(algorithm, globalThis) orelse return CryptoHasherZig.constructor(algorithm) orelse {
|
||||
globalThis.throwInvalidArguments("Unsupported algorithm {any}", .{algorithm});
|
||||
return null;
|
||||
};
|
||||
this = .{ .evp = evp };
|
||||
return CryptoHasher.new(this);
|
||||
const hmac_value = arguments.ptr[1];
|
||||
var hmac_key: ?JSC.Node.StringOrBuffer = null;
|
||||
defer {
|
||||
if (hmac_key) |*key| {
|
||||
key.deinit();
|
||||
}
|
||||
}
|
||||
|
||||
if (!hmac_value.isEmptyOrUndefinedOrNull()) {
|
||||
hmac_key = JSC.Node.StringOrBuffer.fromJS(globalThis, bun.default_allocator, hmac_value) orelse {
|
||||
globalThis.throwInvalidArguments("key must be a string or buffer", .{});
|
||||
return null;
|
||||
};
|
||||
}
|
||||
|
||||
return CryptoHasher.new(brk: {
|
||||
if (hmac_key) |*key| {
|
||||
const chosen_algorithm = algorithm_name.toEnumFromMap(globalThis, "algorithm", EVP.Algorithm, EVP.Algorithm.map) catch return null;
|
||||
if (chosen_algorithm == .ripemd160) {
|
||||
// crashes at runtime.
|
||||
globalThis.throw("ripemd160 is not supported", .{});
|
||||
return null;
|
||||
}
|
||||
|
||||
break :brk .{
|
||||
.hmac = HMAC.init(chosen_algorithm, key.slice()) orelse {
|
||||
if (!globalThis.hasException()) {
|
||||
const err = BoringSSL.ERR_get_error();
|
||||
if (err != 0) {
|
||||
const instance = createCryptoError(globalThis, err);
|
||||
BoringSSL.ERR_clear_error();
|
||||
globalThis.throwValue(instance);
|
||||
} else {
|
||||
globalThis.throwTODO("HMAC is not supported for this algorithm");
|
||||
}
|
||||
}
|
||||
return null;
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
break :brk .{
|
||||
.evp = EVP.byName(algorithm, globalThis) orelse return CryptoHasherZig.constructor(algorithm) orelse {
|
||||
globalThis.throwInvalidArguments("Unsupported algorithm {any}", .{algorithm});
|
||||
return null;
|
||||
},
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
pub fn getter(
|
||||
@@ -2806,6 +2744,21 @@ pub const Crypto = struct {
|
||||
return .zero;
|
||||
}
|
||||
},
|
||||
.hmac => |inner| {
|
||||
const hmac = inner orelse {
|
||||
throwHmacConsumed(globalThis);
|
||||
return JSC.JSValue.zero;
|
||||
};
|
||||
|
||||
hmac.update(buffer.slice());
|
||||
const err = BoringSSL.ERR_get_error();
|
||||
if (err != 0) {
|
||||
const instance = createCryptoError(globalThis, err);
|
||||
BoringSSL.ERR_clear_error();
|
||||
globalThis.throwValue(instance);
|
||||
return .zero;
|
||||
}
|
||||
},
|
||||
.zig => |*inner| {
|
||||
inner.update(buffer.slice());
|
||||
return thisValue;
|
||||
@@ -2825,6 +2778,20 @@ pub const Crypto = struct {
|
||||
.evp => |*inner| {
|
||||
new = .{ .evp = inner.copy(globalObject.bunVM().rareData().boringEngine()) catch bun.outOfMemory() };
|
||||
},
|
||||
.hmac => |inner| {
|
||||
const hmac = inner orelse {
|
||||
throwHmacConsumed(globalObject);
|
||||
return JSC.JSValue.zero;
|
||||
};
|
||||
new = .{
|
||||
.hmac = hmac.copy() catch {
|
||||
const err = createCryptoError(globalObject, BoringSSL.ERR_get_error());
|
||||
BoringSSL.ERR_clear_error();
|
||||
globalObject.throwValue(err);
|
||||
return JSC.JSValue.zero;
|
||||
},
|
||||
};
|
||||
},
|
||||
.zig => |*inner| {
|
||||
new = .{ .zig = inner.copy() };
|
||||
},
|
||||
@@ -2875,6 +2842,9 @@ pub const Crypto = struct {
|
||||
}
|
||||
|
||||
const result = this.final(globalThis, output_digest_slice);
|
||||
if (globalThis.hasException()) {
|
||||
return JSC.JSValue.zero;
|
||||
}
|
||||
|
||||
if (output) |output_buf| {
|
||||
return output_buf.value;
|
||||
@@ -2888,11 +2858,23 @@ pub const Crypto = struct {
|
||||
var output_digest_buf: EVP.Digest = std.mem.zeroes(EVP.Digest);
|
||||
const output_digest_slice: []u8 = &output_digest_buf;
|
||||
const out = this.final(globalThis, output_digest_slice);
|
||||
if (globalThis.hasException()) {
|
||||
return JSC.JSValue.zero;
|
||||
}
|
||||
return encoding.encodeWithMaxSize(globalThis, BoringSSL.EVP_MAX_MD_SIZE, out);
|
||||
}
|
||||
|
||||
fn final(this: *CryptoHasher, globalThis: *JSGlobalObject, output_digest_slice: []u8) []u8 {
|
||||
return switch (this.*) {
|
||||
.hmac => |inner| brk: {
|
||||
const hmac: *HMAC = inner orelse {
|
||||
throwHmacConsumed(globalThis);
|
||||
return &.{};
|
||||
};
|
||||
this.hmac = null;
|
||||
defer hmac.deinit();
|
||||
break :brk hmac.final(output_digest_slice);
|
||||
},
|
||||
.evp => |*inner| inner.final(globalThis.bunVM().rareData().boringEngine(), output_digest_slice),
|
||||
.zig => |*inner| inner.final(output_digest_slice),
|
||||
};
|
||||
@@ -2907,6 +2889,11 @@ pub const Crypto = struct {
|
||||
.zig => |*inner| {
|
||||
inner.deinit();
|
||||
},
|
||||
.hmac => |inner| {
|
||||
if (inner) |hmac| {
|
||||
hmac.deinit();
|
||||
}
|
||||
},
|
||||
}
|
||||
this.destroy();
|
||||
}
|
||||
@@ -3448,7 +3435,7 @@ pub export fn Bun__escapeHTML16(globalObject: *JSC.JSGlobalObject, input_value:
|
||||
assert(len > 0);
|
||||
const input_slice = ptr[0..len];
|
||||
const escaped = strings.escapeHTMLForUTF16Input(globalObject.bunVM().allocator, input_slice) catch {
|
||||
globalObject.vm().throwError(globalObject, ZigString.init("Out of memory").toJS(globalObject));
|
||||
globalObject.vm().throwError(globalObject, bun.String.static("Out of memory").toJS(globalObject));
|
||||
return .undefined;
|
||||
};
|
||||
|
||||
@@ -3494,7 +3481,7 @@ pub export fn Bun__escapeHTML8(globalObject: *JSC.JSGlobalObject, input_value: J
|
||||
const allocator = if (input_slice.len <= 32) stack_allocator.get() else stack_allocator.fallback_allocator;
|
||||
|
||||
const escaped = strings.escapeHTMLForLatin1Input(allocator, input_slice) catch {
|
||||
globalObject.vm().throwError(globalObject, ZigString.init("Out of memory").toJS(globalObject));
|
||||
globalObject.vm().throwError(globalObject, bun.String.static("Out of memory").toJS(globalObject));
|
||||
return .undefined;
|
||||
};
|
||||
|
||||
@@ -4375,7 +4362,7 @@ pub const FFIObject = struct {
|
||||
}
|
||||
}
|
||||
|
||||
if (addr > max_addressible_memory) {
|
||||
if (addr > max_addressable_memory) {
|
||||
return JSC.toInvalidArguments("Pointer is outside max addressible memory, which usually means a bug in your program.", .{}, globalThis);
|
||||
}
|
||||
|
||||
@@ -4457,7 +4444,7 @@ pub const FFIObject = struct {
|
||||
return .{ .err = JSC.toInvalidArguments("length must be > 0. This usually means a bug in your code.", .{}, globalThis) };
|
||||
}
|
||||
|
||||
if (length_i > max_addressible_memory) {
|
||||
if (length_i > max_addressable_memory) {
|
||||
return .{ .err = JSC.toInvalidArguments("length exceeds max addressable memory. This usually means a bug in your code.", .{}, globalThis) };
|
||||
}
|
||||
|
||||
@@ -4612,11 +4599,11 @@ fn stringWidth(globalObject: *JSC.JSGlobalObject, callframe: *JSC.CallFrame) JSC
|
||||
var ambiguous_as_wide = false;
|
||||
|
||||
if (options_object.isObject()) {
|
||||
if (options_object.getOwnTruthy(globalObject, "countAnsiEscapeCodes")) |count_ansi_escapes_value| {
|
||||
if (options_object.getTruthy(globalObject, "countAnsiEscapeCodes")) |count_ansi_escapes_value| {
|
||||
if (count_ansi_escapes_value.isBoolean())
|
||||
count_ansi_escapes = count_ansi_escapes_value.toBoolean();
|
||||
}
|
||||
if (options_object.getOwnTruthy(globalObject, "ambiguousIsNarrow")) |ambiguous_is_narrow| {
|
||||
if (options_object.getTruthy(globalObject, "ambiguousIsNarrow")) |ambiguous_is_narrow| {
|
||||
if (ambiguous_is_narrow.isBoolean())
|
||||
ambiguous_as_wide = !ambiguous_is_narrow.toBoolean();
|
||||
}
|
||||
@@ -4797,7 +4784,7 @@ pub const JSZlib = struct {
|
||||
library = .zlib;
|
||||
}
|
||||
|
||||
if (options_val.getOwnTruthy(globalThis, "library")) |library_value| {
|
||||
if (options_val.getTruthy(globalThis, "library")) |library_value| {
|
||||
if (!library_value.isString()) {
|
||||
globalThis.throwInvalidArguments("Expected library to be a string", .{});
|
||||
return .zero;
|
||||
@@ -4924,7 +4911,7 @@ pub const JSZlib = struct {
|
||||
library = .zlib;
|
||||
}
|
||||
|
||||
if (options_val.getOwnTruthy(globalThis, "library")) |library_value| {
|
||||
if (options_val.getTruthy(globalThis, "library")) |library_value| {
|
||||
if (!library_value.isString()) {
|
||||
globalThis.throwInvalidArguments("Expected library to be a string", .{});
|
||||
return .zero;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user